@@ -368,36 +368,63 @@ func generateWitness(blockchain *core.BlockChain, block *types.Block) (*stateles
368368 if err := blockchain .Validator ().ValidateState (block , statedb , receipts , usedGas ); err != nil {
369369 return nil , fmt .Errorf ("failed to validate block %d: %w" , block .Number (), err )
370370 }
371- return witness , testWitness (blockchain , block , witness )
371+
372+ // FIXME: testWitness will fail from time to time, the problem is caused by occasional state root mismatch
373+ // after processing the block based on witness. We need to investigate the root cause and fix it.
374+ for retries := 0 ; retries < 5 ; retries ++ {
375+ if err = testWitness (blockchain , block , witness ); err == nil {
376+ return witness , nil
377+ } else {
378+ log .Warn ("Failed to validate witness" , "block" , block .Number (), "error" , err )
379+ }
380+ }
381+ return witness , err
372382}
373383
374384func testWitness (blockchain * core.BlockChain , block * types.Block , witness * stateless.Witness ) error {
375385 stateRoot := witness .Root ()
376- if diskRoot , _ := rawdb .ReadDiskStateRoot (blockchain .Database (), stateRoot ); diskRoot != (common.Hash {}) {
386+ diskRoot , err := rawdb .ReadDiskStateRoot (blockchain .Database (), stateRoot )
387+ if err != nil {
388+ return fmt .Errorf ("failed to read disk state root for stateRoot %s: %w" , stateRoot .Hex (), err )
389+ }
390+ if diskRoot != (common.Hash {}) {
391+ log .Debug ("Using disk root for state root" , "stateRoot" , stateRoot .Hex (), "diskRoot" , diskRoot .Hex ())
377392 stateRoot = diskRoot
378393 }
379394
380395 // Create and populate the state database to serve as the stateless backend
381396 statedb , err := state .New (stateRoot , state .NewDatabase (witness .MakeHashDB ()), nil )
382397 if err != nil {
383- return fmt .Errorf ("failed to create state database: %w" , err )
398+ return fmt .Errorf ("failed to create state database with stateRoot %s : %w" , stateRoot . Hex () , err )
384399 }
385400
386401 receipts , _ , usedGas , err := blockchain .Processor ().Process (block , statedb , * blockchain .GetVMConfig ())
387402 if err != nil {
388- return fmt .Errorf ("failed to process block %d: %w" , block .Number (), err )
403+ return fmt .Errorf ("failed to process block %d (hash : %s): % w" , block .Number (), block . Hash (). Hex (), err )
389404 }
390405
391406 if err := blockchain .Validator ().ValidateState (block , statedb , receipts , usedGas ); err != nil {
392- return fmt .Errorf ("failed to validate block %d: %w" , block .Number (), err )
407+ return fmt .Errorf ("failed to validate block %d (hash : %s): % w" , block .Number (), block . Hash (). Hex (), err )
393408 }
394409
395410 postStateRoot := block .Root ()
396- if diskRoot , _ := rawdb .ReadDiskStateRoot (blockchain .Database (), postStateRoot ); diskRoot != (common.Hash {}) {
411+ diskRoot , err = rawdb .ReadDiskStateRoot (blockchain .Database (), postStateRoot )
412+ if err != nil {
413+ return fmt .Errorf ("failed to read disk state root for postStateRoot %s: %w" , postStateRoot .Hex (), err )
414+ }
415+ if diskRoot != (common.Hash {}) {
416+ log .Debug ("Using disk root for post state root" , "postStateRoot" , postStateRoot .Hex (), "diskRoot" , diskRoot .Hex ())
397417 postStateRoot = diskRoot
398418 }
399- if statedb .GetRootHash () != postStateRoot {
400- return fmt .Errorf ("failed to commit statelessly %d: %w" , block .Number (), err )
419+ computedRoot := statedb .GetRootHash ()
420+ if computedRoot != postStateRoot {
421+ log .Debug ("State root mismatch" , "block" , block .Number (), "expected" , postStateRoot .Hex (), "got" , computedRoot )
422+ executionWitness := ToExecutionWitness (witness )
423+ jsonStr , err := json .Marshal (executionWitness )
424+ if err != nil {
425+ return fmt .Errorf ("state root mismatch after processing block %d (hash: %s): expected %s, got %s, but failed to marshal witness: %w" , block .Number (), block .Hash ().Hex (), postStateRoot .Hex (), computedRoot , err )
426+ }
427+ return fmt .Errorf ("state root mismatch after processing block %d (hash: %s): expected %s, got %s, witness: %s" , block .Number (), block .Hash ().Hex (), postStateRoot .Hex (), computedRoot , string (jsonStr ))
401428 }
402429 return nil
403430}
0 commit comments