From 34a09b1aaf23fcd1bb5665fa3a093775918c6781 Mon Sep 17 00:00:00 2001 From: jonny rhea <5555162+jrhea@users.noreply.github.com> Date: Mon, 23 Mar 2026 14:10:47 -0500 Subject: [PATCH] core/rawdb: remove BAL from chain freezer --- core/blockchain.go | 6 +-- core/rawdb/accessors_chain.go | 54 ++------------------ core/rawdb/accessors_chain_test.go | 82 ++---------------------------- core/rawdb/ancient_scheme.go | 4 -- core/rawdb/chain_freezer.go | 4 -- core/txindexer_test.go | 6 +-- 6 files changed, 14 insertions(+), 142 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index b6a5b5d9fb..1b45a5ac39 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1476,7 +1476,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ // Ensure genesis is in the ancient store if blockChain[0].NumberU64() == 1 { if frozen, _ := bc.db.Ancients(); frozen == 0 { - writeSize, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []rlp.RawValue{rlp.EmptyList}, nil) + writeSize, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []rlp.RawValue{rlp.EmptyList}) if err != nil { log.Error("Error writing genesis to ancients", "err", err) return 0, err @@ -1486,7 +1486,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ } } // Write all chain data to ancients. - writeSize, err := rawdb.WriteAncientBlocks(bc.db, blockChain, receiptChain, nil) + writeSize, err := rawdb.WriteAncientBlocks(bc.db, blockChain, receiptChain) if err != nil { log.Error("Error importing chain data to ancients", "err", err) return 0, err @@ -2907,7 +2907,7 @@ func (bc *BlockChain) InsertHeadersBeforeCutoff(headers []*types.Header) (int, e first = headers[0].Number.Uint64() ) if first == 1 && frozen == 0 { - _, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []rlp.RawValue{rlp.EmptyList}, nil) + _, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []rlp.RawValue{rlp.EmptyList}) if err != nil { log.Error("Error writing genesis to ancients", "err", err) return 0, err diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index f101bb150b..b2157bb695 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -611,41 +611,9 @@ func HasAccessList(db ethdb.Reader, hash common.Hash, number uint64) bool { return len(ReadAccessListRLP(db, hash, number)) > 0 } -// ReadAccessListRLP retrieves the RLP-encoded block access list for a block. +// ReadAccessListRLP retrieves the RLP-encoded block access list for a block from KV. func ReadAccessListRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { - var data []byte - err := db.ReadAncients(func(reader ethdb.AncientReaderOp) error { - if isCanon(reader, number, hash) { - data, _ = reader.Ancient(ChainFreezerBALTable, number) - return nil - } - data, _ = db.Get(balKey(number, hash)) - return nil - }) - if err != nil { - log.Crit("error reading from ancient store", "err", err) - } - return data -} - -// ReadCanonicalAccessListRLP retrieves the BAL RLP for the canonical block at number. -// Optionally takes the block hash to avoid looking it up. -func ReadCanonicalAccessListRLP(db ethdb.Reader, number uint64, hash *common.Hash) rlp.RawValue { - var data []byte - db.ReadAncients(func(reader ethdb.AncientReaderOp) error { - data, _ = reader.Ancient(ChainFreezerBALTable, number) - if len(data) > 0 { - return nil - } - // BAL is not in ancients, read from db by hash and number. - if hash != nil { - data, _ = db.Get(balKey(number, *hash)) - } else { - hashBytes, _ := db.Get(headerHashKey(number)) - data, _ = db.Get(balKey(number, common.BytesToHash(hashBytes))) - } - return nil - }) + data, _ := db.Get(balKey(number, hash)) return data } @@ -760,15 +728,11 @@ func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) { } // WriteAncientBlocks writes entire block data into ancient store and returns the total written size. -func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts []rlp.RawValue, bals []rlp.RawValue) (int64, error) { +func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts []rlp.RawValue) (int64, error) { return db.ModifyAncients(func(op ethdb.AncientWriteOp) error { for i, block := range blocks { header := block.Header() - var bal rlp.RawValue - if bals != nil { - bal = bals[i] - } - if err := writeAncientBlock(op, block, header, receipts[i], bal); err != nil { + if err := writeAncientBlock(op, block, header, receipts[i]); err != nil { return err } } @@ -776,7 +740,7 @@ func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts }) } -func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts rlp.RawValue, bal rlp.RawValue) error { +func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts rlp.RawValue) error { num := block.NumberU64() if err := op.AppendRaw(ChainFreezerHashTable, num, block.Hash().Bytes()); err != nil { return fmt.Errorf("can't add block %d hash: %v", num, err) @@ -790,9 +754,6 @@ func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *type if err := op.Append(ChainFreezerReceiptTable, num, receipts); err != nil { return fmt.Errorf("can't append block %d receipts: %v", num, err) } - if err := op.AppendRaw(ChainFreezerBALTable, num, bal); err != nil { - return fmt.Errorf("can't append block %d BAL: %v", num, err) - } return nil } @@ -815,9 +776,6 @@ func WriteAncientHeaderChain(db ethdb.AncientWriter, headers []*types.Header) (i if err := op.AppendRaw(ChainFreezerReceiptTable, num, nil); err != nil { return fmt.Errorf("can't append block %d receipts: %v", num, err) } - if err := op.AppendRaw(ChainFreezerBALTable, num, nil); err != nil { - return fmt.Errorf("can't append block %d BAL: %v", num, err) - } } return nil }) @@ -826,7 +784,6 @@ func WriteAncientHeaderChain(db ethdb.AncientWriter, headers []*types.Header) (i // DeleteBlock removes all block data associated with a hash. func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { DeleteReceipts(db, hash, number) - DeleteAccessList(db, hash, number) DeleteHeader(db, hash, number) DeleteBody(db, hash, number) } @@ -835,7 +792,6 @@ func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { // the hash to number mapping. func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { DeleteReceipts(db, hash, number) - DeleteAccessList(db, hash, number) deleteHeaderWithoutNumber(db, hash, number) DeleteBody(db, hash, number) } diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index 27413bb40a..e6a7bc6362 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -433,7 +433,7 @@ func TestAncientStorage(t *testing.T) { } // Write and verify the header in the database - WriteAncientBlocks(db, []*types.Block{block}, types.EncodeBlockReceiptLists([]types.Receipts{nil}), nil) + WriteAncientBlocks(db, []*types.Block{block}, types.EncodeBlockReceiptLists([]types.Receipts{nil})) if blob := ReadHeaderRLP(db, hash, number); len(blob) == 0 { t.Fatalf("no header returned") @@ -563,7 +563,7 @@ func BenchmarkWriteAncientBlocks(b *testing.B) { blocks := allBlocks[i : i+length] receipts := batchReceipts[:length] - writeSize, err := WriteAncientBlocks(db, blocks, types.EncodeBlockReceiptLists(receipts), nil) + writeSize, err := WriteAncientBlocks(db, blocks, types.EncodeBlockReceiptLists(receipts)) if err != nil { b.Fatal(err) } @@ -868,7 +868,7 @@ func TestHeadersRLPStorage(t *testing.T) { } receipts := make([]types.Receipts, 100) // Write first half to ancients - WriteAncientBlocks(db, chain[:50], types.EncodeBlockReceiptLists(receipts[:50]), nil) + WriteAncientBlocks(db, chain[:50], types.EncodeBlockReceiptLists(receipts[:50])) // Write second half to db for i := 50; i < 100; i++ { WriteCanonicalHash(db, chain[i].Hash(), chain[i].NumberU64()) @@ -977,80 +977,4 @@ func TestBALStorage(t *testing.T) { } } -// TestBALFreezer tests that BALs are frozen alongside other block data -// and can be read from the freezer. -func TestBALFreezer(t *testing.T) { - frdir := t.TempDir() - db, err := Open(NewMemoryDatabase(), OpenOptions{Ancient: frdir}) - if err != nil { - t.Fatalf("failed to create database with ancient backend: %v", err) - } - defer db.Close() - // Create a test block. - block := types.NewBlockWithHeader(&types.Header{ - Number: big.NewInt(0), - Extra: []byte("test block"), - UncleHash: types.EmptyUncleHash, - TxHash: types.EmptyTxsHash, - ReceiptHash: types.EmptyReceiptsHash, - }) - hash, number := block.Hash(), block.NumberU64() - - // Verify no BAL exists before writing. - if blob := ReadAccessListRLP(db, hash, number); len(blob) > 0 { - t.Fatalf("non existent BAL returned") - } - - // Write a BAL to KV first, then freeze. - balRLP, testBAL := makeTestBAL(t) - - // Freeze via WriteAncientBlocks. - WriteAncientBlocks(db, []*types.Block{block}, types.EncodeBlockReceiptLists([]types.Receipts{nil}), []rlp.RawValue{balRLP}) - - // Verify the BAL can be read from the freezer. - if blob := ReadAccessListRLP(db, hash, number); len(blob) == 0 { - t.Fatal("no BAL returned from freezer") - } - if b := ReadAccessList(db, hash, number); b == nil { - t.Fatal("ReadAccessList returned nil from freezer") - } else if b.Hash() != testBAL.Hash() { - t.Fatalf("frozen BAL hash mismatch: got %x, want %x", b.Hash(), testBAL.Hash()) - } - - // Verify ReadCanonicalAccessListRLP works. - if blob := ReadCanonicalAccessListRLP(db, number, &hash); len(blob) == 0 { - t.Fatal("ReadCanonicalAccessListRLP returned empty for frozen block") - } -} - -// TestBALEmptyFreezer tests that pre-EIP-8189 blocks without BALs have empty -// freezer entries. -func TestBALEmptyFreezer(t *testing.T) { - frdir := t.TempDir() - db, err := Open(NewMemoryDatabase(), OpenOptions{Ancient: frdir}) - if err != nil { - t.Fatalf("failed to create database with ancient backend: %v", err) - } - defer db.Close() - - // Create and freeze a block with no BAL. - block := types.NewBlockWithHeader(&types.Header{ - Number: big.NewInt(0), - Extra: []byte("no bal block"), - UncleHash: types.EmptyUncleHash, - TxHash: types.EmptyTxsHash, - ReceiptHash: types.EmptyReceiptsHash, - }) - hash, number := block.Hash(), block.NumberU64() - - WriteAncientBlocks(db, []*types.Block{block}, types.EncodeBlockReceiptLists([]types.Receipts{nil}), nil) - - // HasAccessList should return false for a block with an empty freezer entry. - if HasAccessList(db, hash, number) { - t.Fatal("HasAccessList returned true for block with no BAL") - } - if b := ReadAccessList(db, hash, number); b != nil { - t.Fatalf("ReadAccessList returned non-nil for block with no BAL: %v", b) - } -} diff --git a/core/rawdb/ancient_scheme.go b/core/rawdb/ancient_scheme.go index 0fd5435082..afec7848c8 100644 --- a/core/rawdb/ancient_scheme.go +++ b/core/rawdb/ancient_scheme.go @@ -35,9 +35,6 @@ const ( // ChainFreezerReceiptTable indicates the name of the freezer receipts table. ChainFreezerReceiptTable = "receipts" - - // ChainFreezerBALTable indicates the name of the freezer block access list table. - ChainFreezerBALTable = "bals" ) // chainFreezerTableConfigs configures the settings for tables in the chain freezer. @@ -49,7 +46,6 @@ var chainFreezerTableConfigs = map[string]freezerTableConfig{ ChainFreezerHashTable: {noSnappy: true, prunable: false}, ChainFreezerBodiesTable: {noSnappy: false, prunable: true}, ChainFreezerReceiptTable: {noSnappy: false, prunable: true}, - ChainFreezerBALTable: {noSnappy: false, prunable: true}, } // freezerTableConfig contains the settings for a freezer table. diff --git a/core/rawdb/chain_freezer.go b/core/rawdb/chain_freezer.go index 917014ec5d..d33f7ce33d 100644 --- a/core/rawdb/chain_freezer.go +++ b/core/rawdb/chain_freezer.go @@ -327,7 +327,6 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash if len(receipts) == 0 { return fmt.Errorf("block receipts missing, can't freeze block %d", number) } - bal := ReadAccessListRLP(nfdb, hash, number) // Write to the batch. if err := op.AppendRaw(ChainFreezerHashTable, number, hash[:]); err != nil { return fmt.Errorf("can't write hash to Freezer: %v", err) @@ -341,9 +340,6 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash if err := op.AppendRaw(ChainFreezerReceiptTable, number, receipts); err != nil { return fmt.Errorf("can't write receipts to Freezer: %v", err) } - if err := op.AppendRaw(ChainFreezerBALTable, number, bal); err != nil { - return fmt.Errorf("can't write BAL to Freezer: %v", err) - } hashes = append(hashes, hash) } return nil diff --git a/core/txindexer_test.go b/core/txindexer_test.go index 5d19bd5b36..71c78d506b 100644 --- a/core/txindexer_test.go +++ b/core/txindexer_test.go @@ -117,7 +117,7 @@ func TestTxIndexer(t *testing.T) { } for _, c := range cases { db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) - rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), types.EncodeBlockReceiptLists(append([]types.Receipts{{}}, receipts...)), nil) + rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), types.EncodeBlockReceiptLists(append([]types.Receipts{{}}, receipts...))) // Index the initial blocks from ancient store indexer := &txIndexer{ @@ -237,7 +237,7 @@ func TestTxIndexerRepair(t *testing.T) { for _, c := range cases { db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) encReceipts := types.EncodeBlockReceiptLists(append([]types.Receipts{{}}, receipts...)) - rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), encReceipts, nil) + rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), encReceipts) // Index the initial blocks from ancient store indexer := &txIndexer{ @@ -428,7 +428,7 @@ func TestTxIndexerReport(t *testing.T) { for _, c := range cases { db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) encReceipts := types.EncodeBlockReceiptLists(append([]types.Receipts{{}}, receipts...)) - rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), encReceipts, nil) + rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), encReceipts) // Index the initial blocks from ancient store indexer := &txIndexer{