diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index cc22684e0b..3e0f5f8908 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -17,6 +17,7 @@ package main import ( + "errors" "fmt" "os" @@ -24,7 +25,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" "github.com/urfave/cli/v2" ) @@ -219,35 +219,6 @@ func accountList(ctx *cli.Context) error { return nil } -// tries unlocking the specified account a few times. -func unlockAccount(ks *keystore.KeyStore, address string, i int, passwords []string) (accounts.Account, string) { - account, err := utils.MakeAddress(ks, address) - if err != nil { - utils.Fatalf("Could not list accounts: %v", err) - } - for trials := 0; trials < 3; trials++ { - prompt := fmt.Sprintf("Unlocking account %s | Attempt %d/%d", address, trials+1, 3) - password := utils.GetPassPhraseWithList(prompt, false, i, passwords) - err = ks.Unlock(account, password) - if err == nil { - log.Info("Unlocked account", "address", account.Address.Hex()) - return account, password - } - if err, ok := err.(*keystore.AmbiguousAddrError); ok { - log.Info("Unlocked account", "address", account.Address.Hex()) - return ambiguousAddrRecovery(ks, err, password), password - } - if err != keystore.ErrDecrypt { - // No need to prompt again if the error is not decryption-related. - break - } - } - // All trials expended to unlock account, bail out - utils.Fatalf("Failed to unlock account %s (%v)", address, err) - - return accounts.Account{}, "" -} - func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrError, auth string) accounts.Account { fmt.Printf("Multiple key files exist for address %x:\n", err.Addr) for _, a := range err.Matches { @@ -323,10 +294,24 @@ func accountUpdate(ctx *cli.Context) error { ks := backends[0].(*keystore.KeyStore) for _, addr := range ctx.Args().Slice() { - account, oldPassword := unlockAccount(ks, addr, 0, nil) - newPassword := utils.GetPassPhraseWithList("Please give a new password. Do not forget this password.", true, 0, nil) - if err := ks.Update(account, oldPassword, newPassword); err != nil { - utils.Fatalf("Could not update the account: %v", err) + account, err := utils.MakeAddress(ks, addr) + if err != nil { + return fmt.Errorf("could not locate account: %w", err) + } + newPassword := utils.GetPassPhrase("Please give a NEW password. Do not forget this password.", true) + updateFn := func(attempt int) error { + prompt := fmt.Sprintf("Please provide the OLD password for account %s | Attempt %d/%d", addr, attempt+1, 3) + password := utils.GetPassPhrase(prompt, false) + return ks.Update(account, password, newPassword) + } + // let user attempt unlock thrice. + for attempts := 0; attempts < 3; attempts++ { + if err = updateFn(attempts); !errors.Is(err, keystore.ErrDecrypt) { + break // nil or some other type of error + } + } + if err != nil { + return fmt.Errorf("could not update account: %w", err) } } return nil diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 10d4052737..185647b653 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -23,11 +23,9 @@ import ( "slices" "sort" "strconv" - "strings" "time" "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/console/prompt" @@ -359,8 +357,9 @@ func startNode(ctx *cli.Context, stack *node.Node, isConsole bool) { // Start up the node itself utils.StartNode(ctx, stack, isConsole) - // Unlock any account specifically requested - unlockAccounts(ctx, stack) + if ctx.IsSet(utils.UnlockedAccountFlag.Name) { + log.Warn(`The "unlock" flag has been deprecated and has no effect`) + } // Register wallet event handlers to open and auto-derive wallets events := make(chan accounts.WalletEvent, 16) @@ -427,33 +426,3 @@ func startNode(ctx *cli.Context, stack *node.Node, isConsole bool) { }() } } - -// unlockAccounts unlocks any account specifically requested. -func unlockAccounts(ctx *cli.Context, stack *node.Node) { - var unlocks []string - inputs := strings.Split(ctx.String(utils.UnlockedAccountFlag.Name), ",") - for _, input := range inputs { - if trimmed := strings.TrimSpace(input); trimmed != "" { - unlocks = append(unlocks, trimmed) - } - } - // Short circuit if there is no account to unlock. - if len(unlocks) == 0 { - return - } - // If insecure account unlocking is not allowed if node's APIs are exposed to external. - // Print warning log to user and skip unlocking. - if !stack.Config().InsecureUnlockAllowed && stack.Config().ExtRPCEnabled() { - utils.Fatalf("Account unlock with HTTP access is forbidden!") - } - backends := stack.AccountManager().Backends(keystore.KeyStoreType) - if len(backends) == 0 { - log.Warn("Failed to unlock accounts, keystore is not available") - return - } - ks := backends[0].(*keystore.KeyStore) - passwords := utils.MakePasswordList(ctx) - for i, account := range unlocks { - unlockAccount(ks, account, i, passwords) - } -} diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index f083a25f90..dbc07c6034 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -498,12 +498,6 @@ var ( } // Account settings - UnlockedAccountFlag = &cli.StringFlag{ - Name: "unlock", - Usage: "Comma separated list of accounts to unlock", - Value: "", - Category: flags.AccountCategory, - } PasswordFileFlag = &cli.PathFlag{ Name: "password", Usage: "Password file to use for non-interactive password input", @@ -521,7 +515,6 @@ var ( Usage: "Allow insecure account unlocking when account-related RPCs are exposed by http", Category: flags.AccountCategory, } - // EVM settings VMEnableDebugFlag = &cli.BoolFlag{ Name: "vmdebug", diff --git a/cmd/utils/flags_legacy.go b/cmd/utils/flags_legacy.go index 6209516e05..6d454266e8 100644 --- a/cmd/utils/flags_legacy.go +++ b/cmd/utils/flags_legacy.go @@ -159,6 +159,12 @@ var ( Usage: "This used to enable the 'personal' namespace.", Category: flags.DeprecatedCategory, } + UnlockedAccountFlag = &cli.StringFlag{ + Name: "unlock", + Usage: "Comma separated list of accounts to unlock (deprecated)", + Value: "", + Category: flags.DeprecatedCategory, + } ) // showDeprecated displays deprecated flags that will be soon removed from the codebase.