cmd/geth: make geth account new faster with many keys (#15529)

This commit is contained in:
Martin Holst Swende 2017-11-20 17:39:53 +01:00 committed by Felix Lange
parent b4f2e4de8f
commit bedf6f40af
3 changed files with 46 additions and 18 deletions

View File

@ -28,6 +28,7 @@ package keystore
import ( import (
"bytes" "bytes"
"crypto/aes" "crypto/aes"
crand "crypto/rand"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
@ -90,6 +91,12 @@ func (ks keyStorePassphrase) GetKey(addr common.Address, filename, auth string)
return key, nil return key, nil
} }
// StoreKey generates a key, encrypts with 'auth' and stores in the given directory
func StoreKey(dir, auth string, scryptN, scryptP int) (common.Address, error) {
_, a, err := storeNewKey(&keyStorePassphrase{dir, scryptN, scryptP}, crand.Reader, auth)
return a.Address, err
}
func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) error { func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) error {
keyjson, err := EncryptKey(key, auth, ks.scryptN, ks.scryptP) keyjson, err := EncryptKey(key, auth, ks.scryptN, ks.scryptP)
if err != nil { if err != nil {

View File

@ -291,15 +291,28 @@ func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrErr
// accountCreate creates a new account into the keystore defined by the CLI flags. // accountCreate creates a new account into the keystore defined by the CLI flags.
func accountCreate(ctx *cli.Context) error { func accountCreate(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx) cfg := gethConfig{Node: defaultNodeConfig()}
// Load config file.
if file := ctx.GlobalString(configFileFlag.Name); file != "" {
if err := loadConfig(file, &cfg); err != nil {
utils.Fatalf("%v", err)
}
}
utils.SetNodeConfig(ctx, &cfg.Node)
scryptN, scryptP, keydir, err := cfg.Node.AccountConfig()
if err != nil {
utils.Fatalf("Failed to read configuration: %v", err)
}
password := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) password := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx))
ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) address, err := keystore.StoreKey(keydir, password, scryptN, scryptP)
account, err := ks.NewAccount(password)
if err != nil { if err != nil {
utils.Fatalf("Failed to create account: %v", err) utils.Fatalf("Failed to create account: %v", err)
} }
fmt.Printf("Address: {%x}\n", account.Address) fmt.Printf("Address: {%x}\n", address)
return nil return nil
} }

View File

@ -360,35 +360,43 @@ func (c *Config) parsePersistentNodes(path string) []*discover.Node {
return nodes return nodes
} }
func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { // AccountConfig determines the settings for scrypt and keydirectory
func (c *Config) AccountConfig() (int, int, string, error) {
scryptN := keystore.StandardScryptN scryptN := keystore.StandardScryptN
scryptP := keystore.StandardScryptP scryptP := keystore.StandardScryptP
if conf.UseLightweightKDF { if c.UseLightweightKDF {
scryptN = keystore.LightScryptN scryptN = keystore.LightScryptN
scryptP = keystore.LightScryptP scryptP = keystore.LightScryptP
} }
var ( var (
keydir string keydir string
ephemeral string
err error err error
) )
switch { switch {
case filepath.IsAbs(conf.KeyStoreDir): case filepath.IsAbs(c.KeyStoreDir):
keydir = conf.KeyStoreDir keydir = c.KeyStoreDir
case conf.DataDir != "": case c.DataDir != "":
if conf.KeyStoreDir == "" { if c.KeyStoreDir == "" {
keydir = filepath.Join(conf.DataDir, datadirDefaultKeyStore) keydir = filepath.Join(c.DataDir, datadirDefaultKeyStore)
} else { } else {
keydir, err = filepath.Abs(conf.KeyStoreDir) keydir, err = filepath.Abs(c.KeyStoreDir)
} }
case conf.KeyStoreDir != "": case c.KeyStoreDir != "":
keydir, err = filepath.Abs(conf.KeyStoreDir) keydir, err = filepath.Abs(c.KeyStoreDir)
default: }
return scryptN, scryptP, keydir, err
}
func makeAccountManager(conf *Config) (*accounts.Manager, string, error) {
scryptN, scryptP, keydir, err := conf.AccountConfig()
var ephemeral string
if keydir == "" {
// There is no datadir. // There is no datadir.
keydir, err = ioutil.TempDir("", "go-ethereum-keystore") keydir, err = ioutil.TempDir("", "go-ethereum-keystore")
ephemeral = keydir ephemeral = keydir
} }
if err != nil { if err != nil {
return nil, "", err return nil, "", err
} }