Skip to content

Commit 2ff8403

Browse files
authored
fix: add failure retries in testWitness (#1158)
* add more logs in testWitness * bump version * add more logs * use statedb.IntermediateRoot * add retries * add more retries * remove root compute retries * tweak * add a fixme * print error
1 parent ca9d539 commit 2ff8403

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

eth/api.go

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

374384
func 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
}

params/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
const (
2525
VersionMajor = 5 // Major version component of the current release
2626
VersionMinor = 8 // Minor version component of the current release
27-
VersionPatch = 31 // Patch version component of the current release
27+
VersionPatch = 32 // Patch version component of the current release
2828
VersionMeta = "mainnet" // Version metadata to append to the version string
2929
)
3030

0 commit comments

Comments
 (0)