Skip to content

Commit 26951e3

Browse files
committed
same for traverse-rawstate
1 parent 92c0d0a commit 26951e3

File tree

1 file changed

+46
-48
lines changed

1 file changed

+46
-48
lines changed

cmd/geth/snapshot.go

Lines changed: 46 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ will traverse the whole state from the given state root and will abort if any
112112
referenced trie node or contract code is missing. This command can be used for
113113
state integrity verification. The default checking target is the HEAD state.
114114
115-
If accountHash or accountAddress is provided, traversal will start from that specific account.
115+
If accountHash or accountAddress is provided, traversal will start from that specific account and continue through all subsequent accounts.
116116
The format is auto-detected: 40/42 chars for address, 64/66 chars for hash.
117117
118118
It's also usable without snapshot enabled.
@@ -121,7 +121,7 @@ It's also usable without snapshot enabled.
121121
{
122122
Name: "traverse-rawstate",
123123
Usage: "Traverse the state with given root hash and perform detailed verification",
124-
ArgsUsage: "<root>",
124+
ArgsUsage: "<root> [accountHash|accountAddress]",
125125
Action: traverseRawState,
126126
Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
127127
Description: `
@@ -131,6 +131,9 @@ trie node or contract code is missing. This command can be used for state integr
131131
verification. The default checking target is the HEAD state. It's basically identical
132132
to traverse-state, but the check granularity is smaller.
133133
134+
If accountHash or accountAddress is provided, traversal will start from that specific account and continue through all subsequent accounts.
135+
The format is auto-detected: 40/42 chars for address, 64/66 chars for hash.
136+
134137
It's also usable without snapshot enabled.
135138
`,
136139
},
@@ -293,37 +296,15 @@ func traverseState(ctx *cli.Context) error {
293296
log.Error("Failed to load head block")
294297
return errors.New("no head block")
295298
}
296-
if ctx.NArg() > 2 {
297-
log.Error("Too many arguments given")
298-
return errors.New("too many arguments")
299+
300+
root, startKey, err := parseTraverseArgs(ctx)
301+
if err != nil {
302+
return err
299303
}
300-
var (
301-
root common.Hash
302-
startKey []byte
303-
err error
304-
)
305-
if ctx.NArg() >= 1 {
306-
root, err = parseRoot(ctx.Args().First())
307-
if err != nil {
308-
log.Error("Failed to resolve state root", "err", err)
309-
return err
310-
}
311-
} else {
304+
if root == (common.Hash{}) {
312305
root = headBlock.Root()
313306
}
314307

315-
if ctx.NArg() == 2 {
316-
arg := ctx.Args().Get(1)
317-
switch len(arg) {
318-
case 40, 42:
319-
startKey = crypto.Keccak256Hash(common.HexToAddress(arg).Bytes()).Bytes()
320-
case 64, 66:
321-
startKey = common.HexToHash(arg).Bytes()
322-
default:
323-
return errors.New("invalid account format: must be 40/42 chars for address or 64/66 chars for hash")
324-
}
325-
}
326-
327308
log.Info("Start traversing the state", "root", root.Hex(), "startKey", common.Bytes2Hex(startKey))
328309
t, err := trie.NewStateTrie(trie.StateTrieID(root), triedb)
329310
if err != nil {
@@ -397,6 +378,34 @@ func traverseState(ctx *cli.Context) error {
397378
return nil
398379
}
399380

381+
func parseTraverseArgs(ctx *cli.Context) (root common.Hash, startKey []byte, err error) {
382+
if ctx.NArg() > 2 {
383+
err = errors.New("too many arguments")
384+
return
385+
}
386+
387+
if ctx.NArg() >= 1 {
388+
root, err = parseRoot(ctx.Args().First())
389+
if err != nil {
390+
return
391+
}
392+
}
393+
394+
if ctx.NArg() == 2 {
395+
arg := ctx.Args().Get(1)
396+
switch len(arg) {
397+
case 40, 42:
398+
startKey = crypto.Keccak256Hash(common.HexToAddress(arg).Bytes()).Bytes()
399+
case 64, 66:
400+
startKey = common.HexToHash(arg).Bytes()
401+
default:
402+
err = errors.New("invalid account format: must be 40/42 chars for address or 64/66 chars for hash")
403+
return
404+
}
405+
}
406+
return root, startKey, nil
407+
}
408+
400409
// traverseRawState is a helper function used for pruning verification.
401410
// Basically it just iterates the trie, ensure all nodes and associated
402411
// contract codes are present. It's basically identical to traverseState
@@ -416,25 +425,14 @@ func traverseRawState(ctx *cli.Context) error {
416425
log.Error("Failed to load head block")
417426
return errors.New("no head block")
418427
}
419-
if ctx.NArg() > 1 {
420-
log.Error("Too many arguments given")
421-
return errors.New("too many arguments")
422-
}
423-
var (
424-
root common.Hash
425-
err error
426-
)
427-
if ctx.NArg() == 1 {
428-
root, err = parseRoot(ctx.Args().First())
429-
if err != nil {
430-
log.Error("Failed to resolve state root", "err", err)
431-
return err
432-
}
433-
log.Info("Start traversing the state", "root", root)
434-
} else {
435-
root = headBlock.Root()
436-
log.Info("Start traversing the state", "root", root, "number", headBlock.NumberU64())
428+
429+
root, startKey, err := parseTraverseArgs(ctx)
430+
if err != nil {
431+
log.Error("Failed to parse arguments", "err", err)
432+
return err
437433
}
434+
435+
log.Info("Start traversing the state", "root", root.Hex(), "startKey", common.Bytes2Hex(startKey))
438436
t, err := trie.NewStateTrie(trie.StateTrieID(root), triedb)
439437
if err != nil {
440438
log.Error("Failed to open trie", "root", root, "err", err)
@@ -450,7 +448,7 @@ func traverseRawState(ctx *cli.Context) error {
450448
hasher = crypto.NewKeccakState()
451449
got = make([]byte, 32)
452450
)
453-
accIter, err := t.NodeIterator(nil)
451+
accIter, err := t.NodeIterator(startKey)
454452
if err != nil {
455453
log.Error("Failed to open iterator", "root", root, "err", err)
456454
return err

0 commit comments

Comments
 (0)