mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 11:20:45 +00:00
cmd/geth: snapshot traverse-state by a start account
Signed-off-by: jsvisa <delweng@gmail.com>
This commit is contained in:
parent
1f7f95d718
commit
83330c144a
1 changed files with 26 additions and 9 deletions
|
|
@ -103,15 +103,18 @@ information about the specified address.
|
||||||
{
|
{
|
||||||
Name: "traverse-state",
|
Name: "traverse-state",
|
||||||
Usage: "Traverse the state with given root hash and perform quick verification",
|
Usage: "Traverse the state with given root hash and perform quick verification",
|
||||||
ArgsUsage: "<root>",
|
ArgsUsage: "<root> [accountHash|accountAddress]",
|
||||||
Action: traverseState,
|
Action: traverseState,
|
||||||
Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
|
Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
|
||||||
Description: `
|
Description: `
|
||||||
geth snapshot traverse-state <state-root>
|
geth snapshot traverse-state <state-root> [accountHash|accountAddress]
|
||||||
will traverse the whole state from the given state root and will abort if any
|
will traverse the whole state from the given state root and will abort if any
|
||||||
referenced trie node or contract code is missing. This command can be used for
|
referenced trie node or contract code is missing. This command can be used for
|
||||||
state integrity verification. The default checking target is the HEAD state.
|
state integrity verification. The default checking target is the HEAD state.
|
||||||
|
|
||||||
|
If accountHash or accountAddress is provided, traversal will start from that specific account.
|
||||||
|
The format is auto-detected: 40/42 chars for address, 64/66 chars for hash.
|
||||||
|
|
||||||
It's also usable without snapshot enabled.
|
It's also usable without snapshot enabled.
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|
@ -290,25 +293,38 @@ func traverseState(ctx *cli.Context) error {
|
||||||
log.Error("Failed to load head block")
|
log.Error("Failed to load head block")
|
||||||
return errors.New("no head block")
|
return errors.New("no head block")
|
||||||
}
|
}
|
||||||
if ctx.NArg() > 1 {
|
if ctx.NArg() > 2 {
|
||||||
log.Error("Too many arguments given")
|
log.Error("Too many arguments given")
|
||||||
return errors.New("too many arguments")
|
return errors.New("too many arguments")
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
root common.Hash
|
root common.Hash
|
||||||
err error
|
startKey []byte
|
||||||
|
err error
|
||||||
)
|
)
|
||||||
if ctx.NArg() == 1 {
|
if ctx.NArg() >= 1 {
|
||||||
root, err = parseRoot(ctx.Args().First())
|
root, err = parseRoot(ctx.Args().First())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to resolve state root", "err", err)
|
log.Error("Failed to resolve state root", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Info("Start traversing the state", "root", root)
|
|
||||||
} else {
|
} else {
|
||||||
root = headBlock.Root()
|
root = headBlock.Root()
|
||||||
log.Info("Start traversing the state", "root", root, "number", headBlock.NumberU64())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctx.NArg() == 2 {
|
||||||
|
arg := ctx.Args().Get(1)
|
||||||
|
switch len(arg) {
|
||||||
|
case 40, 42:
|
||||||
|
startKey = crypto.Keccak256Hash(common.HexToAddress(arg).Bytes()).Bytes()
|
||||||
|
case 64, 66:
|
||||||
|
startKey = common.HexToHash(arg).Bytes()
|
||||||
|
default:
|
||||||
|
return errors.New("invalid account format: must be 40/42 chars for address or 64/66 chars for hash")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Start traversing the state", "root", root.Hex(), "startKey", common.Bytes2Hex(startKey))
|
||||||
t, err := trie.NewStateTrie(trie.StateTrieID(root), triedb)
|
t, err := trie.NewStateTrie(trie.StateTrieID(root), triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to open trie", "root", root, "err", err)
|
log.Error("Failed to open trie", "root", root, "err", err)
|
||||||
|
|
@ -321,7 +337,8 @@ func traverseState(ctx *cli.Context) error {
|
||||||
lastReport time.Time
|
lastReport time.Time
|
||||||
start = time.Now()
|
start = time.Now()
|
||||||
)
|
)
|
||||||
acctIt, err := t.NodeIterator(nil)
|
|
||||||
|
acctIt, err := t.NodeIterator(startKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to open iterator", "root", root, "err", err)
|
log.Error("Failed to open iterator", "root", root, "err", err)
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue