-
Notifications
You must be signed in to change notification settings - Fork 721
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RPC-signer configuration #3725
base: master
Are you sure you want to change the base?
RPC-signer configuration #3725
Changes from all commits
3cad5e6
30834ff
3175c0d
9551683
8742f9e
df0e4ce
9801754
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,22 +4,30 @@ | |
package config | ||
|
||
import ( | ||
"context" | ||
"encoding/base64" | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
"net" | ||
"os" | ||
"path/filepath" | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/spf13/pflag" | ||
"github.com/spf13/viper" | ||
"github.com/stretchr/testify/require" | ||
"google.golang.org/grpc" | ||
|
||
"github.com/ava-labs/avalanchego/chains" | ||
"github.com/ava-labs/avalanchego/ids" | ||
"github.com/ava-labs/avalanchego/proto/pb/signer" | ||
"github.com/ava-labs/avalanchego/snow/consensus/snowball" | ||
"github.com/ava-labs/avalanchego/subnets" | ||
"github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" | ||
"github.com/ava-labs/avalanchego/utils/crypto/bls/signer/rpcsigner" | ||
"github.com/ava-labs/avalanchego/utils/perms" | ||
) | ||
|
||
const chainConfigFilenameExtention = ".ex" | ||
|
@@ -541,6 +549,108 @@ func TestGetSubnetConfigsFromFlags(t *testing.T) { | |
} | ||
} | ||
|
||
type signerServer struct { | ||
signer.UnimplementedSignerServer | ||
} | ||
|
||
func (*signerServer) PublicKey(context.Context, *signer.PublicKeyRequest) (*signer.PublicKeyResponse, error) { | ||
// for tests to pass, this must be the base64 encoding of a 32 byte public key | ||
// but it does not need to be associated with any private key | ||
bytes, err := base64.StdEncoding.DecodeString("j8Ndzc1I6EYWYUWAdhcwpQ1I2xX/i4fdwgJIaxbHlf9yQKMT0jlReiiLYsydgaS1") | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &signer.PublicKeyResponse{ | ||
PublicKey: bytes, | ||
}, nil | ||
} | ||
|
||
func TestGetStakingSigner(t *testing.T) { | ||
testKey := "HLimS3vRibTMk9lZD4b+Z+GLuSBShvgbsu0WTLt2Kd4=" | ||
rpcServer := grpc.NewServer() | ||
defer rpcServer.GracefulStop() | ||
|
||
signer.RegisterSignerServer(rpcServer, &signerServer{}) | ||
|
||
listener, err := net.Listen("tcp", "[::1]:0") | ||
require.NoError(t, err) | ||
|
||
go func() { | ||
require.NoError(t, rpcServer.Serve(listener)) | ||
}() | ||
|
||
type config map[string]any | ||
|
||
tests := []struct { | ||
name string | ||
viperKeys string | ||
config config | ||
expectedSignerType reflect.Type | ||
expectedErr error | ||
}{ | ||
{ | ||
name: "default-signer", | ||
expectedSignerType: reflect.TypeOf(&localsigner.LocalSigner{}), | ||
}, | ||
{ | ||
name: "ephemeral-signer", | ||
config: config{StakingEphemeralSignerEnabledKey: true}, | ||
expectedSignerType: reflect.TypeOf(&localsigner.LocalSigner{}), | ||
}, | ||
{ | ||
name: "content-key", | ||
config: config{StakingSignerKeyContentKey: testKey}, | ||
expectedSignerType: reflect.TypeOf(&localsigner.LocalSigner{}), | ||
}, | ||
{ | ||
name: "file-key", | ||
config: config{ | ||
StakingSignerKeyPathKey: func() string { | ||
filePath := filepath.Join(t.TempDir(), "signer.key") | ||
bytes, err := base64.StdEncoding.DecodeString(testKey) | ||
require.NoError(t, err) | ||
require.NoError(t, os.WriteFile(filePath, bytes, perms.ReadWrite)) | ||
return filePath | ||
}(), | ||
}, | ||
expectedSignerType: reflect.TypeOf(&localsigner.LocalSigner{}), | ||
}, | ||
{ | ||
name: "rpc-signer", | ||
config: config{StakingRPCSignerKey: listener.Addr().String()}, | ||
expectedSignerType: reflect.TypeOf(&rpcsigner.Client{}), | ||
}, | ||
{ | ||
name: "multiple-configurations-set", | ||
config: config{ | ||
StakingEphemeralSignerEnabledKey: true, | ||
StakingSignerKeyContentKey: testKey, | ||
}, | ||
expectedErr: errInvalidSignerConfig, | ||
}, | ||
} | ||
|
||
// required for proper write permissions for the default signer-key location | ||
t.Setenv("HOME", t.TempDir()) | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
require := require.New(t) | ||
v := setupViperFlags() | ||
|
||
for key, value := range tt.config { | ||
v.Set(key, value) | ||
} | ||
|
||
signer, err := getStakingSigner(context.Background(), v) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we test this function instead of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't change There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is testing code not exported by the actual package though (i.e, |
||
|
||
require.ErrorIs(err, tt.expectedErr) | ||
require.Equal(tt.expectedSignerType, reflect.TypeOf(signer)) | ||
}) | ||
} | ||
} | ||
|
||
// setups config json file and writes content | ||
func setupConfigJSON(t *testing.T, rootPath string, value string) string { | ||
configFilePath := filepath.Join(rootPath, "config.json") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have a defer step to clean up stuff? Or is this overkill?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe
t.SetEnv
takes care of this for youThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI: