@@ -105,7 +105,7 @@ data, and verifies that all snapshot storage data has a corresponding account.
105105 },
106106 {
107107 Name : "traverse-state" ,
108- Usage : "Traverse the state with given root hash for verification" ,
108+ Usage : "Traverse the state with given root hash and perform quick verification" ,
109109 ArgsUsage : "<root>" ,
110110 Action : utils .MigrateFlags (traverseState ),
111111 Category : "MISCELLANEOUS COMMANDS" ,
@@ -121,7 +121,7 @@ It's also usable without snapshot enabled.
121121 },
122122 {
123123 Name : "traverse-rawstate" ,
124- Usage : "Traverse the state with given root hash for verification" ,
124+ Usage : "Traverse the state with given root hash and perform detailed verification" ,
125125 ArgsUsage : "<root>" ,
126126 Action : utils .MigrateFlags (traverseRawState ),
127127 Category : "MISCELLANEOUS COMMANDS" ,
@@ -367,6 +367,8 @@ func traverseRawState(ctx *cli.Context) error {
367367 codes int
368368 lastReport time.Time
369369 start = time .Now ()
370+ hasher = crypto .NewKeccakState ()
371+ got = make ([]byte , 32 )
370372 )
371373 accIter := t .NodeIterator (nil )
372374 for accIter .Next (true ) {
@@ -376,10 +378,18 @@ func traverseRawState(ctx *cli.Context) error {
376378 // Check the present for non-empty hash node(embedded node doesn't
377379 // have their own hash).
378380 if node != (common.Hash {}) {
379- if ! rawdb .HasTrieNode (chaindb , node ) {
381+ blob := rawdb .ReadTrieNode (chaindb , node )
382+ if len (blob ) == 0 {
380383 log .Error ("Missing trie node(account)" , "hash" , node )
381384 return errors .New ("missing account" )
382385 }
386+ hasher .Reset ()
387+ hasher .Write (blob )
388+ hasher .Read (got )
389+ if ! bytes .Equal (got , node .Bytes ()) {
390+ log .Error ("Invalid trie node(account)" , "hash" , node .Hex (), "value" , blob )
391+ return errors .New ("invalid account node" )
392+ }
383393 }
384394 // If it's a leaf node, yes we are touching an account,
385395 // dig into the storage trie further.
@@ -404,10 +414,18 @@ func traverseRawState(ctx *cli.Context) error {
404414 // Check the present for non-empty hash node(embedded node doesn't
405415 // have their own hash).
406416 if node != (common.Hash {}) {
407- if ! rawdb .HasTrieNode (chaindb , node ) {
417+ blob := rawdb .ReadTrieNode (chaindb , node )
418+ if len (blob ) == 0 {
408419 log .Error ("Missing trie node(storage)" , "hash" , node )
409420 return errors .New ("missing storage" )
410421 }
422+ hasher .Reset ()
423+ hasher .Write (blob )
424+ hasher .Read (got )
425+ if ! bytes .Equal (got , node .Bytes ()) {
426+ log .Error ("Invalid trie node(storage)" , "hash" , node .Hex (), "value" , blob )
427+ return errors .New ("invalid storage node" )
428+ }
411429 }
412430 // Bump the counter if it's leaf node.
413431 if storageIter .Leaf () {
0 commit comments