From bf371120bcc6262fe9877d160ea2ef38273da8e3 Mon Sep 17 00:00:00 2001 From: rauljordan Date: Mon, 27 Jul 2020 09:57:33 -0500 Subject: [PATCH 01/21] change default wallet dir path to not be hidden --- validator/accounts/v2/wallet.go | 4 ++-- validator/flags/flags.go | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/validator/accounts/v2/wallet.go b/validator/accounts/v2/wallet.go index 194251676f5..264f23c41e8 100644 --- a/validator/accounts/v2/wallet.go +++ b/validator/accounts/v2/wallet.go @@ -37,9 +37,9 @@ var ( const ( // WalletDefaultDirName for accounts-v2. - WalletDefaultDirName = ".prysm-wallet-v2" + WalletDefaultDirName = "prysm-wallet-v2" // PasswordsDefaultDirName where account passwords are stored. - PasswordsDefaultDirName = ".prysm-wallet-v2-passwords" + PasswordsDefaultDirName = "prysm-wallet-v2-passwords" // KeymanagerConfigFileName for the keymanager used by the wallet: direct, derived, or remote. KeymanagerConfigFileName = "keymanageropts.json" // DirectoryPermissions for directories created under the wallet path. diff --git a/validator/flags/flags.go b/validator/flags/flags.go index 0e7fa8be35f..0a9c35e1231 100644 --- a/validator/flags/flags.go +++ b/validator/flags/flags.go @@ -10,6 +10,8 @@ import ( "time" "github.com/urfave/cli/v2" + + v2 "github.com/prysmaticlabs/prysm/validator/accounts/v2" ) var ( @@ -124,14 +126,14 @@ var ( WalletDirFlag = &cli.StringFlag{ Name: "wallet-dir", Usage: "Path to a wallet directory on-disk for Prysm validator accounts", - Value: DefaultValidatorDir(), + Value: DefaultValidatorDir()+v2.WalletDefaultDirName, } // WalletPasswordsDirFlag defines the path for a passwords directory for // Prysm accounts-v2. WalletPasswordsDirFlag = &cli.StringFlag{ Name: "passwords-dir", Usage: "Path to a directory on-disk where account passwords are stored", - Value: DefaultValidatorDir(), + Value: DefaultValidatorDir()+v2.PasswordsDefaultDirName, } // PasswordFileFlag is used to enter a file to get a password for new account creation, non-interactively. PasswordFileFlag = &cli.StringFlag{ From dd4b6832e7f9e9d1b48744f31957bd3e2ac4b403 Mon Sep 17 00:00:00 2001 From: shayzluf Date: Tue, 28 Jul 2020 11:25:20 +0300 Subject: [PATCH 02/21] gaz + pass wallet dir --- validator/accounts/v2/cmd_wallet.go | 1 + validator/flags/BUILD.bazel | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/validator/accounts/v2/cmd_wallet.go b/validator/accounts/v2/cmd_wallet.go index 27c22e1af4a..34b16a578be 100644 --- a/validator/accounts/v2/cmd_wallet.go +++ b/validator/accounts/v2/cmd_wallet.go @@ -44,6 +44,7 @@ var WalletCommands = &cli.Command{ flags.RemoteSignerCertPathFlag, flags.RemoteSignerKeyPathFlag, flags.RemoteSignerCACertPathFlag, + flags.WalletPasswordsDirFlag, featureconfig.AltonaTestnet, featureconfig.MedallaTestnet, }, diff --git a/validator/flags/BUILD.bazel b/validator/flags/BUILD.bazel index f04a6f9cad8..d81088496b3 100644 --- a/validator/flags/BUILD.bazel +++ b/validator/flags/BUILD.bazel @@ -8,5 +8,8 @@ go_library( ], importpath = "github.com/prysmaticlabs/prysm/validator/flags", visibility = ["//validator:__subpackages__"], - deps = ["@com_github_urfave_cli_v2//:go_default_library"], + deps = [ + "//validator/accounts/v2:go_default_library", + "@com_github_urfave_cli_v2//:go_default_library", + ], ) From d485e09b56a48f493195fb9b753ad2b45a78217f Mon Sep 17 00:00:00 2001 From: shayzluf Date: Tue, 28 Jul 2020 11:59:05 +0300 Subject: [PATCH 03/21] gaz + move const to flags --- validator/accounts/v2/wallet.go | 21 +++++---------------- validator/flags/BUILD.bazel | 5 +---- validator/flags/flags.go | 15 ++++++++++++--- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/validator/accounts/v2/wallet.go b/validator/accounts/v2/wallet.go index c978b0c0fa1..4a90f1050e7 100644 --- a/validator/accounts/v2/wallet.go +++ b/validator/accounts/v2/wallet.go @@ -37,17 +37,6 @@ var ( } ) -const ( - // WalletDefaultDirName for accounts-v2. - WalletDefaultDirName = "prysm-wallet-v2" - // PasswordsDefaultDirName where account passwords are stored. - PasswordsDefaultDirName = "prysm-wallet-v2-passwords" - // KeymanagerConfigFileName for the keymanager used by the wallet: direct, derived, or remote. - KeymanagerConfigFileName = "keymanageropts.json" - // DirectoryPermissions for directories created under the wallet path. - DirectoryPermissions = os.ModePerm -) - // Wallet is a primitive in Prysm's v2 account management which // has the capability of creating new accounts, reading existing accounts, // and providing secure access to eth2 secrets depending on an @@ -103,7 +92,7 @@ func NewWallet( if err != nil { return nil, errors.Wrap(err, "could not get password directory") } - if err := os.MkdirAll(passwordsDir, DirectoryPermissions); err != nil { + if err := os.MkdirAll(passwordsDir, flags.DirectoryPermissions); err != nil { return nil, errors.Wrap(err, "could not create passwords directory") } w.passwordsDir = passwordsDir @@ -150,11 +139,11 @@ func OpenWallet(cliCtx *cli.Context) (*Wallet, error) { // SaveWallet persists the wallet's directories to disk. func (w *Wallet) SaveWallet() error { - if err := os.MkdirAll(w.accountsPath, DirectoryPermissions); err != nil { + if err := os.MkdirAll(w.accountsPath, flags.DirectoryPermissions); err != nil { return errors.Wrap(err, "could not create wallet directory") } if w.keymanagerKind == v2keymanager.Direct { - if err := os.MkdirAll(w.passwordsDir, DirectoryPermissions); err != nil { + if err := os.MkdirAll(w.passwordsDir, flags.DirectoryPermissions); err != nil { return errors.Wrap(err, "could not create passwords directory") } } @@ -323,7 +312,7 @@ func AccountTimestamp(fileName string) (time.Time, error) { // ReadKeymanagerConfigFromDisk opens a keymanager config file // for reading if it exists at the wallet path. func (w *Wallet) ReadKeymanagerConfigFromDisk(ctx context.Context) (io.ReadCloser, error) { - configFilePath := filepath.Join(w.accountsPath, KeymanagerConfigFileName) + configFilePath := filepath.Join(w.accountsPath, flags.KeymanagerConfigFileName) if !fileExists(configFilePath) { return nil, fmt.Errorf("no keymanager config file found at path: %s", w.accountsPath) } @@ -333,7 +322,7 @@ func (w *Wallet) ReadKeymanagerConfigFromDisk(ctx context.Context) (io.ReadClose // WriteKeymanagerConfigToDisk takes an encoded keymanager config file // and writes it to the wallet path. func (w *Wallet) WriteKeymanagerConfigToDisk(ctx context.Context, encoded []byte) error { - configFilePath := filepath.Join(w.accountsPath, KeymanagerConfigFileName) + configFilePath := filepath.Join(w.accountsPath, flags.KeymanagerConfigFileName) // Write the config file to disk. if err := ioutil.WriteFile(configFilePath, encoded, os.ModePerm); err != nil { return errors.Wrapf(err, "could not write %s", configFilePath) diff --git a/validator/flags/BUILD.bazel b/validator/flags/BUILD.bazel index d81088496b3..f04a6f9cad8 100644 --- a/validator/flags/BUILD.bazel +++ b/validator/flags/BUILD.bazel @@ -8,8 +8,5 @@ go_library( ], importpath = "github.com/prysmaticlabs/prysm/validator/flags", visibility = ["//validator:__subpackages__"], - deps = [ - "//validator/accounts/v2:go_default_library", - "@com_github_urfave_cli_v2//:go_default_library", - ], + deps = ["@com_github_urfave_cli_v2//:go_default_library"], ) diff --git a/validator/flags/flags.go b/validator/flags/flags.go index 0a9c35e1231..ff9ebeee4c1 100644 --- a/validator/flags/flags.go +++ b/validator/flags/flags.go @@ -10,8 +10,17 @@ import ( "time" "github.com/urfave/cli/v2" +) - v2 "github.com/prysmaticlabs/prysm/validator/accounts/v2" +const ( + // WalletDefaultDirName for accounts-v2. + WalletDefaultDirName = "prysm-wallet-v2" + // PasswordsDefaultDirName where account passwords are stored. + PasswordsDefaultDirName = "prysm-wallet-v2-passwords" + // KeymanagerConfigFileName for the keymanager used by the wallet: direct, derived, or remote. + KeymanagerConfigFileName = "keymanageropts.json" + // DirectoryPermissions for directories created under the wallet path. + DirectoryPermissions = os.ModePerm ) var ( @@ -126,14 +135,14 @@ var ( WalletDirFlag = &cli.StringFlag{ Name: "wallet-dir", Usage: "Path to a wallet directory on-disk for Prysm validator accounts", - Value: DefaultValidatorDir()+v2.WalletDefaultDirName, + Value: DefaultValidatorDir() + WalletDefaultDirName, } // WalletPasswordsDirFlag defines the path for a passwords directory for // Prysm accounts-v2. WalletPasswordsDirFlag = &cli.StringFlag{ Name: "passwords-dir", Usage: "Path to a directory on-disk where account passwords are stored", - Value: DefaultValidatorDir()+v2.PasswordsDefaultDirName, + Value: DefaultValidatorDir() + PasswordsDefaultDirName, } // PasswordFileFlag is used to enter a file to get a password for new account creation, non-interactively. PasswordFileFlag = &cli.StringFlag{ From 631e9b027ca1db8795dd632954bb81afe793cc3e Mon Sep 17 00:00:00 2001 From: shayzluf Date: Tue, 28 Jul 2020 12:15:36 +0300 Subject: [PATCH 04/21] move to flags --- validator/accounts/v2/accounts_export.go | 2 +- validator/accounts/v2/accounts_import.go | 4 ++-- validator/accounts/v2/accounts_list.go | 2 +- validator/accounts/v2/prompt.go | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/validator/accounts/v2/accounts_export.go b/validator/accounts/v2/accounts_export.go index b3653d109c5..f6d7498a195 100644 --- a/validator/accounts/v2/accounts_export.go +++ b/validator/accounts/v2/accounts_export.go @@ -130,7 +130,7 @@ func (w *Wallet) zipAccounts(accounts []string, targetPath string) error { if strings.Contains(path, accountName) { // Add all files under the account folder to the archive. isAccount = true - } else if !info.IsDir() && info.Name() == KeymanagerConfigFileName { + } else if !info.IsDir() && info.Name() == flags.KeymanagerConfigFileName { // Add the keymanager config file to the archive as well. isAccount = true } diff --git a/validator/accounts/v2/accounts_import.go b/validator/accounts/v2/accounts_import.go index aadfccc991b..0a9ec634b06 100644 --- a/validator/accounts/v2/accounts_import.go +++ b/validator/accounts/v2/accounts_import.go @@ -34,10 +34,10 @@ func ImportAccount(cliCtx *cli.Context) error { } accountsPath := filepath.Join(walletDir, v2keymanager.Direct.String()) - if err := os.MkdirAll(accountsPath, DirectoryPermissions); err != nil { + if err := os.MkdirAll(accountsPath, flags.DirectoryPermissions); err != nil { return errors.Wrap(err, "could not create wallet directory") } - if err := os.MkdirAll(passwordsDir, DirectoryPermissions); err != nil { + if err := os.MkdirAll(passwordsDir, flags.DirectoryPermissions); err != nil { return errors.Wrap(err, "could not create passwords directory") } accountsImported, err := unzipArchiveToTarget(backupDir, filepath.Dir(walletDir)) diff --git a/validator/accounts/v2/accounts_list.go b/validator/accounts/v2/accounts_list.go index b34d29f4dab..4749f8b2a64 100644 --- a/validator/accounts/v2/accounts_list.go +++ b/validator/accounts/v2/accounts_list.go @@ -223,7 +223,7 @@ func listRemoteKeymanagerAccounts( fmt.Printf("(keymanager kind) %s\n", au.BrightGreen("remote signer").Bold()) fmt.Printf( "(configuration file path) %s\n", - au.BrightGreen(filepath.Join(wallet.AccountsDir(), KeymanagerConfigFileName)).Bold(), + au.BrightGreen(filepath.Join(wallet.AccountsDir(), flags.KeymanagerConfigFileName)).Bold(), ) ctx := context.Background() fmt.Println(" ") diff --git a/validator/accounts/v2/prompt.go b/validator/accounts/v2/prompt.go index 174cb81449c..369a7f58157 100644 --- a/validator/accounts/v2/prompt.go +++ b/validator/accounts/v2/prompt.go @@ -89,9 +89,9 @@ func inputDirectory(cliCtx *cli.Context, promptText string, flag *cli.StringFlag func appendDirName(inputtedDir string, flagName string) string { switch flagName { case flags.WalletDirFlag.Name: - inputtedDir = filepath.Join(inputtedDir, WalletDefaultDirName) + inputtedDir = filepath.Join(inputtedDir, flags.WalletDefaultDirName) case flags.WalletPasswordsDirFlag.Name: - inputtedDir = filepath.Join(inputtedDir, PasswordsDefaultDirName) + inputtedDir = filepath.Join(inputtedDir, flags.PasswordsDefaultDirName) } return inputtedDir } From 15ada8f6282f4bf6da74a96013863d0750a40f63 Mon Sep 17 00:00:00 2001 From: shayzluf Date: Tue, 28 Jul 2020 12:19:46 +0300 Subject: [PATCH 05/21] move to flags --- validator/node/node.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/validator/node/node.go b/validator/node/node.go index 53b3637abab..dc45b786a25 100644 --- a/validator/node/node.go +++ b/validator/node/node.go @@ -85,11 +85,11 @@ func NewValidatorClient(cliCtx *cli.Context) (*ValidatorClient, error) { if featureconfig.Get().EnableAccountsV2 { walletDir := cliCtx.String(flags.WalletDirFlag.Name) if walletDir == flags.DefaultValidatorDir() { - walletDir = path.Join(walletDir, accountsv2.WalletDefaultDirName) + walletDir = path.Join(walletDir, flags.WalletDefaultDirName) } passwordsDir := cliCtx.String(flags.WalletPasswordsDirFlag.Name) if passwordsDir == flags.DefaultValidatorDir() { - passwordsDir = path.Join(passwordsDir, accountsv2.PasswordsDefaultDirName) + passwordsDir = path.Join(passwordsDir, flags.PasswordsDefaultDirName) } // Read the wallet from the specified path. wallet, err := accountsv2.OpenWallet(cliCtx) From 092b43a60557a2153455732376e57c06c31bef62 Mon Sep 17 00:00:00 2001 From: shayzluf Date: Tue, 28 Jul 2020 13:08:53 +0300 Subject: [PATCH 06/21] use filepath join in order to create a valid dir name --- validator/flags/flags.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/validator/flags/flags.go b/validator/flags/flags.go index ff9ebeee4c1..326958e0c17 100644 --- a/validator/flags/flags.go +++ b/validator/flags/flags.go @@ -135,14 +135,14 @@ var ( WalletDirFlag = &cli.StringFlag{ Name: "wallet-dir", Usage: "Path to a wallet directory on-disk for Prysm validator accounts", - Value: DefaultValidatorDir() + WalletDefaultDirName, + Value: filepath.Join(DefaultValidatorDir(), WalletDefaultDirName), } // WalletPasswordsDirFlag defines the path for a passwords directory for // Prysm accounts-v2. WalletPasswordsDirFlag = &cli.StringFlag{ Name: "passwords-dir", Usage: "Path to a directory on-disk where account passwords are stored", - Value: DefaultValidatorDir() + PasswordsDefaultDirName, + Value: filepath.Join(DefaultValidatorDir(), PasswordsDefaultDirName), } // PasswordFileFlag is used to enter a file to get a password for new account creation, non-interactively. PasswordFileFlag = &cli.StringFlag{ From b73fe3f50b51a916dd14c668a91860faf558c878 Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 14:32:53 -0500 Subject: [PATCH 07/21] add wallet dir --- validator/accounts/v2/wallet.go | 2 ++ validator/accounts/v2/wallet_create.go | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/validator/accounts/v2/wallet.go b/validator/accounts/v2/wallet.go index 4a90f1050e7..6829d715c0c 100644 --- a/validator/accounts/v2/wallet.go +++ b/validator/accounts/v2/wallet.go @@ -42,6 +42,7 @@ var ( // and providing secure access to eth2 secrets depending on an // associated keymanager (either direct, derived, or remote signing enabled). type Wallet struct { + walletDir string accountsPath string passwordsDir string keymanagerKind v2keymanager.Kind @@ -79,6 +80,7 @@ func NewWallet( w := &Wallet{ accountsPath: accountsPath, keymanagerKind: keymanagerKind, + walletDir: walletDir, } if keymanagerKind == v2keymanager.Derived { walletPassword, err := inputPassword(cliCtx, newWalletPasswordPromptText, confirmPass) diff --git a/validator/accounts/v2/wallet_create.go b/validator/accounts/v2/wallet_create.go index 4eeeef0e948..0512c9d4fe5 100644 --- a/validator/accounts/v2/wallet_create.go +++ b/validator/accounts/v2/wallet_create.go @@ -29,7 +29,7 @@ func CreateWallet(cliCtx *cli.Context) error { if err = createDirectKeymanagerWallet(cliCtx, w); err != nil { return errors.Wrap(err, "could not initialize wallet with direct keymanager") } - log.WithField("wallet-path", w.accountsPath).Infof( + log.WithField("wallet-path", w.walletDir).Infof( "Successfully created wallet with on-disk keymanager configuration. " + "Make a new validator account with ./prysm.sh validator accounts-v2 create", ) @@ -37,7 +37,7 @@ func CreateWallet(cliCtx *cli.Context) error { if err = createDerivedKeymanagerWallet(cliCtx, w); err != nil { return errors.Wrap(err, "could not initialize wallet with derived keymanager") } - log.WithField("wallet-path", w.accountsPath).Infof( + log.WithField("wallet-path", w.walletDir).Infof( "Successfully created HD wallet and saved configuration to disk. " + "Make a new validator account with ./prysm.sh validator accounts-2 create", ) @@ -45,7 +45,7 @@ func CreateWallet(cliCtx *cli.Context) error { if err = createRemoteKeymanagerWallet(cliCtx, w); err != nil { return errors.Wrap(err, "could not initialize wallet with remote keymanager") } - log.WithField("wallet-path", w.accountsPath).Infof( + log.WithField("wallet-path", w.walletDir).Infof( "Successfully created wallet with remote keymanager configuration", ) default: From c53848e902222a343bd0c0d3ca64310efbc1b95a Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 16:20:19 -0500 Subject: [PATCH 08/21] return err no wallet found issues --- validator/accounts/v2/accounts_create.go | 20 ++------ validator/accounts/v2/accounts_export.go | 5 +- validator/accounts/v2/accounts_import.go | 29 ++++++------ validator/accounts/v2/accounts_list.go | 8 ++-- validator/accounts/v2/cmd_accounts.go | 10 ++-- validator/accounts/v2/cmd_wallet.go | 6 +-- validator/accounts/v2/prompt.go | 20 ++++---- validator/accounts/v2/wallet.go | 48 ++++++++++++++------ validator/accounts/v2/wallet_create.go | 22 +++++---- validator/accounts/v2/wallet_edit.go | 26 ++++++++++- validator/accounts/v2/wallet_recover_test.go | 4 +- validator/accounts/v2/wallet_test.go | 23 ++++++---- validator/flags/flags.go | 13 ++++-- validator/keymanager/v2/direct/BUILD.bazel | 2 + validator/keymanager/v2/direct/direct.go | 33 +++++++++++++- validator/main.go | 3 +- validator/usage.go | 1 - 17 files changed, 179 insertions(+), 94 deletions(-) diff --git a/validator/accounts/v2/accounts_create.go b/validator/accounts/v2/accounts_create.go index 04431d7792f..7ba87c7a2c9 100644 --- a/validator/accounts/v2/accounts_create.go +++ b/validator/accounts/v2/accounts_create.go @@ -20,23 +20,13 @@ var log = logrus.WithField("prefix", "accounts-v2") // a wallet from the user's specified path. func CreateAccount(cliCtx *cli.Context) error { ctx := context.Background() - walletDir, err := inputDirectory(cliCtx, walletDirPromptText, flags.WalletDirFlag) - if err != nil { - return errors.Wrapf(err, "Could not retrieve input directory") - } - ok, err := hasDir(walletDir) - if err != nil { - return err - } - // Create a new wallet if no directory exists. - if !ok { - err = CreateWallet(cliCtx) + wallet, err := OpenWallet(cliCtx) + if errors.Is(err, ErrNoWalletFound) { + wallet, err = CreateWallet(cliCtx) if err != nil { return errors.Wrapf(err, "Could not create wallet") } - } - wallet, err := OpenWallet(cliCtx) - if err != nil { + } else if err != nil { return errors.Wrap(err, "could not open wallet") } skipMnemonicConfirm := cliCtx.Bool(flags.SkipMnemonicConfirmFlag.Name) @@ -52,7 +42,7 @@ func CreateAccount(cliCtx *cli.Context) error { if !ok { return errors.New("not a direct keymanager") } - password, err := inputPassword(cliCtx, newAccountPasswordPromptText, confirmPass) + password, err := inputPassword(cliCtx, flags.AccountPasswordFileFlag, newAccountPasswordPromptText, confirmPass) if err != nil { return errors.Wrap(err, "could not input new account password") } diff --git a/validator/accounts/v2/accounts_export.go b/validator/accounts/v2/accounts_export.go index cdf2de986f2..9b401d28b38 100644 --- a/validator/accounts/v2/accounts_export.go +++ b/validator/accounts/v2/accounts_export.go @@ -28,9 +28,10 @@ func ExportAccount(cliCtx *cli.Context) error { if err != nil { return errors.Wrap(err, "could not parse output directory") } - wallet, err := OpenWallet(cliCtx) - if err != nil { + if errors.Is(err, ErrNoWalletFound) { + return errors.Wrap(err, "no wallet found at path, create a new wallet with wallet-v2 create") + } else if err != nil { return errors.Wrap(err, "could not open wallet") } keymanager, err := wallet.InitializeKeymanager(context.Background(), true /* skip mnemonic confirm */) diff --git a/validator/accounts/v2/accounts_import.go b/validator/accounts/v2/accounts_import.go index b5972841a0e..604f1691f12 100644 --- a/validator/accounts/v2/accounts_import.go +++ b/validator/accounts/v2/accounts_import.go @@ -23,24 +23,24 @@ import ( func ImportAccount(cliCtx *cli.Context) error { walletDir, err := inputDirectory(cliCtx, walletDirPromptText, flags.WalletDirFlag) if err != nil && !errors.Is(err, ErrNoWalletFound) { - return errors.Wrap(err, "could not parse wallet directory") + return errors.Wrapf(err, "Could not retrieve input directory") } - // Check if the user has a wallet at the specified path. If so, only let them continue if it is a non-HD wallet. - walletExists, err := hasDir(walletDir) + ok, err := hasDir(walletDir) if err != nil { - return errors.Wrap(err, "could not check if wallet exists") + return err } - if walletExists { - keymanagerKind, err := readKeymanagerKindFromWalletPath(walletDir) - if err != nil { - return errors.Wrap(err, "could not read keymanager kind for existing wallet") + // Create a new wallet if no directory exists. + if !ok { + w, err := NewWallet(cliCtx, v2keymanager.Direct) + if err != nil && !errors.Is(err, ErrWalletExists) { + return errors.Wrap(err, "could not check if wallet directory exists") } - if keymanagerKind != v2keymanager.Direct { - return fmt.Errorf( - "importing non-HD accounts into a non-direct wallet is not allowed, given wallet path contains a %s wallet", - keymanagerKind.String(), - ) + if err = createDirectKeymanagerWallet(cliCtx, w); err != nil { + return errors.Wrap(err, "could not initialize wallet") } + log.WithField("wallet-path", w.walletDir).Infof( + "Successfully created new wallet", + ) } passwordsDir, err := inputDirectory(cliCtx, passwordsDirPromptText, flags.WalletPasswordsDirFlag) if err != nil { @@ -68,6 +68,9 @@ func ImportAccount(cliCtx *cli.Context) error { var accountsImported []string ctx := context.Background() if err := filepath.Walk(keysDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } if info.IsDir() { return nil } diff --git a/validator/accounts/v2/accounts_list.go b/validator/accounts/v2/accounts_list.go index dd01c6bca18..f64e60d9cc4 100644 --- a/validator/accounts/v2/accounts_list.go +++ b/validator/accounts/v2/accounts_list.go @@ -24,8 +24,10 @@ func ListAccounts(cliCtx *cli.Context) error { // Read the wallet from the specified path. ctx := context.Background() wallet, err := OpenWallet(cliCtx) - if err != nil { - return errors.Wrapf(err, "could not read wallet at specified path %s", wallet.AccountsDir()) + if errors.Is(err, ErrNoWalletFound) { + return errors.Wrap(err, "no wallet found at path, create a new wallet with wallet-v2 create") + } else if err != nil { + return errors.Wrap(err, "could not open wallet") } keymanager, err := wallet.InitializeKeymanager(ctx, true /* skip mnemonic confirm */) if err != nil { @@ -103,7 +105,7 @@ func listDirectKeymanagerAccounts( if err != nil { return errors.Wrap(err, "could not get timestamp from keystore file name") } - fmt.Printf("%s | %s\n", au.BrightGreen(accountNames[i]).Bold(), humanize.Time(unixTimestamp)) + fmt.Printf("%s | %s | Created %s\n", au.BrightBlue(fmt.Sprintf("Account %d", i)).Bold(), au.BrightGreen(accountNames[i]).Bold(), humanize.Time(unixTimestamp)) fmt.Printf("%s %#x\n", au.BrightMagenta("[validating public key]").Bold(), pubKeys[i]) if !showDepositData { continue diff --git a/validator/accounts/v2/cmd_accounts.go b/validator/accounts/v2/cmd_accounts.go index 217598c89d1..05b1d1ee2e8 100644 --- a/validator/accounts/v2/cmd_accounts.go +++ b/validator/accounts/v2/cmd_accounts.go @@ -20,8 +20,8 @@ specified input, capable of creating a direct, derived, or remote wallet. this command outputs a deposit data string which is required to become a validator in eth2.`, Flags: []cli.Flag{ flags.WalletDirFlag, - flags.WalletPasswordsDirFlag, - flags.PasswordFileFlag, + flags.WalletPasswordFileFlag, + flags.AccountPasswordFileFlag, flags.NumAccountsFlag, featureconfig.AltonaTestnet, featureconfig.MedallaTestnet, @@ -38,8 +38,7 @@ this command outputs a deposit data string which is required to become a validat Description: "Lists all validator accounts in a user's wallet directory", Flags: []cli.Flag{ flags.WalletDirFlag, - flags.WalletPasswordsDirFlag, - flags.PasswordFileFlag, + flags.WalletPasswordFileFlag, flags.ShowDepositDataFlag, featureconfig.AltonaTestnet, featureconfig.MedallaTestnet, @@ -56,7 +55,6 @@ this command outputs a deposit data string which is required to become a validat Description: `exports the account of a given directory into a zip of the provided output path. This zip can be used to later import the account to another directory`, Flags: []cli.Flag{ flags.WalletDirFlag, - flags.WalletPasswordsDirFlag, flags.BackupDirFlag, flags.AccountsFlag, featureconfig.AltonaTestnet, @@ -76,7 +74,7 @@ this command outputs a deposit data string which is required to become a validat flags.WalletDirFlag, flags.WalletPasswordsDirFlag, flags.KeysDirFlag, - flags.PasswordFileFlag, + flags.WalletPasswordFileFlag, featureconfig.AltonaTestnet, featureconfig.MedallaTestnet, }, diff --git a/validator/accounts/v2/cmd_wallet.go b/validator/accounts/v2/cmd_wallet.go index 34b16a578be..4a7bd855a85 100644 --- a/validator/accounts/v2/cmd_wallet.go +++ b/validator/accounts/v2/cmd_wallet.go @@ -24,12 +24,12 @@ var WalletCommands = &cli.Command{ flags.RemoteSignerCertPathFlag, flags.RemoteSignerKeyPathFlag, flags.RemoteSignerCACertPathFlag, - flags.PasswordFileFlag, + flags.WalletPasswordFileFlag, featureconfig.AltonaTestnet, featureconfig.MedallaTestnet, }, Action: func(cliCtx *cli.Context) error { - if err := CreateWallet(cliCtx); err != nil { + if _, err := CreateWallet(cliCtx); err != nil { log.Fatalf("Could not create a wallet: %v", err) } return nil @@ -62,7 +62,7 @@ var WalletCommands = &cli.Command{ flags.WalletDirFlag, flags.WalletPasswordsDirFlag, flags.MnemonicFileFlag, - flags.PasswordFileFlag, + flags.WalletPasswordFileFlag, flags.NumAccountsFlag, featureconfig.AltonaTestnet, featureconfig.MedallaTestnet, diff --git a/validator/accounts/v2/prompt.go b/validator/accounts/v2/prompt.go index e97873e011e..e7dd23a2f31 100644 --- a/validator/accounts/v2/prompt.go +++ b/validator/accounts/v2/prompt.go @@ -16,9 +16,8 @@ import ( ) const ( - importDirPromptText = "Enter the file location of the exported wallet zip to import" importKeysDirPromptText = "Enter the directory where your keystores to import are located" - exportDirPromptText = "Enter a file location to write the exported wallet to" + exportDirPromptText = "Enter a file location to write the exported account(s) to" walletDirPromptText = "Enter a wallet directory" passwordsDirPromptText = "Directory where passwords will be stored" newWalletPasswordPromptText = "New wallet password" @@ -93,9 +92,14 @@ func validateDirectoryPath(input string) error { return nil } -func inputPassword(cliCtx *cli.Context, promptText string, confirmPassword passwordConfirm) (string, error) { - if cliCtx.IsSet(flags.PasswordFileFlag.Name) { - passwordFilePath := cliCtx.String(flags.PasswordFileFlag.Name) +func inputPassword( + cliCtx *cli.Context, + passwordFileFlag *cli.StringFlag, + promptText string, + confirmPassword passwordConfirm, +) (string, error) { + if cliCtx.IsSet(passwordFileFlag.Name) { + passwordFilePath := cliCtx.String(passwordFileFlag.Name) data, err := ioutil.ReadFile(passwordFilePath) if err != nil { return "", errors.Wrap(err, "could not read password file") @@ -141,9 +145,9 @@ func inputPassword(cliCtx *cli.Context, promptText string, confirmPassword passw return strings.TrimRight(walletPassword, "\r\n"), nil } -func inputWeakPassword(cliCtx *cli.Context, promptText string) (string, error) { - if cliCtx.IsSet(flags.PasswordFileFlag.Name) { - passwordFilePath := cliCtx.String(flags.PasswordFileFlag.Name) +func inputWeakPassword(cliCtx *cli.Context, passwordFileFlag *cli.StringFlag, promptText string) (string, error) { + if cliCtx.IsSet(passwordFileFlag.Name) { + passwordFilePath := cliCtx.String(passwordFileFlag.Name) data, err := ioutil.ReadFile(passwordFilePath) if err != nil { return "", errors.Wrap(err, "could not read password file") diff --git a/validator/accounts/v2/wallet.go b/validator/accounts/v2/wallet.go index 20ef29e5bdc..1df2fa64b8c 100644 --- a/validator/accounts/v2/wallet.go +++ b/validator/accounts/v2/wallet.go @@ -67,9 +67,6 @@ func NewWallet( keymanagerKind v2keymanager.Kind, ) (*Wallet, error) { walletDir, err := inputDirectory(cliCtx, walletDirPromptText, flags.WalletDirFlag) - if err != nil && !errors.Is(err, ErrNoWalletFound) { - return nil, errors.Wrap(err, "could not parse wallet directory") - } // Check if the user has a wallet at the specified path. // If a user does not have a wallet, we instantiate one // based on specified options. @@ -87,7 +84,12 @@ func NewWallet( walletDir: walletDir, } if keymanagerKind == v2keymanager.Derived { - walletPassword, err := inputPassword(cliCtx, newWalletPasswordPromptText, confirmPass) + walletPassword, err := inputPassword( + cliCtx, + flags.WalletPasswordFileFlag, + newWalletPasswordPromptText, + confirmPass, + ) if err != nil { return nil, errors.Wrap(err, "could not get password") } @@ -112,11 +114,16 @@ func NewWallet( func OpenWallet(cliCtx *cli.Context) (*Wallet, error) { // Read a wallet's directory from user input. walletDir, err := inputDirectory(cliCtx, walletDirPromptText, flags.WalletDirFlag) - if errors.Is(err, ErrNoWalletFound) { - return nil, errors.New("no wallet found, create a new one with ./prysm.sh validator wallet-v2 create") - } else if err != nil { + if err != nil { return nil, err } + ok, err := hasDir(walletDir) + if err != nil { + return nil, errors.Wrap(err, "could not parse wallet directory") + } + if !ok { + return nil, ErrNoWalletFound + } keymanagerKind, err := readKeymanagerKindFromWalletPath(walletDir) if err != nil { return nil, errors.Wrap(err, "could not read keymanager kind for wallet") @@ -127,18 +134,29 @@ func OpenWallet(cliCtx *cli.Context) (*Wallet, error) { keymanagerKind: keymanagerKind, } if keymanagerKind == v2keymanager.Derived { - walletPassword, err := inputPassword(cliCtx, walletPasswordPromptText, noConfirmPass) + walletPassword, err := inputPassword( + cliCtx, + flags.WalletPasswordFileFlag, + walletPasswordPromptText, + noConfirmPass, + ) if err != nil { return nil, err } w.walletPassword = walletPassword } if keymanagerKind == v2keymanager.Direct { - passwordsDir, err := inputDirectory(cliCtx, passwordsDirPromptText, flags.WalletPasswordsDirFlag) + keymanagerCfg, err := w.ReadKeymanagerConfigFromDisk(context.Background()) if err != nil { return nil, err } - w.passwordsDir = passwordsDir + directCfg, err := direct.UnmarshalConfigFile(keymanagerCfg) + if err != nil { + return nil, err + } + w.passwordsDir = directCfg.AccountPasswordsDirectory + au := aurora.NewAurora(true) + log.Infof("%s %s", au.BrightMagenta("(account passwords path)"), w.passwordsDir) } return w, nil } @@ -375,8 +393,8 @@ func (w *Wallet) enterPasswordForAccount(cliCtx *cli.Context, accountName string au := aurora.NewAurora(true) var password string var err error - if cliCtx.IsSet(flags.PasswordFileFlag.Name) { - passwordFilePath := cliCtx.String(flags.PasswordFileFlag.Name) + if cliCtx.IsSet(flags.AccountPasswordFileFlag.Name) { + passwordFilePath := cliCtx.String(flags.AccountPasswordFileFlag.Name) data, err := ioutil.ReadFile(passwordFilePath) if err != nil { return err @@ -394,7 +412,11 @@ func (w *Wallet) enterPasswordForAccount(cliCtx *cli.Context, accountName string // Loop asking for the password until the user enters it correctly. for attemptingPassword { // Ask the user for the password to their account. - password, err = inputWeakPassword(cliCtx, fmt.Sprintf(passwordForAccountPromptText, accountName)) + password, err = inputWeakPassword( + cliCtx, + flags.AccountPasswordFileFlag, + fmt.Sprintf(passwordForAccountPromptText, accountName), + ) if err != nil { return errors.Wrap(err, "could not input password") } diff --git a/validator/accounts/v2/wallet_create.go b/validator/accounts/v2/wallet_create.go index 88b4d8d7e11..0778036bad8 100644 --- a/validator/accounts/v2/wallet_create.go +++ b/validator/accounts/v2/wallet_create.go @@ -15,22 +15,22 @@ import ( // CreateWallet from user input with a desired keymanager. If a // wallet already exists in the path, it suggests the user alternatives // such as how to edit their existing wallet configuration. -func CreateWallet(cliCtx *cli.Context) error { +func CreateWallet(cliCtx *cli.Context) (*Wallet, error) { keymanagerKind, err := inputKeymanagerKind(cliCtx) if err != nil { - return err + return nil, err } w, err := NewWallet(cliCtx, keymanagerKind) if err != nil && !errors.Is(err, ErrWalletExists) { - return errors.Wrap(err, "could not check if wallet directory exists") + return nil, errors.Wrap(err, "could not check if wallet directory exists") } if errors.Is(err, ErrWalletExists) { - return ErrWalletExists + return nil, ErrWalletExists } switch w.KeymanagerKind() { case v2keymanager.Direct: if err = createDirectKeymanagerWallet(cliCtx, w); err != nil { - return errors.Wrap(err, "could not initialize wallet with direct keymanager") + return nil, errors.Wrap(err, "could not initialize wallet with direct keymanager") } log.WithField("wallet-path", w.walletDir).Infof( "Successfully created wallet with on-disk keymanager configuration. " + @@ -38,7 +38,7 @@ func CreateWallet(cliCtx *cli.Context) error { ) case v2keymanager.Derived: if err = createDerivedKeymanagerWallet(cliCtx, w); err != nil { - return errors.Wrap(err, "could not initialize wallet with derived keymanager") + return nil, errors.Wrap(err, "could not initialize wallet with derived keymanager") } log.WithField("wallet-path", w.walletDir).Infof( "Successfully created HD wallet and saved configuration to disk. " + @@ -46,22 +46,24 @@ func CreateWallet(cliCtx *cli.Context) error { ) case v2keymanager.Remote: if err = createRemoteKeymanagerWallet(cliCtx, w); err != nil { - return errors.Wrap(err, "could not initialize wallet with remote keymanager") + return nil, errors.Wrap(err, "could not initialize wallet with remote keymanager") } log.WithField("wallet-path", w.walletDir).Infof( "Successfully created wallet with remote keymanager configuration", ) default: - return errors.Wrapf(err, "keymanager type %s is not supported", w.KeymanagerKind()) + return nil, errors.Wrapf(err, "keymanager type %s is not supported", w.KeymanagerKind()) } - return nil + return w, nil } func createDirectKeymanagerWallet(cliCtx *cli.Context, wallet *Wallet) error { if err := wallet.SaveWallet(); err != nil { return errors.Wrap(err, "could not save wallet to disk") } - keymanagerConfig, err := direct.MarshalConfigFile(context.Background(), direct.DefaultConfig()) + defaultConfig := direct.DefaultConfig() + defaultConfig.AccountPasswordsDirectory = wallet.passwordsDir + keymanagerConfig, err := direct.MarshalConfigFile(context.Background(), defaultConfig) if err != nil { return errors.Wrap(err, "could not marshal keymanager config file") } diff --git a/validator/accounts/v2/wallet_edit.go b/validator/accounts/v2/wallet_edit.go index e43e50d4480..e30f65170d7 100644 --- a/validator/accounts/v2/wallet_edit.go +++ b/validator/accounts/v2/wallet_edit.go @@ -5,7 +5,9 @@ import ( "fmt" "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/validator/flags" v2keymanager "github.com/prysmaticlabs/prysm/validator/keymanager/v2" + "github.com/prysmaticlabs/prysm/validator/keymanager/v2/direct" "github.com/prysmaticlabs/prysm/validator/keymanager/v2/remote" "github.com/urfave/cli/v2" ) @@ -21,7 +23,29 @@ func EditWalletConfiguration(cliCtx *cli.Context) error { } switch wallet.KeymanagerKind() { case v2keymanager.Direct: - return errors.New("no configuration options available to edit for direct keymanager") + enc, err := wallet.ReadKeymanagerConfigFromDisk(ctx) + if err != nil { + return errors.Wrap(err, "could not read config") + } + cfg, err := direct.UnmarshalConfigFile(enc) + if err != nil { + return errors.Wrap(err, "could not unmarshal config") + } + log.Infof("Current configuration") + fmt.Printf("%s\n", cfg) + passwordsDir, err := inputDirectory(cliCtx, passwordsDirPromptText, flags.WalletPasswordsDirFlag) + if err != nil { + return errors.Wrap(err, "could not get password directory") + } + defaultCfg := direct.DefaultConfig() + defaultCfg.AccountPasswordsDirectory = passwordsDir + encodedCfg, err := direct.MarshalConfigFile(ctx, defaultCfg) + if err != nil { + return errors.Wrap(err, "could not marshal config file") + } + if err := wallet.WriteKeymanagerConfigToDisk(ctx, encodedCfg); err != nil { + return errors.Wrap(err, "could not write config to disk") + } case v2keymanager.Derived: return errors.New("derived keymanager is not yet supported") case v2keymanager.Remote: diff --git a/validator/accounts/v2/wallet_recover_test.go b/validator/accounts/v2/wallet_recover_test.go index 15557e17c6e..28c5a83cdcc 100644 --- a/validator/accounts/v2/wallet_recover_test.go +++ b/validator/accounts/v2/wallet_recover_test.go @@ -39,13 +39,13 @@ func TestRecoverDerivedWallet(t *testing.T) { set := flag.NewFlagSet("test", 0) set.String(flags.WalletDirFlag.Name, walletDir, "") set.String(flags.WalletPasswordsDirFlag.Name, passwordsDir, "") - set.String(flags.PasswordFileFlag.Name, passwordFilePath, "") + set.String(flags.WalletPasswordFileFlag.Name, passwordFilePath, "") set.String(flags.KeymanagerKindFlag.Name, v2keymanager.Derived.String(), "") set.String(flags.MnemonicFileFlag.Name, mnemonicFilePath, "") set.Int64(flags.NumAccountsFlag.Name, numAccounts, "") assert.NoError(t, set.Set(flags.WalletDirFlag.Name, walletDir)) assert.NoError(t, set.Set(flags.WalletPasswordsDirFlag.Name, passwordsDir)) - assert.NoError(t, set.Set(flags.PasswordFileFlag.Name, passwordFilePath)) + assert.NoError(t, set.Set(flags.WalletPasswordFileFlag.Name, passwordFilePath)) assert.NoError(t, set.Set(flags.KeymanagerKindFlag.Name, v2keymanager.Derived.String())) assert.NoError(t, set.Set(flags.MnemonicFileFlag.Name, mnemonicFilePath)) assert.NoError(t, set.Set(flags.NumAccountsFlag.Name, strconv.Itoa(int(numAccounts)))) diff --git a/validator/accounts/v2/wallet_test.go b/validator/accounts/v2/wallet_test.go index 6e7cd382e1f..2723bc64d24 100644 --- a/validator/accounts/v2/wallet_test.go +++ b/validator/accounts/v2/wallet_test.go @@ -28,14 +28,15 @@ func init() { } type testWalletConfig struct { - walletDir string - passwordsDir string - exportDir string - keysDir string - accountsToExport string - passwordFile string - numAccounts int64 - keymanagerKind v2keymanager.Kind + walletDir string + passwordsDir string + exportDir string + keysDir string + accountsToExport string + walletPasswordFile string + accountPasswordFile string + numAccounts int64 + keymanagerKind v2keymanager.Kind } func setupWalletCtx( @@ -50,7 +51,8 @@ func setupWalletCtx( set.String(flags.KeymanagerKindFlag.Name, cfg.keymanagerKind.String(), "") set.String(flags.BackupDirFlag.Name, cfg.exportDir, "") set.String(flags.AccountsFlag.Name, cfg.accountsToExport, "") - set.String(flags.PasswordFileFlag.Name, cfg.passwordFile, "") + set.String(flags.WalletPasswordFileFlag.Name, cfg.walletPasswordFile, "") + set.String(flags.AccountPasswordFileFlag.Name, cfg.accountPasswordFile, "") set.Bool(flags.SkipMnemonicConfirmFlag.Name, true, "") set.Int64(flags.NumAccountsFlag.Name, cfg.numAccounts, "") assert.NoError(tb, set.Set(flags.WalletDirFlag.Name, cfg.walletDir)) @@ -59,7 +61,8 @@ func setupWalletCtx( assert.NoError(tb, set.Set(flags.KeymanagerKindFlag.Name, cfg.keymanagerKind.String())) assert.NoError(tb, set.Set(flags.BackupDirFlag.Name, cfg.exportDir)) assert.NoError(tb, set.Set(flags.AccountsFlag.Name, cfg.accountsToExport)) - assert.NoError(tb, set.Set(flags.PasswordFileFlag.Name, cfg.passwordFile)) + 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.SkipMnemonicConfirmFlag.Name, "true")) assert.NoError(tb, set.Set(flags.NumAccountsFlag.Name, strconv.Itoa(int(cfg.numAccounts)))) return cli.NewContext(&app, set, nil) diff --git a/validator/flags/flags.go b/validator/flags/flags.go index c16d1d55c6c..08481567ac3 100644 --- a/validator/flags/flags.go +++ b/validator/flags/flags.go @@ -144,10 +144,15 @@ var ( Usage: "Path to a directory on-disk where account passwords are stored", Value: filepath.Join(DefaultValidatorDir(), PasswordsDefaultDirName), } - // PasswordFileFlag is used to enter a file to get a password for new account creation, non-interactively. - PasswordFileFlag = &cli.StringFlag{ - Name: "password-file", - Usage: "Path to a plaintext password.txt file", + // AccountPasswordFileFlag is path to a file containing a password for a new validator account. + AccountPasswordFileFlag = &cli.StringFlag{ + Name: "account-password-file", + Usage: "Path to a plain-text, .txt file containing a password for a new validator account", + } + // WalletPasswordFileFlag is the path to a file containing your wallet password. + WalletPasswordFileFlag = &cli.StringFlag{ + Name: "wallet-password-file", + Usage: "Path to a plain-text, .txt file containing your wallet password", } // MnemonicFileFlag is used to enter a file to mnemonic phrase for new wallet creation, non-interactively. MnemonicFileFlag = &cli.StringFlag{ diff --git a/validator/keymanager/v2/direct/BUILD.bazel b/validator/keymanager/v2/direct/BUILD.bazel index d979569a86f..bdafaa7ee4c 100644 --- a/validator/keymanager/v2/direct/BUILD.bazel +++ b/validator/keymanager/v2/direct/BUILD.bazel @@ -20,8 +20,10 @@ go_library( "//shared/petnames:go_default_library", "//shared/roughtime:go_default_library", "//validator/accounts/v2/iface:go_default_library", + "//validator/flags:go_default_library", "//validator/keymanager/v2:go_default_library", "@com_github_google_uuid//:go_default_library", + "@com_github_logrusorgru_aurora//:go_default_library", "@com_github_pkg_errors//:go_default_library", "@com_github_prysmaticlabs_go_ssz//:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", diff --git a/validator/keymanager/v2/direct/direct.go b/validator/keymanager/v2/direct/direct.go index 62d9f59748c..2bf0b9c8557 100644 --- a/validator/keymanager/v2/direct/direct.go +++ b/validator/keymanager/v2/direct/direct.go @@ -9,9 +9,11 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "sync" "github.com/google/uuid" + "github.com/logrusorgru/aurora" "github.com/pkg/errors" "github.com/prysmaticlabs/go-ssz" validatorpb "github.com/prysmaticlabs/prysm/proto/validator/accounts/v2" @@ -21,6 +23,7 @@ import ( "github.com/prysmaticlabs/prysm/shared/petnames" "github.com/prysmaticlabs/prysm/shared/roughtime" "github.com/prysmaticlabs/prysm/validator/accounts/v2/iface" + "github.com/prysmaticlabs/prysm/validator/flags" v2keymanager "github.com/prysmaticlabs/prysm/validator/keymanager/v2" "github.com/sirupsen/logrus" keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4" @@ -47,7 +50,8 @@ const ( // Config for a direct keymanager. type Config struct { - EIPVersion string `json:"direct_eip_version"` + EIPVersion string `json:"direct_eip_version"` + AccountPasswordsDirectory string `json:"direct_accounts_passwords_directory"` } // Keymanager implementation for direct keystores utilizing EIP-2335. @@ -61,7 +65,8 @@ type Keymanager struct { // DefaultConfig for a direct keymanager implementation. func DefaultConfig() *Config { return &Config{ - EIPVersion: eipVersion, + EIPVersion: eipVersion, + AccountPasswordsDirectory: flags.WalletPasswordsDirFlag.Value, } } @@ -106,6 +111,30 @@ func MarshalConfigFile(ctx context.Context, cfg *Config) ([]byte, error) { return json.MarshalIndent(cfg, "", "\t") } +// Config for the direct keymanager. +func (dr *Keymanager) Config() *Config { + return dr.cfg +} + +// String pretty-print of a direct keymanager configuration. +func (c *Config) String() string { + au := aurora.NewAurora(true) + var b strings.Builder + strAddr := fmt.Sprintf("%s: %s\n", au.BrightMagenta("EIP Version"), c.EIPVersion) + if _, err := b.WriteString(strAddr); err != nil { + log.Error(err) + return "" + } + strCrt := fmt.Sprintf( + "%s: %s\n", au.BrightMagenta("Accounts Passwords Directory"), c.AccountPasswordsDirectory, + ) + if _, err := b.WriteString(strCrt); err != nil { + log.Error(err) + return "" + } + return b.String() +} + // ValidatingAccountNames for a direct keymanager. func (dr *Keymanager) ValidatingAccountNames() ([]string, error) { return dr.wallet.ListDirs() diff --git a/validator/main.go b/validator/main.go index ad101700478..4d7b9e06f1f 100644 --- a/validator/main.go +++ b/validator/main.go @@ -72,7 +72,8 @@ var appFlags = []cli.Flag{ flags.SlasherRPCProviderFlag, flags.SlasherCertFlag, flags.WalletPasswordsDirFlag, - flags.PasswordFileFlag, + flags.WalletPasswordFileFlag, + flags.AccountPasswordFileFlag, flags.WalletDirFlag, cmd.MinimalConfigFlag, cmd.E2EConfigFlag, diff --git a/validator/usage.go b/validator/usage.go index 025f51980dd..d62b89a9a5e 100644 --- a/validator/usage.go +++ b/validator/usage.go @@ -83,7 +83,6 @@ var appHelpFlagGroups = []flagGroup{ flags.KeyManagerOpts, flags.KeystorePathFlag, flags.PasswordFlag, - flags.PasswordFileFlag, flags.DisablePenaltyRewardLogFlag, flags.UnencryptedKeysFlag, flags.GraffitiFlag, From cc37d1e3badcc297295c33302e6456276e5aa886 Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 16:29:51 -0500 Subject: [PATCH 09/21] fix up edit remote --- validator/accounts/v2/prompt.go | 134 +++++++++++++++++--------------- 1 file changed, 71 insertions(+), 63 deletions(-) diff --git a/validator/accounts/v2/prompt.go b/validator/accounts/v2/prompt.go index e7dd23a2f31..72afd5b1e7d 100644 --- a/validator/accounts/v2/prompt.go +++ b/validator/accounts/v2/prompt.go @@ -10,9 +10,10 @@ import ( "github.com/manifoldco/promptui" strongPasswords "github.com/nbutton23/zxcvbn-go" "github.com/pkg/errors" + "github.com/urfave/cli/v2" + "github.com/prysmaticlabs/prysm/validator/flags" "github.com/prysmaticlabs/prysm/validator/keymanager/v2/remote" - "github.com/urfave/cli/v2" ) const ( @@ -221,68 +222,85 @@ func inputRemoteKeymanagerConfig(cliCtx *cli.Context) (*remote.Config, error) { key := cliCtx.String(flags.RemoteSignerKeyPathFlag.Name) ca := cliCtx.String(flags.RemoteSignerCACertPathFlag.Name) - if addr != "" && crt != "" && key != "" && ca != "" { - if !(isValidUnicode(addr) && isValidUnicode(crt) && isValidUnicode(key) && isValidUnicode(ca)) { + log.Infof("Input desired configuration") + var remoteAddr string + var crtPath string + var keyPath string + var caPath string + var err error + if addr != "" { + if isValidUnicode(addr) { return nil, errors.New("flag inputs contain non-unicode characters") } - newCfg := &remote.Config{ - RemoteCertificate: &remote.CertificateConfig{ - ClientCertPath: strings.TrimRight(crt, "\r\n"), - ClientKeyPath: strings.TrimRight(key, "\r\n"), - CACertPath: strings.TrimRight(ca, "\r\n"), + remoteAddr = addr + } else { + prompt := promptui.Prompt{ + Label: "Remote gRPC address (such as host.example.com:4000)", + Validate: func(input string) error { + if input == "" { + return errors.New("remote host address cannot be empty") + } + if !isValidUnicode(input) { + return errors.New("not valid unicode") + } + return nil }, - RemoteAddr: strings.TrimRight(addr, "\r\n"), } - log.Infof("New configuration") - fmt.Printf("%s\n", newCfg) - return newCfg, nil - } - log.Infof("Input desired configuration") - prompt := promptui.Prompt{ - Label: "Remote gRPC address (such as host.example.com:4000)", - Validate: func(input string) error { - if input == "" { - return errors.New("remote host address cannot be empty") - } - if !isValidUnicode(input) { - return errors.New("not valid unicode") - } - return nil - }, - } - remoteAddr, err := prompt.Run() - if err != nil { - return nil, err - } - prompt = promptui.Prompt{ - Label: "Path to TLS crt (such as /path/to/client.crt)", - Validate: validateCertPath, - } - clientCrtPath, err := prompt.Run() - if err != nil { - return nil, err - } - prompt = promptui.Prompt{ - Label: "Path to TLS key (such as /path/to/client.key)", - Validate: validateCertPath, + remoteAddr, err = prompt.Run() + if err != nil { + return nil, err + } } - clientKeyPath, err := prompt.Run() - if err != nil { - return nil, err + if crt != "" { + if isValidUnicode(crt) { + return nil, errors.New("flag inputs contain non-unicode characters") + } + crtPath = crt + } else { + prompt := promptui.Prompt{ + Label: "Path to TLS crt (such as /path/to/client.crt)", + Validate: validateCertPath, + } + crtPath, err = prompt.Run() + if err != nil { + return nil, err + } } - prompt = promptui.Prompt{ - Label: "(Optional) Path to certificate authority (CA) crt (such as /path/to/ca.crt)", - Validate: validateCACertPath, + if key != "" { + if isValidUnicode(key) { + return nil, errors.New("flag inputs contain non-unicode characters") + } + keyPath = key + } else { + prompt := promptui.Prompt{ + Label: "Path to TLS key (such as /path/to/client.key)", + Validate: validateCertPath, + } + key, err = prompt.Run() + if err != nil { + return nil, err + } } - caCrtPath, err := prompt.Run() - if err != nil { - return nil, err + if ca != "" { + if isValidUnicode(ca) { + return nil, errors.New("flag inputs contain non-unicode characters") + } + caPath = ca + } else { + prompt := promptui.Prompt{ + Label: "Path to certificate authority (CA) crt (such as /path/to/ca.crt)", + Validate: validateCertPath, + } + caPath, err = prompt.Run() + if err != nil { + return nil, err + } } newCfg := &remote.Config{ RemoteCertificate: &remote.CertificateConfig{ - ClientCertPath: strings.TrimRight(clientCrtPath, "\r\n"), - ClientKeyPath: strings.TrimRight(clientKeyPath, "\r\n"), - CACertPath: strings.TrimRight(caCrtPath, "\r\n"), + ClientCertPath: strings.TrimRight(crtPath, "\r\n"), + ClientKeyPath: strings.TrimRight(keyPath, "\r\n"), + CACertPath: strings.TrimRight(caPath, "\r\n"), }, RemoteAddr: strings.TrimRight(remoteAddr, "\r\n"), } @@ -303,16 +321,6 @@ func validateCertPath(input string) error { return nil } -func validateCACertPath(input string) error { - if input != "" && !fileExists(input) { - return fmt.Errorf("no crt found at path: %s", input) - } - if !isValidUnicode(input) { - return errors.New("not valid unicode") - } - return nil -} - func formatPromptError(err error) error { switch err { case promptui.ErrAbort: From 1886052a2733e687ac542ecc1d895a30a7a3ef36 Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 16:49:30 -0500 Subject: [PATCH 10/21] all tests passing --- validator/accounts/v2/accounts_create_test.go | 14 +++--- validator/accounts/v2/accounts_export_test.go | 5 +- validator/accounts/v2/accounts_import_test.go | 12 +++-- validator/accounts/v2/accounts_list_test.go | 8 ++-- validator/accounts/v2/prompt.go | 47 +++++-------------- validator/accounts/v2/wallet_create_test.go | 21 +++++---- validator/accounts/v2/wallet_edit_test.go | 5 +- validator/accounts/v2/wallet_test.go | 2 +- 8 files changed, 51 insertions(+), 63 deletions(-) diff --git a/validator/accounts/v2/accounts_create_test.go b/validator/accounts/v2/accounts_create_test.go index b1a74e63d71..9cffb2af090 100644 --- a/validator/accounts/v2/accounts_create_test.go +++ b/validator/accounts/v2/accounts_create_test.go @@ -14,15 +14,17 @@ func TestCreateAccount_Derived(t *testing.T) { walletDir, passwordsDir, passwordFile := setupWalletAndPasswordsDir(t) numAccounts := int64(5) cliCtx := setupWalletCtx(t, &testWalletConfig{ - walletDir: walletDir, - passwordsDir: passwordsDir, - passwordFile: passwordFile, - keymanagerKind: v2keymanager.Derived, - numAccounts: numAccounts, + walletDir: walletDir, + passwordsDir: passwordsDir, + walletPasswordFile: passwordFile, + accountPasswordFile: passwordFile, + keymanagerKind: v2keymanager.Derived, + numAccounts: numAccounts, }) // We attempt to create the wallet. - require.NoError(t, CreateWallet(cliCtx)) + _, err := CreateWallet(cliCtx) + require.NoError(t, err) // We attempt to open the newly created wallet. ctx := context.Background() diff --git a/validator/accounts/v2/accounts_export_test.go b/validator/accounts/v2/accounts_export_test.go index 80c1355cc36..29058a52738 100644 --- a/validator/accounts/v2/accounts_export_test.go +++ b/validator/accounts/v2/accounts_export_test.go @@ -36,10 +36,12 @@ func TestZipAndUnzip(t *testing.T) { require.NoError(t, err) require.NoError(t, wallet.SaveWallet()) ctx := context.Background() + keymanagerCfg := direct.DefaultConfig() + keymanagerCfg.AccountPasswordsDirectory = passwordsDir keymanager, err := direct.NewKeymanager( ctx, wallet, - direct.DefaultConfig(), + keymanagerCfg, ) require.NoError(t, err) _, err = keymanager.CreateAccount(ctx, password) @@ -80,6 +82,7 @@ func TestExport_Noninteractive(t *testing.T) { require.NoError(t, wallet.SaveWallet()) ctx := context.Background() keymanagerCfg := direct.DefaultConfig() + keymanagerCfg.AccountPasswordsDirectory = passwordsDir encodedCfg, err := direct.MarshalConfigFile(ctx, keymanagerCfg) require.NoError(t, err) require.NoError(t, wallet.WriteKeymanagerConfigToDisk(ctx, encodedCfg)) diff --git a/validator/accounts/v2/accounts_import_test.go b/validator/accounts/v2/accounts_import_test.go index 89469f5b077..448ffa84f25 100644 --- a/validator/accounts/v2/accounts_import_test.go +++ b/validator/accounts/v2/accounts_import_test.go @@ -34,17 +34,19 @@ func TestImport_Noninteractive(t *testing.T) { }) cliCtx := setupWalletCtx(t, &testWalletConfig{ - walletDir: walletDir, - passwordsDir: passwordsDir, - keysDir: keysDir, - keymanagerKind: v2keymanager.Direct, - passwordFile: passwordFilePath, + walletDir: walletDir, + passwordsDir: passwordsDir, + keysDir: keysDir, + keymanagerKind: v2keymanager.Direct, + walletPasswordFile: passwordFilePath, + accountPasswordFile: passwordFilePath, }) wallet, err := NewWallet(cliCtx, v2keymanager.Direct) require.NoError(t, err) require.NoError(t, wallet.SaveWallet()) ctx := context.Background() keymanagerCfg := direct.DefaultConfig() + keymanagerCfg.AccountPasswordsDirectory = passwordsDir encodedCfg, err := direct.MarshalConfigFile(ctx, keymanagerCfg) require.NoError(t, err) require.NoError(t, wallet.WriteKeymanagerConfigToDisk(ctx, encodedCfg)) diff --git a/validator/accounts/v2/accounts_list_test.go b/validator/accounts/v2/accounts_list_test.go index 557e2fc77e4..0c0c135a2ac 100644 --- a/validator/accounts/v2/accounts_list_test.go +++ b/validator/accounts/v2/accounts_list_test.go @@ -127,10 +127,10 @@ func TestListAccounts_DirectKeymanager(t *testing.T) { func TestListAccounts_DerivedKeymanager(t *testing.T) { walletDir, passwordsDir, passwordFilePath := setupWalletAndPasswordsDir(t) cliCtx := setupWalletCtx(t, &testWalletConfig{ - walletDir: walletDir, - passwordsDir: passwordsDir, - keymanagerKind: v2keymanager.Derived, - passwordFile: passwordFilePath, + walletDir: walletDir, + passwordsDir: passwordsDir, + keymanagerKind: v2keymanager.Derived, + walletPasswordFile: passwordFilePath, }) wallet, err := NewWallet(cliCtx, v2keymanager.Derived) require.NoError(t, err) diff --git a/validator/accounts/v2/prompt.go b/validator/accounts/v2/prompt.go index 72afd5b1e7d..01193a622f6 100644 --- a/validator/accounts/v2/prompt.go +++ b/validator/accounts/v2/prompt.go @@ -221,19 +221,9 @@ func inputRemoteKeymanagerConfig(cliCtx *cli.Context) (*remote.Config, error) { crt := cliCtx.String(flags.RemoteSignerCertPathFlag.Name) key := cliCtx.String(flags.RemoteSignerKeyPathFlag.Name) ca := cliCtx.String(flags.RemoteSignerCACertPathFlag.Name) - log.Infof("Input desired configuration") - var remoteAddr string - var crtPath string - var keyPath string - var caPath string var err error - if addr != "" { - if isValidUnicode(addr) { - return nil, errors.New("flag inputs contain non-unicode characters") - } - remoteAddr = addr - } else { + if addr == "" { prompt := promptui.Prompt{ Label: "Remote gRPC address (such as host.example.com:4000)", Validate: func(input string) error { @@ -246,32 +236,22 @@ func inputRemoteKeymanagerConfig(cliCtx *cli.Context) (*remote.Config, error) { return nil }, } - remoteAddr, err = prompt.Run() + addr, err = prompt.Run() if err != nil { return nil, err } } - if crt != "" { - if isValidUnicode(crt) { - return nil, errors.New("flag inputs contain non-unicode characters") - } - crtPath = crt - } else { + if crt == "" { prompt := promptui.Prompt{ Label: "Path to TLS crt (such as /path/to/client.crt)", Validate: validateCertPath, } - crtPath, err = prompt.Run() + crt, err = prompt.Run() if err != nil { return nil, err } } - if key != "" { - if isValidUnicode(key) { - return nil, errors.New("flag inputs contain non-unicode characters") - } - keyPath = key - } else { + if key == "" { prompt := promptui.Prompt{ Label: "Path to TLS key (such as /path/to/client.key)", Validate: validateCertPath, @@ -281,28 +261,23 @@ func inputRemoteKeymanagerConfig(cliCtx *cli.Context) (*remote.Config, error) { return nil, err } } - if ca != "" { - if isValidUnicode(ca) { - return nil, errors.New("flag inputs contain non-unicode characters") - } - caPath = ca - } else { + if ca == "" { prompt := promptui.Prompt{ Label: "Path to certificate authority (CA) crt (such as /path/to/ca.crt)", Validate: validateCertPath, } - caPath, err = prompt.Run() + ca, err = prompt.Run() if err != nil { return nil, err } } newCfg := &remote.Config{ RemoteCertificate: &remote.CertificateConfig{ - ClientCertPath: strings.TrimRight(crtPath, "\r\n"), - ClientKeyPath: strings.TrimRight(keyPath, "\r\n"), - CACertPath: strings.TrimRight(caPath, "\r\n"), + ClientCertPath: strings.TrimRight(crt, "\r\n"), + ClientKeyPath: strings.TrimRight(key, "\r\n"), + CACertPath: strings.TrimRight(ca, "\r\n"), }, - RemoteAddr: strings.TrimRight(remoteAddr, "\r\n"), + RemoteAddr: strings.TrimRight(addr, "\r\n"), } fmt.Printf("%s\n", newCfg) return newCfg, nil diff --git a/validator/accounts/v2/wallet_create_test.go b/validator/accounts/v2/wallet_create_test.go index 576b3f88a5e..0109a36ad0b 100644 --- a/validator/accounts/v2/wallet_create_test.go +++ b/validator/accounts/v2/wallet_create_test.go @@ -26,7 +26,8 @@ func TestCreateWallet_Direct(t *testing.T) { }) // We attempt to create the wallet. - require.NoError(t, CreateWallet(cliCtx)) + _, err := CreateWallet(cliCtx) + require.NoError(t, err) // We attempt to open the newly created wallet. ctx := context.Background() @@ -40,20 +41,23 @@ func TestCreateWallet_Direct(t *testing.T) { assert.NoError(t, err) // We assert the created configuration was as desired. - assert.DeepEqual(t, direct.DefaultConfig(), cfg) + wantedCfg := direct.DefaultConfig() + wantedCfg.AccountPasswordsDirectory = passwordsDir + assert.DeepEqual(t, wantedCfg, cfg) } func TestCreateWallet_Derived(t *testing.T) { walletDir, passwordsDir, passwordFile := setupWalletAndPasswordsDir(t) cliCtx := setupWalletCtx(t, &testWalletConfig{ - walletDir: walletDir, - passwordsDir: passwordsDir, - passwordFile: passwordFile, - keymanagerKind: v2keymanager.Derived, + walletDir: walletDir, + passwordsDir: passwordsDir, + walletPasswordFile: passwordFile, + keymanagerKind: v2keymanager.Derived, }) // We attempt to create the wallet. - require.NoError(t, CreateWallet(cliCtx)) + _, err := CreateWallet(cliCtx) + require.NoError(t, err) // We attempt to open the newly created wallet. ctx := context.Background() @@ -101,7 +105,8 @@ func TestCreateWallet_Remote(t *testing.T) { cliCtx := cli.NewContext(&app, set, nil) // We attempt to create the wallet. - require.NoError(t, CreateWallet(cliCtx)) + _, err := CreateWallet(cliCtx) + require.NoError(t, err) // We attempt to open the newly created wallet. ctx := context.Background() diff --git a/validator/accounts/v2/wallet_edit_test.go b/validator/accounts/v2/wallet_edit_test.go index 60a9686be6d..5cdde2a4d50 100644 --- a/validator/accounts/v2/wallet_edit_test.go +++ b/validator/accounts/v2/wallet_edit_test.go @@ -58,9 +58,10 @@ func TestEditWalletConfiguration(t *testing.T) { assert.NoError(t, set.Set(flags.RemoteSignerCACertPathFlag.Name, wantCfg.RemoteCertificate.CACertPath)) cliCtx = cli.NewContext(&app, set, nil) - assert.NoError(t, EditWalletConfiguration(cliCtx)) + err = EditWalletConfiguration(cliCtx) + require.NoError(t, err) encoded, err := wallet.ReadKeymanagerConfigFromDisk(ctx) - assert.NoError(t, err) + require.NoError(t, err) cfg, err := remote.UnmarshalConfigFile(encoded) assert.NoError(t, err) diff --git a/validator/accounts/v2/wallet_test.go b/validator/accounts/v2/wallet_test.go index 2723bc64d24..00d769c13dd 100644 --- a/validator/accounts/v2/wallet_test.go +++ b/validator/accounts/v2/wallet_test.go @@ -95,8 +95,8 @@ func TestCreateAndReadWallet(t *testing.T) { keymanagerKind: v2keymanager.Direct, }) wallet, err := NewWallet(cliCtx, v2keymanager.Direct) - require.NoError(t, wallet.SaveWallet()) require.NoError(t, err) + require.NoError(t, createDirectKeymanagerWallet(cliCtx, wallet)) // We should be able to now read the wallet as well. _, err = OpenWallet(cliCtx) require.NoError(t, err) From 232bcf5004ad9e731ee1ef2d760273db35190f87 Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 16:56:21 -0500 Subject: [PATCH 11/21] fix test --- validator/accounts/v2/prompt.go | 3 +-- validator/main.go | 1 - validator/usage.go | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/validator/accounts/v2/prompt.go b/validator/accounts/v2/prompt.go index 01193a622f6..c81bf0a7430 100644 --- a/validator/accounts/v2/prompt.go +++ b/validator/accounts/v2/prompt.go @@ -10,10 +10,9 @@ import ( "github.com/manifoldco/promptui" strongPasswords "github.com/nbutton23/zxcvbn-go" "github.com/pkg/errors" - "github.com/urfave/cli/v2" - "github.com/prysmaticlabs/prysm/validator/flags" "github.com/prysmaticlabs/prysm/validator/keymanager/v2/remote" + "github.com/urfave/cli/v2" ) const ( diff --git a/validator/main.go b/validator/main.go index 4d7b9e06f1f..55e72804db2 100644 --- a/validator/main.go +++ b/validator/main.go @@ -73,7 +73,6 @@ var appFlags = []cli.Flag{ flags.SlasherCertFlag, flags.WalletPasswordsDirFlag, flags.WalletPasswordFileFlag, - flags.AccountPasswordFileFlag, flags.WalletDirFlag, cmd.MinimalConfigFlag, cmd.E2EConfigFlag, diff --git a/validator/usage.go b/validator/usage.go index d62b89a9a5e..3fc1ff648ad 100644 --- a/validator/usage.go +++ b/validator/usage.go @@ -97,6 +97,7 @@ var appHelpFlagGroups = []flagGroup{ flags.DisableAccountMetricsFlag, flags.WalletDirFlag, flags.WalletPasswordsDirFlag, + flags.WalletPasswordFileFlag, }, }, { From 758d72aff6284df4c0add4a1acf1d894c072a7f7 Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 17:17:54 -0500 Subject: [PATCH 12/21] create or open wallet --- validator/accounts/v2/accounts_create.go | 16 ++++----- validator/accounts/v2/accounts_import.go | 44 ++++++++---------------- validator/accounts/v2/wallet.go | 21 +++++++++++ 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/validator/accounts/v2/accounts_create.go b/validator/accounts/v2/accounts_create.go index 7ba87c7a2c9..8973d793197 100644 --- a/validator/accounts/v2/accounts_create.go +++ b/validator/accounts/v2/accounts_create.go @@ -6,12 +6,13 @@ import ( "github.com/manifoldco/promptui" "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" + "github.com/prysmaticlabs/prysm/validator/flags" v2keymanager "github.com/prysmaticlabs/prysm/validator/keymanager/v2" "github.com/prysmaticlabs/prysm/validator/keymanager/v2/derived" "github.com/prysmaticlabs/prysm/validator/keymanager/v2/direct" - "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" ) var log = logrus.WithField("prefix", "accounts-v2") @@ -20,14 +21,9 @@ var log = logrus.WithField("prefix", "accounts-v2") // a wallet from the user's specified path. func CreateAccount(cliCtx *cli.Context) error { ctx := context.Background() - wallet, err := OpenWallet(cliCtx) - if errors.Is(err, ErrNoWalletFound) { - wallet, err = CreateWallet(cliCtx) - if err != nil { - return errors.Wrapf(err, "Could not create wallet") - } - } else if err != nil { - return errors.Wrap(err, "could not open wallet") + wallet, err := createOrOpenWallet(cliCtx, CreateWallet) + if err != nil { + return err } skipMnemonicConfirm := cliCtx.Bool(flags.SkipMnemonicConfirmFlag.Name) keymanager, err := wallet.InitializeKeymanager(ctx, skipMnemonicConfirm) diff --git a/validator/accounts/v2/accounts_import.go b/validator/accounts/v2/accounts_import.go index 604f1691f12..cca4c3a61c7 100644 --- a/validator/accounts/v2/accounts_import.go +++ b/validator/accounts/v2/accounts_import.go @@ -21,52 +21,36 @@ import ( // ImportAccount uses the archived account made from ExportAccount to import an account and // asks the users for account passwords. func ImportAccount(cliCtx *cli.Context) error { - walletDir, err := inputDirectory(cliCtx, walletDirPromptText, flags.WalletDirFlag) - if err != nil && !errors.Is(err, ErrNoWalletFound) { - return errors.Wrapf(err, "Could not retrieve input directory") - } - ok, err := hasDir(walletDir) - if err != nil { - return err - } - // Create a new wallet if no directory exists. - if !ok { + ctx := context.Background() + wallet, err := createOrOpenWallet(cliCtx, func(cliCtx *cli.Context) (*Wallet, error) { w, err := NewWallet(cliCtx, v2keymanager.Direct) if err != nil && !errors.Is(err, ErrWalletExists) { - return errors.Wrap(err, "could not check if wallet directory exists") + return nil, errors.Wrap(err, "could not create new wallet") } if err = createDirectKeymanagerWallet(cliCtx, w); err != nil { - return errors.Wrap(err, "could not initialize wallet") + return nil, errors.Wrap(err, "could not initialize wallet") } log.WithField("wallet-path", w.walletDir).Infof( "Successfully created new wallet", ) - } - passwordsDir, err := inputDirectory(cliCtx, passwordsDirPromptText, flags.WalletPasswordsDirFlag) + return w, err + }) if err != nil { - return err + return errors.Wrap(err, "could not initialize wallet") + } + if wallet.KeymanagerKind() != v2keymanager.Direct { + return errors.New( + "only non-HD wallets can import accounts, try creating a new wallet with wallet-v2 create", + ) } keysDir, err := inputDirectory(cliCtx, importKeysDirPromptText, flags.KeysDirFlag) if err != nil { return errors.Wrap(err, "could not parse keys directory") } - - accountsPath := filepath.Join(walletDir, v2keymanager.Direct.String()) - if err := os.MkdirAll(accountsPath, flags.DirectoryPermissions); err != nil { - return errors.Wrap(err, "could not create wallet directory") - } - if err := os.MkdirAll(passwordsDir, flags.DirectoryPermissions); err != nil { - return errors.Wrap(err, "could not create passwords directory") + if err := wallet.SaveWallet(); err != nil { + return errors.Wrap(err, "could not save wallet") } - - wallet := &Wallet{ - accountsPath: accountsPath, - passwordsDir: passwordsDir, - keymanagerKind: v2keymanager.Direct, - } - var accountsImported []string - ctx := context.Background() if err := filepath.Walk(keysDir, func(path string, info os.FileInfo, err error) error { if err != nil { return err diff --git a/validator/accounts/v2/wallet.go b/validator/accounts/v2/wallet.go index 1df2fa64b8c..89dffb47f17 100644 --- a/validator/accounts/v2/wallet.go +++ b/validator/accounts/v2/wallet.go @@ -487,6 +487,27 @@ func readKeymanagerKindFromWalletPath(walletPath string) (v2keymanager.Kind, err return v2keymanager.ParseKind(list[0]) } +func createOrOpenWallet(cliCtx *cli.Context, creationFunc func(cliCtx *cli.Context) (*Wallet, error)) (*Wallet, error) { + directory := cliCtx.String(flags.WalletDirFlag.Name) + ok, err := hasDir(directory) + if err != nil { + return nil, errors.Wrapf(err, "could not check if wallet dir %s exists", directory) + } + var wallet *Wallet + if !ok { + wallet, err = creationFunc(cliCtx) + if err != nil { + return nil, errors.Wrapf(err, "Could not create wallet") + } + } else { + wallet, err = OpenWallet(cliCtx) + if err != nil { + return nil, errors.Wrap(err, "could not open wallet") + } + } + return wallet, nil +} + // Returns true if a file is not a directory and exists // at the specified path. func fileExists(filename string) bool { From 9a71304d51ca6dd3515169670a7b3a542d16377d Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 17:21:42 -0500 Subject: [PATCH 13/21] ivan feedback --- validator/accounts/v2/accounts_import.go | 2 +- validator/accounts/v2/wallet_create.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/validator/accounts/v2/accounts_import.go b/validator/accounts/v2/accounts_import.go index cca4c3a61c7..02b9df433cc 100644 --- a/validator/accounts/v2/accounts_import.go +++ b/validator/accounts/v2/accounts_import.go @@ -30,7 +30,7 @@ func ImportAccount(cliCtx *cli.Context) error { if err = createDirectKeymanagerWallet(cliCtx, w); err != nil { return nil, errors.Wrap(err, "could not initialize wallet") } - log.WithField("wallet-path", w.walletDir).Infof( + log.WithField("wallet-path", w.walletDir).Info( "Successfully created new wallet", ) return w, err diff --git a/validator/accounts/v2/wallet_create.go b/validator/accounts/v2/wallet_create.go index 0778036bad8..47279a335d3 100644 --- a/validator/accounts/v2/wallet_create.go +++ b/validator/accounts/v2/wallet_create.go @@ -32,7 +32,7 @@ func CreateWallet(cliCtx *cli.Context) (*Wallet, error) { if err = createDirectKeymanagerWallet(cliCtx, w); err != nil { return nil, errors.Wrap(err, "could not initialize wallet with direct keymanager") } - log.WithField("wallet-path", w.walletDir).Infof( + log.WithField("wallet-path", w.walletDir).Info( "Successfully created wallet with on-disk keymanager configuration. " + "Make a new validator account with ./prysm.sh validator accounts-v2 create", ) @@ -40,7 +40,7 @@ func CreateWallet(cliCtx *cli.Context) (*Wallet, error) { if err = createDerivedKeymanagerWallet(cliCtx, w); err != nil { return nil, errors.Wrap(err, "could not initialize wallet with derived keymanager") } - log.WithField("wallet-path", w.walletDir).Infof( + log.WithField("wallet-path", w.walletDir).Info( "Successfully created HD wallet and saved configuration to disk. " + "Make a new validator account with ./prysm.sh validator accounts-2 create", ) @@ -48,7 +48,7 @@ func CreateWallet(cliCtx *cli.Context) (*Wallet, error) { if err = createRemoteKeymanagerWallet(cliCtx, w); err != nil { return nil, errors.Wrap(err, "could not initialize wallet with remote keymanager") } - log.WithField("wallet-path", w.walletDir).Infof( + log.WithField("wallet-path", w.walletDir).Info( "Successfully created wallet with remote keymanager configuration", ) default: From 17fa95e08a5d7193d53cd17caad29de21231bc70 Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 17:43:50 -0500 Subject: [PATCH 14/21] enter password for account with pubkey --- validator/accounts/v2/BUILD.bazel | 1 + validator/accounts/v2/accounts_import.go | 16 ++++++++-------- validator/accounts/v2/prompt.go | 2 +- validator/accounts/v2/wallet.go | 7 ++++--- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/validator/accounts/v2/BUILD.bazel b/validator/accounts/v2/BUILD.bazel index 72b0d449cd5..8f87694b787 100644 --- a/validator/accounts/v2/BUILD.bazel +++ b/validator/accounts/v2/BUILD.bazel @@ -23,6 +23,7 @@ go_library( "//validator:__subpackages__", ], deps = [ + "//shared/bytesutil:go_default_library", "//shared/featureconfig:go_default_library", "//shared/params:go_default_library", "//shared/petnames:go_default_library", diff --git a/validator/accounts/v2/accounts_import.go b/validator/accounts/v2/accounts_import.go index 02b9df433cc..25161d57019 100644 --- a/validator/accounts/v2/accounts_import.go +++ b/validator/accounts/v2/accounts_import.go @@ -75,11 +75,11 @@ func ImportAccount(cliCtx *cli.Context) error { return nil } - accountName, err := wallet.importKeystore(ctx, path) + accountName, pubKey, err := wallet.importKeystore(ctx, path) if err != nil { return errors.Wrap(err, "could not import keystore") } - if err := wallet.enterPasswordForAccount(cliCtx, accountName); err != nil { + if err := wallet.enterPasswordForAccount(cliCtx, accountName, pubKey); err != nil { return errors.Wrap(err, "could not verify password for keystore") } accountsImported = append(accountsImported, accountName) @@ -103,25 +103,25 @@ func ImportAccount(cliCtx *cli.Context) error { return nil } -func (w *Wallet) importKeystore(ctx context.Context, keystoreFilePath string) (string, error) { +func (w *Wallet) importKeystore(ctx context.Context, keystoreFilePath string) (string, []byte, error) { keystoreBytes, err := ioutil.ReadFile(keystoreFilePath) if err != nil { - return "", errors.Wrap(err, "could not read keystore file") + return "", nil, errors.Wrap(err, "could not read keystore file") } keystoreFile := &v2keymanager.Keystore{} if err := json.Unmarshal(keystoreBytes, keystoreFile); err != nil { - return "", errors.Wrap(err, "could not decode keystore json") + return "", nil, errors.Wrap(err, "could not decode keystore json") } pubKeyBytes, err := hex.DecodeString(keystoreFile.Pubkey) if err != nil { - return "", errors.Wrap(err, "could not decode public key string in keystore") + return "", nil, errors.Wrap(err, "could not decode public key string in keystore") } accountName := petnames.DeterministicName(pubKeyBytes, "-") keystoreFileName := filepath.Base(keystoreFilePath) if err := w.WriteFileAtPath(ctx, accountName, keystoreFileName, keystoreBytes); err != nil { - return "", errors.Wrap(err, "could not write keystore to account dir") + return "", nil, errors.Wrap(err, "could not write keystore to account dir") } - return accountName, nil + return accountName, pubKeyBytes, nil } func logAccountsImported(wallet *Wallet, keymanager *direct.Keymanager, accountNames []string) error { diff --git a/validator/accounts/v2/prompt.go b/validator/accounts/v2/prompt.go index c81bf0a7430..71d967e388d 100644 --- a/validator/accounts/v2/prompt.go +++ b/validator/accounts/v2/prompt.go @@ -24,7 +24,7 @@ const ( confirmPasswordPromptText = "Confirm password" walletPasswordPromptText = "Wallet password" newAccountPasswordPromptText = "New account password" - passwordForAccountPromptText = "Enter password for account %s" + passwordForAccountPromptText = "Enter password for account with public key %#x" ) type passwordConfirm int diff --git a/validator/accounts/v2/wallet.go b/validator/accounts/v2/wallet.go index 89dffb47f17..ceb3190945f 100644 --- a/validator/accounts/v2/wallet.go +++ b/validator/accounts/v2/wallet.go @@ -15,6 +15,7 @@ import ( petname "github.com/dustinkirkland/golang-petname" "github.com/logrusorgru/aurora" "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/shared/bytesutil" "github.com/prysmaticlabs/prysm/validator/flags" v2keymanager "github.com/prysmaticlabs/prysm/validator/keymanager/v2" "github.com/prysmaticlabs/prysm/validator/keymanager/v2/derived" @@ -389,7 +390,7 @@ func (w *Wallet) ReadPasswordFromDisk(ctx context.Context, passwordFileName stri // enterPasswordForAccount checks if a user has a password specified for the new account // either from a file or from stdin. Then, it saves the password to the wallet. -func (w *Wallet) enterPasswordForAccount(cliCtx *cli.Context, accountName string) error { +func (w *Wallet) enterPasswordForAccount(cliCtx *cli.Context, accountName string, pubKey []byte) error { au := aurora.NewAurora(true) var password string var err error @@ -402,7 +403,7 @@ func (w *Wallet) enterPasswordForAccount(cliCtx *cli.Context, accountName string password = string(data) err = w.checkPasswordForAccount(accountName, password) if err != nil && strings.Contains(err.Error(), "invalid checksum") { - return fmt.Errorf("invalid password entered for account %s", accountName) + return fmt.Errorf("invalid password entered for account with public key %#x", pubKey) } if err != nil { return err @@ -415,7 +416,7 @@ func (w *Wallet) enterPasswordForAccount(cliCtx *cli.Context, accountName string password, err = inputWeakPassword( cliCtx, flags.AccountPasswordFileFlag, - fmt.Sprintf(passwordForAccountPromptText, accountName), + fmt.Sprintf(passwordForAccountPromptText, bytesutil.Trunc(pubKey)), ) if err != nil { return errors.Wrap(err, "could not input password") From cfc7a90f3dd4cd2e1e570ab456fdc4d4d57f58f4 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Tue, 28 Jul 2020 17:58:21 -0500 Subject: [PATCH 15/21] Update validator/accounts/v2/accounts_create.go Co-authored-by: Ivan Martinez --- validator/accounts/v2/accounts_create.go | 1 - 1 file changed, 1 deletion(-) diff --git a/validator/accounts/v2/accounts_create.go b/validator/accounts/v2/accounts_create.go index 8973d793197..ec58afbece8 100644 --- a/validator/accounts/v2/accounts_create.go +++ b/validator/accounts/v2/accounts_create.go @@ -8,7 +8,6 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" - "github.com/prysmaticlabs/prysm/validator/flags" v2keymanager "github.com/prysmaticlabs/prysm/validator/keymanager/v2" "github.com/prysmaticlabs/prysm/validator/keymanager/v2/derived" From 0c05bdbe8aff7760080ca1bff470f78f746c060b Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 18:02:41 -0500 Subject: [PATCH 16/21] works --- validator/accounts/v2/accounts_export.go | 2 +- validator/accounts/v2/accounts_list.go | 2 +- validator/accounts/v2/wallet.go | 28 ++++++++++++++---------- validator/flags/flags.go | 6 +---- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/validator/accounts/v2/accounts_export.go b/validator/accounts/v2/accounts_export.go index 9b401d28b38..70b5e22d32d 100644 --- a/validator/accounts/v2/accounts_export.go +++ b/validator/accounts/v2/accounts_export.go @@ -163,7 +163,7 @@ func (w *Wallet) zipAccounts(accounts []string, targetPath string) error { if strings.Contains(path, accountName) { // Add all files under the account folder to the archive. isAccount = true - } else if !info.IsDir() && info.Name() == flags.KeymanagerConfigFileName { + } else if !info.IsDir() && info.Name() == KeymanagerConfigFileName { // Add the keymanager config file to the archive as well. isAccount = true } diff --git a/validator/accounts/v2/accounts_list.go b/validator/accounts/v2/accounts_list.go index f64e60d9cc4..ea074121a02 100644 --- a/validator/accounts/v2/accounts_list.go +++ b/validator/accounts/v2/accounts_list.go @@ -224,7 +224,7 @@ func listRemoteKeymanagerAccounts( fmt.Printf("(keymanager kind) %s\n", au.BrightGreen("remote signer").Bold()) fmt.Printf( "(configuration file path) %s\n", - au.BrightGreen(filepath.Join(wallet.AccountsDir(), flags.KeymanagerConfigFileName)).Bold(), + au.BrightGreen(filepath.Join(wallet.AccountsDir(), KeymanagerConfigFileName)).Bold(), ) ctx := context.Background() fmt.Println(" ") diff --git a/validator/accounts/v2/wallet.go b/validator/accounts/v2/wallet.go index ceb3190945f..1bf5cd9321c 100644 --- a/validator/accounts/v2/wallet.go +++ b/validator/accounts/v2/wallet.go @@ -26,11 +26,22 @@ import ( keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4" ) +const ( + // KeymanagerConfigFileName for the keymanager used by the wallet: direct, derived, or remote. + KeymanagerConfigFileName = "keymanageropts.json" + // DirectoryPermissions for directories created under the wallet path. + DirectoryPermissions = os.ModePerm +) + var ( // ErrNoWalletFound signifies there was no wallet directory found on-disk. ErrNoWalletFound = errors.New( "no wallet found at path, please create a new wallet using `./prysm.sh validator wallet-v2 create`", ) + // ErrWalletExists is an error returned when a wallet already exists in the path provided. + ErrWalletExists = errors.New("you already have a wallet at the specified path. You can " + + "edit your wallet configuration by running ./prysm.sh validator wallet-v2 edit-config", + ) keymanagerKindSelections = map[v2keymanager.Kind]string{ v2keymanager.Derived: "HD Wallet (Recommended)", v2keymanager.Direct: "Non-HD Wallet (Most Basic)", @@ -38,13 +49,6 @@ var ( } ) -var ( - // ErrWalletExists is an error returned when a wallet already exists in the path provided. - ErrWalletExists = errors.New("you already have a wallet at the specified path. You can " + - "edit your wallet configuration by running ./prysm.sh validator wallet-v2 edit-config", - ) -) - // Wallet is a primitive in Prysm's v2 account management which // has the capability of creating new accounts, reading existing accounts, // and providing secure access to eth2 secrets depending on an @@ -101,7 +105,7 @@ func NewWallet( if err != nil { return nil, errors.Wrap(err, "could not get password directory") } - if err := os.MkdirAll(passwordsDir, flags.DirectoryPermissions); err != nil { + if err := os.MkdirAll(passwordsDir, DirectoryPermissions); err != nil { return nil, errors.Wrap(err, "could not create passwords directory") } w.passwordsDir = passwordsDir @@ -164,11 +168,11 @@ func OpenWallet(cliCtx *cli.Context) (*Wallet, error) { // SaveWallet persists the wallet's directories to disk. func (w *Wallet) SaveWallet() error { - if err := os.MkdirAll(w.accountsPath, flags.DirectoryPermissions); err != nil { + if err := os.MkdirAll(w.accountsPath, DirectoryPermissions); err != nil { return errors.Wrap(err, "could not create wallet directory") } if w.keymanagerKind == v2keymanager.Direct { - if err := os.MkdirAll(w.passwordsDir, flags.DirectoryPermissions); err != nil { + if err := os.MkdirAll(w.passwordsDir, DirectoryPermissions); err != nil { return errors.Wrap(err, "could not create passwords directory") } } @@ -337,7 +341,7 @@ func AccountTimestamp(fileName string) (time.Time, error) { // ReadKeymanagerConfigFromDisk opens a keymanager config file // for reading if it exists at the wallet path. func (w *Wallet) ReadKeymanagerConfigFromDisk(ctx context.Context) (io.ReadCloser, error) { - configFilePath := filepath.Join(w.accountsPath, flags.KeymanagerConfigFileName) + configFilePath := filepath.Join(w.accountsPath, KeymanagerConfigFileName) if !fileExists(configFilePath) { return nil, fmt.Errorf("no keymanager config file found at path: %s", w.accountsPath) } @@ -347,7 +351,7 @@ func (w *Wallet) ReadKeymanagerConfigFromDisk(ctx context.Context) (io.ReadClose // WriteKeymanagerConfigToDisk takes an encoded keymanager config file // and writes it to the wallet path. func (w *Wallet) WriteKeymanagerConfigToDisk(ctx context.Context, encoded []byte) error { - configFilePath := filepath.Join(w.accountsPath, flags.KeymanagerConfigFileName) + configFilePath := filepath.Join(w.accountsPath, KeymanagerConfigFileName) // Write the config file to disk. if err := ioutil.WriteFile(configFilePath, encoded, os.ModePerm); err != nil { return errors.Wrapf(err, "could not write %s", configFilePath) diff --git a/validator/flags/flags.go b/validator/flags/flags.go index 08481567ac3..34676369936 100644 --- a/validator/flags/flags.go +++ b/validator/flags/flags.go @@ -15,12 +15,8 @@ import ( const ( // WalletDefaultDirName for accounts-v2. WalletDefaultDirName = "prysm-wallet-v2" - // PasswordsDefaultDirName where account passwords are stored. + // PasswordsDefaultDirName where account-v2 passwords are stored. PasswordsDefaultDirName = "prysm-wallet-v2-passwords" - // KeymanagerConfigFileName for the keymanager used by the wallet: direct, derived, or remote. - KeymanagerConfigFileName = "keymanageropts.json" - // DirectoryPermissions for directories created under the wallet path. - DirectoryPermissions = os.ModePerm ) var ( From f4c67659013d7e1d692ffe90c73e243d332fa994 Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 18:07:31 -0500 Subject: [PATCH 17/21] preston feedback --- validator/accounts/v2/prompt.go | 2 +- validator/accounts/v2/wallet_edit.go | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/validator/accounts/v2/prompt.go b/validator/accounts/v2/prompt.go index 71d967e388d..895cf12d70d 100644 --- a/validator/accounts/v2/prompt.go +++ b/validator/accounts/v2/prompt.go @@ -220,7 +220,7 @@ func inputRemoteKeymanagerConfig(cliCtx *cli.Context) (*remote.Config, error) { crt := cliCtx.String(flags.RemoteSignerCertPathFlag.Name) key := cliCtx.String(flags.RemoteSignerKeyPathFlag.Name) ca := cliCtx.String(flags.RemoteSignerCACertPathFlag.Name) - log.Infof("Input desired configuration") + log.Info("Input desired configuration") var err error if addr == "" { prompt := promptui.Prompt{ diff --git a/validator/accounts/v2/wallet_edit.go b/validator/accounts/v2/wallet_edit.go index e30f65170d7..41e3a613d6f 100644 --- a/validator/accounts/v2/wallet_edit.go +++ b/validator/accounts/v2/wallet_edit.go @@ -31,8 +31,9 @@ func EditWalletConfiguration(cliCtx *cli.Context) error { if err != nil { return errors.Wrap(err, "could not unmarshal config") } - log.Infof("Current configuration") - fmt.Printf("%s\n", cfg) + log.Info("Current configuration") + // Prints the current configuration to stdout. + fmt.Println(cfg) passwordsDir, err := inputDirectory(cliCtx, passwordsDirPromptText, flags.WalletPasswordsDirFlag) if err != nil { return errors.Wrap(err, "could not get password directory") @@ -57,8 +58,9 @@ func EditWalletConfiguration(cliCtx *cli.Context) error { if err != nil { return errors.Wrap(err, "could not unmarshal config") } - log.Infof("Current configuration") - fmt.Printf("%s\n", cfg) + log.Info("Current configuration") + // Prints the current configuration to stdout. + fmt.Println(cfg) newCfg, err := inputRemoteKeymanagerConfig(cliCtx) if err != nil { return errors.Wrap(err, "could not get keymanager config") From 8665bbf469920bdc6b9e45ea7176b6ad2ab8c8cc Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 18:10:27 -0500 Subject: [PATCH 18/21] nothing to export --- validator/accounts/v2/accounts_export.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validator/accounts/v2/accounts_export.go b/validator/accounts/v2/accounts_export.go index 70b5e22d32d..f89269d9aaa 100644 --- a/validator/accounts/v2/accounts_export.go +++ b/validator/accounts/v2/accounts_export.go @@ -30,7 +30,7 @@ func ExportAccount(cliCtx *cli.Context) error { } wallet, err := OpenWallet(cliCtx) if errors.Is(err, ErrNoWalletFound) { - return errors.Wrap(err, "no wallet found at path, create a new wallet with wallet-v2 create") + return errors.Wrap(err, "nothing to export, no wallet found") } else if err != nil { return errors.Wrap(err, "could not open wallet") } From 7d38761c694a7af792efdfeffdf1d2670e7b304a Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 18:11:09 -0500 Subject: [PATCH 19/21] fmt --- beacon-chain/forkchoice/protoarray/nodes_test.go | 6 +++--- validator/accounts/v2/accounts_create.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/beacon-chain/forkchoice/protoarray/nodes_test.go b/beacon-chain/forkchoice/protoarray/nodes_test.go index ab9aeb7e072..19ec552962a 100644 --- a/beacon-chain/forkchoice/protoarray/nodes_test.go +++ b/beacon-chain/forkchoice/protoarray/nodes_test.go @@ -374,10 +374,10 @@ func TestStore_HasParent(t *testing.T) { want bool }{ {r: [32]byte{'a'}, want: false}, - {m: map[[32]byte]uint64{[32]byte{'a'}: 0}, r: [32]byte{'a'}, want: false}, - {m: map[[32]byte]uint64{[32]byte{'a'}: 0}, r: [32]byte{'a'}, + {m: map[[32]byte]uint64{{'a'}: 0}, r: [32]byte{'a'}, want: false}, + {m: map[[32]byte]uint64{{'a'}: 0}, r: [32]byte{'a'}, n: []*Node{{Parent: NonExistentNode}}, want: false}, - {m: map[[32]byte]uint64{[32]byte{'a'}: 0}, + {m: map[[32]byte]uint64{{'a'}: 0}, n: []*Node{{Parent: 0}}, r: [32]byte{'a'}, want: true}, } diff --git a/validator/accounts/v2/accounts_create.go b/validator/accounts/v2/accounts_create.go index ec58afbece8..1f2d7a5f0bc 100644 --- a/validator/accounts/v2/accounts_create.go +++ b/validator/accounts/v2/accounts_create.go @@ -6,12 +6,12 @@ import ( "github.com/manifoldco/promptui" "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" "github.com/prysmaticlabs/prysm/validator/flags" v2keymanager "github.com/prysmaticlabs/prysm/validator/keymanager/v2" "github.com/prysmaticlabs/prysm/validator/keymanager/v2/derived" "github.com/prysmaticlabs/prysm/validator/keymanager/v2/direct" + "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" ) var log = logrus.WithField("prefix", "accounts-v2") From 4b237aa0023132019b58c9f23258be704a2f5b9a Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 18:23:46 -0500 Subject: [PATCH 20/21] test for create or open --- validator/accounts/v2/BUILD.bazel | 1 + validator/accounts/v2/wallet.go | 1 + validator/accounts/v2/wallet_create_test.go | 35 +++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/validator/accounts/v2/BUILD.bazel b/validator/accounts/v2/BUILD.bazel index 8f87694b787..2448fed3950 100644 --- a/validator/accounts/v2/BUILD.bazel +++ b/validator/accounts/v2/BUILD.bazel @@ -75,6 +75,7 @@ go_test( "@com_github_dustin_go_humanize//:go_default_library", "@com_github_google_uuid//:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", + "@com_github_sirupsen_logrus//hooks/test:go_default_library", "@com_github_urfave_cli_v2//:go_default_library", "@com_github_wealdtech_go_eth2_wallet_encryptor_keystorev4//:go_default_library", ], diff --git a/validator/accounts/v2/wallet.go b/validator/accounts/v2/wallet.go index 1bf5cd9321c..150b936f233 100644 --- a/validator/accounts/v2/wallet.go +++ b/validator/accounts/v2/wallet.go @@ -163,6 +163,7 @@ func OpenWallet(cliCtx *cli.Context) (*Wallet, error) { au := aurora.NewAurora(true) log.Infof("%s %s", au.BrightMagenta("(account passwords path)"), w.passwordsDir) } + log.Info("Successfully opened wallet") return w, nil } diff --git a/validator/accounts/v2/wallet_create_test.go b/validator/accounts/v2/wallet_create_test.go index 0109a36ad0b..1ee60b4adb7 100644 --- a/validator/accounts/v2/wallet_create_test.go +++ b/validator/accounts/v2/wallet_create_test.go @@ -6,6 +6,7 @@ import ( "os" "testing" + "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/shared/testutil" "github.com/prysmaticlabs/prysm/shared/testutil/assert" "github.com/prysmaticlabs/prysm/shared/testutil/require" @@ -14,9 +15,43 @@ import ( "github.com/prysmaticlabs/prysm/validator/keymanager/v2/derived" "github.com/prysmaticlabs/prysm/validator/keymanager/v2/direct" "github.com/prysmaticlabs/prysm/validator/keymanager/v2/remote" + logTest "github.com/sirupsen/logrus/hooks/test" "github.com/urfave/cli/v2" ) +func TestCreateOrOpenWallet(t *testing.T) { + hook := logTest.NewGlobal() + walletDir, passwordsDir, _ := setupWalletAndPasswordsDir(t) + cliCtx := setupWalletCtx(t, &testWalletConfig{ + walletDir: walletDir, + passwordsDir: passwordsDir, + keymanagerKind: v2keymanager.Direct, + }) + createDirectWallet := func(cliCtx *cli.Context) (*Wallet, error) { + w, err := NewWallet(cliCtx, v2keymanager.Direct) + if err != nil && !errors.Is(err, ErrWalletExists) { + return nil, errors.Wrap(err, "could not create new wallet") + } + if err = createDirectKeymanagerWallet(cliCtx, w); err != nil { + return nil, errors.Wrap(err, "could not initialize wallet") + } + log.WithField("wallet-path", w.walletDir).Info( + "Successfully created new wallet", + ) + return w, err + } + createdWallet, err := createOrOpenWallet(cliCtx, createDirectWallet) + require.NoError(t, err) + testutil.AssertLogsContain(t, hook, "Successfully created new wallet") + testutil.AssertLogsDoNotContain(t, hook, "Successfully opened wallet") + + openedWallet, err := createOrOpenWallet(cliCtx, createDirectWallet) + require.NoError(t, err) + testutil.AssertLogsContain(t, hook, "Successfully opened wallet") + assert.Equal(t, createdWallet.KeymanagerKind(), openedWallet.KeymanagerKind()) + assert.Equal(t, createdWallet.AccountsDir(), openedWallet.AccountsDir()) +} + func TestCreateWallet_Direct(t *testing.T) { walletDir, passwordsDir, _ := setupWalletAndPasswordsDir(t) cliCtx := setupWalletCtx(t, &testWalletConfig{ From 78549d1a4e1883d3619a68480f695a06bfdb6be5 Mon Sep 17 00:00:00 2001 From: rauljordan Date: Tue, 28 Jul 2020 18:29:23 -0500 Subject: [PATCH 21/21] gaz --- validator/accounts/v2/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/validator/accounts/v2/BUILD.bazel b/validator/accounts/v2/BUILD.bazel index 2448fed3950..6ea1436644b 100644 --- a/validator/accounts/v2/BUILD.bazel +++ b/validator/accounts/v2/BUILD.bazel @@ -74,6 +74,7 @@ go_test( "//validator/keymanager/v2/remote:go_default_library", "@com_github_dustin_go_humanize//:go_default_library", "@com_github_google_uuid//: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", "@com_github_urfave_cli_v2//:go_default_library",