Skip to content

Commit a5f0001

Browse files
authored
cmd/geth: remove unlock commandline flag (ethereum#30737)
This is one further step towards removing account management from `geth`. This PR deprecates the flag `unlock`, and makes the flag moot: unlock via geth is no longer possible.
1 parent ec280e0 commit a5f0001

File tree

16 files changed

+82
-450
lines changed

16 files changed

+82
-450
lines changed

accounts/keystore/account_cache.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ func byURL(a, b accounts.Account) int {
4444
return a.URL.Cmp(b.URL)
4545
}
4646

47-
// AmbiguousAddrError is returned when attempting to unlock
48-
// an address for which more than one file exists.
47+
// AmbiguousAddrError is returned when an address matches multiple files.
4948
type AmbiguousAddrError struct {
5049
Addr common.Address
5150
Matches []accounts.Account

accounts/keystore/testdata/dupes/1

-1
This file was deleted.

accounts/keystore/testdata/dupes/2

-1
This file was deleted.

accounts/keystore/testdata/dupes/foo

-1
This file was deleted.

accounts/manager.go

+2-12
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,9 @@ import (
2929
// the manager will buffer in its channel.
3030
const managerSubBufferSize = 50
3131

32-
// Config contains the settings of the global account manager.
33-
//
34-
// TODO(rjl493456442, karalabe, holiman): Get rid of this when account management
35-
// is removed in favor of Clef.
32+
// Config is a legacy struct which is not used
3633
type Config struct {
37-
InsecureUnlockAllowed bool // Whether account unlocking in insecure environment is allowed
34+
InsecureUnlockAllowed bool // Unused legacy-parameter
3835
}
3936

4037
// newBackendEvent lets the manager know it should
@@ -47,7 +44,6 @@ type newBackendEvent struct {
4744
// Manager is an overarching account manager that can communicate with various
4845
// backends for signing transactions.
4946
type Manager struct {
50-
config *Config // Global account manager configurations
5147
backends map[reflect.Type][]Backend // Index of backends currently registered
5248
updaters []event.Subscription // Wallet update subscriptions for all backends
5349
updates chan WalletEvent // Subscription sink for backend wallet changes
@@ -78,7 +74,6 @@ func NewManager(config *Config, backends ...Backend) *Manager {
7874
}
7975
// Assemble the account manager and return
8076
am := &Manager{
81-
config: config,
8277
backends: make(map[reflect.Type][]Backend),
8378
updaters: subs,
8479
updates: updates,
@@ -106,11 +101,6 @@ func (am *Manager) Close() error {
106101
return <-errc
107102
}
108103

109-
// Config returns the configuration of account manager.
110-
func (am *Manager) Config() *Config {
111-
return am.config
112-
}
113-
114104
// AddBackend starts the tracking of an additional backend for wallet updates.
115105
// cmd/geth assumes once this func returns the backends have been already integrated.
116106
func (am *Manager) AddBackend(backend Backend) {

cmd/geth/accountcmd.go

+48-65
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@
1717
package main
1818

1919
import (
20+
"errors"
2021
"fmt"
2122
"os"
23+
"strings"
2224

2325
"github.com/ethereum/go-ethereum/accounts"
2426
"github.com/ethereum/go-ethereum/accounts/keystore"
2527
"github.com/ethereum/go-ethereum/cmd/utils"
28+
"github.com/ethereum/go-ethereum/common"
2629
"github.com/ethereum/go-ethereum/crypto"
27-
"github.com/ethereum/go-ethereum/log"
2830
"github.com/urfave/cli/v2"
2931
)
3032

@@ -191,7 +193,7 @@ nodes.
191193
// makeAccountManager creates an account manager with backends
192194
func makeAccountManager(ctx *cli.Context) *accounts.Manager {
193195
cfg := loadBaseConfig(ctx)
194-
am := accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: cfg.Node.InsecureUnlockAllowed})
196+
am := accounts.NewManager(nil)
195197
keydir, isEphemeral, err := cfg.Node.GetKeyStoreDir()
196198
if err != nil {
197199
utils.Fatalf("Failed to get the keystore directory: %v", err)
@@ -219,60 +221,22 @@ func accountList(ctx *cli.Context) error {
219221
return nil
220222
}
221223

222-
// tries unlocking the specified account a few times.
223-
func unlockAccount(ks *keystore.KeyStore, address string, i int, passwords []string) (accounts.Account, string) {
224-
account, err := utils.MakeAddress(ks, address)
225-
if err != nil {
226-
utils.Fatalf("Could not list accounts: %v", err)
227-
}
228-
for trials := 0; trials < 3; trials++ {
229-
prompt := fmt.Sprintf("Unlocking account %s | Attempt %d/%d", address, trials+1, 3)
230-
password := utils.GetPassPhraseWithList(prompt, false, i, passwords)
231-
err = ks.Unlock(account, password)
232-
if err == nil {
233-
log.Info("Unlocked account", "address", account.Address.Hex())
234-
return account, password
235-
}
236-
if err, ok := err.(*keystore.AmbiguousAddrError); ok {
237-
log.Info("Unlocked account", "address", account.Address.Hex())
238-
return ambiguousAddrRecovery(ks, err, password), password
239-
}
240-
if err != keystore.ErrDecrypt {
241-
// No need to prompt again if the error is not decryption-related.
242-
break
243-
}
244-
}
245-
// All trials expended to unlock account, bail out
246-
utils.Fatalf("Failed to unlock account %s (%v)", address, err)
247-
248-
return accounts.Account{}, ""
249-
}
250-
251-
func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrError, auth string) accounts.Account {
252-
fmt.Printf("Multiple key files exist for address %x:\n", err.Addr)
253-
for _, a := range err.Matches {
254-
fmt.Println(" ", a.URL)
255-
}
256-
fmt.Println("Testing your password against all of them...")
257-
var match *accounts.Account
258-
for i, a := range err.Matches {
259-
if e := ks.Unlock(a, auth); e == nil {
260-
match = &err.Matches[i]
261-
break
262-
}
224+
// readPasswordFromFile reads the first line of the given file, trims line endings,
225+
// and returns the password and whether the reading was successful.
226+
func readPasswordFromFile(path string) (string, bool) {
227+
if path == "" {
228+
return "", false
263229
}
264-
if match == nil {
265-
utils.Fatalf("None of the listed files could be unlocked.")
266-
return accounts.Account{}
230+
text, err := os.ReadFile(path)
231+
if err != nil {
232+
utils.Fatalf("Failed to read password file: %v", err)
267233
}
268-
fmt.Printf("Your password unlocked %s\n", match.URL)
269-
fmt.Println("In order to avoid this warning, you need to remove the following duplicate key files:")
270-
for _, a := range err.Matches {
271-
if a != *match {
272-
fmt.Println(" ", a.URL)
273-
}
234+
lines := strings.Split(string(text), "\n")
235+
if len(lines) == 0 {
236+
return "", false
274237
}
275-
return *match
238+
// Sanitise DOS line endings.
239+
return strings.TrimRight(lines[0], "\r"), true
276240
}
277241

278242
// accountCreate creates a new account into the keystore defined by the CLI flags.
@@ -292,8 +256,10 @@ func accountCreate(ctx *cli.Context) error {
292256
scryptP = keystore.LightScryptP
293257
}
294258

295-
password := utils.GetPassPhraseWithList("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx))
296-
259+
password, ok := readPasswordFromFile(ctx.Path(utils.PasswordFileFlag.Name))
260+
if !ok {
261+
password = utils.GetPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true)
262+
}
297263
account, err := keystore.StoreKey(keydir, password, scryptN, scryptP)
298264

299265
if err != nil {
@@ -323,10 +289,23 @@ func accountUpdate(ctx *cli.Context) error {
323289
ks := backends[0].(*keystore.KeyStore)
324290

325291
for _, addr := range ctx.Args().Slice() {
326-
account, oldPassword := unlockAccount(ks, addr, 0, nil)
327-
newPassword := utils.GetPassPhraseWithList("Please give a new password. Do not forget this password.", true, 0, nil)
328-
if err := ks.Update(account, oldPassword, newPassword); err != nil {
329-
utils.Fatalf("Could not update the account: %v", err)
292+
if !common.IsHexAddress(addr) {
293+
return errors.New("address must be specified in hexadecimal form")
294+
}
295+
account := accounts.Account{Address: common.HexToAddress(addr)}
296+
newPassword := utils.GetPassPhrase("Please give a NEW password. Do not forget this password.", true)
297+
updateFn := func(attempt int) error {
298+
prompt := fmt.Sprintf("Please provide the OLD password for account %s | Attempt %d/%d", addr, attempt+1, 3)
299+
password := utils.GetPassPhrase(prompt, false)
300+
return ks.Update(account, password, newPassword)
301+
}
302+
// let user attempt unlock thrice.
303+
err := updateFn(0)
304+
for attempts := 1; attempts < 3 && errors.Is(err, keystore.ErrDecrypt); attempts++ {
305+
err = updateFn(attempts)
306+
}
307+
if err != nil {
308+
return fmt.Errorf("could not update account: %w", err)
330309
}
331310
}
332311
return nil
@@ -347,10 +326,12 @@ func importWallet(ctx *cli.Context) error {
347326
if len(backends) == 0 {
348327
utils.Fatalf("Keystore is not available")
349328
}
329+
password, ok := readPasswordFromFile(ctx.Path(utils.PasswordFileFlag.Name))
330+
if !ok {
331+
password = utils.GetPassPhrase("", false)
332+
}
350333
ks := backends[0].(*keystore.KeyStore)
351-
passphrase := utils.GetPassPhraseWithList("", false, 0, utils.MakePasswordList(ctx))
352-
353-
acct, err := ks.ImportPreSaleKey(keyJSON, passphrase)
334+
acct, err := ks.ImportPreSaleKey(keyJSON, password)
354335
if err != nil {
355336
utils.Fatalf("%v", err)
356337
}
@@ -373,9 +354,11 @@ func accountImport(ctx *cli.Context) error {
373354
utils.Fatalf("Keystore is not available")
374355
}
375356
ks := backends[0].(*keystore.KeyStore)
376-
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))
377-
378-
acct, err := ks.ImportECDSA(key, passphrase)
357+
password, ok := readPasswordFromFile(ctx.Path(utils.PasswordFileFlag.Name))
358+
if !ok {
359+
password = utils.GetPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true)
360+
}
361+
acct, err := ks.ImportECDSA(key, password)
379362
if err != nil {
380363
utils.Fatalf("Could not create the account: %v", err)
381364
}

0 commit comments

Comments
 (0)