mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
Merge branch 'ethereum:master' into portal
This commit is contained in:
commit
7815dab7af
19 changed files with 303 additions and 573 deletions
|
|
@ -44,8 +44,7 @@ func byURL(a, b accounts.Account) int {
|
|||
return a.URL.Cmp(b.URL)
|
||||
}
|
||||
|
||||
// AmbiguousAddrError is returned when attempting to unlock
|
||||
// an address for which more than one file exists.
|
||||
// AmbiguousAddrError is returned when an address matches multiple files.
|
||||
type AmbiguousAddrError struct {
|
||||
Addr common.Address
|
||||
Matches []accounts.Account
|
||||
|
|
|
|||
1
accounts/keystore/testdata/dupes/1
vendored
1
accounts/keystore/testdata/dupes/1
vendored
|
|
@ -1 +0,0 @@
|
|||
{"address":"f466859ead1932d743d622cb74fc058882e8648a","crypto":{"cipher":"aes-128-ctr","ciphertext":"cb664472deacb41a2e995fa7f96fe29ce744471deb8d146a0e43c7898c9ddd4d","cipherparams":{"iv":"dfd9ee70812add5f4b8f89d0811c9158"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"0d6769bf016d45c479213990d6a08d938469c4adad8a02ce507b4a4e7b7739f1"},"mac":"bac9af994b15a45dd39669fc66f9aa8a3b9dd8c22cb16e4d8d7ea089d0f1a1a9"},"id":"472e8b3d-afb6-45b5-8111-72c89895099a","version":3}
|
||||
1
accounts/keystore/testdata/dupes/2
vendored
1
accounts/keystore/testdata/dupes/2
vendored
|
|
@ -1 +0,0 @@
|
|||
{"address":"f466859ead1932d743d622cb74fc058882e8648a","crypto":{"cipher":"aes-128-ctr","ciphertext":"cb664472deacb41a2e995fa7f96fe29ce744471deb8d146a0e43c7898c9ddd4d","cipherparams":{"iv":"dfd9ee70812add5f4b8f89d0811c9158"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"0d6769bf016d45c479213990d6a08d938469c4adad8a02ce507b4a4e7b7739f1"},"mac":"bac9af994b15a45dd39669fc66f9aa8a3b9dd8c22cb16e4d8d7ea089d0f1a1a9"},"id":"472e8b3d-afb6-45b5-8111-72c89895099a","version":3}
|
||||
1
accounts/keystore/testdata/dupes/foo
vendored
1
accounts/keystore/testdata/dupes/foo
vendored
|
|
@ -1 +0,0 @@
|
|||
{"address":"7ef5a6135f1fd6a02593eedc869c6d41d934aef8","crypto":{"cipher":"aes-128-ctr","ciphertext":"1d0839166e7a15b9c1333fc865d69858b22df26815ccf601b28219b6192974e1","cipherparams":{"iv":"8df6caa7ff1b00c4e871f002cb7921ed"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"e5e6ef3f4ea695f496b643ebd3f75c0aa58ef4070e90c80c5d3fb0241bf1595c"},"mac":"6d16dfde774845e4585357f24bce530528bc69f4f84e1e22880d34fa45c273e5"},"id":"950077c7-71e3-4c44-a4a1-143919141ed4","version":3}
|
||||
|
|
@ -29,12 +29,9 @@ import (
|
|||
// the manager will buffer in its channel.
|
||||
const managerSubBufferSize = 50
|
||||
|
||||
// Config contains the settings of the global account manager.
|
||||
//
|
||||
// TODO(rjl493456442, karalabe, holiman): Get rid of this when account management
|
||||
// is removed in favor of Clef.
|
||||
// Config is a legacy struct which is not used
|
||||
type Config struct {
|
||||
InsecureUnlockAllowed bool // Whether account unlocking in insecure environment is allowed
|
||||
InsecureUnlockAllowed bool // Unused legacy-parameter
|
||||
}
|
||||
|
||||
// newBackendEvent lets the manager know it should
|
||||
|
|
@ -47,7 +44,6 @@ type newBackendEvent struct {
|
|||
// Manager is an overarching account manager that can communicate with various
|
||||
// backends for signing transactions.
|
||||
type Manager struct {
|
||||
config *Config // Global account manager configurations
|
||||
backends map[reflect.Type][]Backend // Index of backends currently registered
|
||||
updaters []event.Subscription // Wallet update subscriptions for all backends
|
||||
updates chan WalletEvent // Subscription sink for backend wallet changes
|
||||
|
|
@ -78,7 +74,6 @@ func NewManager(config *Config, backends ...Backend) *Manager {
|
|||
}
|
||||
// Assemble the account manager and return
|
||||
am := &Manager{
|
||||
config: config,
|
||||
backends: make(map[reflect.Type][]Backend),
|
||||
updaters: subs,
|
||||
updates: updates,
|
||||
|
|
@ -106,11 +101,6 @@ func (am *Manager) Close() error {
|
|||
return <-errc
|
||||
}
|
||||
|
||||
// Config returns the configuration of account manager.
|
||||
func (am *Manager) Config() *Config {
|
||||
return am.config
|
||||
}
|
||||
|
||||
// AddBackend starts the tracking of an additional backend for wallet updates.
|
||||
// cmd/geth assumes once this func returns the backends have been already integrated.
|
||||
func (am *Manager) AddBackend(backend Backend) {
|
||||
|
|
|
|||
|
|
@ -5,56 +5,56 @@
|
|||
# https://github.com/ethereum/execution-spec-tests/releases/download/v2.1.0/
|
||||
ca89c76851b0900bfcc3cbb9a26cbece1f3d7c64a3bed38723e914713290df6c fixtures_develop.tar.gz
|
||||
|
||||
# version:golang 1.23.2
|
||||
# version:golang 1.23.3
|
||||
# https://go.dev/dl/
|
||||
36930162a93df417d90bd22c6e14daff4705baac2b02418edda671cdfa9cd07f go1.23.2.src.tar.gz
|
||||
025d77f1780906142023a364c31a572afd7d56d3a3be1e4e562e367ca88d3267 go1.23.2.freebsd-amd64.tar.gz
|
||||
0d50bade977b84e173cb350946087f5de8c75f8df19456c3b60c5d58e186089d go1.23.2.windows-arm64.zip
|
||||
0edd985dbd6de64d9c88dbc8835bae21203c58444bf26fce0739cbec4eb1b610 go1.23.2.windows-arm64.msi
|
||||
2283d12dfe7c8c8a46a41bbf7d11fe007434e7590cd1b89e221e478640b7ee3a go1.23.2.linux-mips64le.tar.gz
|
||||
2293c5c3ffc595418308b4059ce214b99f0383cba83232e47a1a8c3b710c24e8 go1.23.2.linux-loong64.tar.gz
|
||||
23b93144e754bbcf5eda700e9decbdbd44d29ceedb1bf1de75f95e8a6ea986bb go1.23.2.openbsd-arm64.tar.gz
|
||||
2734a5b54905cea45f136c28249e626d0241b865b0637fa1db64bf533d9d843e go1.23.2.netbsd-amd64.tar.gz
|
||||
28af3c40687afdda6b33b300833b6d662716cc2d624fb9fd61a49bdad44cd869 go1.23.2.freebsd-arm.tar.gz
|
||||
367d522b47c7ce7761a671efcb8b12c8af8f509db1cd6160c91f410ef3201987 go1.23.2.windows-arm.msi
|
||||
36b7228bae235eee6c8193f5a956e1a9a17874955affb86b3564709b0fab5874 go1.23.2.linux-mipsle.tar.gz
|
||||
3bd1130a08195d23960b154d2e6eaa80ac7325ebd9d01d74c58b6d12580e6b12 go1.23.2.linux-mips.tar.gz
|
||||
3bf66879b38a233c5cbb5d2eb982004117f05d6bf06279e886e087d7c504427d go1.23.2.openbsd-riscv64.tar.gz
|
||||
3e80b943d70c7e1633822b42c1aa7234e61da14f13ff8efff7ee6e1347f37648 go1.23.2.netbsd-arm64.tar.gz
|
||||
40c0b61971a1a74fd4566c536f682c9d4976fa71d40d9daabc875c06113d0fee go1.23.2.darwin-amd64.pkg
|
||||
445c0ef19d8692283f4c3a92052cc0568f5a048f4e546105f58e991d4aea54f5 go1.23.2.darwin-amd64.tar.gz
|
||||
542d3c1705f1c6a1c5a80d5dc62e2e45171af291e755d591c5e6531ef63b454e go1.23.2.linux-amd64.tar.gz
|
||||
560aff7fe1eeadc32248db35ed5c0a81e190d171b6ecec404cf46d808c13e92f go1.23.2.aix-ppc64.tar.gz
|
||||
5611cd648f5100b73a7d6fd85589a481af18fdbaf9c153a92de9a8e39a6e061f go1.23.2.darwin-arm64.pkg
|
||||
695aac64532da8d9a243601ffa0411cd763be891fcf7fd2e857eea4ab10b8bcc go1.23.2.plan9-386.tar.gz
|
||||
69b31edcd3d4f7d8bbf9aee2b25cafba30b444ef19bc7a033e15026f7d0cc5c2 go1.23.2.netbsd-arm.tar.gz
|
||||
6ffa4ac1f4368a3121a032917577a4e0a3feaf696c3e98f213b74ac04c318bc4 go1.23.2.plan9-arm.tar.gz
|
||||
72a6def70300cc804c70073d8b579603d9b39b39b02b3b5d340968d9e7e0e9d4 go1.23.2.windows-386.msi
|
||||
791ca685ee5ca0f6fe849dc078145cb1323d0ea9dd308e9cca9ba2e7186dbb3d go1.23.2.linux-ppc64.tar.gz
|
||||
86b5de91fdf7bd9b52c77c62f8762518cf3fc256fe912af9bbff1d073054aa5b go1.23.2.plan9-amd64.tar.gz
|
||||
8734c7cd464a0620f6605bd3f9256bed062f262d0d58e4f45099c329a08ed966 go1.23.2.openbsd-amd64.tar.gz
|
||||
980ceb889915695d94b166ca1300250dba76fa37a2d41eca2c5e7727dcb4fb7f go1.23.2.openbsd-arm.tar.gz
|
||||
a0cf25f236a0fa0a465816fe7f5c930f3b0b90c5c247b09c43a6adeff654e6ae go1.23.2.linux-mips64.tar.gz
|
||||
a13cc0d621af4f35afd90b886c60b1bf66f771939d226dc36fa61a337d90eb30 go1.23.2.openbsd-ppc64.tar.gz
|
||||
b29ff163b34cb4943c521fcfc1d956eaa6286561089042051a3fab22e79e9283 go1.23.2.windows-arm.zip
|
||||
bc28fe3002cd65cec65d0e4f6000584dacb8c71bfaff8801dfb532855ca42513 go1.23.2.windows-amd64.zip
|
||||
c164ce7d894b10fd861d7d7b96f1dbea3f993663d9f0c30bc4f8ae3915db8b0c go1.23.2.linux-ppc64le.tar.gz
|
||||
c4ae1087dce4daf45a837f5fca36ac0e29a02ada9addf857f1c426e60bce6f21 go1.23.2.netbsd-386.tar.gz
|
||||
c80cbc5e66d6fb8b0c3300b0dda1fe925c429e199954d3327da2933d9870b041 go1.23.2.windows-amd64.msi
|
||||
cb1ed4410f68d8be1156cee0a74fcfbdcd9bca377c83db3a9e1b07eebc6d71ef go1.23.2.linux-386.tar.gz
|
||||
d1fde255843fec1f7f0611d468effd98e1f4309f589ac13037db07b032f9da35 go1.23.2.openbsd-386.tar.gz
|
||||
d47e40366cd6c6b6ee14b811554cd7dde0351309f4a8a4569ec5ba2bd7689437 go1.23.2.illumos-amd64.tar.gz
|
||||
d87031194fe3e01abdcaf3c7302148ade97a7add6eac3fec26765bcb3207b80f go1.23.2.darwin-arm64.tar.gz
|
||||
de1f94d7dd3548ba3036de1ea97eb8243881c22a88fcc04cc08c704ded769e02 go1.23.2.linux-s390x.tar.gz
|
||||
e3286bdde186077e65e961cbe18874d42a461e5b9c472c26572b8d4a98d15c40 go1.23.2.linux-armv6l.tar.gz
|
||||
e4d9a1319dfdaa827407855e406c43e85c878a1f93f4f3984c85dce969c8bf70 go1.23.2.freebsd-386.tar.gz
|
||||
ea8ab49c5c04c9f94a3f4894d1b030fbce8d10413905fa399f6c39c0a44d5556 go1.23.2.linux-riscv64.tar.gz
|
||||
eaa3bc377badbdcae144633f8b29bf2680475b72dcd4c135343d3bdc0ba7671e go1.23.2.windows-386.zip
|
||||
f11b9b4d4a0679909202fc5e88093d6ff720a8a417bfe6a34d502c3862367039 go1.23.2.freebsd-riscv64.tar.gz
|
||||
f163b99b03e4bbc64cd30363f1694a08fcd44094415db1f092f13f9d1bb7c28e go1.23.2.dragonfly-amd64.tar.gz
|
||||
f45af3e1434175ff85620a74c07fb41d6844655f1f2cd2389c5fca6de000f58c go1.23.2.freebsd-arm64.tar.gz
|
||||
f626cdd92fc21a88b31c1251f419c17782933a42903db87a174ce74eeecc66a9 go1.23.2.linux-arm64.tar.gz
|
||||
fa70d39ddeb6b55241a30b48d7af4e681c6a7d7104e8326c3bc1b12a75e091cc go1.23.2.solaris-amd64.tar.gz
|
||||
8d6a77332487557c6afa2421131b50f83db4ae3c579c3bc72e670ee1f6968599 go1.23.3.src.tar.gz
|
||||
bdbf2a243ed4a121c9988684e5b15989cb244c1ff9e41ca823d0187b5c859114 go1.23.3.aix-ppc64.tar.gz
|
||||
b79c77bbdf61e6e486aa6bea9286f3f7969c28e2ff7686ce10c334f746bfb724 go1.23.3.darwin-amd64.pkg
|
||||
c7e024d5c0bc81845070f23598caf02f05b8ae88fd4ad2cd3e236ddbea833ad2 go1.23.3.darwin-amd64.tar.gz
|
||||
3e764df0db8f3c7470b9ff641954a380510a4822613c06bd5a195fd083f4731d go1.23.3.darwin-arm64.pkg
|
||||
31e119fe9bde6e105407a32558d5b5fa6ca11e2bd17f8b7b2f8a06aba16a0632 go1.23.3.darwin-arm64.tar.gz
|
||||
3872c9a98331050a242afe63fa6abc8fc313aca83dcaefda318e903309ac0c8d go1.23.3.dragonfly-amd64.tar.gz
|
||||
69479fa016ec5b4605885643ce0c2dd5c583e02353978feb6de38c961863b9cc go1.23.3.freebsd-386.tar.gz
|
||||
bf1de22a900646ef4f79480ed88337856d47089cc610f87e6fef46f6b8db0e1f go1.23.3.freebsd-amd64.tar.gz
|
||||
e461f866479bc36bdd4cfec32bfecb1bb243152268a1b3223de109410dec3407 go1.23.3.freebsd-arm.tar.gz
|
||||
24154b4018a45540aefeb6b5b9ffdcc8d9a8cdb78cd7fec262787b89fed19997 go1.23.3.freebsd-arm64.tar.gz
|
||||
218f3f1532e61dd65c330c2a5fc85bec18cc3690489763e62ffa9bb9fc85a68e go1.23.3.freebsd-riscv64.tar.gz
|
||||
24e3f34858b8687c31f5e5ab9e46d27fb613b0d50a94261c500cebb2d79c0672 go1.23.3.illumos-amd64.tar.gz
|
||||
3d7b00191a43c50d28e0903a0c576104bc7e171a8670de419d41111c08dfa299 go1.23.3.linux-386.tar.gz
|
||||
a0afb9744c00648bafb1b90b4aba5bdb86f424f02f9275399ce0c20b93a2c3a8 go1.23.3.linux-amd64.tar.gz
|
||||
1f7cbd7f668ea32a107ecd41b6488aaee1f5d77a66efd885b175494439d4e1ce go1.23.3.linux-arm64.tar.gz
|
||||
5f0332754beffc65af65a7b2da76e9dd997567d0d81b6f4f71d3588dc7b4cb00 go1.23.3.linux-armv6l.tar.gz
|
||||
1d0161a8946c7d99f717bad23631738408511f9f87e78d852224a023d8882ad8 go1.23.3.linux-loong64.tar.gz
|
||||
e924a7c9027f521f8a3563541ed0f89a4db3ef005b6b71263415b38e0b46e63a go1.23.3.linux-mips.tar.gz
|
||||
4cdf8c38165627f032c2b17cdd95e4aafff40d75fc873824d4c94914284098ca go1.23.3.linux-mips64.tar.gz
|
||||
5e49347e7325d2e268fb14040529b704e66eed77154cc73a919e9167d8527a2f go1.23.3.linux-mips64le.tar.gz
|
||||
142eabc17cee99403e895383ed7a6b7b40e740e8c2f73b79352bb9d1242fbd98 go1.23.3.linux-mipsle.tar.gz
|
||||
96ad61ba6b6cc0f5adfd75e65231c61e7db26d8236f01117023899528164d1b0 go1.23.3.linux-ppc64.tar.gz
|
||||
e3b926c81e8099d3cee6e6e270b85b39c3bd44263f8d3df29aacb4d7e00507c8 go1.23.3.linux-ppc64le.tar.gz
|
||||
324e03b6f59be841dfbaeabc466224b0f0905f5ad3a225b7c0703090e6c4b1a5 go1.23.3.linux-riscv64.tar.gz
|
||||
6bd72fcef72b046b6282c2d1f2c38f31600e4fe9361fcd8341500c754fb09c38 go1.23.3.linux-s390x.tar.gz
|
||||
5df382337fe2e4ea6adaafa823da5e083513a97534a38f89d691dd6f599084ca go1.23.3.netbsd-386.tar.gz
|
||||
9ae7cb6095a3e91182ac03547167e230fddd4941ed02dbdb6af663b2a53d9db7 go1.23.3.netbsd-amd64.tar.gz
|
||||
4a452c4134a9bea6213d8925d322f26b01c0eccda1330585bb2b241c76a0c3ea go1.23.3.netbsd-arm.tar.gz
|
||||
8ff3b5184d840148dbca061c04dca35a7070dc894255d3b755066bd76a7094dc go1.23.3.netbsd-arm64.tar.gz
|
||||
5b6940922e68ac1162a704a8b583fb4f039f955bfe97c35a56c40269cbcff9b1 go1.23.3.openbsd-386.tar.gz
|
||||
6ae4aeb6a88f3754b10ecec90422a30fb8bf86c3187be2be9408d67a5a235ace go1.23.3.openbsd-amd64.tar.gz
|
||||
e5eae226391b60c4d1ea1022663f55b225c6d7bab67f31fbafd5dd7a04684006 go1.23.3.openbsd-arm.tar.gz
|
||||
e12b2c04535e0bf5561d54831122b410d708519c1ec2c56b0c2350b15243c331 go1.23.3.openbsd-arm64.tar.gz
|
||||
599818e4062166d7a112f6f3fcca2dd4e2cdd3111fe48f9757bd8debf38c7f52 go1.23.3.openbsd-ppc64.tar.gz
|
||||
9ca4db8cab2a07d561f5b2a9397793684ab3b22326add1fe8cda8a545a1693db go1.23.3.openbsd-riscv64.tar.gz
|
||||
8fca1ec2aced936e0170605378ee7f0acb38f002490321f67fc83728ee281967 go1.23.3.plan9-386.tar.gz
|
||||
22d663692224fc1933a97f61d9fe49815e3b9ef1c2be97046505683fdf2e23c7 go1.23.3.plan9-amd64.tar.gz
|
||||
d0417a702d0e776d57e450fa2ce1ce7efa199a636644776862dbf946c409a462 go1.23.3.plan9-arm.tar.gz
|
||||
b5d9db1c02e0ca266a142eb687bd7749890c30872b09a4a0ffcd491425039754 go1.23.3.solaris-amd64.tar.gz
|
||||
14b7baf4af2046013b74dfac6e9a0a7403f15ee9940a16890bc028dfd32c49ac go1.23.3.windows-386.msi
|
||||
23da9089ea6c5612d718f13c26e9bfc9aaaabe222838075346a8191d48f9dfe5 go1.23.3.windows-386.zip
|
||||
614f0e3eed82245dfb4356d4e8d5b96abecca6a4c4f0168c0e389e4dd6284db8 go1.23.3.windows-amd64.msi
|
||||
81968b563642096b8a7521171e2be6e77ff6f44032f7493b7bdec9d33f44f31d go1.23.3.windows-amd64.zip
|
||||
c9951eecad732c59dfde6dc4803fa9253eb074663c61035c8d856f4d2eb146cb go1.23.3.windows-arm.msi
|
||||
1a7db02be47deada42082d21d63eba0013f93375cfa0e7768962f1295a469022 go1.23.3.windows-arm.zip
|
||||
a74e3e195219af4330b93c71cd4b736b709a5654a07cc37eebe181c4984afb82 go1.23.3.windows-arm64.msi
|
||||
dbdfa868b1a3f8c62950373e4975d83f90dd8b869a3907319af8384919bcaffe go1.23.3.windows-arm64.zip
|
||||
|
||||
# version:golangci 1.61.0
|
||||
# https://github.com/golangci/golangci-lint/releases/
|
||||
|
|
|
|||
|
|
@ -17,14 +17,16 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"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/crypto"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
|
|
@ -191,7 +193,7 @@ 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})
|
||||
am := accounts.NewManager(nil)
|
||||
keydir, isEphemeral, err := cfg.Node.GetKeyStoreDir()
|
||||
if err != nil {
|
||||
utils.Fatalf("Failed to get the keystore directory: %v", err)
|
||||
|
|
@ -219,60 +221,22 @@ func accountList(ctx *cli.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// tries unlocking the specified account a few times.
|
||||
func unlockAccount(ks *keystore.KeyStore, address string, i int, passwords []string) (accounts.Account, string) {
|
||||
account, err := utils.MakeAddress(ks, address)
|
||||
// readPasswordFromFile reads the first line of the given file, trims line endings,
|
||||
// and returns the password and whether the reading was successful.
|
||||
func readPasswordFromFile(path string) (string, bool) {
|
||||
if path == "" {
|
||||
return "", false
|
||||
}
|
||||
text, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
utils.Fatalf("Could not list accounts: %v", err)
|
||||
utils.Fatalf("Failed to read password file: %v", err)
|
||||
}
|
||||
for trials := 0; trials < 3; trials++ {
|
||||
prompt := fmt.Sprintf("Unlocking account %s | Attempt %d/%d", address, trials+1, 3)
|
||||
password := utils.GetPassPhraseWithList(prompt, false, i, passwords)
|
||||
err = ks.Unlock(account, password)
|
||||
if err == nil {
|
||||
log.Info("Unlocked account", "address", account.Address.Hex())
|
||||
return account, password
|
||||
}
|
||||
if err, ok := err.(*keystore.AmbiguousAddrError); ok {
|
||||
log.Info("Unlocked account", "address", account.Address.Hex())
|
||||
return ambiguousAddrRecovery(ks, err, password), password
|
||||
}
|
||||
if err != keystore.ErrDecrypt {
|
||||
// No need to prompt again if the error is not decryption-related.
|
||||
break
|
||||
}
|
||||
lines := strings.Split(string(text), "\n")
|
||||
if len(lines) == 0 {
|
||||
return "", false
|
||||
}
|
||||
// All trials expended to unlock account, bail out
|
||||
utils.Fatalf("Failed to unlock account %s (%v)", address, err)
|
||||
|
||||
return 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.URL)
|
||||
}
|
||||
fmt.Println("Testing your password against all of them...")
|
||||
var match *accounts.Account
|
||||
for i, a := range err.Matches {
|
||||
if e := ks.Unlock(a, auth); e == nil {
|
||||
match = &err.Matches[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
if match == nil {
|
||||
utils.Fatalf("None of the listed files could be unlocked.")
|
||||
return accounts.Account{}
|
||||
}
|
||||
fmt.Printf("Your password 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.URL)
|
||||
}
|
||||
}
|
||||
return *match
|
||||
// Sanitise DOS line endings.
|
||||
return strings.TrimRight(lines[0], "\r"), true
|
||||
}
|
||||
|
||||
// accountCreate creates a new account into the keystore defined by the CLI flags.
|
||||
|
|
@ -292,8 +256,10 @@ func accountCreate(ctx *cli.Context) error {
|
|||
scryptP = keystore.LightScryptP
|
||||
}
|
||||
|
||||
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))
|
||||
|
||||
password, ok := readPasswordFromFile(ctx.Path(utils.PasswordFileFlag.Name))
|
||||
if !ok {
|
||||
password = utils.GetPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true)
|
||||
}
|
||||
account, err := keystore.StoreKey(keydir, password, scryptN, scryptP)
|
||||
|
||||
if err != nil {
|
||||
|
|
@ -323,10 +289,23 @@ func accountUpdate(ctx *cli.Context) error {
|
|||
ks := backends[0].(*keystore.KeyStore)
|
||||
|
||||
for _, addr := range ctx.Args().Slice() {
|
||||
account, oldPassword := unlockAccount(ks, addr, 0, nil)
|
||||
newPassword := utils.GetPassPhraseWithList("Please give a new password. Do not forget this password.", true, 0, nil)
|
||||
if err := ks.Update(account, oldPassword, newPassword); err != nil {
|
||||
utils.Fatalf("Could not update the account: %v", err)
|
||||
if !common.IsHexAddress(addr) {
|
||||
return errors.New("address must be specified in hexadecimal form")
|
||||
}
|
||||
account := accounts.Account{Address: common.HexToAddress(addr)}
|
||||
newPassword := utils.GetPassPhrase("Please give a NEW password. Do not forget this password.", true)
|
||||
updateFn := func(attempt int) error {
|
||||
prompt := fmt.Sprintf("Please provide the OLD password for account %s | Attempt %d/%d", addr, attempt+1, 3)
|
||||
password := utils.GetPassPhrase(prompt, false)
|
||||
return ks.Update(account, password, newPassword)
|
||||
}
|
||||
// let user attempt unlock thrice.
|
||||
err := updateFn(0)
|
||||
for attempts := 1; attempts < 3 && errors.Is(err, keystore.ErrDecrypt); attempts++ {
|
||||
err = updateFn(attempts)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not update account: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
@ -347,10 +326,12 @@ func importWallet(ctx *cli.Context) error {
|
|||
if len(backends) == 0 {
|
||||
utils.Fatalf("Keystore is not available")
|
||||
}
|
||||
password, ok := readPasswordFromFile(ctx.Path(utils.PasswordFileFlag.Name))
|
||||
if !ok {
|
||||
password = utils.GetPassPhrase("", false)
|
||||
}
|
||||
ks := backends[0].(*keystore.KeyStore)
|
||||
passphrase := utils.GetPassPhraseWithList("", false, 0, utils.MakePasswordList(ctx))
|
||||
|
||||
acct, err := ks.ImportPreSaleKey(keyJSON, passphrase)
|
||||
acct, err := ks.ImportPreSaleKey(keyJSON, password)
|
||||
if err != nil {
|
||||
utils.Fatalf("%v", err)
|
||||
}
|
||||
|
|
@ -373,9 +354,11 @@ func accountImport(ctx *cli.Context) error {
|
|||
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)
|
||||
password, ok := readPasswordFromFile(ctx.Path(utils.PasswordFileFlag.Name))
|
||||
if !ok {
|
||||
password = utils.GetPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true)
|
||||
}
|
||||
acct, err := ks.ImportECDSA(key, password)
|
||||
if err != nil {
|
||||
utils.Fatalf("Could not create the account: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/cespare/cp"
|
||||
|
|
@ -171,12 +170,12 @@ func TestAccountUpdate(t *testing.T) {
|
|||
"f466859ead1932d743d622cb74fc058882e8648a")
|
||||
defer geth.ExpectExit()
|
||||
geth.Expect(`
|
||||
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
|
||||
Please give a NEW password. Do not forget this password.
|
||||
!! Unsupported terminal, password will be echoed.
|
||||
Password: {{.InputLine "foobar"}}
|
||||
Please give a new password. Do not forget this password.
|
||||
Password: {{.InputLine "foobar2"}}
|
||||
Repeat password: {{.InputLine "foobar2"}}
|
||||
Please provide the OLD password for account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
|
||||
Password: {{.InputLine "foobar"}}
|
||||
`)
|
||||
}
|
||||
|
||||
|
|
@ -206,172 +205,3 @@ Password: {{.InputLine "wrong"}}
|
|||
Fatal: could not decrypt key with given password
|
||||
`)
|
||||
}
|
||||
|
||||
func TestUnlockFlag(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "console", "--exec", "loadScript('testdata/empty.js')")
|
||||
geth.Expect(`
|
||||
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
|
||||
!! Unsupported terminal, password will be echoed.
|
||||
Password: {{.InputLine "foobar"}}
|
||||
undefined
|
||||
`)
|
||||
geth.ExpectExit()
|
||||
|
||||
wantMessages := []string{
|
||||
"Unlocked account",
|
||||
"=0xf466859eAD1932D743d622CB74FC058882E8648A",
|
||||
}
|
||||
for _, m := range wantMessages {
|
||||
if !strings.Contains(geth.StderrText(), m) {
|
||||
t.Errorf("stderr text does not contain %q", m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnlockFlagWrongPassword(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "console", "--exec", "loadScript('testdata/empty.js')")
|
||||
|
||||
defer geth.ExpectExit()
|
||||
geth.Expect(`
|
||||
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
|
||||
!! Unsupported terminal, password will be echoed.
|
||||
Password: {{.InputLine "wrong1"}}
|
||||
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 2/3
|
||||
Password: {{.InputLine "wrong2"}}
|
||||
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 3/3
|
||||
Password: {{.InputLine "wrong3"}}
|
||||
Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could not decrypt key with given password)
|
||||
`)
|
||||
}
|
||||
|
||||
// https://github.com/ethereum/go-ethereum/issues/1785
|
||||
func TestUnlockFlagMultiIndex(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--unlock", "0,2", "console", "--exec", "loadScript('testdata/empty.js')")
|
||||
|
||||
geth.Expect(`
|
||||
Unlocking account 0 | Attempt 1/3
|
||||
!! Unsupported terminal, password will be echoed.
|
||||
Password: {{.InputLine "foobar"}}
|
||||
Unlocking account 2 | Attempt 1/3
|
||||
Password: {{.InputLine "foobar"}}
|
||||
undefined
|
||||
`)
|
||||
geth.ExpectExit()
|
||||
|
||||
wantMessages := []string{
|
||||
"Unlocked account",
|
||||
"=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
|
||||
"=0x289d485D9771714CCe91D3393D764E1311907ACc",
|
||||
}
|
||||
for _, m := range wantMessages {
|
||||
if !strings.Contains(geth.StderrText(), m) {
|
||||
t.Errorf("stderr text does not contain %q", m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnlockFlagPasswordFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--password", "testdata/passwords.txt", "--unlock", "0,2", "console", "--exec", "loadScript('testdata/empty.js')")
|
||||
|
||||
geth.Expect(`
|
||||
undefined
|
||||
`)
|
||||
geth.ExpectExit()
|
||||
|
||||
wantMessages := []string{
|
||||
"Unlocked account",
|
||||
"=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
|
||||
"=0x289d485D9771714CCe91D3393D764E1311907ACc",
|
||||
}
|
||||
for _, m := range wantMessages {
|
||||
if !strings.Contains(geth.StderrText(), m) {
|
||||
t.Errorf("stderr text does not contain %q", m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) {
|
||||
t.Parallel()
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--password",
|
||||
"testdata/wrong-passwords.txt", "--unlock", "0,2")
|
||||
defer geth.ExpectExit()
|
||||
geth.Expect(`
|
||||
Fatal: Failed to unlock account 0 (could not decrypt key with given password)
|
||||
`)
|
||||
}
|
||||
|
||||
func TestUnlockFlagAmbiguous(t *testing.T) {
|
||||
t.Parallel()
|
||||
store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--keystore",
|
||||
store, "--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
|
||||
"console", "--exec", "loadScript('testdata/empty.js')")
|
||||
defer geth.ExpectExit()
|
||||
|
||||
// Helper for the expect template, returns absolute keystore path.
|
||||
geth.SetTemplateFunc("keypath", func(file string) string {
|
||||
abs, _ := filepath.Abs(filepath.Join(store, file))
|
||||
return abs
|
||||
})
|
||||
geth.Expect(`
|
||||
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
|
||||
!! Unsupported terminal, password will be echoed.
|
||||
Password: {{.InputLine "foobar"}}
|
||||
Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
|
||||
keystore://{{keypath "1"}}
|
||||
keystore://{{keypath "2"}}
|
||||
Testing your password against all of them...
|
||||
Your password unlocked keystore://{{keypath "1"}}
|
||||
In order to avoid this warning, you need to remove the following duplicate key files:
|
||||
keystore://{{keypath "2"}}
|
||||
undefined
|
||||
`)
|
||||
geth.ExpectExit()
|
||||
|
||||
wantMessages := []string{
|
||||
"Unlocked account",
|
||||
"=0xf466859eAD1932D743d622CB74FC058882E8648A",
|
||||
}
|
||||
for _, m := range wantMessages {
|
||||
if !strings.Contains(geth.StderrText(), m) {
|
||||
t.Errorf("stderr text does not contain %q", m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) {
|
||||
t.Parallel()
|
||||
store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--keystore",
|
||||
store, "--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
|
||||
|
||||
defer geth.ExpectExit()
|
||||
|
||||
// Helper for the expect template, returns absolute keystore path.
|
||||
geth.SetTemplateFunc("keypath", func(file string) string {
|
||||
abs, _ := filepath.Abs(filepath.Join(store, file))
|
||||
return abs
|
||||
})
|
||||
geth.Expect(`
|
||||
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
|
||||
!! Unsupported terminal, password will be echoed.
|
||||
Password: {{.InputLine "wrong"}}
|
||||
Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
|
||||
keystore://{{keypath "1"}}
|
||||
keystore://{{keypath "2"}}
|
||||
Testing your password against all of them...
|
||||
Fatal: None of the listed files could be unlocked.
|
||||
`)
|
||||
geth.ExpectExit()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,11 +23,9 @@ import (
|
|||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
"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/prompt"
|
||||
|
|
@ -353,14 +351,14 @@ func geth(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
// startNode boots up the system node and all registered protocols, after which
|
||||
// it unlocks any requested accounts, and starts the RPC/IPC interfaces and the
|
||||
// miner.
|
||||
// it starts the RPC/IPC interfaces and the miner.
|
||||
func startNode(ctx *cli.Context, stack *node.Node, isConsole bool) {
|
||||
// Start up the node itself
|
||||
utils.StartNode(ctx, stack, isConsole)
|
||||
|
||||
// Unlock any account specifically requested
|
||||
unlockAccounts(ctx, stack)
|
||||
if ctx.IsSet(utils.UnlockedAccountFlag.Name) {
|
||||
log.Warn(`The "unlock" flag has been deprecated and has no effect`)
|
||||
}
|
||||
|
||||
// Register wallet event handlers to open and auto-derive wallets
|
||||
events := make(chan accounts.WalletEvent, 16)
|
||||
|
|
@ -427,33 +425,3 @@ func startNode(ctx *cli.Context, stack *node.Node, isConsole bool) {
|
|||
}()
|
||||
}
|
||||
}
|
||||
|
||||
// unlockAccounts unlocks any account specifically requested.
|
||||
func unlockAccounts(ctx *cli.Context, stack *node.Node) {
|
||||
var unlocks []string
|
||||
inputs := strings.Split(ctx.String(utils.UnlockedAccountFlag.Name), ",")
|
||||
for _, input := range inputs {
|
||||
if trimmed := strings.TrimSpace(input); trimmed != "" {
|
||||
unlocks = append(unlocks, trimmed)
|
||||
}
|
||||
}
|
||||
// Short circuit if there is no account to unlock.
|
||||
if len(unlocks) == 0 {
|
||||
return
|
||||
}
|
||||
// If insecure account unlocking is not allowed if node's APIs are exposed to external.
|
||||
// Print warning log to user and skip unlocking.
|
||||
if !stack.Config().InsecureUnlockAllowed && stack.Config().ExtRPCEnabled() {
|
||||
utils.Fatalf("Account unlock with HTTP access is forbidden!")
|
||||
}
|
||||
backends := stack.AccountManager().Backends(keystore.KeyStoreType)
|
||||
if len(backends) == 0 {
|
||||
log.Warn("Failed to unlock accounts, keystore is not available")
|
||||
return
|
||||
}
|
||||
ks := backends[0].(*keystore.KeyStore)
|
||||
passwords := utils.MakePasswordList(ctx)
|
||||
for i, account := range unlocks {
|
||||
unlockAccount(ks, account, i, passwords)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -500,12 +500,6 @@ var (
|
|||
}
|
||||
|
||||
// Account settings
|
||||
UnlockedAccountFlag = &cli.StringFlag{
|
||||
Name: "unlock",
|
||||
Usage: "Comma separated list of accounts to unlock",
|
||||
Value: "",
|
||||
Category: flags.AccountCategory,
|
||||
}
|
||||
PasswordFileFlag = &cli.PathFlag{
|
||||
Name: "password",
|
||||
Usage: "Password file to use for non-interactive password input",
|
||||
|
|
@ -518,12 +512,6 @@ var (
|
|||
Value: "",
|
||||
Category: flags.AccountCategory,
|
||||
}
|
||||
InsecureUnlockAllowedFlag = &cli.BoolFlag{
|
||||
Name: "allow-insecure-unlock",
|
||||
Usage: "Allow insecure account unlocking when account-related RPCs are exposed by http",
|
||||
Category: flags.AccountCategory,
|
||||
}
|
||||
|
||||
// EVM settings
|
||||
VMEnableDebugFlag = &cli.BoolFlag{
|
||||
Name: "vmdebug",
|
||||
|
|
@ -1349,31 +1337,6 @@ func MakeDatabaseHandles(max int) int {
|
|||
return int(raised / 2) // Leave half for networking and other stuff
|
||||
}
|
||||
|
||||
// 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(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 || index < 0 {
|
||||
return accounts.Account{}, fmt.Errorf("invalid account address or index %q", account)
|
||||
}
|
||||
log.Warn("-------------------------------------------------------------------")
|
||||
log.Warn("Referring to accounts by order in the keystore folder is dangerous!")
|
||||
log.Warn("This functionality is deprecated and will be removed in the future!")
|
||||
log.Warn("Please use explicit addresses! (can search via `geth account list`)")
|
||||
log.Warn("-------------------------------------------------------------------")
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// setEtherbase retrieves the etherbase from the directly specified command line flags.
|
||||
func setEtherbase(ctx *cli.Context, cfg *ethconfig.Config) {
|
||||
if ctx.IsSet(MinerEtherbaseFlag.Name) {
|
||||
|
|
@ -1394,24 +1357,6 @@ func setEtherbase(ctx *cli.Context, cfg *ethconfig.Config) {
|
|||
cfg.Miner.PendingFeeRecipient = common.BytesToAddress(b)
|
||||
}
|
||||
|
||||
// MakePasswordList reads password lines from the file specified by the global --password flag.
|
||||
func MakePasswordList(ctx *cli.Context) []string {
|
||||
path := ctx.Path(PasswordFileFlag.Name)
|
||||
if path == "" {
|
||||
return nil
|
||||
}
|
||||
text, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
Fatalf("Failed to read password file: %v", err)
|
||||
}
|
||||
lines := strings.Split(string(text), "\n")
|
||||
// Sanitise DOS line endings.
|
||||
for i := range lines {
|
||||
lines[i] = strings.TrimRight(lines[i], "\r")
|
||||
}
|
||||
return lines
|
||||
}
|
||||
|
||||
func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
|
||||
setNodeKey(ctx, cfg)
|
||||
setNAT(ctx, cfg)
|
||||
|
|
@ -1493,7 +1438,7 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
|
|||
cfg.USB = ctx.Bool(USBFlag.Name)
|
||||
}
|
||||
if ctx.IsSet(InsecureUnlockAllowedFlag.Name) {
|
||||
cfg.InsecureUnlockAllowed = ctx.Bool(InsecureUnlockAllowedFlag.Name)
|
||||
log.Warn(fmt.Sprintf("Option %q is deprecated and has no effect", InsecureUnlockAllowedFlag.Name))
|
||||
}
|
||||
if ctx.IsSet(DBEngineFlag.Name) {
|
||||
dbEngine := ctx.String(DBEngineFlag.Name)
|
||||
|
|
@ -1886,13 +1831,15 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
|||
passphrase string
|
||||
err error
|
||||
)
|
||||
if list := MakePasswordList(ctx); len(list) > 0 {
|
||||
// Just take the first value. Although the function returns a possible multiple values and
|
||||
// some usages iterate through them as attempts, that doesn't make sense in this setting,
|
||||
// when we're definitely concerned with only one account.
|
||||
passphrase = list[0]
|
||||
if path := ctx.Path(PasswordFileFlag.Name); path != "" {
|
||||
if text, err := os.ReadFile(path); err != nil {
|
||||
Fatalf("Failed to read password file: %v", err)
|
||||
} else {
|
||||
if lines := strings.Split(string(text), "\n"); len(lines) > 0 {
|
||||
passphrase = strings.TrimRight(lines[0], "\r") // Sanitise DOS line endings.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock the developer account by local keystore.
|
||||
var ks *keystore.KeyStore
|
||||
if keystores := stack.AccountManager().Backends(keystore.KeyStoreType); len(keystores) > 0 {
|
||||
|
|
|
|||
|
|
@ -159,6 +159,17 @@ var (
|
|||
Usage: "This used to enable the 'personal' namespace.",
|
||||
Category: flags.DeprecatedCategory,
|
||||
}
|
||||
UnlockedAccountFlag = &cli.StringFlag{
|
||||
Name: "unlock",
|
||||
Usage: "Comma separated list of accounts to unlock (deprecated)",
|
||||
Value: "",
|
||||
Category: flags.DeprecatedCategory,
|
||||
}
|
||||
InsecureUnlockAllowedFlag = &cli.BoolFlag{
|
||||
Name: "allow-insecure-unlock",
|
||||
Usage: "Allow insecure account unlocking when account-related RPCs are exposed by http (deprecated)",
|
||||
Category: flags.DeprecatedCategory,
|
||||
}
|
||||
)
|
||||
|
||||
// showDeprecated displays deprecated flags that will be soon removed from the codebase.
|
||||
|
|
|
|||
|
|
@ -45,18 +45,3 @@ func GetPassPhrase(text string, confirmation bool) string {
|
|||
}
|
||||
return password
|
||||
}
|
||||
|
||||
// GetPassPhraseWithList retrieves the password associated with an account, either fetched
|
||||
// from a list of preloaded passphrases, or requested interactively from the user.
|
||||
func GetPassPhraseWithList(text string, confirmation bool, index int, passwords []string) string {
|
||||
// If a list of passwords was supplied, retrieve from them
|
||||
if len(passwords) > 0 {
|
||||
if index < len(passwords) {
|
||||
return passwords[index]
|
||||
}
|
||||
return passwords[len(passwords)-1]
|
||||
}
|
||||
// Otherwise prompt the user for the password
|
||||
password := GetPassPhrase(text, confirmation)
|
||||
return password
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
// Copyright 2020 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Package utils contains internal helper functions for go-ethereum commands.
|
||||
package utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetPassPhraseWithList(t *testing.T) {
|
||||
t.Parallel()
|
||||
type args struct {
|
||||
text string
|
||||
confirmation bool
|
||||
index int
|
||||
passwords []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
"test1",
|
||||
args{
|
||||
"text1",
|
||||
false,
|
||||
0,
|
||||
[]string{"zero", "one", "two"},
|
||||
},
|
||||
"zero",
|
||||
},
|
||||
{
|
||||
"test2",
|
||||
args{
|
||||
"text2",
|
||||
false,
|
||||
5,
|
||||
[]string{"zero", "one", "two"},
|
||||
},
|
||||
"two",
|
||||
},
|
||||
{
|
||||
"test3",
|
||||
args{
|
||||
"text3",
|
||||
true,
|
||||
1,
|
||||
[]string{"zero", "one", "two"},
|
||||
},
|
||||
"one",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
if got := GetPassPhraseWithList(tt.args.text, tt.args.confirmation, tt.args.index, tt.args.passwords); got != tt.want {
|
||||
t.Errorf("GetPassPhraseWithList() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -39,12 +39,12 @@ type binaryIterator struct {
|
|||
// initBinaryAccountIterator creates a simplistic iterator to step over all the
|
||||
// accounts in a slow, but easily verifiable way. Note this function is used for
|
||||
// initialization, use `newBinaryAccountIterator` as the API.
|
||||
func (dl *diffLayer) initBinaryAccountIterator() Iterator {
|
||||
func (dl *diffLayer) initBinaryAccountIterator(seek common.Hash) Iterator {
|
||||
parent, ok := dl.parent.(*diffLayer)
|
||||
if !ok {
|
||||
l := &binaryIterator{
|
||||
a: dl.AccountIterator(common.Hash{}),
|
||||
b: dl.Parent().AccountIterator(common.Hash{}),
|
||||
a: dl.AccountIterator(seek),
|
||||
b: dl.Parent().AccountIterator(seek),
|
||||
accountIterator: true,
|
||||
}
|
||||
l.aDone = !l.a.Next()
|
||||
|
|
@ -52,8 +52,8 @@ func (dl *diffLayer) initBinaryAccountIterator() Iterator {
|
|||
return l
|
||||
}
|
||||
l := &binaryIterator{
|
||||
a: dl.AccountIterator(common.Hash{}),
|
||||
b: parent.initBinaryAccountIterator(),
|
||||
a: dl.AccountIterator(seek),
|
||||
b: parent.initBinaryAccountIterator(seek),
|
||||
accountIterator: true,
|
||||
}
|
||||
l.aDone = !l.a.Next()
|
||||
|
|
@ -64,12 +64,12 @@ func (dl *diffLayer) initBinaryAccountIterator() Iterator {
|
|||
// initBinaryStorageIterator creates a simplistic iterator to step over all the
|
||||
// storage slots in a slow, but easily verifiable way. Note this function is used
|
||||
// for initialization, use `newBinaryStorageIterator` as the API.
|
||||
func (dl *diffLayer) initBinaryStorageIterator(account common.Hash) Iterator {
|
||||
func (dl *diffLayer) initBinaryStorageIterator(account, seek common.Hash) Iterator {
|
||||
parent, ok := dl.parent.(*diffLayer)
|
||||
if !ok {
|
||||
// If the storage in this layer is already destructed, discard all
|
||||
// deeper layers but still return a valid single-branch iterator.
|
||||
a, destructed := dl.StorageIterator(account, common.Hash{})
|
||||
a, destructed := dl.StorageIterator(account, seek)
|
||||
if destructed {
|
||||
l := &binaryIterator{
|
||||
a: a,
|
||||
|
|
@ -81,7 +81,7 @@ func (dl *diffLayer) initBinaryStorageIterator(account common.Hash) Iterator {
|
|||
}
|
||||
// The parent is disk layer, don't need to take care "destructed"
|
||||
// anymore.
|
||||
b, _ := dl.Parent().StorageIterator(account, common.Hash{})
|
||||
b, _ := dl.Parent().StorageIterator(account, seek)
|
||||
l := &binaryIterator{
|
||||
a: a,
|
||||
b: b,
|
||||
|
|
@ -93,7 +93,7 @@ func (dl *diffLayer) initBinaryStorageIterator(account common.Hash) Iterator {
|
|||
}
|
||||
// If the storage in this layer is already destructed, discard all
|
||||
// deeper layers but still return a valid single-branch iterator.
|
||||
a, destructed := dl.StorageIterator(account, common.Hash{})
|
||||
a, destructed := dl.StorageIterator(account, seek)
|
||||
if destructed {
|
||||
l := &binaryIterator{
|
||||
a: a,
|
||||
|
|
@ -105,7 +105,7 @@ func (dl *diffLayer) initBinaryStorageIterator(account common.Hash) Iterator {
|
|||
}
|
||||
l := &binaryIterator{
|
||||
a: a,
|
||||
b: parent.initBinaryStorageIterator(account),
|
||||
b: parent.initBinaryStorageIterator(account, seek),
|
||||
account: account,
|
||||
}
|
||||
l.aDone = !l.a.Next()
|
||||
|
|
@ -117,33 +117,50 @@ func (dl *diffLayer) initBinaryStorageIterator(account common.Hash) Iterator {
|
|||
// or an error if iteration failed for some reason (e.g. root being iterated
|
||||
// becomes stale and garbage collected).
|
||||
func (it *binaryIterator) Next() bool {
|
||||
for {
|
||||
if !it.next() {
|
||||
return false
|
||||
}
|
||||
if len(it.Account()) != 0 || len(it.Slot()) != 0 {
|
||||
return true
|
||||
}
|
||||
// it.fail might be set if error occurs by calling
|
||||
// it.Account() or it.Slot(), stop iteration if so.
|
||||
if it.fail != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (it *binaryIterator) next() bool {
|
||||
if it.aDone && it.bDone {
|
||||
return false
|
||||
}
|
||||
first:
|
||||
if it.aDone {
|
||||
it.k = it.b.Hash()
|
||||
for {
|
||||
if it.aDone {
|
||||
it.k = it.b.Hash()
|
||||
it.bDone = !it.b.Next()
|
||||
return true
|
||||
}
|
||||
if it.bDone {
|
||||
it.k = it.a.Hash()
|
||||
it.aDone = !it.a.Next()
|
||||
return true
|
||||
}
|
||||
nextA, nextB := it.a.Hash(), it.b.Hash()
|
||||
if diff := bytes.Compare(nextA[:], nextB[:]); diff < 0 {
|
||||
it.aDone = !it.a.Next()
|
||||
it.k = nextA
|
||||
return true
|
||||
} else if diff == 0 {
|
||||
// Now we need to advance one of them
|
||||
it.aDone = !it.a.Next()
|
||||
continue
|
||||
}
|
||||
it.bDone = !it.b.Next()
|
||||
it.k = nextB
|
||||
return true
|
||||
}
|
||||
if it.bDone {
|
||||
it.k = it.a.Hash()
|
||||
it.aDone = !it.a.Next()
|
||||
return true
|
||||
}
|
||||
nextA, nextB := it.a.Hash(), it.b.Hash()
|
||||
if diff := bytes.Compare(nextA[:], nextB[:]); diff < 0 {
|
||||
it.aDone = !it.a.Next()
|
||||
it.k = nextA
|
||||
return true
|
||||
} else if diff == 0 {
|
||||
// Now we need to advance one of them
|
||||
it.aDone = !it.a.Next()
|
||||
goto first
|
||||
}
|
||||
it.bDone = !it.b.Next()
|
||||
it.k = nextB
|
||||
return true
|
||||
}
|
||||
|
||||
// Error returns any failure that occurred during iteration, which might have
|
||||
|
|
@ -195,19 +212,21 @@ func (it *binaryIterator) Slot() []byte {
|
|||
// Release recursively releases all the iterators in the stack.
|
||||
func (it *binaryIterator) Release() {
|
||||
it.a.Release()
|
||||
it.b.Release()
|
||||
if it.b != nil {
|
||||
it.b.Release()
|
||||
}
|
||||
}
|
||||
|
||||
// newBinaryAccountIterator creates a simplistic account iterator to step over
|
||||
// all the accounts in a slow, but easily verifiable way.
|
||||
func (dl *diffLayer) newBinaryAccountIterator() AccountIterator {
|
||||
iter := dl.initBinaryAccountIterator()
|
||||
func (dl *diffLayer) newBinaryAccountIterator(seek common.Hash) AccountIterator {
|
||||
iter := dl.initBinaryAccountIterator(seek)
|
||||
return iter.(AccountIterator)
|
||||
}
|
||||
|
||||
// newBinaryStorageIterator creates a simplistic account iterator to step over
|
||||
// all the storage slots in a slow, but easily verifiable way.
|
||||
func (dl *diffLayer) newBinaryStorageIterator(account common.Hash) StorageIterator {
|
||||
iter := dl.initBinaryStorageIterator(account)
|
||||
func (dl *diffLayer) newBinaryStorageIterator(account, seek common.Hash) StorageIterator {
|
||||
iter := dl.initBinaryStorageIterator(account, seek)
|
||||
return iter.(StorageIterator)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@ func TestAccountIteratorBasics(t *testing.T) {
|
|||
it := diffLayer.AccountIterator(common.Hash{})
|
||||
verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator
|
||||
|
||||
it = diffLayer.newBinaryAccountIterator(common.Hash{})
|
||||
verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator
|
||||
|
||||
diskLayer := diffToDisk(diffLayer)
|
||||
it = diskLayer.AccountIterator(common.Hash{})
|
||||
verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator
|
||||
|
|
@ -235,7 +238,7 @@ func TestAccountIteratorTraversal(t *testing.T) {
|
|||
head := snaps.Snapshot(common.HexToHash("0x04"))
|
||||
|
||||
verifyIterator(t, 3, head.(snapshot).AccountIterator(common.Hash{}), verifyNothing)
|
||||
verifyIterator(t, 7, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount)
|
||||
verifyIterator(t, 7, head.(*diffLayer).newBinaryAccountIterator(common.Hash{}), verifyAccount)
|
||||
|
||||
it, _ := snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{})
|
||||
verifyIterator(t, 7, it, verifyAccount)
|
||||
|
|
@ -249,7 +252,7 @@ func TestAccountIteratorTraversal(t *testing.T) {
|
|||
}()
|
||||
aggregatorMemoryLimit = 0 // Force pushing the bottom-most layer into disk
|
||||
snaps.Cap(common.HexToHash("0x04"), 2)
|
||||
verifyIterator(t, 7, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount)
|
||||
verifyIterator(t, 7, head.(*diffLayer).newBinaryAccountIterator(common.Hash{}), verifyAccount)
|
||||
|
||||
it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{})
|
||||
verifyIterator(t, 7, it, verifyAccount)
|
||||
|
|
@ -283,7 +286,7 @@ func TestStorageIteratorTraversal(t *testing.T) {
|
|||
|
||||
diffIter, _ := head.(snapshot).StorageIterator(common.HexToHash("0xaa"), common.Hash{})
|
||||
verifyIterator(t, 3, diffIter, verifyNothing)
|
||||
verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage)
|
||||
verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa"), common.Hash{}), verifyStorage)
|
||||
|
||||
it, _ := snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{})
|
||||
verifyIterator(t, 6, it, verifyStorage)
|
||||
|
|
@ -297,7 +300,7 @@ func TestStorageIteratorTraversal(t *testing.T) {
|
|||
}()
|
||||
aggregatorMemoryLimit = 0 // Force pushing the bottom-most layer into disk
|
||||
snaps.Cap(common.HexToHash("0x04"), 2)
|
||||
verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage)
|
||||
verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa"), common.Hash{}), verifyStorage)
|
||||
|
||||
it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{})
|
||||
verifyIterator(t, 6, it, verifyStorage)
|
||||
|
|
@ -528,7 +531,7 @@ func TestAccountIteratorLargeTraversal(t *testing.T) {
|
|||
// Iterate the entire stack and ensure everything is hit only once
|
||||
head := snaps.Snapshot(common.HexToHash("0x80"))
|
||||
verifyIterator(t, 200, head.(snapshot).AccountIterator(common.Hash{}), verifyNothing)
|
||||
verifyIterator(t, 200, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount)
|
||||
verifyIterator(t, 200, head.(*diffLayer).newBinaryAccountIterator(common.Hash{}), verifyAccount)
|
||||
|
||||
it, _ := snaps.AccountIterator(common.HexToHash("0x80"), common.Hash{})
|
||||
verifyIterator(t, 200, it, verifyAccount)
|
||||
|
|
@ -543,7 +546,7 @@ func TestAccountIteratorLargeTraversal(t *testing.T) {
|
|||
aggregatorMemoryLimit = 0 // Force pushing the bottom-most layer into disk
|
||||
snaps.Cap(common.HexToHash("0x80"), 2)
|
||||
|
||||
verifyIterator(t, 200, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount)
|
||||
verifyIterator(t, 200, head.(*diffLayer).newBinaryAccountIterator(common.Hash{}), verifyAccount)
|
||||
|
||||
it, _ = snaps.AccountIterator(common.HexToHash("0x80"), common.Hash{})
|
||||
verifyIterator(t, 200, it, verifyAccount)
|
||||
|
|
@ -555,6 +558,20 @@ func TestAccountIteratorLargeTraversal(t *testing.T) {
|
|||
// - flattens C2 all the way into CN
|
||||
// - continues iterating
|
||||
func TestAccountIteratorFlattening(t *testing.T) {
|
||||
t.Run("fast", func(t *testing.T) {
|
||||
testAccountIteratorFlattening(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
|
||||
it, _ := snaps.AccountIterator(root, seek)
|
||||
return it
|
||||
})
|
||||
})
|
||||
t.Run("binary", func(t *testing.T) {
|
||||
testAccountIteratorFlattening(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
|
||||
return snaps.layers[root].(*diffLayer).newBinaryAccountIterator(seek)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func testAccountIteratorFlattening(t *testing.T, newIterator func(snaps *Tree, root, seek common.Hash) AccountIterator) {
|
||||
// Create an empty base layer and a snapshot tree out of it
|
||||
base := &diskLayer{
|
||||
diskdb: rawdb.NewMemoryDatabase(),
|
||||
|
|
@ -577,7 +594,7 @@ func TestAccountIteratorFlattening(t *testing.T) {
|
|||
randomAccountSet("0xcc", "0xf0", "0xff"), nil)
|
||||
|
||||
// Create an iterator and flatten the data from underneath it
|
||||
it, _ := snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{})
|
||||
it := newIterator(snaps, common.HexToHash("0x04"), common.Hash{})
|
||||
defer it.Release()
|
||||
|
||||
if err := snaps.Cap(common.HexToHash("0x04"), 1); err != nil {
|
||||
|
|
@ -587,6 +604,21 @@ func TestAccountIteratorFlattening(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAccountIteratorSeek(t *testing.T) {
|
||||
t.Run("fast", func(t *testing.T) {
|
||||
testAccountIteratorSeek(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
|
||||
it, _ := snaps.AccountIterator(root, seek)
|
||||
return it
|
||||
})
|
||||
})
|
||||
t.Run("binary", func(t *testing.T) {
|
||||
testAccountIteratorSeek(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
|
||||
it := snaps.layers[root].(*diffLayer).newBinaryAccountIterator(seek)
|
||||
return it
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func testAccountIteratorSeek(t *testing.T, newIterator func(snaps *Tree, root, seek common.Hash) AccountIterator) {
|
||||
// Create a snapshot stack with some initial data
|
||||
base := &diskLayer{
|
||||
diskdb: rawdb.NewMemoryDatabase(),
|
||||
|
|
@ -612,44 +644,58 @@ func TestAccountIteratorSeek(t *testing.T) {
|
|||
// 03: aa, bb, dd, ee, f0 (, f0), ff
|
||||
// 04: aa, bb, cc, dd, ee, f0 (, f0), ff (, ff)
|
||||
// Construct various iterators and ensure their traversal is correct
|
||||
it, _ := snaps.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xdd"))
|
||||
it := newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xdd"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 3, it, verifyAccount) // expected: ee, f0, ff
|
||||
|
||||
it, _ = snaps.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"))
|
||||
it = newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xaa"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 4, it, verifyAccount) // expected: aa, ee, f0, ff
|
||||
|
||||
it, _ = snaps.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xff"))
|
||||
it = newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xff"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 1, it, verifyAccount) // expected: ff
|
||||
|
||||
it, _ = snaps.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xff1"))
|
||||
it = newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xff1"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 0, it, verifyAccount) // expected: nothing
|
||||
|
||||
it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xbb"))
|
||||
it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xbb"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 6, it, verifyAccount) // expected: bb, cc, dd, ee, f0, ff
|
||||
|
||||
it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xef"))
|
||||
it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xef"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 2, it, verifyAccount) // expected: f0, ff
|
||||
|
||||
it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xf0"))
|
||||
it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xf0"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 2, it, verifyAccount) // expected: f0, ff
|
||||
|
||||
it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xff"))
|
||||
it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xff"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 1, it, verifyAccount) // expected: ff
|
||||
|
||||
it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xff1"))
|
||||
it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xff1"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 0, it, verifyAccount) // expected: nothing
|
||||
}
|
||||
|
||||
func TestStorageIteratorSeek(t *testing.T) {
|
||||
t.Run("fast", func(t *testing.T) {
|
||||
testStorageIteratorSeek(t, func(snaps *Tree, root, account, seek common.Hash) StorageIterator {
|
||||
it, _ := snaps.StorageIterator(root, account, seek)
|
||||
return it
|
||||
})
|
||||
})
|
||||
t.Run("binary", func(t *testing.T) {
|
||||
testStorageIteratorSeek(t, func(snaps *Tree, root, account, seek common.Hash) StorageIterator {
|
||||
return snaps.layers[root].(*diffLayer).newBinaryStorageIterator(account, seek)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func testStorageIteratorSeek(t *testing.T, newIterator func(snaps *Tree, root, account, seek common.Hash) StorageIterator) {
|
||||
// Create a snapshot stack with some initial data
|
||||
base := &diskLayer{
|
||||
diskdb: rawdb.NewMemoryDatabase(),
|
||||
|
|
@ -676,35 +722,35 @@ func TestStorageIteratorSeek(t *testing.T) {
|
|||
// 03: 01, 02, 03, 05 (, 05), 06
|
||||
// 04: 01(, 01), 02, 03, 05(, 05, 05), 06, 08
|
||||
// Construct various iterators and ensure their traversal is correct
|
||||
it, _ := snaps.StorageIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x01"))
|
||||
it := newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x01"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 3, it, verifyStorage) // expected: 01, 03, 05
|
||||
|
||||
it, _ = snaps.StorageIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x02"))
|
||||
it = newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x02"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 2, it, verifyStorage) // expected: 03, 05
|
||||
|
||||
it, _ = snaps.StorageIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x5"))
|
||||
it = newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x5"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 1, it, verifyStorage) // expected: 05
|
||||
|
||||
it, _ = snaps.StorageIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x6"))
|
||||
it = newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x6"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 0, it, verifyStorage) // expected: nothing
|
||||
|
||||
it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x01"))
|
||||
it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x01"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 6, it, verifyStorage) // expected: 01, 02, 03, 05, 06, 08
|
||||
|
||||
it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x05"))
|
||||
it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x05"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 3, it, verifyStorage) // expected: 05, 06, 08
|
||||
|
||||
it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x08"))
|
||||
it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x08"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 1, it, verifyStorage) // expected: 08
|
||||
|
||||
it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x09"))
|
||||
it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x09"))
|
||||
defer it.Release()
|
||||
verifyIterator(t, 0, it, verifyStorage) // expected: nothing
|
||||
}
|
||||
|
|
@ -713,6 +759,20 @@ func TestStorageIteratorSeek(t *testing.T) {
|
|||
// deleted accounts (where the Account() value is nil). The iterator
|
||||
// should not output any accounts or nil-values for those cases.
|
||||
func TestAccountIteratorDeletions(t *testing.T) {
|
||||
t.Run("fast", func(t *testing.T) {
|
||||
testAccountIteratorDeletions(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
|
||||
it, _ := snaps.AccountIterator(root, seek)
|
||||
return it
|
||||
})
|
||||
})
|
||||
t.Run("binary", func(t *testing.T) {
|
||||
testAccountIteratorDeletions(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
|
||||
return snaps.layers[root].(*diffLayer).newBinaryAccountIterator(seek)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func testAccountIteratorDeletions(t *testing.T, newIterator func(snaps *Tree, root, seek common.Hash) AccountIterator) {
|
||||
// Create an empty base layer and a snapshot tree out of it
|
||||
base := &diskLayer{
|
||||
diskdb: rawdb.NewMemoryDatabase(),
|
||||
|
|
@ -739,7 +799,8 @@ func TestAccountIteratorDeletions(t *testing.T) {
|
|||
nil, randomAccountSet("0x33", "0x44", "0x55"), nil)
|
||||
|
||||
// The output should be 11,33,44,55
|
||||
it, _ := snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{})
|
||||
it := newIterator(snaps, common.HexToHash("0x04"), (common.Hash{}))
|
||||
|
||||
// Do a quick check
|
||||
verifyIterator(t, 4, it, verifyAccount)
|
||||
it.Release()
|
||||
|
|
@ -759,6 +820,20 @@ func TestAccountIteratorDeletions(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestStorageIteratorDeletions(t *testing.T) {
|
||||
t.Run("fast", func(t *testing.T) {
|
||||
testStorageIteratorDeletions(t, func(snaps *Tree, root, account, seek common.Hash) StorageIterator {
|
||||
it, _ := snaps.StorageIterator(root, account, seek)
|
||||
return it
|
||||
})
|
||||
})
|
||||
t.Run("binary", func(t *testing.T) {
|
||||
testStorageIteratorDeletions(t, func(snaps *Tree, root, account, seek common.Hash) StorageIterator {
|
||||
return snaps.layers[root].(*diffLayer).newBinaryStorageIterator(account, seek)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func testStorageIteratorDeletions(t *testing.T, newIterator func(snaps *Tree, root, account, seek common.Hash) StorageIterator) {
|
||||
// Create an empty base layer and a snapshot tree out of it
|
||||
base := &diskLayer{
|
||||
diskdb: rawdb.NewMemoryDatabase(),
|
||||
|
|
@ -778,12 +853,12 @@ func TestStorageIteratorDeletions(t *testing.T) {
|
|||
randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x04", "0x06"}}, [][]string{{"0x01", "0x03"}}))
|
||||
|
||||
// The output should be 02,04,05,06
|
||||
it, _ := snaps.StorageIterator(common.HexToHash("0x03"), common.HexToHash("0xaa"), common.Hash{})
|
||||
it := newIterator(snaps, common.HexToHash("0x03"), common.HexToHash("0xaa"), common.Hash{})
|
||||
verifyIterator(t, 4, it, verifyStorage)
|
||||
it.Release()
|
||||
|
||||
// The output should be 04,05,06
|
||||
it, _ = snaps.StorageIterator(common.HexToHash("0x03"), common.HexToHash("0xaa"), common.HexToHash("0x03"))
|
||||
it = newIterator(snaps, common.HexToHash("0x03"), common.HexToHash("0xaa"), common.HexToHash("0x03"))
|
||||
verifyIterator(t, 3, it, verifyStorage)
|
||||
it.Release()
|
||||
|
||||
|
|
@ -793,7 +868,7 @@ func TestStorageIteratorDeletions(t *testing.T) {
|
|||
}
|
||||
snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), destructed, nil, nil)
|
||||
|
||||
it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{})
|
||||
it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{})
|
||||
verifyIterator(t, 0, it, verifyStorage)
|
||||
it.Release()
|
||||
|
||||
|
|
@ -802,17 +877,21 @@ func TestStorageIteratorDeletions(t *testing.T) {
|
|||
randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x07", "0x08", "0x09"}}, nil))
|
||||
|
||||
// The output should be 07,08,09
|
||||
it, _ = snaps.StorageIterator(common.HexToHash("0x05"), common.HexToHash("0xaa"), common.Hash{})
|
||||
|
||||
it = newIterator(snaps, common.HexToHash("0x05"), common.HexToHash("0xaa"), common.Hash{})
|
||||
verifyIterator(t, 3, it, verifyStorage)
|
||||
it.Release()
|
||||
|
||||
// Destruct the whole storage but re-create the account in the same layer
|
||||
snaps.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), destructed, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x11", "0x12"}}, nil))
|
||||
it, _ = snaps.StorageIterator(common.HexToHash("0x06"), common.HexToHash("0xaa"), common.Hash{})
|
||||
it = newIterator(snaps, common.HexToHash("0x06"), common.HexToHash("0xaa"), common.Hash{})
|
||||
verifyIterator(t, 2, it, verifyStorage) // The output should be 11,12
|
||||
it.Release()
|
||||
|
||||
verifyIterator(t, 2, snaps.Snapshot(common.HexToHash("0x06")).(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage)
|
||||
verifyIterator(t, 2, snaps.Snapshot(
|
||||
common.HexToHash("0x06")).(*diffLayer).
|
||||
newBinaryStorageIterator(common.HexToHash("0xaa"), common.Hash{}),
|
||||
verifyStorage)
|
||||
}
|
||||
|
||||
// BenchmarkAccountIteratorTraversal is a bit notorious -- all layers contain the
|
||||
|
|
@ -854,12 +933,12 @@ func BenchmarkAccountIteratorTraversal(b *testing.B) {
|
|||
// We call this once before the benchmark, so the creation of
|
||||
// sorted accountlists are not included in the results.
|
||||
head := snaps.Snapshot(common.HexToHash("0x65"))
|
||||
head.(*diffLayer).newBinaryAccountIterator()
|
||||
head.(*diffLayer).newBinaryAccountIterator(common.Hash{})
|
||||
|
||||
b.Run("binary iterator keys", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
got := 0
|
||||
it := head.(*diffLayer).newBinaryAccountIterator()
|
||||
it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{})
|
||||
for it.Next() {
|
||||
got++
|
||||
}
|
||||
|
|
@ -871,7 +950,7 @@ func BenchmarkAccountIteratorTraversal(b *testing.B) {
|
|||
b.Run("binary iterator values", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
got := 0
|
||||
it := head.(*diffLayer).newBinaryAccountIterator()
|
||||
it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{})
|
||||
for it.Next() {
|
||||
got++
|
||||
head.(*diffLayer).accountRLP(it.Hash(), 0)
|
||||
|
|
@ -951,12 +1030,12 @@ func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) {
|
|||
// We call this once before the benchmark, so the creation of
|
||||
// sorted accountlists are not included in the results.
|
||||
head := snaps.Snapshot(common.HexToHash("0x65"))
|
||||
head.(*diffLayer).newBinaryAccountIterator()
|
||||
head.(*diffLayer).newBinaryAccountIterator(common.Hash{})
|
||||
|
||||
b.Run("binary iterator (keys)", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
got := 0
|
||||
it := head.(*diffLayer).newBinaryAccountIterator()
|
||||
it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{})
|
||||
for it.Next() {
|
||||
got++
|
||||
}
|
||||
|
|
@ -968,7 +1047,7 @@ func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) {
|
|||
b.Run("binary iterator (values)", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
got := 0
|
||||
it := head.(*diffLayer).newBinaryAccountIterator()
|
||||
it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{})
|
||||
for it.Next() {
|
||||
got++
|
||||
v := it.Hash()
|
||||
|
|
@ -1013,7 +1092,7 @@ func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) {
|
|||
/*
|
||||
func BenchmarkBinaryAccountIteration(b *testing.B) {
|
||||
benchmarkAccountIteration(b, func(snap snapshot) AccountIterator {
|
||||
return snap.(*diffLayer).newBinaryAccountIterator()
|
||||
return snap.(*diffLayer).newBinaryAccountIterator(common.Hash{})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -416,7 +416,7 @@ func allBlobTxs(addr common.Address, config *params.ChainConfig) []txData {
|
|||
func newTestAccountManager(t *testing.T) (*accounts.Manager, accounts.Account) {
|
||||
var (
|
||||
dir = t.TempDir()
|
||||
am = accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: true})
|
||||
am = accounts.NewManager(nil)
|
||||
b = keystore.NewKeyStore(dir, 2, 1)
|
||||
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ type Config struct {
|
|||
// scrypt KDF at the expense of security.
|
||||
UseLightweightKDF bool `toml:",omitempty"`
|
||||
|
||||
// InsecureUnlockAllowed allows user to unlock accounts in unsafe http environment.
|
||||
// InsecureUnlockAllowed is a deprecated option to allow users to accounts in unsafe http environment.
|
||||
InsecureUnlockAllowed bool `toml:",omitempty"`
|
||||
|
||||
// NoUSB disables hardware wallet monitoring and connectivity.
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ func New(conf *Config) (*Node, error) {
|
|||
node.keyDirTemp = isEphem
|
||||
// Creates an empty AccountManager with no backends. Callers (e.g. cmd/geth)
|
||||
// are required to add the backends later on.
|
||||
node.accman = accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: conf.InsecureUnlockAllowed})
|
||||
node.accman = accounts.NewManager(nil)
|
||||
|
||||
// Initialize the p2p server. This creates the node key and discovery databases.
|
||||
node.server.Config.PrivateKey = node.config.NodeKey()
|
||||
|
|
|
|||
|
|
@ -184,9 +184,7 @@ func StartClefAccountManager(ksLocation string, nousb, lightKDF bool, scpath str
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clef doesn't allow insecure http account unlock.
|
||||
return accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: false}, backends...)
|
||||
return accounts.NewManager(nil, backends...)
|
||||
}
|
||||
|
||||
// MetadataFromContext extracts Metadata from a given context.Context
|
||||
|
|
|
|||
Loading…
Reference in a new issue