From 5fc2ef2f10a53b0fe059036503826567fd8c5768 Mon Sep 17 00:00:00 2001 From: jeevan-sid Date: Tue, 3 Feb 2026 15:25:52 +0530 Subject: [PATCH] fix: cleanup txloopup --- core/blockchain.go | 7 ++++++- core/blockchain_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/core/blockchain.go b/core/blockchain.go index 6f1db96463..99e294a63f 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1085,10 +1085,15 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha // Remove the associated body and receipts from the key-value store. // The header, hash-to-number mapping, and canonical hash will be // removed by the hc.SetHead function. + if body := rawdb.ReadBody(bc.db, hash, num); body != nil { + for _, tx := range body.Transactions { + rawdb.DeleteTxLookupEntry(db, tx.Hash()) + } + } rawdb.DeleteBody(db, hash, num) rawdb.DeleteReceipts(db, hash, num) } - // Todo(rjl493456442) txlookup, log index, etc + // Todo(rjl493456442) log index, etc } // If SetHead was only called as a chain reparation method, try to skip // touching the header chain altogether, unless the freezer is broken diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 73ffce93fb..4c7b0e9f8e 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -4557,3 +4557,38 @@ func TestSetHeadBeyondRootFinalizedBug(t *testing.T) { currentFinal.Number.Uint64()) } } + +// TestSetHeadTxLookupCleanup tests that rewinding the chain correctly cleans up +// transaction lookup entries (indices) +func TestSetHeadTxLookupCleanup(t *testing.T) { + // Create a clean blockchain with 100 blocks + _, _, blockchain, err := newCanonical(ethash.NewFaker(), 100, true, rawdb.PathScheme) + if err != nil { + t.Fatalf("failed to create pristine chain: %v", err) + } + defer blockchain.Stop() + + // The default newCanonical blocks are empty (no txs). + // Manually overwrite Block 100's body to include a transaction. + headBlock := blockchain.CurrentBlock() + tx := types.NewTransaction(0, common.Address{0x01}, big.NewInt(0), 0, big.NewInt(0), nil) + txHash := tx.Hash() + body := &types.Body{Transactions: []*types.Transaction{tx}} + + rawdb.WriteBody(blockchain.db, headBlock.Hash(), headBlock.Number.Uint64(), body) + txHashes := []common.Hash{txHash} + rawdb.WriteTxLookupEntries(blockchain.db, headBlock.Number.Uint64(), txHashes) + + if entry := rawdb.ReadTxLookupEntry(blockchain.db, txHash); entry == nil { + t.Fatalf("Setup failed: TxLookup entry was not written to DB") + } + + targetBlock := blockchain.GetBlockByNumber(50) + if _, err := blockchain.setHeadBeyondRoot(50, 0, targetBlock.Root(), false); err != nil { + t.Fatalf("Failed to rewind: %v", err) + } + + if entry := rawdb.ReadTxLookupEntry(blockchain.db, txHash); entry != nil { + t.Errorf("FAIL: TxLookup entry still exists after rewind! Tx is still pointing to block %d", *entry) + } +}