From 8f373227ac481685148019b21ef9e1478d3ba609 Mon Sep 17 00:00:00 2001 From: Delweng Date: Thu, 27 Apr 2023 18:57:29 +0800 Subject: [PATCH] cmd/geth: make account commands not require datadir lock (#27084) Makes the `geth account ... ` commands usable even if a geth-process is already executing, since the account commands do not read the chaindata, it was not required for those to use the same locking mechanism. --- Signed-off-by: jsvisa Co-authored-by: Martin Holst Swende Co-authored-by: Sina Mahmoodi --- cmd/geth/accountcmd.go | 59 ++++++++++++++++++++++++++---------------- cmd/geth/config.go | 19 +++++++++----- node/config.go | 6 ++--- node/node.go | 2 +- 4 files changed, 53 insertions(+), 33 deletions(-) diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index a36da7d55..cc22684e0 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -188,15 +188,34 @@ nodes. } ) +// makeAccountManager creates an account manager with backends +func makeAccountManager(ctx *cli.Context) *accounts.Manager { + cfg := loadBaseConfig(ctx) + am := accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: cfg.Node.InsecureUnlockAllowed}) + keydir, isEphemeral, err := cfg.Node.GetKeyStoreDir() + if err != nil { + utils.Fatalf("Failed to get the keystore directory: %v", err) + } + if isEphemeral { + utils.Fatalf("Can't use ephemeral directory as keystore path") + } + + if err := setAccountManagerBackends(&cfg.Node, am, keydir); err != nil { + utils.Fatalf("Failed to set account manager backends: %v", err) + } + return am +} + func accountList(ctx *cli.Context) error { - stack, _ := makeConfigNode(ctx) + am := makeAccountManager(ctx) var index int - for _, wallet := range stack.AccountManager().Wallets() { + for _, wallet := range am.Wallets() { for _, account := range wallet.Accounts() { fmt.Printf("Account #%d: {%x} %s\n", index, account.Address, &account.URL) index++ } } + return nil } @@ -258,17 +277,13 @@ func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrErr // accountCreate creates a new account into the keystore defined by the CLI flags. func accountCreate(ctx *cli.Context) error { - cfg := gethConfig{Node: defaultNodeConfig()} - // Load config file. - if file := ctx.String(configFileFlag.Name); file != "" { - if err := loadConfig(file, &cfg); err != nil { - utils.Fatalf("%v", err) - } - } - utils.SetNodeConfig(ctx, &cfg.Node) - keydir, err := cfg.Node.KeyDirConfig() + cfg := loadBaseConfig(ctx) + keydir, isEphemeral, err := cfg.Node.GetKeyStoreDir() if err != nil { - utils.Fatalf("Failed to read configuration: %v", err) + utils.Fatalf("Failed to get the keystore directory: %v", err) + } + if isEphemeral { + utils.Fatalf("Can't use ephemeral directory as keystore path") } scryptN := keystore.StandardScryptN scryptP := keystore.StandardScryptP @@ -300,8 +315,8 @@ func accountUpdate(ctx *cli.Context) error { if ctx.Args().Len() == 0 { utils.Fatalf("No accounts specified to update") } - stack, _ := makeConfigNode(ctx) - backends := stack.AccountManager().Backends(keystore.KeyStoreType) + am := makeAccountManager(ctx) + backends := am.Backends(keystore.KeyStoreType) if len(backends) == 0 { utils.Fatalf("Keystore is not available") } @@ -327,14 +342,14 @@ func importWallet(ctx *cli.Context) error { utils.Fatalf("Could not read wallet file: %v", err) } - stack, _ := makeConfigNode(ctx) - passphrase := utils.GetPassPhraseWithList("", false, 0, utils.MakePasswordList(ctx)) - - backends := stack.AccountManager().Backends(keystore.KeyStoreType) + am := makeAccountManager(ctx) + backends := am.Backends(keystore.KeyStoreType) if len(backends) == 0 { utils.Fatalf("Keystore is not available") } ks := backends[0].(*keystore.KeyStore) + passphrase := utils.GetPassPhraseWithList("", false, 0, utils.MakePasswordList(ctx)) + acct, err := ks.ImportPreSaleKey(keyJSON, passphrase) if err != nil { utils.Fatalf("%v", err) @@ -352,14 +367,14 @@ func accountImport(ctx *cli.Context) error { if err != nil { utils.Fatalf("Failed to load the private key: %v", err) } - stack, _ := makeConfigNode(ctx) - passphrase := utils.GetPassPhraseWithList("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) - - backends := stack.AccountManager().Backends(keystore.KeyStoreType) + am := makeAccountManager(ctx) + backends := am.Backends(keystore.KeyStoreType) if len(backends) == 0 { utils.Fatalf("Keystore is not available") } ks := backends[0].(*keystore.KeyStore) + passphrase := utils.GetPassPhraseWithList("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) + acct, err := ks.ImportECDSA(key, passphrase) if err != nil { utils.Fatalf("Could not create the account: %v", err) diff --git a/cmd/geth/config.go b/cmd/geth/config.go index ad7fd4d71..816762a68 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -26,6 +26,7 @@ import ( "github.com/urfave/cli/v2" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/external" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/accounts/scwallet" @@ -119,8 +120,9 @@ func defaultNodeConfig() node.Config { return cfg } -// makeConfigNode loads geth configuration and creates a blank node instance. -func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { +// loadBaseConfig loads the gethConfig based on the given command line +// parameters and config file. +func loadBaseConfig(ctx *cli.Context) gethConfig { // Load defaults. cfg := gethConfig{ Eth: ethconfig.Defaults, @@ -137,12 +139,18 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { // Apply flags. utils.SetNodeConfig(ctx, &cfg.Node) + return cfg +} + +// makeConfigNode loads geth configuration and creates a blank node instance. +func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { + cfg := loadBaseConfig(ctx) stack, err := node.New(&cfg.Node) if err != nil { utils.Fatalf("Failed to create the protocol stack: %v", err) } // Node doesn't by default populate account manager backends - if err := setAccountManagerBackends(stack); err != nil { + if err := setAccountManagerBackends(stack.Config(), stack.AccountManager(), stack.KeyStoreDir()); err != nil { utils.Fatalf("Failed to set account manager backends: %v", err) } @@ -269,10 +277,7 @@ func deprecated(field string) bool { } } -func setAccountManagerBackends(stack *node.Node) error { - conf := stack.Config() - am := stack.AccountManager() - keydir := stack.KeyStoreDir() +func setAccountManagerBackends(conf *node.Config, am *accounts.Manager, keydir string) error { scryptN := keystore.StandardScryptN scryptP := keystore.StandardScryptP if conf.UseLightweightKDF { diff --git a/node/config.go b/node/config.go index 37a7d5837..35115eaa8 100644 --- a/node/config.go +++ b/node/config.go @@ -448,10 +448,10 @@ func (c *Config) KeyDirConfig() (string, error) { return keydir, err } -// getKeyStoreDir retrieves the key directory and will create +// GetKeyStoreDir retrieves the key directory and will create // and ephemeral one if necessary. -func getKeyStoreDir(conf *Config) (string, bool, error) { - keydir, err := conf.KeyDirConfig() +func (c *Config) GetKeyStoreDir() (string, bool, error) { + keydir, err := c.KeyDirConfig() if err != nil { return "", false, err } diff --git a/node/node.go b/node/node.go index 2f89bc1ad..e8494ac3b 100644 --- a/node/node.go +++ b/node/node.go @@ -119,7 +119,7 @@ func New(conf *Config) (*Node, error) { if err := node.openDataDir(); err != nil { return nil, err } - keyDir, isEphem, err := getKeyStoreDir(conf) + keyDir, isEphem, err := conf.GetKeyStoreDir() if err != nil { return nil, err }