mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-24 08:49:29 +00:00
core/blockchain.go: cleanup finalized block on rewind in setHeadBeyondRoot (#33486)
Fix #33390 `setHeadBeyondRoot` was failing to invalidate finalized blocks because it compared against the original head instead of the rewound root. This fix updates the comparison to use the post-rewind block number, preventing the node from reporting a finalized block that no longer exists. Also added relevant test cases for it.
This commit is contained in:
parent
b2843a11d6
commit
32fea008d8
2 changed files with 45 additions and 2 deletions
|
|
@ -1105,11 +1105,12 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
|
||||||
bc.txLookupCache.Purge()
|
bc.txLookupCache.Purge()
|
||||||
|
|
||||||
// Clear safe block, finalized block if needed
|
// Clear safe block, finalized block if needed
|
||||||
if safe := bc.CurrentSafeBlock(); safe != nil && head < safe.Number.Uint64() {
|
headBlock := bc.CurrentBlock()
|
||||||
|
if safe := bc.CurrentSafeBlock(); safe != nil && headBlock.Number.Uint64() < safe.Number.Uint64() {
|
||||||
log.Warn("SetHead invalidated safe block")
|
log.Warn("SetHead invalidated safe block")
|
||||||
bc.SetSafe(nil)
|
bc.SetSafe(nil)
|
||||||
}
|
}
|
||||||
if finalized := bc.CurrentFinalBlock(); finalized != nil && head < finalized.Number.Uint64() {
|
if finalized := bc.CurrentFinalBlock(); finalized != nil && headBlock.Number.Uint64() < finalized.Number.Uint64() {
|
||||||
log.Error("SetHead invalidated finalized block")
|
log.Error("SetHead invalidated finalized block")
|
||||||
bc.SetFinalized(nil)
|
bc.SetFinalized(nil)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4515,3 +4515,45 @@ func TestGetCanonicalReceipt(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestSetHeadBeyondRootFinalizedBug tests the issue where the finalized block
|
||||||
|
// is not cleared when rewinding past it using setHeadBeyondRoot.
|
||||||
|
func TestSetHeadBeyondRootFinalizedBug(t *testing.T) {
|
||||||
|
// Create a clean blockchain with 100 blocks using PathScheme (PBSS)
|
||||||
|
_, _, blockchain, err := newCanonical(ethash.NewFaker(), 100, true, rawdb.PathScheme)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create pristine chain: %v", err)
|
||||||
|
}
|
||||||
|
defer blockchain.Stop()
|
||||||
|
|
||||||
|
// Set the "Finalized" marker to the current Head (Block 100)
|
||||||
|
headBlock := blockchain.CurrentBlock()
|
||||||
|
if headBlock.Number.Uint64() != 100 {
|
||||||
|
t.Fatalf("Setup failed: expected head 100, got %d", headBlock.Number.Uint64())
|
||||||
|
}
|
||||||
|
blockchain.SetFinalized(headBlock)
|
||||||
|
|
||||||
|
// Verify setup
|
||||||
|
if blockchain.CurrentFinalBlock().Number.Uint64() != 100 {
|
||||||
|
t.Fatalf("Setup failed: Finalized block should be 100")
|
||||||
|
}
|
||||||
|
targetBlock := blockchain.GetBlockByNumber(50)
|
||||||
|
|
||||||
|
// Call setHeadBeyondRoot with:
|
||||||
|
// head = 100
|
||||||
|
// repair = true
|
||||||
|
if _, err := blockchain.setHeadBeyondRoot(100, 0, targetBlock.Root(), true); err != nil {
|
||||||
|
t.Fatalf("Failed to rewind: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
currentFinal := blockchain.CurrentFinalBlock()
|
||||||
|
currentHead := blockchain.CurrentBlock().Number.Uint64()
|
||||||
|
|
||||||
|
// The previous finalized block (100) is now invalid because we rewound to 50.
|
||||||
|
// The function should have cleared the finalized marker (set to nil).
|
||||||
|
if currentFinal != nil && currentFinal.Number.Uint64() > currentHead {
|
||||||
|
t.Errorf("Chain Head: %d , Finalized Block: %d , Finalized block was >= head block.",
|
||||||
|
currentHead,
|
||||||
|
currentFinal.Number.Uint64())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue