From 753e285fb6f0b43c4870f5c5ff2854604103bf0f Mon Sep 17 00:00:00 2001 From: james-prysm <90280386+james-prysm@users.noreply.github.com> Date: Wed, 8 Mar 2023 21:21:12 -0600 Subject: [PATCH] Prysm V4: Remove Prysm Remote Signer (#11895) * removing all prysm remote signer code * fixing unit tests * resolving more build issues * resolving deepsource complaint * fixing lint * trying to fix bazel library * trying testonly true * removing assert and require from non test settings * fixing bazel and tests * removing more unused files related to remote signer * fixing linting * reverting some changes * reverting a change that broke some code * removing typo * fixing unit test * fixing mnemonic information --- cmd/validator/flags/flags.go | 13 +- cmd/validator/wallet/BUILD.bazel | 5 +- cmd/validator/wallet/create.go | 8 - cmd/validator/wallet/create_test.go | 149 ++++--- cmd/validator/wallet/edit.go | 54 --- cmd/validator/wallet/edit_test.go | 164 ------- cmd/validator/wallet/wallet.go | 34 -- validator/accounts/BUILD.bazel | 7 - validator/accounts/accounts_list_test.go | 253 ++--------- validator/accounts/cli_manager.go | 2 - validator/accounts/cli_options.go | 9 - validator/accounts/userprompt/BUILD.bazel | 1 - validator/accounts/userprompt/prompt.go | 97 ---- validator/accounts/wallet/BUILD.bazel | 1 - validator/accounts/wallet/wallet.go | 20 +- validator/accounts/wallet_create.go | 22 - validator/accounts/wallet_edit.go | 21 - validator/client/BUILD.bazel | 3 - validator/client/runner.go | 23 +- validator/client/runner_test.go | 52 +-- validator/client/wait_for_activation.go | 78 +--- validator/client/wait_for_activation_test.go | 133 +----- validator/keymanager/BUILD.bazel | 1 - validator/keymanager/remote-utils/BUILD.bazel | 15 - validator/keymanager/remote-utils/format.go | 22 - .../keymanager/remote-web3signer/BUILD.bazel | 2 +- .../remote-web3signer/keymanager.go | 18 +- validator/keymanager/remote/BUILD.bazel | 52 --- validator/keymanager/remote/doc.go | 59 --- validator/keymanager/remote/keymanager.go | 314 ------------- .../keymanager/remote/keymanager_test.go | 414 ------------------ validator/keymanager/remote/log.go | 5 - validator/keymanager/remote/mock/BUILD.bazel | 21 - .../keymanager/remote/mock/mock_keymanager.go | 82 ---- validator/keymanager/types.go | 6 - validator/keymanager/types_test.go | 2 - validator/rpc/wallet.go | 4 - 37 files changed, 177 insertions(+), 1989 deletions(-) delete mode 100644 cmd/validator/wallet/edit.go delete mode 100644 cmd/validator/wallet/edit_test.go delete mode 100644 validator/accounts/wallet_edit.go delete mode 100644 validator/keymanager/remote-utils/BUILD.bazel delete mode 100644 validator/keymanager/remote-utils/format.go delete mode 100644 validator/keymanager/remote/BUILD.bazel delete mode 100644 validator/keymanager/remote/doc.go delete mode 100644 validator/keymanager/remote/keymanager.go delete mode 100644 validator/keymanager/remote/keymanager_test.go delete mode 100644 validator/keymanager/remote/log.go delete mode 100644 validator/keymanager/remote/mock/BUILD.bazel delete mode 100644 validator/keymanager/remote/mock/mock_keymanager.go diff --git a/cmd/validator/flags/flags.go b/cmd/validator/flags/flags.go index 308e523235..3cbe243a84 100644 --- a/cmd/validator/flags/flags.go +++ b/cmd/validator/flags/flags.go @@ -252,18 +252,7 @@ var ( Name: "keys-dir", Usage: "Path to a directory where keystores to be imported are stored", } - // GrpcRemoteAddressFlag defines the host:port address for a remote keymanager to connect to. - GrpcRemoteAddressFlag = &cli.StringFlag{ - Name: "grpc-remote-address", - Usage: "Host:port of a gRPC server for a remote keymanager", - Value: "", - } - // DisableRemoteSignerTlsFlag disables TLS when connecting to a remote signer. - DisableRemoteSignerTlsFlag = &cli.BoolFlag{ - Name: "disable-remote-signer-tls", - Usage: "Disables TLS when connecting to a remote signer. (WARNING! This will result in insecure requests!)", - Value: false, - } + // RemoteSignerCertPathFlag defines the path to a client.crt file for a wallet to connect to // a secure signer via TLS and gRPC. RemoteSignerCertPathFlag = &cli.StringFlag{ diff --git a/cmd/validator/wallet/BUILD.bazel b/cmd/validator/wallet/BUILD.bazel index b2daa08528..40ce0cd150 100644 --- a/cmd/validator/wallet/BUILD.bazel +++ b/cmd/validator/wallet/BUILD.bazel @@ -4,7 +4,6 @@ go_library( name = "go_default_library", srcs = [ "create.go", - "edit.go", "recover.go", "wallet.go", ], @@ -20,7 +19,6 @@ go_library( "//validator/accounts/userprompt:go_default_library", "//validator/accounts/wallet:go_default_library", "//validator/keymanager:go_default_library", - "//validator/keymanager/remote:go_default_library", "@com_github_manifoldco_promptui//:go_default_library", "@com_github_pkg_errors//:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", @@ -32,9 +30,9 @@ go_library( go_test( name = "go_default_test", + testonly = True, srcs = [ "create_test.go", - "edit_test.go", "recover_test.go", ], embed = [":go_default_library"], @@ -50,7 +48,6 @@ go_test( "//validator/keymanager:go_default_library", "//validator/keymanager/derived:go_default_library", "//validator/keymanager/local:go_default_library", - "//validator/keymanager/remote:go_default_library", "@com_github_pkg_errors//:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", "@com_github_sirupsen_logrus//hooks/test:go_default_library", diff --git a/cmd/validator/wallet/create.go b/cmd/validator/wallet/create.go index 949bb90d65..da54709a94 100644 --- a/cmd/validator/wallet/create.go +++ b/cmd/validator/wallet/create.go @@ -117,13 +117,6 @@ func ConstructCLIManagerOpts(cliCtx *cli.Context, keymanagerKind keymanager.Kind cliOpts = append(cliOpts, accounts.WithMnemonic25thWord(mnemonicPassphrase)) } } - if keymanagerKind == keymanager.Remote { - opts, err := userprompt.InputRemoteKeymanagerConfig(cliCtx) - if err != nil { - return []accounts.Option{}, errors.Wrap(err, "could not input remote keymanager config") - } - cliOpts = append(cliOpts, accounts.WithKeymanagerOpts(opts)) - } if keymanagerKind == keymanager.Web3Signer { return []accounts.Option{}, errors.New("web3signer keymanager does not require persistent wallets.") } @@ -139,7 +132,6 @@ func inputKeymanagerKind(cliCtx *cli.Context) (keymanager.Kind, error) { Items: []string{ wallet.KeymanagerKindSelections[keymanager.Local], wallet.KeymanagerKindSelections[keymanager.Derived], - wallet.KeymanagerKindSelections[keymanager.Remote], wallet.KeymanagerKindSelections[keymanager.Web3Signer], }, } diff --git a/cmd/validator/wallet/create_test.go b/cmd/validator/wallet/create_test.go index 20dddbeb30..9de0bd018f 100644 --- a/cmd/validator/wallet/create_test.go +++ b/cmd/validator/wallet/create_test.go @@ -1,26 +1,108 @@ package wallet import ( - "context" "flag" "io" + "os" + "path/filepath" + "strconv" "testing" "github.com/pkg/errors" cmdacc "github.com/prysmaticlabs/prysm/v3/cmd/validator/accounts" "github.com/prysmaticlabs/prysm/v3/cmd/validator/flags" + "github.com/prysmaticlabs/prysm/v3/config/params" "github.com/prysmaticlabs/prysm/v3/testing/assert" "github.com/prysmaticlabs/prysm/v3/testing/require" "github.com/prysmaticlabs/prysm/v3/validator/accounts" "github.com/prysmaticlabs/prysm/v3/validator/accounts/wallet" "github.com/prysmaticlabs/prysm/v3/validator/keymanager" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/local" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" "github.com/sirupsen/logrus" logTest "github.com/sirupsen/logrus/hooks/test" "github.com/urfave/cli/v2" ) +const ( + passwordFileName = "password.txt" + password = "OhWOWthisisatest42!$" +) + +// `cmd/validator/accounts/delete_test.go`. https://pastebin.com/2n2VB7Ez is +// the error I couldn't get around. +func setupWalletAndPasswordsDir(t testing.TB) (string, string, string) { + walletDir := filepath.Join(t.TempDir(), "wallet") + passwordsDir := filepath.Join(t.TempDir(), "passwords") + passwordFileDir := filepath.Join(t.TempDir(), "passwordFile") + require.NoError(t, os.MkdirAll(passwordFileDir, params.BeaconIoConfig().ReadWriteExecutePermissions)) + passwordFilePath := filepath.Join(passwordFileDir, passwordFileName) + require.NoError(t, os.WriteFile(passwordFilePath, []byte(password), os.ModePerm)) + return walletDir, passwordsDir, passwordFilePath +} + +type testWalletConfig struct { + exitAll bool + skipDepositConfirm bool + keymanagerKind keymanager.Kind + numAccounts int64 + grpcHeaders string + privateKeyFile string + accountPasswordFile string + walletPasswordFile string + backupPasswordFile string + backupPublicKeys string + voluntaryExitPublicKeys string + deletePublicKeys string + keysDir string + backupDir string + walletDir string + passwordsDir string +} + +func setupWalletCtx( + tb testing.TB, + cfg *testWalletConfig, +) *cli.Context { + app := cli.App{} + set := flag.NewFlagSet("test", 0) + set.String(flags.WalletDirFlag.Name, cfg.walletDir, "") + set.String(flags.KeysDirFlag.Name, cfg.keysDir, "") + set.String(flags.KeymanagerKindFlag.Name, cfg.keymanagerKind.String(), "") + set.String(flags.DeletePublicKeysFlag.Name, cfg.deletePublicKeys, "") + set.String(flags.VoluntaryExitPublicKeysFlag.Name, cfg.voluntaryExitPublicKeys, "") + set.String(flags.BackupDirFlag.Name, cfg.backupDir, "") + set.String(flags.BackupPasswordFile.Name, cfg.backupPasswordFile, "") + set.String(flags.BackupPublicKeysFlag.Name, cfg.backupPublicKeys, "") + set.String(flags.WalletPasswordFileFlag.Name, cfg.walletPasswordFile, "") + set.String(flags.AccountPasswordFileFlag.Name, cfg.accountPasswordFile, "") + set.Int64(flags.NumAccountsFlag.Name, cfg.numAccounts, "") + set.Bool(flags.SkipDepositConfirmationFlag.Name, cfg.skipDepositConfirm, "") + set.Bool(flags.SkipMnemonic25thWordCheckFlag.Name, true, "") + set.Bool(flags.ExitAllFlag.Name, cfg.exitAll, "") + set.String(flags.GrpcHeadersFlag.Name, cfg.grpcHeaders, "") + + if cfg.privateKeyFile != "" { + set.String(flags.ImportPrivateKeyFileFlag.Name, cfg.privateKeyFile, "") + assert.NoError(tb, set.Set(flags.ImportPrivateKeyFileFlag.Name, cfg.privateKeyFile)) + } + assert.NoError(tb, set.Set(flags.WalletDirFlag.Name, cfg.walletDir)) + assert.NoError(tb, set.Set(flags.SkipMnemonic25thWordCheckFlag.Name, "true")) + assert.NoError(tb, set.Set(flags.KeysDirFlag.Name, cfg.keysDir)) + assert.NoError(tb, set.Set(flags.KeymanagerKindFlag.Name, cfg.keymanagerKind.String())) + assert.NoError(tb, set.Set(flags.DeletePublicKeysFlag.Name, cfg.deletePublicKeys)) + assert.NoError(tb, set.Set(flags.VoluntaryExitPublicKeysFlag.Name, cfg.voluntaryExitPublicKeys)) + assert.NoError(tb, set.Set(flags.BackupDirFlag.Name, cfg.backupDir)) + assert.NoError(tb, set.Set(flags.BackupPublicKeysFlag.Name, cfg.backupPublicKeys)) + assert.NoError(tb, set.Set(flags.BackupPasswordFile.Name, cfg.backupPasswordFile)) + assert.NoError(tb, set.Set(flags.WalletPasswordFileFlag.Name, cfg.walletPasswordFile)) + assert.NoError(tb, set.Set(flags.AccountPasswordFileFlag.Name, cfg.accountPasswordFile)) + assert.NoError(tb, set.Set(flags.NumAccountsFlag.Name, strconv.Itoa(int(cfg.numAccounts)))) + assert.NoError(tb, set.Set(flags.SkipDepositConfirmationFlag.Name, strconv.FormatBool(cfg.skipDepositConfirm))) + assert.NoError(tb, set.Set(flags.ExitAllFlag.Name, strconv.FormatBool(cfg.exitAll))) + assert.NoError(tb, set.Set(flags.GrpcHeadersFlag.Name, cfg.grpcHeaders)) + return cli.NewContext(&app, set, nil) +} + func init() { logrus.SetLevel(logrus.DebugLevel) logrus.SetOutput(io.Discard) @@ -137,57 +219,6 @@ func TestCreateWallet_WalletAlreadyExists(t *testing.T) { require.ErrorContains(t, "already exists", err) } -func TestCreateWallet_Remote(t *testing.T) { - walletDir, _, walletPasswordFile := setupWalletAndPasswordsDir(t) - wantCfg := &remote.KeymanagerOpts{ - RemoteCertificate: &remote.CertificateConfig{ - RequireTls: true, - ClientCertPath: "/tmp/client.crt", - ClientKeyPath: "/tmp/client.key", - CACertPath: "/tmp/ca.crt", - }, - RemoteAddr: "host.example.com:4000", - } - app := cli.App{} - set := flag.NewFlagSet("test", 0) - keymanagerKind := "remote" - set.String(flags.WalletDirFlag.Name, walletDir, "") - set.String(flags.WalletPasswordFileFlag.Name, walletDir, "") - set.String(flags.KeymanagerKindFlag.Name, keymanagerKind, "") - set.String(flags.GrpcRemoteAddressFlag.Name, wantCfg.RemoteAddr, "") - set.String(flags.RemoteSignerCertPathFlag.Name, wantCfg.RemoteCertificate.ClientCertPath, "") - set.String(flags.RemoteSignerKeyPathFlag.Name, wantCfg.RemoteCertificate.ClientKeyPath, "") - set.String(flags.RemoteSignerCACertPathFlag.Name, wantCfg.RemoteCertificate.CACertPath, "") - assert.NoError(t, set.Set(flags.WalletDirFlag.Name, walletDir)) - assert.NoError(t, set.Set(flags.WalletPasswordFileFlag.Name, walletPasswordFile)) - assert.NoError(t, set.Set(flags.KeymanagerKindFlag.Name, keymanagerKind)) - assert.NoError(t, set.Set(flags.GrpcRemoteAddressFlag.Name, wantCfg.RemoteAddr)) - assert.NoError(t, set.Set(flags.RemoteSignerCertPathFlag.Name, wantCfg.RemoteCertificate.ClientCertPath)) - assert.NoError(t, set.Set(flags.RemoteSignerKeyPathFlag.Name, wantCfg.RemoteCertificate.ClientKeyPath)) - assert.NoError(t, set.Set(flags.RemoteSignerCACertPathFlag.Name, wantCfg.RemoteCertificate.CACertPath)) - cliCtx := cli.NewContext(&app, set, nil) - - // We attempt to create the wallet. - _, err := CreateAndSaveWalletCli(cliCtx) - require.NoError(t, err) - - // We attempt to open the newly created wallet. - ctx := context.Background() - w, err := wallet.OpenWallet(cliCtx.Context, &wallet.Config{ - WalletDir: walletDir, - }) - assert.NoError(t, err) - - // We read the keymanager config for the newly created wallet. - encoded, err := w.ReadKeymanagerConfigFromDisk(ctx) - assert.NoError(t, err) - cfg, err := remote.UnmarshalOptionsFile(encoded) - assert.NoError(t, err) - - // We assert the created configuration was as desired. - assert.DeepEqual(t, wantCfg, cfg) -} - func TestInputKeymanagerKind(t *testing.T) { tests := []struct { name string @@ -219,18 +250,6 @@ func TestInputKeymanagerKind(t *testing.T) { want: keymanager.Derived, wantErr: false, }, - { - name: "remote returns remote kind", - args: "remote", - want: keymanager.Remote, - wantErr: false, - }, - { - name: "REMOTE (capitalized) returns remote kind", - args: "REMOTE", - want: keymanager.Remote, - wantErr: false, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/cmd/validator/wallet/edit.go b/cmd/validator/wallet/edit.go deleted file mode 100644 index 69153f6bad..0000000000 --- a/cmd/validator/wallet/edit.go +++ /dev/null @@ -1,54 +0,0 @@ -package wallet - -import ( - "fmt" - - "github.com/pkg/errors" - "github.com/prysmaticlabs/prysm/v3/validator/accounts" - "github.com/prysmaticlabs/prysm/v3/validator/accounts/userprompt" - "github.com/prysmaticlabs/prysm/v3/validator/accounts/wallet" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" - "github.com/urfave/cli/v2" -) - -func remoteWalletEdit(c *cli.Context) error { - w, err := wallet.OpenWalletOrElseCli(c, func(cliCtx *cli.Context) (*wallet.Wallet, error) { - return nil, wallet.ErrNoWalletFound - }) - if err != nil { - return errors.Wrap(err, "could not open wallet") - } - if w.KeymanagerKind() != keymanager.Remote { - return errors.New( - fmt.Sprintf("Keymanager type: %s doesn't support configuration editing", - w.KeymanagerKind().String())) - } - - enc, err := w.ReadKeymanagerConfigFromDisk(c.Context) - if err != nil { - return errors.Wrap(err, "could not read config") - } - fileOpts, err := remote.UnmarshalOptionsFile(enc) - if err != nil { - return errors.Wrap(err, "could not unmarshal config") - } - log.Info("Current configuration") - // Prints the current configuration to stdout. - fmt.Println(fileOpts) - newCfg, err := userprompt.InputRemoteKeymanagerConfig(c) - if err != nil { - return errors.Wrap(err, "could not get keymanager config") - } - - opts := []accounts.Option{ - accounts.WithWallet(w), - accounts.WithKeymanagerOpts(newCfg), - } - - acc, err := accounts.NewCLIManager(opts...) - if err != nil { - return err - } - return acc.WalletEdit(c.Context) -} diff --git a/cmd/validator/wallet/edit_test.go b/cmd/validator/wallet/edit_test.go deleted file mode 100644 index f25af3c8ac..0000000000 --- a/cmd/validator/wallet/edit_test.go +++ /dev/null @@ -1,164 +0,0 @@ -package wallet - -import ( - "flag" - "os" - "path/filepath" - "strconv" - "testing" - - "github.com/prysmaticlabs/prysm/v3/cmd/validator/flags" - "github.com/prysmaticlabs/prysm/v3/config/params" - "github.com/prysmaticlabs/prysm/v3/testing/assert" - "github.com/prysmaticlabs/prysm/v3/testing/require" - "github.com/prysmaticlabs/prysm/v3/validator/accounts" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" - "github.com/urfave/cli/v2" -) - -const ( - passwordFileName = "password.txt" - password = "OhWOWthisisatest42!$" -) - -// TODO(mikeneuder): Figure out how to shared these functions with -// `cmd/validator/accounts/delete_test.go`. https://pastebin.com/2n2VB7Ez is -// the error I couldn't get around. -func setupWalletAndPasswordsDir(t testing.TB) (string, string, string) { - walletDir := filepath.Join(t.TempDir(), "wallet") - passwordsDir := filepath.Join(t.TempDir(), "passwords") - passwordFileDir := filepath.Join(t.TempDir(), "passwordFile") - require.NoError(t, os.MkdirAll(passwordFileDir, params.BeaconIoConfig().ReadWriteExecutePermissions)) - passwordFilePath := filepath.Join(passwordFileDir, passwordFileName) - require.NoError(t, os.WriteFile(passwordFilePath, []byte(password), os.ModePerm)) - return walletDir, passwordsDir, passwordFilePath -} - -type testWalletConfig struct { - exitAll bool - skipDepositConfirm bool - keymanagerKind keymanager.Kind - numAccounts int64 - grpcHeaders string - privateKeyFile string - accountPasswordFile string - walletPasswordFile string - backupPasswordFile string - backupPublicKeys string - voluntaryExitPublicKeys string - deletePublicKeys string - keysDir string - backupDir string - walletDir string - passwordsDir string - mnemonicLanguage string -} - -func setupWalletCtx( - tb testing.TB, - cfg *testWalletConfig, -) *cli.Context { - app := cli.App{} - set := flag.NewFlagSet("test", 0) - set.String(flags.WalletDirFlag.Name, cfg.walletDir, "") - set.String(flags.KeysDirFlag.Name, cfg.keysDir, "") - set.String(flags.KeymanagerKindFlag.Name, cfg.keymanagerKind.String(), "") - set.String(flags.DeletePublicKeysFlag.Name, cfg.deletePublicKeys, "") - set.String(flags.VoluntaryExitPublicKeysFlag.Name, cfg.voluntaryExitPublicKeys, "") - set.String(flags.BackupDirFlag.Name, cfg.backupDir, "") - set.String(flags.BackupPasswordFile.Name, cfg.backupPasswordFile, "") - set.String(flags.BackupPublicKeysFlag.Name, cfg.backupPublicKeys, "") - set.String(flags.WalletPasswordFileFlag.Name, cfg.walletPasswordFile, "") - set.String(flags.AccountPasswordFileFlag.Name, cfg.accountPasswordFile, "") - set.Int64(flags.NumAccountsFlag.Name, cfg.numAccounts, "") - set.Bool(flags.SkipDepositConfirmationFlag.Name, cfg.skipDepositConfirm, "") - set.Bool(flags.SkipMnemonic25thWordCheckFlag.Name, true, "") - set.Bool(flags.ExitAllFlag.Name, cfg.exitAll, "") - set.String(flags.GrpcHeadersFlag.Name, cfg.grpcHeaders, "") - - if cfg.privateKeyFile != "" { - set.String(flags.ImportPrivateKeyFileFlag.Name, cfg.privateKeyFile, "") - assert.NoError(tb, set.Set(flags.ImportPrivateKeyFileFlag.Name, cfg.privateKeyFile)) - } - assert.NoError(tb, set.Set(flags.WalletDirFlag.Name, cfg.walletDir)) - assert.NoError(tb, set.Set(flags.SkipMnemonic25thWordCheckFlag.Name, "true")) - assert.NoError(tb, set.Set(flags.KeysDirFlag.Name, cfg.keysDir)) - assert.NoError(tb, set.Set(flags.KeymanagerKindFlag.Name, cfg.keymanagerKind.String())) - assert.NoError(tb, set.Set(flags.DeletePublicKeysFlag.Name, cfg.deletePublicKeys)) - assert.NoError(tb, set.Set(flags.VoluntaryExitPublicKeysFlag.Name, cfg.voluntaryExitPublicKeys)) - assert.NoError(tb, set.Set(flags.BackupDirFlag.Name, cfg.backupDir)) - assert.NoError(tb, set.Set(flags.BackupPublicKeysFlag.Name, cfg.backupPublicKeys)) - assert.NoError(tb, set.Set(flags.BackupPasswordFile.Name, cfg.backupPasswordFile)) - assert.NoError(tb, set.Set(flags.WalletPasswordFileFlag.Name, cfg.walletPasswordFile)) - assert.NoError(tb, set.Set(flags.AccountPasswordFileFlag.Name, cfg.accountPasswordFile)) - assert.NoError(tb, set.Set(flags.NumAccountsFlag.Name, strconv.Itoa(int(cfg.numAccounts)))) - assert.NoError(tb, set.Set(flags.SkipDepositConfirmationFlag.Name, strconv.FormatBool(cfg.skipDepositConfirm))) - assert.NoError(tb, set.Set(flags.ExitAllFlag.Name, strconv.FormatBool(cfg.exitAll))) - assert.NoError(tb, set.Set(flags.GrpcHeadersFlag.Name, cfg.grpcHeaders)) - return cli.NewContext(&app, set, nil) -} - -func TestEditWalletConfiguration(t *testing.T) { - walletDir, _, passwordFile := setupWalletAndPasswordsDir(t) - cliCtx := setupWalletCtx(t, &testWalletConfig{ - walletDir: walletDir, - keymanagerKind: keymanager.Remote, - }) - opts := []accounts.Option{ - accounts.WithWalletDir(walletDir), - accounts.WithKeymanagerType(keymanager.Remote), - accounts.WithWalletPassword("Passwordz0320$"), - } - acc, err := accounts.NewCLIManager(opts...) - require.NoError(t, err) - w, err := acc.WalletCreate(cliCtx.Context) - require.NoError(t, err) - - originalCfg := &remote.KeymanagerOpts{ - RemoteCertificate: &remote.CertificateConfig{ - RequireTls: true, - ClientCertPath: "/tmp/a.crt", - ClientKeyPath: "/tmp/b.key", - CACertPath: "/tmp/c.crt", - }, - RemoteAddr: "my.server.com:4000", - } - encodedCfg, err := remote.MarshalOptionsFile(cliCtx.Context, originalCfg) - assert.NoError(t, err) - assert.NoError(t, w.WriteKeymanagerConfigToDisk(cliCtx.Context, encodedCfg)) - - wantCfg := &remote.KeymanagerOpts{ - RemoteCertificate: &remote.CertificateConfig{ - RequireTls: true, - ClientCertPath: "/tmp/client.crt", - ClientKeyPath: "/tmp/client.key", - CACertPath: "/tmp/ca.crt", - }, - RemoteAddr: "host.example.com:4000", - } - app := cli.App{} - set := flag.NewFlagSet("test", 0) - set.String(flags.WalletDirFlag.Name, walletDir, "") - set.String(flags.WalletPasswordFileFlag.Name, passwordFile, "") - set.String(flags.GrpcRemoteAddressFlag.Name, wantCfg.RemoteAddr, "") - set.String(flags.RemoteSignerCertPathFlag.Name, wantCfg.RemoteCertificate.ClientCertPath, "") - set.String(flags.RemoteSignerKeyPathFlag.Name, wantCfg.RemoteCertificate.ClientKeyPath, "") - set.String(flags.RemoteSignerCACertPathFlag.Name, wantCfg.RemoteCertificate.CACertPath, "") - assert.NoError(t, set.Set(flags.WalletDirFlag.Name, walletDir)) - assert.NoError(t, set.Set(flags.WalletPasswordFileFlag.Name, passwordFile)) - assert.NoError(t, set.Set(flags.GrpcRemoteAddressFlag.Name, wantCfg.RemoteAddr)) - assert.NoError(t, set.Set(flags.RemoteSignerCertPathFlag.Name, wantCfg.RemoteCertificate.ClientCertPath)) - assert.NoError(t, set.Set(flags.RemoteSignerKeyPathFlag.Name, wantCfg.RemoteCertificate.ClientKeyPath)) - assert.NoError(t, set.Set(flags.RemoteSignerCACertPathFlag.Name, wantCfg.RemoteCertificate.CACertPath)) - cliCtx = cli.NewContext(&app, set, nil) - - err = remoteWalletEdit(cliCtx) - require.NoError(t, err) - encoded, err := w.ReadKeymanagerConfigFromDisk(cliCtx.Context) - require.NoError(t, err) - - cfg, err := remote.UnmarshalOptionsFile(encoded) - assert.NoError(t, err) - assert.DeepEqual(t, wantCfg, cfg) -} diff --git a/cmd/validator/wallet/wallet.go b/cmd/validator/wallet/wallet.go index 5817a460b4..c7737aa9ba 100644 --- a/cmd/validator/wallet/wallet.go +++ b/cmd/validator/wallet/wallet.go @@ -24,8 +24,6 @@ var Commands = &cli.Command{ Flags: cmd.WrapFlags([]cli.Flag{ flags.WalletDirFlag, flags.KeymanagerKindFlag, - flags.GrpcRemoteAddressFlag, - flags.DisableRemoteSignerTlsFlag, flags.RemoteSignerCertPathFlag, flags.RemoteSignerKeyPathFlag, flags.RemoteSignerCACertPathFlag, @@ -53,38 +51,6 @@ var Commands = &cli.Command{ return nil }, }, - { - Name: "edit-config", - Usage: "edits a wallet configuration options, such as gRPC connection credentials and TLS certificates", - Flags: cmd.WrapFlags([]cli.Flag{ - flags.WalletDirFlag, - flags.WalletPasswordFileFlag, - flags.GrpcRemoteAddressFlag, - flags.DisableRemoteSignerTlsFlag, - flags.RemoteSignerCertPathFlag, - flags.RemoteSignerKeyPathFlag, - flags.RemoteSignerCACertPathFlag, - features.Mainnet, - features.PraterTestnet, - features.SepoliaTestnet, - cmd.AcceptTosFlag, - }), - Before: func(cliCtx *cli.Context) error { - if err := cmd.LoadFlagsFromConfig(cliCtx, cliCtx.Command.Flags); err != nil { - return err - } - if err := tos.VerifyTosAcceptedOrPrompt(cliCtx); err != nil { - return err - } - return features.ConfigureValidator(cliCtx) - }, - Action: func(cliCtx *cli.Context) error { - if err := remoteWalletEdit(cliCtx); err != nil { - log.WithError(err).Fatal("Could not edit wallet configuration") - } - return nil - }, - }, { Name: "recover", Usage: "uses a derived wallet seed recovery phase to recreate an existing HD wallet", diff --git a/validator/accounts/BUILD.bazel b/validator/accounts/BUILD.bazel index fe47345a90..0a4504c8c0 100644 --- a/validator/accounts/BUILD.bazel +++ b/validator/accounts/BUILD.bazel @@ -15,7 +15,6 @@ go_library( "doc.go", "log.go", "wallet_create.go", - "wallet_edit.go", "wallet_recover.go", ], importpath = "github.com/prysmaticlabs/prysm/v3/validator/accounts", @@ -47,7 +46,6 @@ go_library( "//validator/keymanager:go_default_library", "//validator/keymanager/derived:go_default_library", "//validator/keymanager/local:go_default_library", - "//validator/keymanager/remote:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", "@com_github_google_uuid//:go_default_library", "@com_github_logrusorgru_aurora//:go_default_library", @@ -73,7 +71,6 @@ go_test( data = glob(["testdata/**"]), embed = [":go_default_library"], deps = [ - "//async/event:go_default_library", "//cmd/validator/flags:go_default_library", "//config/fieldparams:go_default_library", "//config/params:go_default_library", @@ -82,17 +79,13 @@ go_test( "//encoding/bytesutil:go_default_library", "//proto/eth/service:go_default_library", "//proto/prysm/v1alpha1:go_default_library", - "//proto/prysm/v1alpha1/validator-client:go_default_library", "//testing/assert:go_default_library", "//testing/mock:go_default_library", "//testing/require:go_default_library", "//validator/accounts/iface:go_default_library", - "//validator/accounts/petnames:go_default_library", - "//validator/accounts/wallet:go_default_library", "//validator/keymanager:go_default_library", "//validator/keymanager/derived:go_default_library", "//validator/keymanager/local:go_default_library", - "//validator/keymanager/remote:go_default_library", "//validator/testing:go_default_library", "@com_github_golang_mock//gomock:go_default_library", "@com_github_google_uuid//:go_default_library", diff --git a/validator/accounts/accounts_list_test.go b/validator/accounts/accounts_list_test.go index be58a1e67c..bfb19ef427 100644 --- a/validator/accounts/accounts_list_test.go +++ b/validator/accounts/accounts_list_test.go @@ -1,7 +1,6 @@ package accounts import ( - "context" "flag" "fmt" "io" @@ -14,25 +13,17 @@ import ( "github.com/golang/mock/gomock" "github.com/google/uuid" - "github.com/prysmaticlabs/prysm/v3/async/event" "github.com/prysmaticlabs/prysm/v3/cmd/validator/flags" - fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams" "github.com/prysmaticlabs/prysm/v3/config/params" - "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" + types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v3/crypto/bls" - "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" - ethpbservice "github.com/prysmaticlabs/prysm/v3/proto/eth/service" ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1" - validatorpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1/validator-client" "github.com/prysmaticlabs/prysm/v3/testing/assert" "github.com/prysmaticlabs/prysm/v3/testing/mock" "github.com/prysmaticlabs/prysm/v3/testing/require" - "github.com/prysmaticlabs/prysm/v3/validator/accounts/petnames" - "github.com/prysmaticlabs/prysm/v3/validator/accounts/wallet" "github.com/prysmaticlabs/prysm/v3/validator/keymanager" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/derived" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/local" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" constant "github.com/prysmaticlabs/prysm/v3/validator/testing" "github.com/urfave/cli/v2" keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4" @@ -116,37 +107,6 @@ func setupWalletAndPasswordsDir(t testing.TB) (string, string, string) { return walletDir, passwordsDir, passwordFilePath } -type mockRemoteKeymanager struct { - publicKeys [][fieldparams.BLSPubkeyLength]byte - opts *remote.KeymanagerOpts -} - -func (m *mockRemoteKeymanager) FetchValidatingPublicKeys(_ context.Context) ([][fieldparams.BLSPubkeyLength]byte, error) { - return m.publicKeys, nil -} - -func (*mockRemoteKeymanager) Sign(context.Context, *validatorpb.SignRequest) (bls.Signature, error) { - return nil, nil -} - -func (*mockRemoteKeymanager) SubscribeAccountChanges(_ chan [][fieldparams.BLSPubkeyLength]byte) event.Subscription { - return nil -} - -func (*mockRemoteKeymanager) ExtractKeystores( - _ context.Context, _ []bls.PublicKey, _ string, -) ([]*keymanager.Keystore, error) { - return nil, nil -} - -func (km *mockRemoteKeymanager) ListKeymanagerAccounts(ctx context.Context, cfg keymanager.ListKeymanagerAccountConfig) error { - return remote.ListKeymanagerAccountsImpl(ctx, cfg, km, km.opts) -} - -func (*mockRemoteKeymanager) DeleteKeystores(context.Context, [][]byte) ([]*ethpbservice.DeletedKeystoreStatus, error) { - return nil, nil -} - func createRandomKeystore(t testing.TB, password string) *keymanager.Keystore { encryptor := keystorev4.New() id, err := uuid.NewRandom() @@ -319,6 +279,44 @@ func TestListAccounts_LocalKeymanager(t *testing.T) { keyFound := strings.Contains(lines[lineNumber], keyString) assert.Equal(t, true, keyFound, "Private Key %s not found on line number %d", keyString, lineNumber) } + + rescueStdout = os.Stdout + r, writer, err = os.Pipe() + require.NoError(t, err) + os.Stdout = writer + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + m := mock.NewMockValidatorClient(ctrl) + var pks [][]byte + for i := range pubKeys { + pks = append(pks, pubKeys[i][:]) + } + req := ðpb.MultipleValidatorStatusRequest{PublicKeys: pks} + resp := ðpb.MultipleValidatorStatusResponse{Indices: []types.ValidatorIndex{1, math.MaxUint64, 2}} + + m. + EXPECT(). + MultipleValidatorStatus(gomock.Any(), gomock.Eq(req)). + Return(resp, nil) + + require.NoError( + t, + listValidatorIndices( + cliCtx.Context, + km, + m, + ), + ) + require.NoError(t, writer.Close()) + out, err = io.ReadAll(r) + require.NoError(t, err) + os.Stdout = rescueStdout + + expectedStdout := au.BrightGreen("Validator indices:").Bold().String() + + fmt.Sprintf("\n%#x: %d", pubKeys[0][0:4], 1) + + fmt.Sprintf("\n%#x: %d\n", pubKeys[2][0:4], 2) + require.Equal(t, expectedStdout, string(out)) } func TestListAccounts_DerivedKeymanager(t *testing.T) { @@ -462,176 +460,3 @@ func TestListAccounts_DerivedKeymanager(t *testing.T) { assert.Equal(t, true, keyFound, "Validating Private Key %s not found on line number %d", keyString, lineNumber) } } - -func TestListAccounts_RemoteKeymanager(t *testing.T) { - walletDir, _, _ := setupWalletAndPasswordsDir(t) - cliCtx := setupWalletCtx(t, &testWalletConfig{ - walletDir: walletDir, - keymanagerKind: keymanager.Remote, - }) - opts := []Option{ - WithWalletDir(walletDir), - WithKeymanagerType(keymanager.Remote), - WithWalletPassword(password), - } - acc, err := NewCLIManager(opts...) - require.NoError(t, err) - w, err := acc.WalletCreate(cliCtx.Context) - require.NoError(t, err) - - rescueStdout := os.Stdout - r, writer, err := os.Pipe() - require.NoError(t, err) - os.Stdout = writer - - numAccounts := 3 - pubKeys := make([][fieldparams.BLSPubkeyLength]byte, numAccounts) - for i := 0; i < numAccounts; i++ { - key := make([]byte, 48) - copy(key, strconv.Itoa(i)) - pubKeys[i] = bytesutil.ToBytes48(key) - } - km := &mockRemoteKeymanager{ - publicKeys: pubKeys, - opts: &remote.KeymanagerOpts{ - RemoteCertificate: &remote.CertificateConfig{ - RequireTls: true, - ClientCertPath: "/tmp/client.crt", - ClientKeyPath: "/tmp/client.key", - CACertPath: "/tmp/ca.crt", - }, - RemoteAddr: "localhost:4000", - }, - } - // We call the list remote keymanager accounts function. - require.NoError(t, - km.ListKeymanagerAccounts(context.Background(), - keymanager.ListKeymanagerAccountConfig{ - KeymanagerConfigFileName: wallet.KeymanagerConfigFileName, - })) - - require.NoError(t, writer.Close()) - out, err := io.ReadAll(r) - require.NoError(t, err) - os.Stdout = rescueStdout - - // Get stdout content and split to lines - newLine := fmt.Sprintln() - lines := strings.Split(string(out), newLine) - - // Expected output example: - /* - (keymanager kind) remote signer - (configuration file path) /tmp/79336/wallet/remote/keymanageropts.json - - Configuration options - Remote gRPC address: localhost:4000 - Require TLS: true - Client cert path: /tmp/client.crt - Client key path: /tmp/client.key - CA cert path: /tmp/ca.crt - - Showing 3 validator accounts - - equally-primary-foal - [validating public key] 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - - - rationally-charmed-werewolf - [validating public key] 0x310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - - - */ - - // Expected output format definition - const prologLength = 11 - const configOffset = 4 - const configLength = 5 - const accountLength = 4 - const nameOffset = 1 - const keyOffset = 2 - const epilogLength = 1 - - // Require the output has correct number of lines - lineCount := prologLength + accountLength*numAccounts + epilogLength - require.Equal(t, lineCount, len(lines)) - - // Assert the keymanager kind is printed on the first line. - kindString := w.KeymanagerKind().String() - kindFound := strings.Contains(lines[0], kindString) - assert.Equal(t, true, kindFound, "Keymanager Kind %s not found on the first line", kindString) - - // Assert that Configuration is printed in the right position - configLines := lines[configOffset:(configOffset + configLength)] - configExpected := km.opts.String() - configActual := fmt.Sprintln(strings.Join(configLines, newLine)) - assert.Equal(t, configExpected, configActual, "Configuration not found at the expected position") - - // Assert that account names are printed on the correct lines - for i := 0; i < numAccounts; i++ { - lineNumber := prologLength + accountLength*i + nameOffset - accountName := petnames.DeterministicName(pubKeys[i][:], "-") - accountNameFound := strings.Contains(lines[lineNumber], accountName) - assert.Equal(t, true, accountNameFound, "Account Name %s not found on line number %d", accountName, lineNumber) - } - - // Assert that public keys are printed on the correct lines - for i, key := range pubKeys { - lineNumber := prologLength + accountLength*i + keyOffset - keyString := fmt.Sprintf("%#x", key) - keyFound := strings.Contains(lines[lineNumber], keyString) - assert.Equal(t, true, keyFound, "Public Key %s not found on line number %d", keyString, lineNumber) - } -} - -func TestListAccounts_ListValidatorIndices(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - numAccounts := 3 - pubKeys := make([][fieldparams.BLSPubkeyLength]byte, numAccounts) - pks := make([][]byte, numAccounts) - - for i := 0; i < numAccounts; i++ { - key := make([]byte, 48) - copy(key, strconv.Itoa(i)) - pubKeys[i] = bytesutil.ToBytes48(key) - pks[i] = key - } - - km := &mockRemoteKeymanager{ - publicKeys: pubKeys, - } - - rescueStdout := os.Stdout - r, writer, err := os.Pipe() - require.NoError(t, err) - os.Stdout = writer - - m := mock.NewMockValidatorClient(ctrl) - - req := ðpb.MultipleValidatorStatusRequest{PublicKeys: pks} - resp := ðpb.MultipleValidatorStatusResponse{Indices: []primitives.ValidatorIndex{1, math.MaxUint64, 2}} - - m. - EXPECT(). - MultipleValidatorStatus(gomock.Eq(context.Background()), gomock.Eq(req)). - Return(resp, nil) - - require.NoError( - t, - listValidatorIndices( - context.Background(), - km, - m, - ), - ) - - require.NoError(t, writer.Close()) - out, err := io.ReadAll(r) - require.NoError(t, err) - os.Stdout = rescueStdout - - expectedStdout := au.BrightGreen("Validator indices:").Bold().String() + "\n0x30000000: 1\n0x32000000: 2\n" - require.Equal(t, expectedStdout, string(out)) -} diff --git a/validator/accounts/cli_manager.go b/validator/accounts/cli_manager.go index 96d0a1e134..99a767ce04 100644 --- a/validator/accounts/cli_manager.go +++ b/validator/accounts/cli_manager.go @@ -14,7 +14,6 @@ import ( validatorHelpers "github.com/prysmaticlabs/prysm/v3/validator/helpers" "github.com/prysmaticlabs/prysm/v3/validator/keymanager" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/derived" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" "google.golang.org/grpc" ) @@ -37,7 +36,6 @@ type AccountsCLIManager struct { wallet *wallet.Wallet keymanager keymanager.IKeymanager keymanagerKind keymanager.Kind - keymanagerOpts *remote.KeymanagerOpts showDepositData bool showPrivateKeys bool listValidatorIndices bool diff --git a/validator/accounts/cli_options.go b/validator/accounts/cli_options.go index d314d15d64..6d0ed254d5 100644 --- a/validator/accounts/cli_options.go +++ b/validator/accounts/cli_options.go @@ -6,7 +6,6 @@ import ( "github.com/prysmaticlabs/prysm/v3/crypto/bls" "github.com/prysmaticlabs/prysm/v3/validator/accounts/wallet" "github.com/prysmaticlabs/prysm/v3/validator/keymanager" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" "google.golang.org/grpc" ) @@ -37,14 +36,6 @@ func WithKeymanagerType(k keymanager.Kind) Option { } } -// WithKeymanagerOpts provides a keymanager configuration to the accounts cli manager. -func WithKeymanagerOpts(kmo *remote.KeymanagerOpts) Option { - return func(acc *AccountsCLIManager) error { - acc.keymanagerOpts = kmo - return nil - } -} - // WithShowDepositData enables displaying deposit data in the accounts cli manager. func WithShowDepositData() Option { return func(acc *AccountsCLIManager) error { diff --git a/validator/accounts/userprompt/BUILD.bazel b/validator/accounts/userprompt/BUILD.bazel index c314d32713..f54322c879 100644 --- a/validator/accounts/userprompt/BUILD.bazel +++ b/validator/accounts/userprompt/BUILD.bazel @@ -15,7 +15,6 @@ go_library( "//cmd/validator/flags:go_default_library", "//io/file:go_default_library", "//io/prompt:go_default_library", - "//validator/keymanager/remote:go_default_library", "@com_github_logrusorgru_aurora//:go_default_library", "@com_github_manifoldco_promptui//:go_default_library", "@com_github_pkg_errors//:go_default_library", diff --git a/validator/accounts/userprompt/prompt.go b/validator/accounts/userprompt/prompt.go index 2ca5af54fa..9eea342ad4 100644 --- a/validator/accounts/userprompt/prompt.go +++ b/validator/accounts/userprompt/prompt.go @@ -1,17 +1,12 @@ package userprompt import ( - "fmt" - "os" - "strings" - "github.com/logrusorgru/aurora" "github.com/manifoldco/promptui" "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v3/cmd/validator/flags" "github.com/prysmaticlabs/prysm/v3/io/file" "github.com/prysmaticlabs/prysm/v3/io/prompt" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" "github.com/urfave/cli/v2" ) @@ -62,98 +57,6 @@ func InputDirectory(cliCtx *cli.Context, promptText string, flag *cli.StringFlag return file.ExpandPath(inputtedDir) } -// InputRemoteKeymanagerConfig via the cli. -func InputRemoteKeymanagerConfig(cliCtx *cli.Context) (*remote.KeymanagerOpts, error) { - addr := cliCtx.String(flags.GrpcRemoteAddressFlag.Name) - requireTls := !cliCtx.Bool(flags.DisableRemoteSignerTlsFlag.Name) - crt := cliCtx.String(flags.RemoteSignerCertPathFlag.Name) - key := cliCtx.String(flags.RemoteSignerKeyPathFlag.Name) - ca := cliCtx.String(flags.RemoteSignerCACertPathFlag.Name) - log.Info("Input desired configuration") - var err error - if addr == "" { - addr, err = prompt.ValidatePrompt( - os.Stdin, - "Remote gRPC address (such as host.example.com:4000)", - prompt.NotEmpty) - if err != nil { - return nil, err - } - } - if requireTls && crt == "" { - crt, err = prompt.ValidatePrompt( - os.Stdin, - "Path to TLS crt (such as /path/to/client.crt)", - validateCertPath) - if err != nil { - return nil, err - } - } - if requireTls && key == "" { - key, err = prompt.ValidatePrompt( - os.Stdin, - "Path to TLS key (such as /path/to/client.key)", - validateCertPath) - if err != nil { - return nil, err - } - } - if requireTls && ca == "" { - ca, err = prompt.ValidatePrompt( - os.Stdin, - "Path to certificate authority (CA) crt (such as /path/to/ca.crt)", - validateCertPath) - if err != nil { - return nil, err - } - } - - crtPath, keyPath, caPath := "", "", "" - if crt != "" { - crtPath, err = file.ExpandPath(strings.TrimRight(crt, "\r\n")) - if err != nil { - return nil, errors.Wrapf(err, "could not determine absolute path for %s", crt) - } - } - if key != "" { - keyPath, err = file.ExpandPath(strings.TrimRight(key, "\r\n")) - if err != nil { - return nil, errors.Wrapf(err, "could not determine absolute path for %s", crt) - } - } - if ca != "" { - caPath, err = file.ExpandPath(strings.TrimRight(ca, "\r\n")) - if err != nil { - return nil, errors.Wrapf(err, "could not determine absolute path for %s", crt) - } - } - - newCfg := &remote.KeymanagerOpts{ - RemoteCertificate: &remote.CertificateConfig{ - RequireTls: requireTls, - ClientCertPath: crtPath, - ClientKeyPath: keyPath, - CACertPath: caPath, - }, - RemoteAddr: addr, - } - fmt.Printf("%s\n", newCfg) - return newCfg, nil -} - -func validateCertPath(input string) error { - if input == "" { - return errors.New("crt path cannot be empty") - } - if !prompt.IsValidUnicode(input) { - return errors.New("not valid unicode") - } - if !file.FileExists(input) { - return fmt.Errorf("no crt found at path: %s", input) - } - return nil -} - // FormatPromptError for the user. func FormatPromptError(err error) error { switch err { diff --git a/validator/accounts/wallet/BUILD.bazel b/validator/accounts/wallet/BUILD.bazel index 72072c177c..57719ba086 100644 --- a/validator/accounts/wallet/BUILD.bazel +++ b/validator/accounts/wallet/BUILD.bazel @@ -22,7 +22,6 @@ go_library( "//validator/keymanager:go_default_library", "//validator/keymanager/derived:go_default_library", "//validator/keymanager/local:go_default_library", - "//validator/keymanager/remote:go_default_library", "//validator/keymanager/remote-web3signer:go_default_library", "@com_github_pkg_errors//:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", diff --git a/validator/accounts/wallet/wallet.go b/validator/accounts/wallet/wallet.go index 8e5def67e9..ea8a8fa8d0 100644 --- a/validator/accounts/wallet/wallet.go +++ b/validator/accounts/wallet/wallet.go @@ -18,7 +18,6 @@ import ( "github.com/prysmaticlabs/prysm/v3/validator/keymanager" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/derived" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/local" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" remoteweb3signer "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote-web3signer" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" @@ -55,7 +54,6 @@ var ( KeymanagerKindSelections = map[keymanager.Kind]string{ keymanager.Local: "Imported Wallet (Recommended)", keymanager.Derived: "HD Wallet", - keymanager.Remote: "Remote Signing Wallet (Advanced)", keymanager.Web3Signer: "Consensys Web3Signer (Advanced)", } // ValidateExistingPass checks that an input cannot be empty. @@ -145,7 +143,7 @@ func IsValid(walletDir string) (bool, error) { // Count how many wallet types we have in the directory numWalletTypes := 0 for _, name := range names { - // Nil error means input name is `derived`, `remote` or `imported` + // Nil error means input name is `derived` or `imported` _, err = keymanager.ParseKind(name) if err == nil { numWalletTypes++ @@ -287,22 +285,6 @@ func (w *Wallet) InitializeKeymanager(ctx context.Context, cfg iface.InitKeymana if err != nil { return nil, errors.Wrap(err, "could not initialize derived keymanager") } - case keymanager.Remote: - configFile, err := w.ReadKeymanagerConfigFromDisk(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not read keymanager config") - } - opts, err := remote.UnmarshalOptionsFile(configFile) - if err != nil { - return nil, errors.Wrap(err, "could not unmarshal keymanager config file") - } - km, err = remote.NewKeymanager(ctx, &remote.SetupConfig{ - Opts: opts, - MaxMessageSize: 100000000, - }) - if err != nil { - return nil, errors.Wrap(err, "could not initialize remote keymanager") - } case keymanager.Web3Signer: config := cfg.Web3SignerConfig if config == nil { diff --git a/validator/accounts/wallet_create.go b/validator/accounts/wallet_create.go index 36a1eaba07..81a4727203 100644 --- a/validator/accounts/wallet_create.go +++ b/validator/accounts/wallet_create.go @@ -10,7 +10,6 @@ import ( "github.com/prysmaticlabs/prysm/v3/validator/keymanager" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/derived" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/local" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" ) // WalletCreate creates wallet specified by configuration options. @@ -64,13 +63,6 @@ func (acm *AccountsCLIManager) WalletCreate(ctx context.Context) (*wallet.Wallet log.WithField("--wallet-dir", acm.walletDir).Info( "Successfully created HD wallet from mnemonic and regenerated accounts", ) - case keymanager.Remote: - if err = createRemoteKeymanagerWallet(ctx, w, acm.keymanagerOpts); err != nil { - return nil, errors.Wrap(err, "could not initialize wallet") - } - log.WithField("--wallet-dir", acm.walletDir).Info( - "Successfully created wallet with remote keymanager configuration", - ) case keymanager.Web3Signer: return nil, errors.New("web3signer keymanager does not require persistent wallets.") default: @@ -119,17 +111,3 @@ func createDerivedKeymanagerWallet( } return nil } - -func createRemoteKeymanagerWallet(ctx context.Context, wallet *wallet.Wallet, opts *remote.KeymanagerOpts) error { - keymanagerConfig, err := remote.MarshalOptionsFile(ctx, opts) - if err != nil { - return errors.Wrap(err, "could not marshal config file") - } - if err := wallet.SaveWallet(); err != nil { - return errors.Wrap(err, "could not save wallet to disk") - } - if err := wallet.WriteKeymanagerConfigToDisk(ctx, keymanagerConfig); err != nil { - return errors.Wrap(err, "could not write keymanager config to disk") - } - return nil -} diff --git a/validator/accounts/wallet_edit.go b/validator/accounts/wallet_edit.go deleted file mode 100644 index d0c28c9189..0000000000 --- a/validator/accounts/wallet_edit.go +++ /dev/null @@ -1,21 +0,0 @@ -package accounts - -import ( - "context" - - "github.com/pkg/errors" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" -) - -// WalletEdit changes a user's on-disk wallet configuration: remote gRPC -// credentials for remote signing, derivation paths for HD wallets, etc. -func (acm *AccountsCLIManager) WalletEdit(ctx context.Context) error { - encodedCfg, err := remote.MarshalOptionsFile(ctx, acm.keymanagerOpts) - if err != nil { - return errors.Wrap(err, "could not marshal config file") - } - if err := acm.wallet.WriteKeymanagerConfigToDisk(ctx, encodedCfg); err != nil { - return errors.Wrap(err, "could not write config to disk") - } - return nil -} diff --git a/validator/client/BUILD.bazel b/validator/client/BUILD.bazel index 073209ffaf..404fa660f8 100644 --- a/validator/client/BUILD.bazel +++ b/validator/client/BUILD.bazel @@ -62,7 +62,6 @@ go_library( "//validator/helpers:go_default_library", "//validator/keymanager:go_default_library", "//validator/keymanager/local:go_default_library", - "//validator/keymanager/remote:go_default_library", "//validator/keymanager/remote-web3signer:go_default_library", "@com_github_dgraph_io_ristretto//:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", @@ -140,7 +139,6 @@ go_test( "//testing/util:go_default_library", "//time:go_default_library", "//time/slots:go_default_library", - "//time/slots/testing:go_default_library", "//validator/accounts/testing:go_default_library", "//validator/accounts/wallet:go_default_library", "//validator/client/iface:go_default_library", @@ -151,7 +149,6 @@ go_test( "//validator/keymanager/derived:go_default_library", "//validator/keymanager/local:go_default_library", "//validator/keymanager/remote-web3signer:go_default_library", - "//validator/keymanager/remote/mock:go_default_library", "//validator/slashing-protection-history:go_default_library", "//validator/testing:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", diff --git a/validator/client/runner.go b/validator/client/runner.go index 7339f3cf25..15ff1360fe 100644 --- a/validator/client/runner.go +++ b/validator/client/runner.go @@ -10,12 +10,10 @@ import ( "github.com/prysmaticlabs/prysm/v3/cmd/validator/flags" fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams" "github.com/prysmaticlabs/prysm/v3/config/params" - "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" + types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" "github.com/prysmaticlabs/prysm/v3/time/slots" "github.com/prysmaticlabs/prysm/v3/validator/client/iface" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" "go.opencensus.io/trace" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -103,7 +101,6 @@ func run(ctx context.Context, v iface.Validator) { } case slot := <-v.NextSlot(): span.AddAttributes(trace.Int64Attribute("slot", int64(slot))) // lint:ignore uintcast -- This conversion is OK for tracing. - reloadRemoteKeys(ctx, km) allExited, err := v.AllValidatorsAreExited(ctx) if err != nil { log.WithError(err).Error("Could not check if validators are exited") @@ -155,21 +152,11 @@ func run(ctx context.Context, v iface.Validator) { } } -func reloadRemoteKeys(ctx context.Context, km keymanager.IKeymanager) { - remoteKm, ok := km.(remote.RemoteKeymanager) - if ok { - _, err := remoteKm.ReloadPublicKeys(ctx) - if err != nil { - log.WithError(err).Error(msgCouldNotFetchKeys) - } - } -} - -func initializeValidatorAndGetHeadSlot(ctx context.Context, v iface.Validator) (primitives.Slot, error) { +func initializeValidatorAndGetHeadSlot(ctx context.Context, v iface.Validator) (types.Slot, error) { ticker := time.NewTicker(backOffPeriod) defer ticker.Stop() - var headSlot primitives.Slot + var headSlot types.Slot firstTime := true for { if !firstTime { @@ -231,7 +218,7 @@ func initializeValidatorAndGetHeadSlot(ctx context.Context, v iface.Validator) ( return headSlot, nil } -func performRoles(slotCtx context.Context, allRoles map[[48]byte][]iface.ValidatorRole, v iface.Validator, slot primitives.Slot, wg *sync.WaitGroup, span *trace.Span) { +func performRoles(slotCtx context.Context, allRoles map[[48]byte][]iface.ValidatorRole, v iface.Validator, slot types.Slot, wg *sync.WaitGroup, span *trace.Span) { for pubKey, roles := range allRoles { wg.Add(len(roles)) for _, role := range roles { @@ -281,7 +268,7 @@ func isConnectionError(err error) bool { return err != nil && errors.Is(err, iface.ErrConnectionIssue) } -func handleAssignmentError(err error, slot primitives.Slot) { +func handleAssignmentError(err error, slot types.Slot) { if errCode, ok := status.FromError(err); ok && errCode.Code() == codes.NotFound { log.WithField( "epoch", slot/params.BeaconConfig().SlotsPerEpoch, diff --git a/validator/client/runner_test.go b/validator/client/runner_test.go index 51c563ea94..9564d7bc18 100644 --- a/validator/client/runner_test.go +++ b/validator/client/runner_test.go @@ -11,12 +11,11 @@ import ( fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams" "github.com/prysmaticlabs/prysm/v3/config/params" validatorserviceconfig "github.com/prysmaticlabs/prysm/v3/config/validator/service" - "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" + types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v3/testing/assert" "github.com/prysmaticlabs/prysm/v3/testing/require" "github.com/prysmaticlabs/prysm/v3/validator/client/iface" "github.com/prysmaticlabs/prysm/v3/validator/client/testutil" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote/mock" logTest "github.com/sirupsen/logrus/hooks/test" ) @@ -69,8 +68,8 @@ func TestUpdateDuties_NextSlot(t *testing.T) { v := &testutil.FakeValidator{Km: &mockKeymanager{accountsChangedFeed: &event.Feed{}}} ctx, cancel := context.WithCancel(context.Background()) - slot := primitives.Slot(55) - ticker := make(chan primitives.Slot) + slot := types.Slot(55) + ticker := make(chan types.Slot) v.NextSlotRet = ticker go func() { ticker <- slot @@ -89,8 +88,8 @@ func TestUpdateDuties_HandlesError(t *testing.T) { v := &testutil.FakeValidator{Km: &mockKeymanager{accountsChangedFeed: &event.Feed{}}} ctx, cancel := context.WithCancel(context.Background()) - slot := primitives.Slot(55) - ticker := make(chan primitives.Slot) + slot := types.Slot(55) + ticker := make(chan types.Slot) v.NextSlotRet = ticker go func() { ticker <- slot @@ -108,8 +107,8 @@ func TestRoleAt_NextSlot(t *testing.T) { v := &testutil.FakeValidator{Km: &mockKeymanager{accountsChangedFeed: &event.Feed{}}} ctx, cancel := context.WithCancel(context.Background()) - slot := primitives.Slot(55) - ticker := make(chan primitives.Slot) + slot := types.Slot(55) + ticker := make(chan types.Slot) v.NextSlotRet = ticker go func() { ticker <- slot @@ -127,8 +126,8 @@ func TestAttests_NextSlot(t *testing.T) { v := &testutil.FakeValidator{Km: &mockKeymanager{accountsChangedFeed: &event.Feed{}}} ctx, cancel := context.WithCancel(context.Background()) - slot := primitives.Slot(55) - ticker := make(chan primitives.Slot) + slot := types.Slot(55) + ticker := make(chan types.Slot) v.NextSlotRet = ticker v.RolesAtRet = []iface.ValidatorRole{iface.RoleAttester} go func() { @@ -147,8 +146,8 @@ func TestProposes_NextSlot(t *testing.T) { v := &testutil.FakeValidator{Km: &mockKeymanager{accountsChangedFeed: &event.Feed{}}} ctx, cancel := context.WithCancel(context.Background()) - slot := primitives.Slot(55) - ticker := make(chan primitives.Slot) + slot := types.Slot(55) + ticker := make(chan types.Slot) v.NextSlotRet = ticker v.RolesAtRet = []iface.ValidatorRole{iface.RoleProposer} go func() { @@ -167,8 +166,8 @@ func TestBothProposesAndAttests_NextSlot(t *testing.T) { v := &testutil.FakeValidator{Km: &mockKeymanager{accountsChangedFeed: &event.Feed{}}} ctx, cancel := context.WithCancel(context.Background()) - slot := primitives.Slot(55) - ticker := make(chan primitives.Slot) + slot := types.Slot(55) + ticker := make(chan types.Slot) v.NextSlotRet = ticker v.RolesAtRet = []iface.ValidatorRole{iface.RoleAttester, iface.RoleProposer} go func() { @@ -190,8 +189,8 @@ func TestAllValidatorsAreExited_NextSlot(t *testing.T) { ctx, cancel := context.WithCancel(context.WithValue(context.Background(), testutil.AllValidatorsAreExitedCtxKey, true)) hook := logTest.NewGlobal() - slot := primitives.Slot(55) - ticker := make(chan primitives.Slot) + slot := types.Slot(55) + ticker := make(chan types.Slot) v.NextSlotRet = ticker go func() { ticker <- slot @@ -232,23 +231,6 @@ func TestKeyReload_NoActiveKey(t *testing.T) { assert.Equal(t, 2, v.WaitForActivationCalled) } -func TestKeyReload_RemoteKeymanager(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - - km := mock.NewMock() - v := &testutil.FakeValidator{Km: &km} - - ticker := make(chan primitives.Slot) - v.NextSlotRet = ticker - go func() { - ticker <- primitives.Slot(55) - - cancel() - }() - run(ctx, v) - assert.Equal(t, true, km.ReloadPublicKeysCalled) -} - func TestUpdateProposerSettingsAt_EpochStart(t *testing.T) { v := &testutil.FakeValidator{Km: &mockKeymanager{accountsChangedFeed: &event.Feed{}}} v.SetProposerSettings(&validatorserviceconfig.ProposerSettings{ @@ -261,7 +243,7 @@ func TestUpdateProposerSettingsAt_EpochStart(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) hook := logTest.NewGlobal() slot := params.BeaconConfig().SlotsPerEpoch - ticker := make(chan primitives.Slot) + ticker := make(chan types.Slot) v.NextSlotRet = ticker go func() { ticker <- slot @@ -289,7 +271,7 @@ func TestUpdateProposerSettings_ContinuesAfterValidatorRegistrationFails(t *test ctx, cancel := context.WithCancel(context.Background()) hook := logTest.NewGlobal() slot := params.BeaconConfig().SlotsPerEpoch - ticker := make(chan primitives.Slot) + ticker := make(chan types.Slot) v.NextSlotRet = ticker go func() { ticker <- slot diff --git a/validator/client/wait_for_activation.go b/validator/client/wait_for_activation.go index 41a150a827..3d82ba0a50 100644 --- a/validator/client/wait_for_activation.go +++ b/validator/client/wait_for_activation.go @@ -13,7 +13,6 @@ import ( "github.com/prysmaticlabs/prysm/v3/monitoring/tracing" ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v3/time/slots" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" "go.opencensus.io/trace" ) @@ -38,17 +37,17 @@ func (v *validator) WaitForActivation(ctx context.Context, accountsChangedChan c }() } - return v.waitForActivation(ctx, accountsChangedChan) + return v.internalWaitForActivation(ctx, accountsChangedChan) } -// waitForActivation performs the following: +// internalWaitForActivation performs the following: // 1) While the key manager is empty, poll the key manager until some validator keys exist. // 2) Open a server side stream for activation events against the given keys. // 3) In another go routine, the key manager is monitored for updates and emits an update event on -// the accountsChangedChan. When an event signal is received, restart the waitForActivation routine. +// the accountsChangedChan. When an event signal is received, restart the internalWaitForActivation routine. // 4) If the stream is reset in error, restart the routine. // 5) If the stream returns a response indicating one or more validators are active, exit the routine. -func (v *validator) waitForActivation(ctx context.Context, accountsChangedChan <-chan [][fieldparams.BLSPubkeyLength]byte) error { +func (v *validator) internalWaitForActivation(ctx context.Context, accountsChangedChan <-chan [][fieldparams.BLSPubkeyLength]byte) error { ctx, span := trace.StartSpan(ctx, "validator.WaitForActivation") defer span.End() @@ -91,80 +90,23 @@ func (v *validator) waitForActivation(ctx context.Context, accountsChangedChan < Error("Stream broken while waiting for activation. Reconnecting...") // Reconnection attempt backoff, up to 60s. time.Sleep(time.Second * time.Duration(math.Min(uint64(attempts), 60))) - return v.waitForActivation(incrementRetries(ctx), accountsChangedChan) + return v.internalWaitForActivation(incrementRetries(ctx), accountsChangedChan) } - remoteKm, ok := v.keyManager.(remote.RemoteKeymanager) - if ok { - if err = v.handleWithRemoteKeyManager(ctx, accountsChangedChan, &remoteKm); err != nil { - return err - } - } else { - if err = v.handleWithoutRemoteKeyManager(ctx, accountsChangedChan, &stream, span); err != nil { - return err - } + if err = v.handleAccountsChanged(ctx, accountsChangedChan, &stream, span); err != nil { + return err } v.ticker = slots.NewSlotTicker(time.Unix(int64(v.genesisTime), 0), params.BeaconConfig().SecondsPerSlot) return nil } -func (v *validator) handleWithRemoteKeyManager(ctx context.Context, accountsChangedChan <-chan [][fieldparams.BLSPubkeyLength]byte, remoteKm *remote.RemoteKeymanager) error { +func (v *validator) handleAccountsChanged(ctx context.Context, accountsChangedChan <-chan [][fieldparams.BLSPubkeyLength]byte, stream *ethpb.BeaconNodeValidator_WaitForActivationClient, span *trace.Span) error { for { select { case <-accountsChangedChan: // Accounts (keys) changed, restart the process. - return v.waitForActivation(ctx, accountsChangedChan) - case <-v.NextSlot(): - if ctx.Err() == context.Canceled { - return errors.Wrap(ctx.Err(), "context canceled, not waiting for activation anymore") - } - validatingKeys, err := (*remoteKm).ReloadPublicKeys(ctx) - if err != nil { - return errors.Wrap(err, msgCouldNotFetchKeys) - } - statusRequestKeys := make([][]byte, len(validatingKeys)) - for i := range validatingKeys { - statusRequestKeys[i] = validatingKeys[i][:] - } - resp, err := v.validatorClient.MultipleValidatorStatus(ctx, ðpb.MultipleValidatorStatusRequest{ - PublicKeys: statusRequestKeys, - }) - if err != nil { - return err - } - statuses := make([]*validatorStatus, len(resp.Statuses)) - for i, s := range resp.Statuses { - statuses[i] = &validatorStatus{ - publicKey: resp.PublicKeys[i], - status: s, - index: resp.Indices[i], - } - } - - vals, err := v.beaconClient.ListValidators(ctx, ðpb.ListValidatorsRequest{Active: true, PageSize: 0}) - if err != nil { - return errors.Wrap(err, "could not get active validator count") - } - - valActivated := v.checkAndLogValidatorStatus(statuses, uint64(vals.TotalSize)) - if valActivated { - logActiveValidatorStatus(statuses) - } else { - continue - } - } - break - } - return nil -} - -func (v *validator) handleWithoutRemoteKeyManager(ctx context.Context, accountsChangedChan <-chan [][fieldparams.BLSPubkeyLength]byte, stream *ethpb.BeaconNodeValidator_WaitForActivationClient, span *trace.Span) error { - for { - select { - case <-accountsChangedChan: - // Accounts (keys) changed, restart the process. - return v.waitForActivation(ctx, accountsChangedChan) + return v.internalWaitForActivation(ctx, accountsChangedChan) default: res, err := (*stream).Recv() // If the stream is closed, we stop the loop. @@ -182,7 +124,7 @@ func (v *validator) handleWithoutRemoteKeyManager(ctx context.Context, accountsC Error("Stream broken while waiting for activation. Reconnecting...") // Reconnection attempt backoff, up to 60s. time.Sleep(time.Second * time.Duration(math.Min(uint64(attempts), 60))) - return v.waitForActivation(incrementRetries(ctx), accountsChangedChan) + return v.internalWaitForActivation(incrementRetries(ctx), accountsChangedChan) } statuses := make([]*validatorStatus, len(res.Statuses)) diff --git a/validator/client/wait_for_activation_test.go b/validator/client/wait_for_activation_test.go index 02506c8264..aa3615a7e5 100644 --- a/validator/client/wait_for_activation_test.go +++ b/validator/client/wait_for_activation_test.go @@ -9,18 +9,13 @@ import ( "github.com/golang/mock/gomock" "github.com/pkg/errors" fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams" - "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v3/crypto/bls" - "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v3/testing/assert" "github.com/prysmaticlabs/prysm/v3/testing/mock" "github.com/prysmaticlabs/prysm/v3/testing/require" - slotutilmock "github.com/prysmaticlabs/prysm/v3/time/slots/testing" walletMock "github.com/prysmaticlabs/prysm/v3/validator/accounts/testing" - "github.com/prysmaticlabs/prysm/v3/validator/client/testutil" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/derived" - remotekeymanagermock "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote/mock" constant "github.com/prysmaticlabs/prysm/v3/validator/testing" logTest "github.com/sirupsen/logrus/hooks/test" "github.com/tyler-smith/go-bip39" @@ -248,7 +243,7 @@ func TestWaitForActivation_RefetchKeys(t *testing.T) { clientStream.EXPECT().Recv().Return( resp, nil) - assert.NoError(t, v.waitForActivation(context.Background(), make(chan [][fieldparams.BLSPubkeyLength]byte)), "Could not wait for activation") + assert.NoError(t, v.internalWaitForActivation(context.Background(), make(chan [][fieldparams.BLSPubkeyLength]byte)), "Could not wait for activation") assert.LogsContain(t, hook, msgNoKeysFetched) assert.LogsContain(t, hook, "Validator activated") } @@ -395,131 +390,7 @@ func TestWaitForActivation_AccountsChanged(t *testing.T) { channel <- [][fieldparams.BLSPubkeyLength]byte{} }() - assert.NoError(t, v.waitForActivation(context.Background(), channel)) - assert.LogsContain(t, hook, "Waiting for deposit to be observed by beacon node") - assert.LogsContain(t, hook, "Validator activated") - }) -} - -func TestWaitForActivation_RemoteKeymanager(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - validatorClient := mock.NewMockValidatorClient(ctrl) - beaconClient := mock.NewMockBeaconChainClient(ctrl) - stream := mock.NewMockBeaconNodeValidator_WaitForActivationClient(ctrl) - validatorClient.EXPECT().WaitForActivation( - gomock.Any(), - gomock.Any(), - ).Return(stream, nil /* err */).AnyTimes() - beaconClient.EXPECT().ListValidators(gomock.Any(), gomock.Any()).Return(ðpb.Validators{}, nil).AnyTimes() - - inactiveKey := bytesutil.ToBytes48([]byte("inactive")) - activeKey := bytesutil.ToBytes48([]byte("active")) - km := remotekeymanagermock.NewMock() - km.PublicKeys = [][fieldparams.BLSPubkeyLength]byte{inactiveKey, activeKey} - slot := primitives.Slot(0) - - t.Run("activated", func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - hook := logTest.NewGlobal() - tickerChan := make(chan primitives.Slot) - ticker := &slotutilmock.MockTicker{ - Channel: tickerChan, - } - v := validator{ - validatorClient: validatorClient, - keyManager: &km, - ticker: ticker, - beaconClient: beaconClient, - } - go func() { - tickerChan <- slot - // Cancel after timeout to avoid waiting on channel forever in case test goes wrong. - time.Sleep(time.Second) - cancel() - }() - - resp := testutil.GenerateMultipleValidatorStatusResponse([][]byte{inactiveKey[:], activeKey[:]}) - resp.Statuses[0].Status = ethpb.ValidatorStatus_UNKNOWN_STATUS - resp.Statuses[1].Status = ethpb.ValidatorStatus_ACTIVE - validatorClient.EXPECT().MultipleValidatorStatus( - gomock.Any(), - ðpb.MultipleValidatorStatusRequest{ - PublicKeys: [][]byte{inactiveKey[:], activeKey[:]}, - }, - ).Return(resp, nil /* err */) - err := v.waitForActivation(ctx, nil /* accountsChangedChan */) - require.NoError(t, err) - assert.LogsContain(t, hook, "Waiting for deposit to be observed by beacon node") - assert.LogsContain(t, hook, "Validator activated") - }) - - t.Run("cancelled", func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - - tickerChan := make(chan primitives.Slot) - ticker := &slotutilmock.MockTicker{ - Channel: tickerChan, - } - v := validator{ - validatorClient: validatorClient, - keyManager: &km, - ticker: ticker, - } - go func() { - cancel() - tickerChan <- slot - }() - - err := v.waitForActivation(ctx, nil /* accountsChangedChan */) - assert.ErrorContains(t, "context canceled, not waiting for activation anymore", err) - }) - t.Run("reloaded", func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - hook := logTest.NewGlobal() - remoteKm := remotekeymanagermock.NewMock() - remoteKm.PublicKeys = [][fieldparams.BLSPubkeyLength]byte{inactiveKey} - tickerChan := make(chan primitives.Slot) - ticker := &slotutilmock.MockTicker{ - Channel: tickerChan, - } - v := validator{ - validatorClient: validatorClient, - keyManager: &remoteKm, - ticker: ticker, - beaconClient: beaconClient, - } - go func() { - tickerChan <- slot - time.Sleep(time.Second) - remoteKm.PublicKeys = [][fieldparams.BLSPubkeyLength]byte{inactiveKey, activeKey} - tickerChan <- slot - // Cancel after timeout to avoid waiting on channel forever in case test goes wrong. - time.Sleep(time.Second) - cancel() - }() - - resp := testutil.GenerateMultipleValidatorStatusResponse([][]byte{inactiveKey[:]}) - resp.Statuses[0].Status = ethpb.ValidatorStatus_UNKNOWN_STATUS - validatorClient.EXPECT().MultipleValidatorStatus( - gomock.Any(), - ðpb.MultipleValidatorStatusRequest{ - PublicKeys: [][]byte{inactiveKey[:]}, - }, - ).Return(resp, nil /* err */) - resp2 := testutil.GenerateMultipleValidatorStatusResponse([][]byte{inactiveKey[:], activeKey[:]}) - resp2.Statuses[0].Status = ethpb.ValidatorStatus_UNKNOWN_STATUS - resp2.Statuses[1].Status = ethpb.ValidatorStatus_ACTIVE - validatorClient.EXPECT().MultipleValidatorStatus( - gomock.Any(), - ðpb.MultipleValidatorStatusRequest{ - PublicKeys: [][]byte{inactiveKey[:], activeKey[:]}, - }, - ).Return(resp2, nil /* err */) - - err := v.waitForActivation(ctx, remoteKm.ReloadPublicKeysChan /* accountsChangedChan */) - require.NoError(t, err) + assert.NoError(t, v.internalWaitForActivation(context.Background(), channel)) assert.LogsContain(t, hook, "Waiting for deposit to be observed by beacon node") assert.LogsContain(t, hook, "Validator activated") }) diff --git a/validator/keymanager/BUILD.bazel b/validator/keymanager/BUILD.bazel index da0535bfe3..d41f961b7a 100644 --- a/validator/keymanager/BUILD.bazel +++ b/validator/keymanager/BUILD.bazel @@ -32,7 +32,6 @@ go_test( "//testing/require:go_default_library", "//validator/keymanager/derived:go_default_library", "//validator/keymanager/local:go_default_library", - "//validator/keymanager/remote:go_default_library", "//validator/keymanager/remote-web3signer:go_default_library", ], ) diff --git a/validator/keymanager/remote-utils/BUILD.bazel b/validator/keymanager/remote-utils/BUILD.bazel deleted file mode 100644 index 32d63560e9..0000000000 --- a/validator/keymanager/remote-utils/BUILD.bazel +++ /dev/null @@ -1,15 +0,0 @@ -load("@prysm//tools/go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["format.go"], - importpath = "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote-utils", - visibility = [ - "//validator:__pkg__", - "//validator:__subpackages__", - ], - deps = [ - "//validator/accounts/petnames:go_default_library", - "@com_github_logrusorgru_aurora//:go_default_library", - ], -) diff --git a/validator/keymanager/remote-utils/format.go b/validator/keymanager/remote-utils/format.go deleted file mode 100644 index 6dc925b943..0000000000 --- a/validator/keymanager/remote-utils/format.go +++ /dev/null @@ -1,22 +0,0 @@ -package remote_utils - -import ( - "fmt" - - "github.com/logrusorgru/aurora" - "github.com/prysmaticlabs/prysm/v3/validator/accounts/petnames" -) - -// DisplayRemotePublicKeys prints remote public keys to stdout. -func DisplayRemotePublicKeys(validatingPubKeys [][48]byte) { - au := aurora.NewAurora(true) - for i := 0; i < len(validatingPubKeys); i++ { - fmt.Println("") - fmt.Printf( - "%s\n", au.BrightGreen(petnames.DeterministicName(validatingPubKeys[i][:], "-")).Bold(), - ) - // Retrieve the validating key account metadata. - fmt.Printf("%s %#x\n", au.BrightCyan("[validating public key]").Bold(), validatingPubKeys[i]) - fmt.Println(" ") - } -} diff --git a/validator/keymanager/remote-web3signer/BUILD.bazel b/validator/keymanager/remote-web3signer/BUILD.bazel index 13234ee044..0579331e31 100644 --- a/validator/keymanager/remote-web3signer/BUILD.bazel +++ b/validator/keymanager/remote-web3signer/BUILD.bazel @@ -18,8 +18,8 @@ go_library( "//encoding/bytesutil:go_default_library", "//proto/eth/service:go_default_library", "//proto/prysm/v1alpha1/validator-client:go_default_library", + "//validator/accounts/petnames:go_default_library", "//validator/keymanager:go_default_library", - "//validator/keymanager/remote-utils:go_default_library", "//validator/keymanager/remote-web3signer/internal:go_default_library", "//validator/keymanager/remote-web3signer/v1:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", diff --git a/validator/keymanager/remote-web3signer/keymanager.go b/validator/keymanager/remote-web3signer/keymanager.go index 45b5af96a1..35db914be2 100644 --- a/validator/keymanager/remote-web3signer/keymanager.go +++ b/validator/keymanager/remote-web3signer/keymanager.go @@ -17,8 +17,8 @@ import ( "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" ethpbservice "github.com/prysmaticlabs/prysm/v3/proto/eth/service" validatorpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1/validator-client" + "github.com/prysmaticlabs/prysm/v3/validator/accounts/petnames" "github.com/prysmaticlabs/prysm/v3/validator/keymanager" - remoteutils "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote-utils" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote-web3signer/internal" web3signerv1 "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote-web3signer/v1" log "github.com/sirupsen/logrus" @@ -313,10 +313,24 @@ func (km *Keymanager) ListKeymanagerAccounts(ctx context.Context, cfg keymanager } else { fmt.Printf("Showing %d validator accounts\n", len(validatingPubKeys)) } - remoteutils.DisplayRemotePublicKeys(validatingPubKeys) + DisplayRemotePublicKeys(validatingPubKeys) return nil } +// DisplayRemotePublicKeys prints remote public keys to stdout. +func DisplayRemotePublicKeys(validatingPubKeys [][48]byte) { + au := aurora.NewAurora(true) + for i := 0; i < len(validatingPubKeys); i++ { + fmt.Println("") + fmt.Printf( + "%s\n", au.BrightGreen(petnames.DeterministicName(validatingPubKeys[i][:], "-")).Bold(), + ) + // Retrieve the validating key account metadata. + fmt.Printf("%s %#x\n", au.BrightCyan("[validating public key]").Bold(), validatingPubKeys[i]) + fmt.Println(" ") + } +} + // AddPublicKeys imports a list of public keys into the keymanager for web3signer use. Returns status with message. func (km *Keymanager) AddPublicKeys(ctx context.Context, pubKeys [][fieldparams.BLSPubkeyLength]byte) ([]*ethpbservice.ImportedRemoteKeysStatus, error) { if ctx == nil { diff --git a/validator/keymanager/remote/BUILD.bazel b/validator/keymanager/remote/BUILD.bazel deleted file mode 100644 index e79c6dea15..0000000000 --- a/validator/keymanager/remote/BUILD.bazel +++ /dev/null @@ -1,52 +0,0 @@ -load("@prysm//tools/go:def.bzl", "go_library", "go_test") - -go_library( - name = "go_default_library", - srcs = [ - "doc.go", - "keymanager.go", - "log.go", - ], - importpath = "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote", - visibility = [ - "//cmd/validator:__subpackages__", - "//validator:__pkg__", - "//validator:__subpackages__", - ], - deps = [ - "//async/event:go_default_library", - "//config/fieldparams:go_default_library", - "//crypto/bls:go_default_library", - "//encoding/bytesutil:go_default_library", - "//proto/eth/service:go_default_library", - "//proto/prysm/v1alpha1/validator-client:go_default_library", - "//validator/keymanager:go_default_library", - "//validator/keymanager/remote-utils:go_default_library", - "@com_github_logrusorgru_aurora//:go_default_library", - "@com_github_pkg_errors//:go_default_library", - "@com_github_sirupsen_logrus//:go_default_library", - "@io_bazel_rules_go//proto/wkt:empty_go_proto", - "@org_golang_google_grpc//:go_default_library", - "@org_golang_google_grpc//credentials:go_default_library", - ], -) - -go_test( - name = "go_default_test", - srcs = ["keymanager_test.go"], - embed = [":go_default_library"], - deps = [ - "//async/event:go_default_library", - "//config/fieldparams:go_default_library", - "//config/params:go_default_library", - "//crypto/bls:go_default_library", - "//encoding/bytesutil:go_default_library", - "//proto/prysm/v1alpha1/validator-client:go_default_library", - "//testing/assert:go_default_library", - "//testing/mock:go_default_library", - "//testing/require:go_default_library", - "//validator/keymanager:go_default_library", - "@com_github_golang_mock//gomock:go_default_library", - "@com_github_sirupsen_logrus//hooks/test:go_default_library", - ], -) diff --git a/validator/keymanager/remote/doc.go b/validator/keymanager/remote/doc.go deleted file mode 100644 index 7970b8c02b..0000000000 --- a/validator/keymanager/remote/doc.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -Package remote defines an implementation of an on-disk, EIP-2335 keystore.json -approach towards defining validator accounts in Prysm. A validating private key is -encrypted using a passphrase and its resulting encrypted file is stored as a -keystore.json file under a unique, human-readable, account namespace. This imported keymanager approach -relies on storing account information on-disk, making it trivial to import, backup and -list all associated accounts for a user. - -Package remote defines a keymanager implementation which connects to a remote signer -server via gRPC. The connection is established via TLS using supplied paths to -certificates and key files and allows for submitting remote signing requests for -Ethereum data structures as well as retrieving the available signing public keys from -the remote server. - -Remote sign requests are defined by the following protobuf schema: - - // SignRequest is a message type used by a keymanager - // as part of Prysm's accounts implementation. - message SignRequest { - // 48 byte public key corresponding to an associated private key - // being requested to sign data. - bytes public_key = 1; - - // Raw bytes signing root the client is requesting to sign. The client is - // expected to determine these raw bytes from the appropriate BLS - // signing domain as well as the signing root of the data structure - // the bytes represent. - bytes signing_root = 2; - } - -Remote signing responses will contain a BLS12-381 signature along with the -status of the signing response from the remote server, signifying the -request either failed, was denied, or completed successfully. - - message SignResponse { - enum Status { - UNKNOWN = 0; - SUCCEEDED = 1; - DENIED = 2; - FAILED = 3; - } - - // BLS12-381 signature for the data specified in the request. - bytes signature = 1; - } - -The remote keymanager can be customized via a keymanageropts.json file -which requires the following schema: - - { - "remote_address": "remoteserver.com:4000", // Remote gRPC server address. - "remote_cert": { - "crt_path": "/home/eth2/certs/client.crt", // Client certificate path. - "ca_crt_path": "/home/eth2/certs/ca.crt", // Certificate authority cert path. - "key_path": "/home/eth2/certs/client.key", // Client key path. - } - } -*/ -package remote diff --git a/validator/keymanager/remote/keymanager.go b/validator/keymanager/remote/keymanager.go deleted file mode 100644 index aecc71d744..0000000000 --- a/validator/keymanager/remote/keymanager.go +++ /dev/null @@ -1,314 +0,0 @@ -package remote - -import ( - "bytes" - "context" - "crypto/tls" - "crypto/x509" - "encoding/json" - "fmt" - "io" - "os" - "path/filepath" - "sort" - "strings" - - "github.com/golang/protobuf/ptypes/empty" - "github.com/logrusorgru/aurora" - "github.com/pkg/errors" - "github.com/prysmaticlabs/prysm/v3/async/event" - fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams" - "github.com/prysmaticlabs/prysm/v3/crypto/bls" - "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" - ethpbservice "github.com/prysmaticlabs/prysm/v3/proto/eth/service" - validatorpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1/validator-client" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager" - remoteutils "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote-utils" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" -) - -var ( - // ErrSigningFailed defines a failure from the remote server - // when performing a signing operation. - ErrSigningFailed = errors.New("signing failed in the remote server") - // ErrSigningDenied defines a failure from the remote server when - // performing a signing operation was denied by a remote server. - ErrSigningDenied = errors.New("signing request was denied by remote server") -) - -// RemoteKeymanager defines the interface for remote Prysm wallets. -type RemoteKeymanager interface { - keymanager.IKeymanager - ReloadPublicKeys(ctx context.Context) ([][fieldparams.BLSPubkeyLength]byte, error) -} - -// KeymanagerOpts for a remote keymanager. -type KeymanagerOpts struct { - RemoteCertificate *CertificateConfig `json:"remote_cert"` - RemoteAddr string `json:"remote_address"` -} - -// CertificateConfig defines configuration options for -// certificate authority certs, client certs, and client keys -// for TLS gRPC connections. -type CertificateConfig struct { - RequireTls bool `json:"require_tls"` - ClientCertPath string `json:"crt_path"` - ClientKeyPath string `json:"key_path"` - CACertPath string `json:"ca_crt_path"` -} - -// SetupConfig includes configuration values for initializing -// a keymanager, such as passwords, the wallet, and more. -type SetupConfig struct { - Opts *KeymanagerOpts - MaxMessageSize int -} - -// Keymanager implementation using remote signing keys via gRPC. -type Keymanager struct { - opts *KeymanagerOpts - client validatorpb.RemoteSignerClient - orderedPubKeys [][fieldparams.BLSPubkeyLength]byte - accountsChangedFeed *event.Feed -} - -// NewKeymanager instantiates a new imported keymanager from configuration options. -func NewKeymanager(_ context.Context, cfg *SetupConfig) (*Keymanager, error) { - // Load the client certificates. - if cfg.Opts.RemoteCertificate == nil { - return nil, errors.New("certificate configuration is missing") - } - - var clientCreds credentials.TransportCredentials - - if cfg.Opts.RemoteCertificate.RequireTls { - if cfg.Opts.RemoteCertificate.ClientCertPath == "" { - return nil, errors.New("client certificate is required") - } - if cfg.Opts.RemoteCertificate.ClientKeyPath == "" { - return nil, errors.New("client key is required") - } - clientPair, err := tls.LoadX509KeyPair(cfg.Opts.RemoteCertificate.ClientCertPath, cfg.Opts.RemoteCertificate.ClientKeyPath) - if err != nil { - return nil, errors.Wrap(err, "failed to obtain client's certificate and/or key") - } - - // Load the CA for the server certificate if present. - cp := x509.NewCertPool() - if cfg.Opts.RemoteCertificate.CACertPath != "" { - serverCA, err := os.ReadFile(cfg.Opts.RemoteCertificate.CACertPath) - if err != nil { - return nil, errors.Wrap(err, "failed to obtain server's CA certificate") - } - if !cp.AppendCertsFromPEM(serverCA) { - return nil, errors.Wrap(err, "failed to add server's CA certificate to pool") - } - } - - tlsCfg := &tls.Config{ - Certificates: []tls.Certificate{clientPair}, - RootCAs: cp, - MinVersion: tls.VersionTLS13, - } - clientCreds = credentials.NewTLS(tlsCfg) - } - - grpcOpts := []grpc.DialOption{ - // Receive large messages without erroring. - grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(cfg.MaxMessageSize)), - } - if cfg.Opts.RemoteCertificate.RequireTls { - // Require TLS with client certificate. - grpcOpts = append(grpcOpts, grpc.WithTransportCredentials(clientCreds)) - } else { - grpcOpts = append(grpcOpts, grpc.WithInsecure()) - } - - conn, err := grpc.Dial(cfg.Opts.RemoteAddr, grpcOpts...) - if err != nil { - return nil, errors.New("failed to connect to remote wallet") - } - client := validatorpb.NewRemoteSignerClient(conn) - k := &Keymanager{ - opts: cfg.Opts, - client: client, - orderedPubKeys: make([][fieldparams.BLSPubkeyLength]byte, 0), - accountsChangedFeed: new(event.Feed), - } - return k, nil -} - -// UnmarshalOptionsFile attempts to JSON unmarshal a keymanager -// options file into a struct. -func UnmarshalOptionsFile(r io.ReadCloser) (*KeymanagerOpts, error) { - enc, err := io.ReadAll(r) - if err != nil { - return nil, errors.Wrap(err, "could not read config") - } - defer func() { - if err := r.Close(); err != nil { - log.WithError(err).Error("Could not close keymanager config file") - } - }() - opts := &KeymanagerOpts{ - RemoteCertificate: &CertificateConfig{RequireTls: true}, - } - if err := json.Unmarshal(enc, opts); err != nil { - return nil, errors.Wrap(err, "could not JSON unmarshal") - } - return opts, nil -} - -// MarshalOptionsFile for the keymanager. -func MarshalOptionsFile(_ context.Context, cfg *KeymanagerOpts) ([]byte, error) { - return json.MarshalIndent(cfg, "", "\t") -} - -// String pretty-print of a remote keymanager options. -func (opts *KeymanagerOpts) String() string { - au := aurora.NewAurora(true) - var b strings.Builder - strAddr := fmt.Sprintf("%s: %s\n", au.BrightMagenta("Remote gRPC address"), opts.RemoteAddr) - if _, err := b.WriteString(strAddr); err != nil { - log.Error(err) - return "" - } - strRequireTls := fmt.Sprintf( - "%s: %t\n", au.BrightMagenta("Require TLS"), opts.RemoteCertificate.RequireTls, - ) - if _, err := b.WriteString(strRequireTls); err != nil { - log.Error(err) - return "" - } - strCrt := fmt.Sprintf( - "%s: %s\n", au.BrightMagenta("Client cert path"), opts.RemoteCertificate.ClientCertPath, - ) - if _, err := b.WriteString(strCrt); err != nil { - log.Error(err) - return "" - } - strKey := fmt.Sprintf( - "%s: %s\n", au.BrightMagenta("Client key path"), opts.RemoteCertificate.ClientKeyPath, - ) - if _, err := b.WriteString(strKey); err != nil { - log.Error(err) - return "" - } - strCa := fmt.Sprintf( - "%s: %s\n", au.BrightMagenta("CA cert path"), opts.RemoteCertificate.CACertPath, - ) - if _, err := b.WriteString(strCa); err != nil { - log.Error(err) - return "" - } - return b.String() -} - -// KeymanagerOpts for the remote keymanager. -func (km *Keymanager) KeymanagerOpts() *KeymanagerOpts { - return km.opts -} - -// ReloadPublicKeys reloads public keys. -func (km *Keymanager) ReloadPublicKeys(ctx context.Context) ([][fieldparams.BLSPubkeyLength]byte, error) { - pubKeys, err := km.FetchValidatingPublicKeys(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not reload public keys") - } - - sort.Slice(pubKeys, func(i, j int) bool { return bytes.Compare(pubKeys[i][:], pubKeys[j][:]) == -1 }) - if len(km.orderedPubKeys) != len(pubKeys) { - log.Info(keymanager.KeysReloaded) - km.accountsChangedFeed.Send(pubKeys) - } else { - for i := range km.orderedPubKeys { - if !bytes.Equal(km.orderedPubKeys[i][:], pubKeys[i][:]) { - log.Info(keymanager.KeysReloaded) - km.accountsChangedFeed.Send(pubKeys) - break - } - } - } - - km.orderedPubKeys = pubKeys - return km.orderedPubKeys, nil -} - -// FetchValidatingPublicKeys fetches the list of public keys that should be used to validate with. -func (km *Keymanager) FetchValidatingPublicKeys(ctx context.Context) ([][fieldparams.BLSPubkeyLength]byte, error) { - resp, err := km.client.ListValidatingPublicKeys(ctx, &empty.Empty{}) - if err != nil { - return nil, errors.Wrap(err, "could not list accounts from remote server") - } - pubKeys := make([][fieldparams.BLSPubkeyLength]byte, len(resp.ValidatingPublicKeys)) - for i := range resp.ValidatingPublicKeys { - pubKeys[i] = bytesutil.ToBytes48(resp.ValidatingPublicKeys[i]) - } - return pubKeys, nil -} - -// Sign signs a message for a validator key via a gRPC request. -func (km *Keymanager) Sign(ctx context.Context, req *validatorpb.SignRequest) (bls.Signature, error) { - resp, err := km.client.Sign(ctx, req) - if err != nil { - return nil, err - } - switch resp.Status { - case validatorpb.SignResponse_DENIED: - return nil, ErrSigningDenied - case validatorpb.SignResponse_FAILED: - return nil, ErrSigningFailed - } - return bls.SignatureFromBytes(resp.Signature) -} - -// SubscribeAccountChanges creates an event subscription for a channel -// to listen for public key changes at runtime, such as when new validator accounts -// are imported into the keymanager while the validator process is running. -func (km *Keymanager) SubscribeAccountChanges(pubKeysChan chan [][fieldparams.BLSPubkeyLength]byte) event.Subscription { - return km.accountsChangedFeed.Subscribe(pubKeysChan) -} - -// ExtractKeystores is not supported for the remote keymanager type. -func (*Keymanager) ExtractKeystores( - _ context.Context, _ []bls.PublicKey, _ string, -) ([]*keymanager.Keystore, error) { - return nil, errors.New("extracting keys not supported for a remote keymanager") -} - -// DeleteKeystores is not supported for the remote keymanager type. -func (*Keymanager) DeleteKeystores(context.Context, [][]byte) ([]*ethpbservice.DeletedKeystoreStatus, error) { - return nil, errors.New("Wrong wallet type: web3-signer. Only Imported or Derived wallets can delete accounts") -} - -func (km *Keymanager) ListKeymanagerAccounts(ctx context.Context, cfg keymanager.ListKeymanagerAccountConfig) error { - return ListKeymanagerAccountsImpl(ctx, cfg, km, km.KeymanagerOpts()) -} - -func ListKeymanagerAccountsImpl(ctx context.Context, cfg keymanager.ListKeymanagerAccountConfig, km keymanager.IKeymanager, opts *KeymanagerOpts) error { - au := aurora.NewAurora(true) - fmt.Printf("(keymanager kind) %s\n", au.BrightGreen("remote signer").Bold()) - fmt.Printf( - "(configuration file path) %s\n", - au.BrightGreen(filepath.Join(cfg.WalletAccountsDir, cfg.KeymanagerConfigFileName)).Bold(), - ) - fmt.Println(" ") - fmt.Printf("%s\n", au.BrightGreen("Configuration options").Bold()) - fmt.Println(opts) - validatingPubKeys, err := km.FetchValidatingPublicKeys(ctx) - if err != nil { - return errors.Wrap(err, "could not fetch validating public keys") - } - if len(validatingPubKeys) == 1 { - fmt.Print("Showing 1 validator account\n") - } else if len(validatingPubKeys) == 0 { - fmt.Print("No accounts found\n") - return nil - } else { - fmt.Printf("Showing %d validator accounts\n", len(validatingPubKeys)) - } - remoteutils.DisplayRemotePublicKeys(validatingPubKeys) - return nil -} diff --git a/validator/keymanager/remote/keymanager_test.go b/validator/keymanager/remote/keymanager_test.go deleted file mode 100644 index ac8c332267..0000000000 --- a/validator/keymanager/remote/keymanager_test.go +++ /dev/null @@ -1,414 +0,0 @@ -package remote - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "io" - "os" - "strconv" - "testing" - - "github.com/golang/mock/gomock" - "github.com/prysmaticlabs/prysm/v3/async/event" - fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams" - "github.com/prysmaticlabs/prysm/v3/config/params" - "github.com/prysmaticlabs/prysm/v3/crypto/bls" - "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" - validatorpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1/validator-client" - "github.com/prysmaticlabs/prysm/v3/testing/assert" - "github.com/prysmaticlabs/prysm/v3/testing/mock" - "github.com/prysmaticlabs/prysm/v3/testing/require" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager" - logTest "github.com/sirupsen/logrus/hooks/test" -) - -var validClientCert = `-----BEGIN CERTIFICATE----- -MIIEITCCAgmgAwIBAgIQXUJWQZgVO4IX+zlWGI1/mTANBgkqhkiG9w0BAQsFADAU -MRIwEAYDVQQDEwlBdHRlc3RhbnQwHhcNMjAwMzE3MDgwNjU3WhcNMjEwOTE3MDc1 -OTUyWjASMRAwDgYDVQQDEwdjbGllbnQxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAsc977g16Tan2j7YuA+zQOlDntb4Bkfs4sDOznOEvnozHwRZOgfcP -jVcA9AS5eZOGIRrsTssptrgVNDPoIHWoKk7LAKyyLM3dGp5PWeyMBoQA5cq+yPAT -4JkJpDnBFfwxXB99osJH0z3jSTRa62CSVvPRBisK4B9AlLQfcleEQlKJugy9tOAj -G7zodwEi+J4AYQHmOiwL38ZsKq9We5y4HMQ0E7de0FoU5QHrtuPNrTuwVwrq825l -cEAAFey6Btngx+sziysPHWHYOq4xOZ1UPBApeaAFLguzusc/4VwM7kzRNr4VOD8a -eC3CtKLhBBVVxHI5ZlaHS+YylNGYD4+FxQIDAQABo3EwbzAOBgNVHQ8BAf8EBAMC -A7gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBQDGCE0 -3k4rHzB+Ycf3pt1MzeDPgzAfBgNVHSMEGDAWgBScIYZa4dQBIW/gVwR0ctGCuHhe -9jANBgkqhkiG9w0BAQsFAAOCAgEAHG/EfvqIwbhYfci+zRCYC7aQPuvhivJblBwN -mbXo2qsxvje1hcKm0ptJLOy/cjJzeLJYREhQlXDPRJC/xgELnbXRjgag82r35+pf -wVJwP6Yw53VCM3o0QKsUrKyMm4sAijOBrJyqpB5untAieZsry5Bfj0S4YobbtdJa -VsEioU07fVVczf5lYN0XrLgRnXq3LMkTiZ6drFiqLkwmXQZVxNujmcaFSm7yCALl -EdhYNmaqedS5me5UOGxwPacrsZwWF9dvMsl3OswgTcaGdsUtx2/q+S2vbZUAM/Gw -qaTanDfvVtVTF7KzVN9hiqKe4mO0HHHK2HWJYBLdRJjInOgRW+53hCmUhLxD+Dq+ -31jLKxn/Y4hyH9E+55b1sJHCFpsbEtVD53fojiH2C/uLbhq4Wr1PXgOoxzf2KeSQ -B3ENu8C4b6AlNhqOnz5zeDcx8Ug0vMfVDAwf6RAYMG5b/MoWNKcLNXhk8H1nbVkt -16ppjh6I27JqfNqfP2J/p3BF++ZugZuWfN9DRaJ6UPz+yyF7eW8fyDAQNl7LS0Kh -8PlF5cYvyIIKVHe38Mn8ZAWboKUs0xNv2vhA9V/4Q1ZzAEkXjmbk8H26sjGvJnvg -Lgm/+6LVWR4EnUlU8aEWASEpTWq2lSRF3ZOvNstHnufyiDfcwDcl/IKKQiVQQ3mX -tw8Jf74= ------END CERTIFICATE-----` - -// skipcq: SCT-1000 -var validClientKey = `-----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAsc977g16Tan2j7YuA+zQOlDntb4Bkfs4sDOznOEvnozHwRZO -gfcPjVcA9AS5eZOGIRrsTssptrgVNDPoIHWoKk7LAKyyLM3dGp5PWeyMBoQA5cq+ -yPAT4JkJpDnBFfwxXB99osJH0z3jSTRa62CSVvPRBisK4B9AlLQfcleEQlKJugy9 -tOAjG7zodwEi+J4AYQHmOiwL38ZsKq9We5y4HMQ0E7de0FoU5QHrtuPNrTuwVwrq -825lcEAAFey6Btngx+sziysPHWHYOq4xOZ1UPBApeaAFLguzusc/4VwM7kzRNr4V -OD8aeC3CtKLhBBVVxHI5ZlaHS+YylNGYD4+FxQIDAQABAoIBAQCjV2MVcDQmHDhw -FH95A5bVu3TgM8flfs64rwYU25iPIexuqDs+kOMsh/xMLfrkgGz7BGyIhYGwZLK1 -3ekjyHHPS8qYuAyFtCelSEDE7tRDOAhLEFDq7gCUloGQ561EsQP3CMa1OZwZpgSh -PwM2ruRAFIK0E95NvOfqsv0gYN0Svo7hYjNsvW6ok/ZGMyN2ikcRR04wGOFOGjfT -xTmfURc9ejnOjHAOqLTpToPwM1/gWWR2iMQefC4njy4MO2BXqOPUmHxmmR4PYhu2 -8EcKbyRs+/fvL3GgD3VAlOe5vnkfBzssQhHmexgSk5lHZrcSxUGXYGrYKPAeV2mk -5HRBWp0RAoGBAOUn5w+NCAugcTGP0hfNlyGXsXqUZvnMyFWvUcxgzgPlJyEyDnKn -aIb1DFOF2HckCfLZdrHqqgaF6K3TDvW9BgSKIsvISpo1S95ZPD6DKUo6YQ10CQRW -q/ZZVbxtFksVgFRGYpCVmPNULmx7CiXDT1b/suwNMAwCZwiNPTSvKQVLAoGBAMaj -zDo1/eepRslqnz5s8hh7dGEjfG/ZJcLgAJAxCyAgnIP4Tls7QkNhCVp9LcN6i1bc -CnT6AIuZRXSJWEdp4k2QnVFUmh9Q5MGgwrKYSY5M/1puTISlF1yQ8J6FX8BlDVmy -4dyaSyC0RIvgBzF9/KBDxxmJcHgGQ0awLeeyl4cvAoGBAN83FS3itLmOmXQrofyp -uNNyDeFXeU9OmL5OPqGUkljc+Favib9JLtp3DIC3WfoD0uUJy0LXULN18QaRFnts -mtYFMIvMGE9KJxL5XWOPI8M4Rp1yL+5X9r3Km2cl45dT5GMzBIPOFOTBVU86MtJC -A6C9Bi5FUk4AcRi1a69MB+stAoGAWNiwoyS9IV38dGCFQ4W1LzAg2MXnhZuJoUVR -2yykfkU33Gs2mOXDeKGxblDpJDLumfYnkzSzA72VbE92NdLtTqYtR1Bg8zraZqTC -EOG+nLBh0o/dF8ND1LpbdXvQXRyVwRYaofI9Qi5/LlUQwplIYmKObiSkMnsSok5w -6d5emi8CgYBjtUihOFaAmgqkTHOn4j4eKS1O7/H8QQSVe5M0bocmAIbgJ4At3GnI -E1JcIY2SZtSwAWs6aQPGE42gwsNCCsQWdJNtViO23JbCwlcPToC4aDfc0JJNaYqp -oVV7C5jmJh9VRd2tXIXIZMMNOfThfNf2qDQuJ1S2t5KugozFiRsHUg== ------END RSA PRIVATE KEY-----` - -func TestNewRemoteKeymanager(t *testing.T) { - tests := []struct { - name string - opts *KeymanagerOpts - clientCert string - clientKey string - caCert string - err string - }{ - { - name: "NoCertificates", - opts: &KeymanagerOpts{ - RemoteCertificate: nil, - }, - err: "certificate configuration is missing", - }, - { - name: "NoClientCertificate", - opts: &KeymanagerOpts{ - RemoteCertificate: &CertificateConfig{ - RequireTls: true, - }, - }, - err: "client certificate is required", - }, - { - name: "NoClientKey", - opts: &KeymanagerOpts{ - RemoteCertificate: &CertificateConfig{ - RequireTls: true, - ClientCertPath: "/foo/client.crt", - ClientKeyPath: "", - }, - }, - err: "client key is required", - }, - { - name: "MissingClientKey", - opts: &KeymanagerOpts{ - RemoteCertificate: &CertificateConfig{ - RequireTls: true, - ClientCertPath: "/foo/client.crt", - ClientKeyPath: "/foo/client.key", - CACertPath: "", - }, - }, - err: "failed to obtain client's certificate and/or key", - }, - { - name: "BadClientCert", - clientCert: `bad`, - clientKey: validClientKey, - opts: &KeymanagerOpts{ - RemoteCertificate: &CertificateConfig{ - RequireTls: true, - }, - }, - err: "failed to obtain client's certificate and/or key: tls: failed to find any PEM data in certificate input", - }, - { - name: "BadClientKey", - clientCert: validClientCert, - clientKey: `bad`, - opts: &KeymanagerOpts{ - RemoteCertificate: &CertificateConfig{ - RequireTls: true, - }, - }, - err: "failed to obtain client's certificate and/or key: tls: failed to find any PEM data in key input", - }, - { - name: "MissingCACert", - clientCert: validClientCert, - clientKey: validClientKey, - opts: &KeymanagerOpts{ - RemoteCertificate: &CertificateConfig{ - RequireTls: true, - CACertPath: `bad`, - }, - }, - err: "failed to obtain server's CA certificate: open bad: no such file or directory", - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - if test.caCert != "" || test.clientCert != "" || test.clientKey != "" { - dir := fmt.Sprintf("%s/%s", t.TempDir(), test.name) - require.NoError(t, os.MkdirAll(dir, 0777)) - if test.caCert != "" { - caCertPath := fmt.Sprintf("%s/ca.crt", dir) - err := os.WriteFile(caCertPath, []byte(test.caCert), params.BeaconIoConfig().ReadWritePermissions) - require.NoError(t, err, "Failed to write CA certificate") - test.opts.RemoteCertificate.CACertPath = caCertPath - } - if test.clientCert != "" { - clientCertPath := fmt.Sprintf("%s/client.crt", dir) - err := os.WriteFile(clientCertPath, []byte(test.clientCert), params.BeaconIoConfig().ReadWritePermissions) - require.NoError(t, err, "Failed to write client certificate") - test.opts.RemoteCertificate.ClientCertPath = clientCertPath - } - if test.clientKey != "" { - clientKeyPath := fmt.Sprintf("%s/client.key", dir) - err := os.WriteFile(clientKeyPath, []byte(test.clientKey), params.BeaconIoConfig().ReadWritePermissions) - require.NoError(t, err, "Failed to write client key") - test.opts.RemoteCertificate.ClientKeyPath = clientKeyPath - } - } - _, err := NewKeymanager(context.Background(), &SetupConfig{Opts: test.opts, MaxMessageSize: 1}) - if test.err == "" { - require.NoError(t, err) - } else { - require.ErrorContains(t, test.err, err) - } - }) - } -} - -func TestNewRemoteKeymanager_TlsDisabled(t *testing.T) { - opts := &KeymanagerOpts{ - RemoteCertificate: &CertificateConfig{ - RequireTls: false, - }, - } - _, err := NewKeymanager(context.Background(), &SetupConfig{Opts: opts, MaxMessageSize: 1}) - assert.NoError(t, err) -} - -func TestRemoteKeymanager_Sign(t *testing.T) { - ctrl := gomock.NewController(t) - m := mock.NewMockRemoteSignerClient(ctrl) - k := &Keymanager{ - client: m, - } - - // Expect error handling to work. - m.EXPECT().Sign( - gomock.Any(), // ctx - gomock.Any(), // epoch - ).Return(nil, errors.New("could not sign")) - _, err := k.Sign(context.Background(), nil) - require.ErrorContains(t, "could not sign", err) - - // Expected proper error handling for signing response statuses. - m.EXPECT().Sign( - gomock.Any(), // ctx - gomock.Any(), // epoch - ).Return(&validatorpb.SignResponse{ - Status: validatorpb.SignResponse_FAILED, - }, nil /*err*/) - _, err = k.Sign(context.Background(), nil) - if err == nil { - t.Fatal(err) - } - if err != ErrSigningFailed { - t.Errorf("Expected %v, received %v", ErrSigningFailed, err) - } - m.EXPECT().Sign( - gomock.Any(), // ctx - gomock.Any(), // epoch - ).Return(&validatorpb.SignResponse{ - Status: validatorpb.SignResponse_DENIED, - }, nil /*err*/) - _, err = k.Sign(context.Background(), nil) - if err == nil { - t.Fatal(err) - } - if err != ErrSigningDenied { - t.Errorf("Expected %v, received %v", ErrSigningDenied, err) - } - - // Expected signing success. - randKey, err := bls.RandKey() - require.NoError(t, err) - data := []byte("hello-world") - sig := randKey.Sign(data) - m.EXPECT().Sign( - gomock.Any(), // ctx - gomock.Any(), // epoch - ).Return(&validatorpb.SignResponse{ - Status: validatorpb.SignResponse_SUCCEEDED, - Signature: sig.Marshal(), - }, nil /*err*/) - resp, err := k.Sign(context.Background(), nil) - require.NoError(t, err) - assert.DeepEqual(t, sig.Marshal(), resp.Marshal()) -} - -func TestRemoteKeymanager_FetchValidatingPublicKeys(t *testing.T) { - ctrl := gomock.NewController(t) - m := mock.NewMockRemoteSignerClient(ctrl) - k := &Keymanager{ - client: m, - accountsChangedFeed: new(event.Feed), - } - - // Expect error handling to work. - m.EXPECT().ListValidatingPublicKeys( - gomock.Any(), // ctx - gomock.Any(), // epoch - ).Return(nil, errors.New("could not fetch keys")) - _, err := k.FetchValidatingPublicKeys(context.Background()) - require.ErrorContains(t, "could not fetch keys", err) - - // Expect an empty response to return empty keys. - m.EXPECT().ListValidatingPublicKeys( - gomock.Any(), // ctx - gomock.Any(), // epoch - ).Return(&validatorpb.ListPublicKeysResponse{ - ValidatingPublicKeys: make([][]byte, 0), - }, nil /*err*/) - keys, err := k.FetchValidatingPublicKeys(context.Background()) - require.NoError(t, err) - assert.Equal(t, 0, len(keys), "Expected empty response") - - numKeys := 10 - pubKeys := make([][]byte, numKeys) - for i := 0; i < numKeys; i++ { - key := make([]byte, 48) - copy(key, strconv.Itoa(i)) - pubKeys[i] = key - } - m.EXPECT().ListValidatingPublicKeys( - gomock.Any(), // ctx - gomock.Any(), // epoch - ).Return(&validatorpb.ListPublicKeysResponse{ - ValidatingPublicKeys: pubKeys, - }, nil /*err*/) - keys, err = k.FetchValidatingPublicKeys(context.Background()) - require.NoError(t, err) - rawKeys := make([][]byte, len(keys)) - for i := 0; i < len(rawKeys); i++ { - rawKeys[i] = keys[i][:] - } - assert.DeepEqual(t, pubKeys, rawKeys) -} - -func TestUnmarshalOptionsFile_DefaultRequireTls(t *testing.T) { - optsWithoutTls := struct { - RemoteCertificate struct { - ClientCertPath string - ClientKeyPath string - CACertPath string - } - }{} - var buffer bytes.Buffer - b, err := json.Marshal(optsWithoutTls) - require.NoError(t, err) - _, err = buffer.Write(b) - require.NoError(t, err) - r := io.NopCloser(&buffer) - - opts, err := UnmarshalOptionsFile(r) - assert.NoError(t, err) - assert.Equal(t, true, opts.RemoteCertificate.RequireTls) -} - -func TestReloadPublicKeys(t *testing.T) { - hook := logTest.NewGlobal() - ctx := context.Background() - ctrl := gomock.NewController(t) - m := mock.NewMockRemoteSignerClient(ctrl) - - k := &Keymanager{ - client: m, - accountsChangedFeed: new(event.Feed), - orderedPubKeys: [][fieldparams.BLSPubkeyLength]byte{bytesutil.ToBytes48([]byte("100"))}, - } - - // Add key - m.EXPECT().ListValidatingPublicKeys( - gomock.Any(), // ctx - gomock.Any(), // epoch - ).Return(&validatorpb.ListPublicKeysResponse{ - // Return keys in reverse order to verify ordering - ValidatingPublicKeys: [][]byte{[]byte("200"), []byte("100")}, - }, nil /* err */) - - keys, err := k.ReloadPublicKeys(ctx) - require.NoError(t, err) - assert.DeepEqual(t, [][fieldparams.BLSPubkeyLength]byte{bytesutil.ToBytes48([]byte("100")), bytesutil.ToBytes48([]byte("200"))}, k.orderedPubKeys) - assert.DeepEqual(t, keys, k.orderedPubKeys) - assert.LogsContain(t, hook, keymanager.KeysReloaded) - - hook.Reset() - - // Remove key - m.EXPECT().ListValidatingPublicKeys( - gomock.Any(), // ctx - gomock.Any(), // epoch - ).Return(&validatorpb.ListPublicKeysResponse{ - ValidatingPublicKeys: [][]byte{[]byte("200")}, - }, nil /* err */) - - keys, err = k.ReloadPublicKeys(ctx) - require.NoError(t, err) - assert.DeepEqual(t, [][fieldparams.BLSPubkeyLength]byte{bytesutil.ToBytes48([]byte("200"))}, k.orderedPubKeys) - assert.DeepEqual(t, keys, k.orderedPubKeys) - assert.LogsContain(t, hook, keymanager.KeysReloaded) - - hook.Reset() - - // Change key - m.EXPECT().ListValidatingPublicKeys( - gomock.Any(), // ctx - gomock.Any(), // epoch - ).Return(&validatorpb.ListPublicKeysResponse{ - ValidatingPublicKeys: [][]byte{[]byte("300")}, - }, nil /* err */) - - keys, err = k.ReloadPublicKeys(ctx) - require.NoError(t, err) - assert.DeepEqual(t, [][fieldparams.BLSPubkeyLength]byte{bytesutil.ToBytes48([]byte("300"))}, k.orderedPubKeys) - assert.DeepEqual(t, keys, k.orderedPubKeys) - assert.LogsContain(t, hook, keymanager.KeysReloaded) - - hook.Reset() - - // No change - m.EXPECT().ListValidatingPublicKeys( - gomock.Any(), // ctx - gomock.Any(), // epoch - ).Return(&validatorpb.ListPublicKeysResponse{ - ValidatingPublicKeys: [][]byte{[]byte("300")}, - }, nil /* err */) - - keys, err = k.ReloadPublicKeys(ctx) - require.NoError(t, err) - assert.DeepEqual(t, [][fieldparams.BLSPubkeyLength]byte{bytesutil.ToBytes48([]byte("300"))}, k.orderedPubKeys) - assert.DeepEqual(t, keys, k.orderedPubKeys) - assert.LogsDoNotContain(t, hook, keymanager.KeysReloaded) -} diff --git a/validator/keymanager/remote/log.go b/validator/keymanager/remote/log.go deleted file mode 100644 index 3e7e5ec2f0..0000000000 --- a/validator/keymanager/remote/log.go +++ /dev/null @@ -1,5 +0,0 @@ -package remote - -import "github.com/sirupsen/logrus" - -var log = logrus.WithField("prefix", "remote-keymanager") diff --git a/validator/keymanager/remote/mock/BUILD.bazel b/validator/keymanager/remote/mock/BUILD.bazel deleted file mode 100644 index 303bb41afe..0000000000 --- a/validator/keymanager/remote/mock/BUILD.bazel +++ /dev/null @@ -1,21 +0,0 @@ -load("@prysm//tools/go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - testonly = True, - srcs = ["mock_keymanager.go"], - importpath = "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote/mock", - visibility = ["//visibility:public"], - deps = [ - "//async/event:go_default_library", - "//beacon-chain/core/signing:go_default_library", - "//config/fieldparams:go_default_library", - "//crypto/bls:go_default_library", - "//encoding/bytesutil:go_default_library", - "//proto/eth/service:go_default_library", - "//proto/prysm/v1alpha1/validator-client:go_default_library", - "//testing/util:go_default_library", - "//time/slots:go_default_library", - "//validator/keymanager:go_default_library", - ], -) diff --git a/validator/keymanager/remote/mock/mock_keymanager.go b/validator/keymanager/remote/mock/mock_keymanager.go deleted file mode 100644 index ea44162b76..0000000000 --- a/validator/keymanager/remote/mock/mock_keymanager.go +++ /dev/null @@ -1,82 +0,0 @@ -package mock - -import ( - "context" - "errors" - - "github.com/prysmaticlabs/prysm/v3/async/event" - "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/signing" - fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams" - "github.com/prysmaticlabs/prysm/v3/crypto/bls" - "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" - ethpbservice "github.com/prysmaticlabs/prysm/v3/proto/eth/service" - validatorpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1/validator-client" - "github.com/prysmaticlabs/prysm/v3/testing/util" - "github.com/prysmaticlabs/prysm/v3/time/slots" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager" -) - -// MockKeymanager -- -type MockKeymanager struct { - PublicKeys [][fieldparams.BLSPubkeyLength]byte - ReloadPublicKeysChan chan [][fieldparams.BLSPubkeyLength]byte - ReloadPublicKeysCalled bool - accountsChangedFeed *event.Feed -} - -func NewMock() MockKeymanager { - return MockKeymanager{ - accountsChangedFeed: new(event.Feed), - ReloadPublicKeysChan: make(chan [][fieldparams.BLSPubkeyLength]byte, 1), - } -} - -// FetchValidatingPublicKeys -- -func (m *MockKeymanager) FetchValidatingPublicKeys(context.Context) ([][fieldparams.BLSPubkeyLength]byte, error) { - return m.PublicKeys, nil -} - -// Sign -- -func (*MockKeymanager) Sign(_ context.Context, s *validatorpb.SignRequest) (bls.Signature, error) { - key, err := bls.RandKey() - if err != nil { - return nil, err - } - st, _ := util.DeterministicGenesisState(nil, 1) - e := slots.ToEpoch(st.Slot()) - byteValue, err := signing.ComputeDomainAndSign(st, e, s.SigningSlot, bytesutil.ToBytes4(s.SignatureDomain), key) - if err != nil { - return nil, err - } - return bls.SignatureFromBytes(byteValue) -} - -// SubscribeAccountChanges -- -func (m *MockKeymanager) SubscribeAccountChanges(chan [][fieldparams.BLSPubkeyLength]byte) event.Subscription { - return m.accountsChangedFeed.Subscribe(m.ReloadPublicKeysChan) -} - -// ReloadPublicKeys -- -func (m *MockKeymanager) ReloadPublicKeys(context.Context) ([][fieldparams.BLSPubkeyLength]byte, error) { - m.ReloadPublicKeysCalled = true - m.ReloadPublicKeysChan <- m.PublicKeys - return m.PublicKeys, nil -} - -// ExtractKeystores -- -func (*MockKeymanager) ExtractKeystores( - _ context.Context, _ []bls.PublicKey, _ string, -) ([]*keymanager.Keystore, error) { - return nil, errors.New("extracting keys not supported for a remote keymanager") -} - -// ListKeymanagerAccounts -- -func (*MockKeymanager) ListKeymanagerAccounts( - context.Context, keymanager.ListKeymanagerAccountConfig) error { - return nil -} - -func (*MockKeymanager) DeleteKeystores(context.Context, [][]byte, -) ([]*ethpbservice.DeletedKeystoreStatus, error) { - return nil, nil -} diff --git a/validator/keymanager/types.go b/validator/keymanager/types.go index fb1445ade3..63a2ac8b19 100644 --- a/validator/keymanager/types.go +++ b/validator/keymanager/types.go @@ -100,8 +100,6 @@ const ( Local Kind = iota // Derived keymanager using a hierarchical-deterministic algorithm. Derived - // Remote keymanager capable of remote-signing data. - Remote // Web3Signer keymanager capable of signing data using a remote signer called Web3Signer. Web3Signer ) @@ -121,8 +119,6 @@ func (k Kind) String() string { // multiple directories will cause the isValid function to fail in wallet.go // and may result in using a unintended wallet. return "direct" - case Remote: - return "remote" case Web3Signer: return "web3signer" default: @@ -137,8 +133,6 @@ func ParseKind(k string) (Kind, error) { return Derived, nil case "direct", "imported", "local": return Local, nil - case "remote": - return Remote, nil case "web3signer": return Web3Signer, nil default: diff --git a/validator/keymanager/types_test.go b/validator/keymanager/types_test.go index 2fc47fcc66..13dce64745 100644 --- a/validator/keymanager/types_test.go +++ b/validator/keymanager/types_test.go @@ -10,14 +10,12 @@ import ( "github.com/prysmaticlabs/prysm/v3/validator/keymanager" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/derived" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/local" - "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" remoteweb3signer "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote-web3signer" ) var ( _ = keymanager.IKeymanager(&local.Keymanager{}) _ = keymanager.IKeymanager(&derived.Keymanager{}) - _ = keymanager.IKeymanager(&remote.Keymanager{}) // More granular assertions. _ = keymanager.KeysFetcher(&local.Keymanager{}) diff --git a/validator/rpc/wallet.go b/validator/rpc/wallet.go index 47ba1aab3e..0cb5e843a8 100644 --- a/validator/rpc/wallet.go +++ b/validator/rpc/wallet.go @@ -50,8 +50,6 @@ func (s *Server) CreateWallet(ctx context.Context, req *pb.CreateWalletRequest) switch s.wallet.KeymanagerKind() { case keymanager.Derived: keymanagerKind = pb.KeymanagerKind_DERIVED - case keymanager.Remote: - keymanagerKind = pb.KeymanagerKind_REMOTE case keymanager.Web3Signer: keymanagerKind = pb.KeymanagerKind_WEB3SIGNER } @@ -132,8 +130,6 @@ func (s *Server) WalletConfig(_ context.Context, _ *empty.Empty) (*pb.WalletResp keymanagerKind = pb.KeymanagerKind_DERIVED case keymanager.Local: keymanagerKind = pb.KeymanagerKind_IMPORTED - case keymanager.Remote: - keymanagerKind = pb.KeymanagerKind_REMOTE case keymanager.Web3Signer: keymanagerKind = pb.KeymanagerKind_WEB3SIGNER }