From 833e4d1319336fbb66fd8f1e473c24472d65b17b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 24 Jan 2017 11:49:20 +0200 Subject: accounts, cmd, eth, internal, mobile, node: split account backends --- cmd/geth/accountcmd.go | 42 +++++++++++++++++++++++++----------------- cmd/geth/accountcmd_test.go | 6 +++--- cmd/geth/main.go | 6 ++++-- cmd/gethrpctest/main.go | 8 +++++--- cmd/swarm/main.go | 22 +++++++++++++++------- cmd/utils/flags.go | 20 +++++++++++++------- 6 files changed, 65 insertions(+), 39 deletions(-) (limited to 'cmd') diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index 237af99eb..3a0eb13e8 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -21,6 +21,7 @@ import ( "io/ioutil" "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/console" "github.com/ethereum/go-ethereum/crypto" @@ -181,30 +182,30 @@ nodes. func accountList(ctx *cli.Context) error { stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) for i, acct := range stack.AccountManager().Accounts() { - fmt.Printf("Account #%d: {%x} %s\n", i, acct.Address, acct.File) + fmt.Printf("Account #%d: {%x} %s\n", i, acct.Address, acct.URL) } return nil } // tries unlocking the specified account a few times. -func unlockAccount(ctx *cli.Context, accman *accounts.Manager, address string, i int, passwords []string) (accounts.Account, string) { - account, err := utils.MakeAddress(accman, address) +func unlockAccount(ctx *cli.Context, 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 := getPassPhrase(prompt, false, i, passwords) - err = accman.Unlock(account, password) + err = ks.Unlock(account, password) if err == nil { glog.V(logger.Info).Infof("Unlocked account %x", account.Address) return account, password } - if err, ok := err.(*accounts.AmbiguousAddrError); ok { + if err, ok := err.(*keystore.AmbiguousAddrError); ok { glog.V(logger.Info).Infof("Unlocked account %x", account.Address) - return ambiguousAddrRecovery(accman, err, password), password + return ambiguousAddrRecovery(ks, err, password), password } - if err != accounts.ErrDecrypt { + if err != keystore.ErrDecrypt { // No need to prompt again if the error is not decryption-related. break } @@ -244,15 +245,15 @@ func getPassPhrase(prompt string, confirmation bool, i int, passwords []string) return password } -func ambiguousAddrRecovery(am *accounts.Manager, err *accounts.AmbiguousAddrError, auth string) 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 { - fmt.Println(" ", a.File) + fmt.Println(" ", a.URL) } fmt.Println("Testing your passphrase against all of them...") var match *accounts.Account for _, a := range err.Matches { - if err := am.Unlock(a, auth); err == nil { + if err := ks.Unlock(a, auth); err == nil { match = &a break } @@ -260,11 +261,11 @@ func ambiguousAddrRecovery(am *accounts.Manager, err *accounts.AmbiguousAddrErro if match == nil { utils.Fatalf("None of the listed files could be unlocked.") } - fmt.Printf("Your passphrase unlocked %s\n", match.File) + fmt.Printf("Your passphrase unlocked %s\n", match.URL) fmt.Println("In order to avoid this warning, you need to remove the following duplicate key files:") for _, a := range err.Matches { if a != *match { - fmt.Println(" ", a.File) + fmt.Println(" ", a.URL) } } return *match @@ -275,7 +276,8 @@ func accountCreate(ctx *cli.Context) error { stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) 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 := stack.AccountManager().NewAccount(password) + ks := stack.AccountManager().Backend(keystore.BackendType).(*keystore.KeyStore) + account, err := ks.NewAccount(password) if err != nil { utils.Fatalf("Failed to create account: %v", err) } @@ -290,9 +292,11 @@ func accountUpdate(ctx *cli.Context) error { utils.Fatalf("No accounts specified to update") } stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) - account, oldPassword := unlockAccount(ctx, stack.AccountManager(), ctx.Args().First(), 0, nil) + ks := stack.AccountManager().Backend(keystore.BackendType).(*keystore.KeyStore) + + account, oldPassword := unlockAccount(ctx, ks, ctx.Args().First(), 0, nil) newPassword := getPassPhrase("Please give a new password. Do not forget this password.", true, 0, nil) - if err := stack.AccountManager().Update(account, oldPassword, newPassword); err != nil { + if err := ks.Update(account, oldPassword, newPassword); err != nil { utils.Fatalf("Could not update the account: %v", err) } return nil @@ -310,7 +314,9 @@ func importWallet(ctx *cli.Context) error { stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) passphrase := getPassPhrase("", false, 0, utils.MakePasswordList(ctx)) - acct, err := stack.AccountManager().ImportPreSaleKey(keyJson, passphrase) + + ks := stack.AccountManager().Backend(keystore.BackendType).(*keystore.KeyStore) + acct, err := ks.ImportPreSaleKey(keyJson, passphrase) if err != nil { utils.Fatalf("%v", err) } @@ -329,7 +335,9 @@ func accountImport(ctx *cli.Context) error { } stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) passphrase := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) - acct, err := stack.AccountManager().ImportECDSA(key, passphrase) + + ks := stack.AccountManager().Backend(keystore.BackendType).(*keystore.KeyStore) + acct, err := ks.ImportECDSA(key, passphrase) if err != nil { utils.Fatalf("Could not create the account: %v", err) } diff --git a/cmd/geth/accountcmd_test.go b/cmd/geth/accountcmd_test.go index 113df983e..7e03d7548 100644 --- a/cmd/geth/accountcmd_test.go +++ b/cmd/geth/accountcmd_test.go @@ -35,7 +35,7 @@ import ( func tmpDatadirWithKeystore(t *testing.T) string { datadir := tmpdir(t) keystore := filepath.Join(datadir, "keystore") - source := filepath.Join("..", "..", "accounts", "testdata", "keystore") + source := filepath.Join("..", "..", "accounts", "keystore", "testdata", "keystore") if err := cp.CopyAll(keystore, source); err != nil { t.Fatal(err) } @@ -230,7 +230,7 @@ Fatal: Failed to unlock account 0 (could not decrypt key with given passphrase) } func TestUnlockFlagAmbiguous(t *testing.T) { - store := filepath.Join("..", "..", "accounts", "testdata", "dupes") + store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") geth := runGeth(t, "--keystore", store, "--nat", "none", "--nodiscover", "--dev", "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", @@ -267,7 +267,7 @@ In order to avoid this warning, you need to remove the following duplicate key f } func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) { - store := filepath.Join("..", "..", "accounts", "testdata", "dupes") + store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") geth := runGeth(t, "--keystore", store, "--nat", "none", "--nodiscover", "--dev", "--unlock", "f466859ead1932d743d622cb74fc058882e8648a") diff --git a/cmd/geth/main.go b/cmd/geth/main.go index d7e4cc7b5..2c4963cac 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -25,6 +25,7 @@ import ( "strings" "time" + "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" @@ -245,12 +246,13 @@ func startNode(ctx *cli.Context, stack *node.Node) { utils.StartNode(stack) // Unlock any account specifically requested - accman := stack.AccountManager() + ks := stack.AccountManager().Backend(keystore.BackendType).(*keystore.KeyStore) + passwords := utils.MakePasswordList(ctx) accounts := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") for i, account := range accounts { if trimmed := strings.TrimSpace(account); trimmed != "" { - unlockAccount(ctx, accman, trimmed, i, passwords) + unlockAccount(ctx, ks, trimmed, i, passwords) } } // Start auxiliary services if enabled diff --git a/cmd/gethrpctest/main.go b/cmd/gethrpctest/main.go index 850bf8eb2..348eeebce 100644 --- a/cmd/gethrpctest/main.go +++ b/cmd/gethrpctest/main.go @@ -23,6 +23,7 @@ import ( "os" "os/signal" + "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/ethdb" @@ -99,17 +100,18 @@ func MakeSystemNode(privkey string, test *tests.BlockTest) (*node.Node, error) { return nil, err } // Create the keystore and inject an unlocked account if requested - accman := stack.AccountManager() + ks := stack.AccountManager().Backend(keystore.BackendType).(*keystore.KeyStore) + if len(privkey) > 0 { key, err := crypto.HexToECDSA(privkey) if err != nil { return nil, err } - a, err := accman.ImportECDSA(key, "") + a, err := ks.ImportECDSA(key, "") if err != nil { return nil, err } - if err := accman.Unlock(a, ""); err != nil { + if err := ks.Unlock(a, ""); err != nil { return nil, err } } diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go index 546c646f1..466b17f30 100644 --- a/cmd/swarm/main.go +++ b/cmd/swarm/main.go @@ -26,6 +26,7 @@ import ( "strings" "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" @@ -327,29 +328,36 @@ func getAccount(ctx *cli.Context, stack *node.Node) *ecdsa.PrivateKey { return key } // Otherwise try getting it from the keystore. - return decryptStoreAccount(stack.AccountManager(), keyid) + am := stack.AccountManager() + ks := am.Backend(keystore.BackendType).(*keystore.KeyStore) + + return decryptStoreAccount(ks, keyid) } -func decryptStoreAccount(accman *accounts.Manager, account string) *ecdsa.PrivateKey { +func decryptStoreAccount(ks *keystore.KeyStore, account string) *ecdsa.PrivateKey { var a accounts.Account var err error if common.IsHexAddress(account) { - a, err = accman.Find(accounts.Account{Address: common.HexToAddress(account)}) - } else if ix, ixerr := strconv.Atoi(account); ixerr == nil { - a, err = accman.AccountByIndex(ix) + a, err = ks.Find(accounts.Account{Address: common.HexToAddress(account)}) + } else if ix, ixerr := strconv.Atoi(account); ixerr == nil && ix > 0 { + if accounts := ks.Accounts(); len(accounts) > ix { + a = accounts[ix] + } else { + err = fmt.Errorf("index %d higher than number of accounts %d", ix, len(accounts)) + } } else { utils.Fatalf("Can't find swarm account key %s", account) } if err != nil { utils.Fatalf("Can't find swarm account key: %v", err) } - keyjson, err := ioutil.ReadFile(a.File) + keyjson, err := ioutil.ReadFile(a.URL) if err != nil { utils.Fatalf("Can't load swarm account key: %v", err) } for i := 1; i <= 3; i++ { passphrase := promptPassphrase(fmt.Sprintf("Unlocking swarm account %s [%d/3]", a.Address.Hex(), i)) - key, err := accounts.DecryptKey(keyjson, passphrase) + key, err := keystore.DecryptKey(keyjson, passphrase) if err == nil { return key.PrivateKey } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 9ba33df80..1196a64b5 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -30,6 +30,7 @@ import ( "github.com/ethereum/ethash" "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" @@ -587,23 +588,27 @@ func MakeDatabaseHandles() int { // MakeAddress converts an account specified directly as a hex encoded string or // a key index in the key store to an internal account representation. -func MakeAddress(accman *accounts.Manager, account string) (accounts.Account, error) { +func MakeAddress(ks *keystore.KeyStore, account string) (accounts.Account, error) { // If the specified account is a valid address, return it if common.IsHexAddress(account) { return accounts.Account{Address: common.HexToAddress(account)}, nil } // Otherwise try to interpret the account as a keystore index index, err := strconv.Atoi(account) - if err != nil { + if err != nil || index < 0 { return accounts.Account{}, fmt.Errorf("invalid account address or index %q", account) } - return accman.AccountByIndex(index) + accs := ks.Accounts() + if len(accs) <= index { + return accounts.Account{}, fmt.Errorf("index %d higher than number of accounts %d", index, len(accs)) + } + return accs[index], nil } // MakeEtherbase retrieves the etherbase either from the directly specified // command line flags or from the keystore if CLI indexed. -func MakeEtherbase(accman *accounts.Manager, ctx *cli.Context) common.Address { - accounts := accman.Accounts() +func MakeEtherbase(ks *keystore.KeyStore, ctx *cli.Context) common.Address { + accounts := ks.Accounts() if !ctx.GlobalIsSet(EtherbaseFlag.Name) && len(accounts) == 0 { glog.V(logger.Error).Infoln("WARNING: No etherbase set and no accounts found as default") return common.Address{} @@ -613,7 +618,7 @@ func MakeEtherbase(accman *accounts.Manager, ctx *cli.Context) common.Address { return common.Address{} } // If the specified etherbase is a valid address, return it - account, err := MakeAddress(accman, etherbase) + account, err := MakeAddress(ks, etherbase) if err != nil { Fatalf("Option %q: %v", EtherbaseFlag.Name, err) } @@ -721,9 +726,10 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) { if networks > 1 { Fatalf("The %v flags are mutually exclusive", netFlags) } + ks := stack.AccountManager().Backend(keystore.BackendType).(*keystore.KeyStore) ethConf := ð.Config{ - Etherbase: MakeEtherbase(stack.AccountManager(), ctx), + Etherbase: MakeEtherbase(ks, ctx), ChainConfig: MakeChainConfig(ctx, stack), FastSync: ctx.GlobalBool(FastSyncFlag.Name), LightMode: ctx.GlobalBool(LightModeFlag.Name), -- cgit v1.2.3 From fad5eb0a87abfc12812647344a26de8a43830182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 7 Feb 2017 12:47:34 +0200 Subject: accounts, cmd, eth, internal, miner, node: wallets and HD APIs --- cmd/geth/accountcmd.go | 17 +++++++++++------ cmd/geth/main.go | 2 +- cmd/gethrpctest/main.go | 2 +- cmd/swarm/main.go | 2 +- cmd/utils/flags.go | 2 +- 5 files changed, 15 insertions(+), 10 deletions(-) (limited to 'cmd') diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index 3a0eb13e8..97a060e48 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -181,8 +181,13 @@ nodes. func accountList(ctx *cli.Context) error { stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) - for i, acct := range stack.AccountManager().Accounts() { - fmt.Printf("Account #%d: {%x} %s\n", i, acct.Address, acct.URL) + + var index int + for _, wallet := range stack.AccountManager().Wallets() { + for _, account := range wallet.Accounts() { + fmt.Printf("Account #%d: {%x} %s\n", index, account.Address, account.URL) + index++ + } } return nil } @@ -276,7 +281,7 @@ func accountCreate(ctx *cli.Context) error { stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) 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().Backend(keystore.BackendType).(*keystore.KeyStore) + ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) account, err := ks.NewAccount(password) if err != nil { utils.Fatalf("Failed to create account: %v", err) @@ -292,7 +297,7 @@ func accountUpdate(ctx *cli.Context) error { utils.Fatalf("No accounts specified to update") } stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) - ks := stack.AccountManager().Backend(keystore.BackendType).(*keystore.KeyStore) + ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) account, oldPassword := unlockAccount(ctx, ks, ctx.Args().First(), 0, nil) newPassword := getPassPhrase("Please give a new password. Do not forget this password.", true, 0, nil) @@ -315,7 +320,7 @@ func importWallet(ctx *cli.Context) error { stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) passphrase := getPassPhrase("", false, 0, utils.MakePasswordList(ctx)) - ks := stack.AccountManager().Backend(keystore.BackendType).(*keystore.KeyStore) + ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) acct, err := ks.ImportPreSaleKey(keyJson, passphrase) if err != nil { utils.Fatalf("%v", err) @@ -336,7 +341,7 @@ func accountImport(ctx *cli.Context) error { stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) passphrase := 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().Backend(keystore.BackendType).(*keystore.KeyStore) + ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) acct, err := ks.ImportECDSA(key, passphrase) if err != nil { utils.Fatalf("Could not create the account: %v", err) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 2c4963cac..e324802b5 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -246,7 +246,7 @@ func startNode(ctx *cli.Context, stack *node.Node) { utils.StartNode(stack) // Unlock any account specifically requested - ks := stack.AccountManager().Backend(keystore.BackendType).(*keystore.KeyStore) + ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) passwords := utils.MakePasswordList(ctx) accounts := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") diff --git a/cmd/gethrpctest/main.go b/cmd/gethrpctest/main.go index 348eeebce..9e80ad05d 100644 --- a/cmd/gethrpctest/main.go +++ b/cmd/gethrpctest/main.go @@ -100,7 +100,7 @@ func MakeSystemNode(privkey string, test *tests.BlockTest) (*node.Node, error) { return nil, err } // Create the keystore and inject an unlocked account if requested - ks := stack.AccountManager().Backend(keystore.BackendType).(*keystore.KeyStore) + ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) if len(privkey) > 0 { key, err := crypto.HexToECDSA(privkey) diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go index 466b17f30..a7fc72d57 100644 --- a/cmd/swarm/main.go +++ b/cmd/swarm/main.go @@ -329,7 +329,7 @@ func getAccount(ctx *cli.Context, stack *node.Node) *ecdsa.PrivateKey { } // Otherwise try getting it from the keystore. am := stack.AccountManager() - ks := am.Backend(keystore.BackendType).(*keystore.KeyStore) + ks := am.Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) return decryptStoreAccount(ks, keyid) } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 1196a64b5..92eb05e32 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -726,7 +726,7 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) { if networks > 1 { Fatalf("The %v flags are mutually exclusive", netFlags) } - ks := stack.AccountManager().Backend(keystore.BackendType).(*keystore.KeyStore) + ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) ethConf := ð.Config{ Etherbase: MakeEtherbase(ks, ctx), -- cgit v1.2.3 From c5215fdd48231622dd56aba63a5187c6e42828d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 8 Feb 2017 15:53:02 +0200 Subject: accounts, cmd, internal, mobile, node: canonical account URLs --- cmd/geth/accountcmd.go | 2 +- cmd/geth/accountcmd_test.go | 24 ++++++++++++------------ cmd/swarm/main.go | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'cmd') diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index 97a060e48..cd398eadb 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -185,7 +185,7 @@ func accountList(ctx *cli.Context) error { var index int for _, wallet := range stack.AccountManager().Wallets() { for _, account := range wallet.Accounts() { - fmt.Printf("Account #%d: {%x} %s\n", index, account.Address, account.URL) + fmt.Printf("Account #%d: {%x} %s\n", index, account.Address, &account.URL) index++ } } diff --git a/cmd/geth/accountcmd_test.go b/cmd/geth/accountcmd_test.go index 7e03d7548..679a7ec30 100644 --- a/cmd/geth/accountcmd_test.go +++ b/cmd/geth/accountcmd_test.go @@ -53,15 +53,15 @@ func TestAccountList(t *testing.T) { defer geth.expectExit() if runtime.GOOS == "windows" { geth.expect(` -Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} {{.Datadir}}\keystore\UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 -Account #1: {f466859ead1932d743d622cb74fc058882e8648a} {{.Datadir}}\keystore\aaa -Account #2: {289d485d9771714cce91d3393d764e1311907acc} {{.Datadir}}\keystore\zzz +Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}\keystore\UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 +Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}\keystore\aaa +Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}\keystore\zzz `) } else { geth.expect(` -Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} {{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 -Account #1: {f466859ead1932d743d622cb74fc058882e8648a} {{.Datadir}}/keystore/aaa -Account #2: {289d485d9771714cce91d3393d764e1311907acc} {{.Datadir}}/keystore/zzz +Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 +Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}/keystore/aaa +Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}/keystore/zzz `) } } @@ -247,12 +247,12 @@ Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 !! Unsupported terminal, password will be echoed. Passphrase: {{.InputLine "foobar"}} Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a: - {{keypath "1"}} - {{keypath "2"}} + keystore://{{keypath "1"}} + keystore://{{keypath "2"}} Testing your passphrase against all of them... -Your passphrase unlocked {{keypath "1"}} +Your passphrase unlocked keystore://{{keypath "1"}} In order to avoid this warning, you need to remove the following duplicate key files: - {{keypath "2"}} + keystore://{{keypath "2"}} `) geth.expectExit() @@ -283,8 +283,8 @@ Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3 !! Unsupported terminal, password will be echoed. Passphrase: {{.InputLine "wrong"}} Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a: - {{keypath "1"}} - {{keypath "2"}} + keystore://{{keypath "1"}} + keystore://{{keypath "2"}} Testing your passphrase against all of them... Fatal: None of the listed files could be unlocked. `) diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go index a7fc72d57..f9d661bb3 100644 --- a/cmd/swarm/main.go +++ b/cmd/swarm/main.go @@ -351,7 +351,7 @@ func decryptStoreAccount(ks *keystore.KeyStore, account string) *ecdsa.PrivateKe if err != nil { utils.Fatalf("Can't find swarm account key: %v", err) } - keyjson, err := ioutil.ReadFile(a.URL) + keyjson, err := ioutil.ReadFile(a.URL.Path) if err != nil { utils.Fatalf("Can't load swarm account key: %v", err) } -- cgit v1.2.3 From 205ea9580215cca4093dff22ec61222bc3a6ff96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 8 Feb 2017 20:25:52 +0200 Subject: accounts, cmd, internal, node: implement HD wallet self-derivation --- cmd/geth/main.go | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/geth/main.go b/cmd/geth/main.go index e324802b5..06dc55ba8 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -25,12 +25,14 @@ import ( "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" "github.com/ethereum/go-ethereum/contracts/release" "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/internal/debug" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" @@ -249,12 +251,38 @@ func startNode(ctx *cli.Context, stack *node.Node) { ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) passwords := utils.MakePasswordList(ctx) - accounts := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") - for i, account := range accounts { + unlocks := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") + for i, account := range unlocks { if trimmed := strings.TrimSpace(account); trimmed != "" { unlockAccount(ctx, ks, trimmed, i, passwords) } } + // Register wallet event handlers to open and auto-derive wallets + events := make(chan accounts.WalletEvent, 16) + stack.AccountManager().Subscribe(events) + + go func() { + // Create an chain state reader for self-derivation + rpcClient, err := stack.Attach() + if err != nil { + utils.Fatalf("Failed to attach to self: %v", err) + } + stateReader := ethclient.NewClient(rpcClient) + + // Listen for wallet event till termination + for event := range events { + if event.Arrive { + if err := event.Wallet.Open(""); err != nil { + glog.V(logger.Info).Infof("New wallet appeared: %s, failed to open: %s", event.Wallet.URL(), err) + } else { + glog.V(logger.Info).Infof("New wallet appeared: %s, %s", event.Wallet.URL(), event.Wallet.Status()) + } + event.Wallet.SelfDerive(accounts.DefaultBaseDerivationPath, stateReader) + } else { + glog.V(logger.Info).Infof("Old wallet dropped: %s", event.Wallet.URL()) + } + } + }() // Start auxiliary services if enabled if ctx.GlobalBool(utils.MiningEnabledFlag.Name) { var ethereum *eth.Ethereum -- cgit v1.2.3 From 26cd41f0c7a1d1e379f15117d3a62235f6c2d739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 9 Feb 2017 14:39:26 +0200 Subject: accounts/usbwallet: make wallet responsive while Ledger is busy --- cmd/geth/main.go | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'cmd') diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 06dc55ba8..cc597717e 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -269,6 +269,13 @@ func startNode(ctx *cli.Context, stack *node.Node) { } stateReader := ethclient.NewClient(rpcClient) + // Open and self derive any wallets already attached + for _, wallet := range stack.AccountManager().Wallets() { + if err := wallet.Open(""); err != nil { + glog.V(logger.Warn).Infof("Failed to open wallet %s: %v", wallet.URL(), err) + } + wallet.SelfDerive(accounts.DefaultBaseDerivationPath, stateReader) + } // Listen for wallet event till termination for event := range events { if event.Arrive { @@ -280,6 +287,7 @@ func startNode(ctx *cli.Context, stack *node.Node) { event.Wallet.SelfDerive(accounts.DefaultBaseDerivationPath, stateReader) } else { glog.V(logger.Info).Infof("Old wallet dropped: %s", event.Wallet.URL()) + event.Wallet.Close() } } }() -- cgit v1.2.3 From e99c788155ddd754c73d2c81b6051dcbd42e6575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Sat, 11 Feb 2017 17:02:00 +0200 Subject: accounts: ledger and HD review fixes - Handle a data race where a Ledger drops between list and open - Prolong Ledger tx confirmation window to 30 days from 1 minute - Simplify Ledger chainid-signature calculation and validation - Simplify Ledger USB APDU request chunking algorithm - Silence keystore account cache notifications for manual actions - Only enable self derivations if wallet open succeeds --- cmd/geth/main.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/geth/main.go b/cmd/geth/main.go index cc597717e..c19770bfa 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -273,8 +273,9 @@ func startNode(ctx *cli.Context, stack *node.Node) { for _, wallet := range stack.AccountManager().Wallets() { if err := wallet.Open(""); err != nil { glog.V(logger.Warn).Infof("Failed to open wallet %s: %v", wallet.URL(), err) + } else { + wallet.SelfDerive(accounts.DefaultBaseDerivationPath, stateReader) } - wallet.SelfDerive(accounts.DefaultBaseDerivationPath, stateReader) } // Listen for wallet event till termination for event := range events { @@ -283,8 +284,8 @@ func startNode(ctx *cli.Context, stack *node.Node) { glog.V(logger.Info).Infof("New wallet appeared: %s, failed to open: %s", event.Wallet.URL(), err) } else { glog.V(logger.Info).Infof("New wallet appeared: %s, %s", event.Wallet.URL(), event.Wallet.Status()) + event.Wallet.SelfDerive(accounts.DefaultBaseDerivationPath, stateReader) } - event.Wallet.SelfDerive(accounts.DefaultBaseDerivationPath, stateReader) } else { glog.V(logger.Info).Infof("Old wallet dropped: %s", event.Wallet.URL()) event.Wallet.Close() -- cgit v1.2.3