This commit is contained in:
Martin Holst Swende 2017-11-20 13:31:33 +00:00 committed by GitHub
commit 9663e4780b
4 changed files with 53 additions and 18 deletions

View file

@ -75,10 +75,19 @@ type unlocked struct {
abort chan struct{} abort chan struct{}
} }
// NewKeyStore creates a keystore for the given directory. // NewUninitializedKeyStore creates a keystore for the given directory, but does not load the existing keys
func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore { func NewUninitializedKeyStore(keydir string, scryptN, scryptP int) *KeyStore {
keydir, _ = filepath.Abs(keydir) keydir, _ = filepath.Abs(keydir)
ks := &KeyStore{storage: &keyStorePassphrase{keydir, scryptN, scryptP}} ks := &KeyStore{storage: &keyStorePassphrase{keydir, scryptN, scryptP}}
// Initialize the set of unlocked keys and the account cache
ks.unlocked = make(map[common.Address]*unlocked)
ks.cache, ks.changes = newAccountCache(keydir)
return ks
}
// NewKeyStore creates a keystore for the given directory.
func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore {
ks := NewUninitializedKeyStore(keydir, scryptN, scryptP)
ks.init(keydir) ks.init(keydir)
return ks return ks
} }
@ -88,19 +97,19 @@ func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore {
func NewPlaintextKeyStore(keydir string) *KeyStore { func NewPlaintextKeyStore(keydir string) *KeyStore {
keydir, _ = filepath.Abs(keydir) keydir, _ = filepath.Abs(keydir)
ks := &KeyStore{storage: &keyStorePlain{keydir}} ks := &KeyStore{storage: &keyStorePlain{keydir}}
// Initialize the set of unlocked keys and the account cache
ks.unlocked = make(map[common.Address]*unlocked)
ks.cache, ks.changes = newAccountCache(keydir)
ks.init(keydir) ks.init(keydir)
return ks return ks
} }
// init initalizes the keystore by loading the accounts
func (ks *KeyStore) init(keydir string) { func (ks *KeyStore) init(keydir string) {
// Lock the mutex since the account cache might call back with events // Lock the mutex since the account cache might call back with events
ks.mu.Lock() ks.mu.Lock()
defer ks.mu.Unlock() defer ks.mu.Unlock()
// Initialize the set of unlocked keys and the account cache
ks.unlocked = make(map[common.Address]*unlocked)
ks.cache, ks.changes = newAccountCache(keydir)
// TODO: In order for this finalizer to work, there must be no references // TODO: In order for this finalizer to work, there must be no references
// to ks. addressCache doesn't keep a reference but unlocked keys do, // to ks. addressCache doesn't keep a reference but unlocked keys do,
// so the finalizer will not trigger until all timed unlocks have expired. // so the finalizer will not trigger until all timed unlocks have expired.
@ -403,13 +412,23 @@ func (ks *KeyStore) expire(addr common.Address, u *unlocked, timeout time.Durati
} }
} }
// NewAccount generates a new key and stores it into the key directory, // CreateNewAccount generates a new key and stores it into the key directory,
// encrypting it with the passphrase. // encrypting it with the passphrase.
func (ks *KeyStore) NewAccount(passphrase string) (accounts.Account, error) { func (ks *KeyStore) CreateNewAccount(passphrase string) (accounts.Account, error) {
_, account, err := storeNewKey(ks.storage, crand.Reader, passphrase) _, account, err := storeNewKey(ks.storage, crand.Reader, passphrase)
if err != nil { if err != nil {
return accounts.Account{}, err return accounts.Account{}, err
} }
return account, nil
}
// NewAccount generates a new key and stores it into the key directory,
// encrypting it with the passphrase, and adds it to the cache
func (ks *KeyStore) NewAccount(passphrase string) (accounts.Account, error) {
account, err := ks.CreateNewAccount(passphrase)
if err != nil {
return account, err
}
// Add the account to the cache immediately rather // Add the account to the cache immediately rather
// than waiting for file system notifications to pick it up. // than waiting for file system notifications to pick it up.
ks.cache.add(account) ks.cache.add(account)

View file

@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/console" "github.com/ethereum/go-ethereum/console"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node"
"gopkg.in/urfave/cli.v1" "gopkg.in/urfave/cli.v1"
) )
@ -291,11 +292,11 @@ 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 := createConfig(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, _, err := node.MakeKeystoreBackend(&cfg.Node, false)
ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) password := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx))
account, err := ks.NewAccount(password) account, err := ks.CreateNewAccount(password)
if err != nil { if err != nil {
utils.Fatalf("Failed to create account: %v", err) utils.Fatalf("Failed to create account: %v", err)
} }

View file

@ -109,7 +109,7 @@ func defaultNodeConfig() node.Config {
return cfg return cfg
} }
func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { func createConfig(ctx *cli.Context) gethConfig {
// Load defaults. // Load defaults.
cfg := gethConfig{ cfg := gethConfig{
Eth: eth.DefaultConfig, Eth: eth.DefaultConfig,
@ -124,9 +124,13 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
utils.Fatalf("%v", err) utils.Fatalf("%v", err)
} }
} }
// Apply flags. // Apply flags.
utils.SetNodeConfig(ctx, &cfg.Node) utils.SetNodeConfig(ctx, &cfg.Node)
return cfg
}
func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
cfg := createConfig(ctx)
stack, err := node.New(&cfg.Node) stack, err := node.New(&cfg.Node)
if err != nil { if err != nil {
utils.Fatalf("Failed to create the protocol stack: %v", err) utils.Fatalf("Failed to create the protocol stack: %v", err)

View file

@ -360,7 +360,7 @@ func (c *Config) parsePersistentNodes(path string) []*discover.Node {
return nodes return nodes
} }
func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { func MakeKeystoreBackend(conf *Config, loadKeys bool) (*keystore.KeyStore, string, error) {
scryptN := keystore.StandardScryptN scryptN := keystore.StandardScryptN
scryptP := keystore.StandardScryptP scryptP := keystore.StandardScryptP
if conf.UseLightweightKDF { if conf.UseLightweightKDF {
@ -395,10 +395,21 @@ func makeAccountManager(conf *Config) (*accounts.Manager, string, error) {
if err := os.MkdirAll(keydir, 0700); err != nil { if err := os.MkdirAll(keydir, 0700); err != nil {
return nil, "", err return nil, "", err
} }
// Assemble the account manager and supported backends if !loadKeys {
backends := []accounts.Backend{ return keystore.NewUninitializedKeyStore(keydir, scryptN, scryptP), ephemeral, nil
keystore.NewKeyStore(keydir, scryptN, scryptP),
} }
return keystore.NewKeyStore(keydir, scryptN, scryptP), ephemeral, nil
}
func makeAccountManager(conf *Config) (*accounts.Manager, string, error) {
ks, ephemeral, err := MakeKeystoreBackend(conf, true)
if err != nil {
return nil, "", err
}
// Assemble the account manager and supported backends
backends := []accounts.Backend{ks}
if !conf.NoUSB { if !conf.NoUSB {
// Start a USB hub for Ledger hardware wallets // Start a USB hub for Ledger hardware wallets
if ledgerhub, err := usbwallet.NewLedgerHub(); err != nil { if ledgerhub, err := usbwallet.NewLedgerHub(); err != nil {