mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-08 09:11:34 +00:00
same for traverse-rawstate
Signed-off-by: jsvisa <delweng@gmail.com>
This commit is contained in:
parent
83330c144a
commit
cd54a41336
1 changed files with 47 additions and 49 deletions
|
|
@ -112,7 +112,7 @@ 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.
|
If accountHash or accountAddress is provided, traversal will start from that specific account and continue through all subsequent accounts.
|
||||||
The format is auto-detected: 40/42 chars for address, 64/66 chars for hash.
|
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.
|
||||||
|
|
@ -121,7 +121,7 @@ It's also usable without snapshot enabled.
|
||||||
{
|
{
|
||||||
Name: "traverse-rawstate",
|
Name: "traverse-rawstate",
|
||||||
Usage: "Traverse the state with given root hash and perform detailed verification",
|
Usage: "Traverse the state with given root hash and perform detailed verification",
|
||||||
ArgsUsage: "<root>",
|
ArgsUsage: "<root> [accountHash|accountAddress]",
|
||||||
Action: traverseRawState,
|
Action: traverseRawState,
|
||||||
Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
|
Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
|
||||||
Description: `
|
Description: `
|
||||||
|
|
@ -131,6 +131,9 @@ trie node or contract code is missing. This command can be used for state integr
|
||||||
verification. The default checking target is the HEAD state. It's basically identical
|
verification. The default checking target is the HEAD state. It's basically identical
|
||||||
to traverse-state, but the check granularity is smaller.
|
to traverse-state, but the check granularity is smaller.
|
||||||
|
|
||||||
|
If accountHash or accountAddress is provided, traversal will start from that specific account and continue through all subsequent accounts.
|
||||||
|
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.
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|
@ -293,35 +296,13 @@ 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() > 2 {
|
|
||||||
log.Error("Too many arguments given")
|
|
||||||
return errors.New("too many arguments")
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
root common.Hash
|
|
||||||
startKey []byte
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if ctx.NArg() >= 1 {
|
|
||||||
root, err = parseRoot(ctx.Args().First())
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Failed to resolve state root", "err", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
root = headBlock.Root()
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctx.NArg() == 2 {
|
root, startKey, err := parseTraverseArgs(ctx)
|
||||||
arg := ctx.Args().Get(1)
|
if err != nil {
|
||||||
switch len(arg) {
|
return err
|
||||||
case 40, 42:
|
}
|
||||||
startKey = crypto.Keccak256Hash(common.HexToAddress(arg).Bytes()).Bytes()
|
if root == (common.Hash{}) {
|
||||||
case 64, 66:
|
root = headBlock.Root()
|
||||||
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))
|
log.Info("Start traversing the state", "root", root.Hex(), "startKey", common.Bytes2Hex(startKey))
|
||||||
|
|
@ -397,6 +378,34 @@ func traverseState(ctx *cli.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseTraverseArgs(ctx *cli.Context) (root common.Hash, startKey []byte, err error) {
|
||||||
|
if ctx.NArg() > 2 {
|
||||||
|
err = errors.New("too many arguments")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.NArg() >= 1 {
|
||||||
|
root, err = parseRoot(ctx.Args().First())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
err = errors.New("invalid account format: must be 40/42 chars for address or 64/66 chars for hash")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root, startKey, nil
|
||||||
|
}
|
||||||
|
|
||||||
// traverseRawState is a helper function used for pruning verification.
|
// traverseRawState is a helper function used for pruning verification.
|
||||||
// Basically it just iterates the trie, ensure all nodes and associated
|
// Basically it just iterates the trie, ensure all nodes and associated
|
||||||
// contract codes are present. It's basically identical to traverseState
|
// contract codes are present. It's basically identical to traverseState
|
||||||
|
|
@ -416,25 +425,14 @@ func traverseRawState(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 {
|
|
||||||
log.Error("Too many arguments given")
|
root, startKey, err := parseTraverseArgs(ctx)
|
||||||
return errors.New("too many arguments")
|
if err != nil {
|
||||||
}
|
log.Error("Failed to parse arguments", "err", err)
|
||||||
var (
|
return err
|
||||||
root common.Hash
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if ctx.NArg() == 1 {
|
|
||||||
root, err = parseRoot(ctx.Args().First())
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Failed to resolve state root", "err", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Info("Start traversing the state", "root", root)
|
|
||||||
} else {
|
|
||||||
root = headBlock.Root()
|
|
||||||
log.Info("Start traversing the state", "root", root, "number", headBlock.NumberU64())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
@ -450,7 +448,7 @@ func traverseRawState(ctx *cli.Context) error {
|
||||||
hasher = crypto.NewKeccakState()
|
hasher = crypto.NewKeccakState()
|
||||||
got = make([]byte, 32)
|
got = make([]byte, 32)
|
||||||
)
|
)
|
||||||
accIter, err := t.NodeIterator(nil)
|
accIter, 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