diff --git a/core/blockchain.go b/core/blockchain.go index 1b45a5ac39..b6a5b5d9fb 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}) + writeSize, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []rlp.RawValue{rlp.EmptyList}, nil) 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) + writeSize, err := rawdb.WriteAncientBlocks(bc.db, blockChain, receiptChain, nil) 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}) + _, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{bc.genesisBlock}, []rlp.RawValue{rlp.EmptyList}, nil) 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 a67db4bac1..7f042f4a8f 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -755,11 +755,15 @@ 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) (int64, error) { +func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts []rlp.RawValue, bals []rlp.RawValue) (int64, error) { return db.ModifyAncients(func(op ethdb.AncientWriteOp) error { for i, block := range blocks { header := block.Header() - if err := writeAncientBlock(op, block, header, receipts[i]); err != nil { + var bal rlp.RawValue + if bals != nil { + bal = bals[i] + } + if err := writeAncientBlock(op, block, header, receipts[i], bal); err != nil { return err } } @@ -767,7 +771,7 @@ func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts }) } -func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts rlp.RawValue) error { +func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts rlp.RawValue, bal 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) @@ -781,6 +785,9 @@ 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 } @@ -803,6 +810,9 @@ 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 }) @@ -811,6 +821,7 @@ 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) + DeleteBAL(db, hash, number) DeleteHeader(db, hash, number) DeleteBody(db, hash, number) } @@ -819,6 +830,7 @@ 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) + DeleteBAL(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 280fc21e8f..90e4903323 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -431,7 +431,7 @@ func TestAncientStorage(t *testing.T) { } // Write and verify the header in the database - WriteAncientBlocks(db, []*types.Block{block}, types.EncodeBlockReceiptLists([]types.Receipts{nil})) + WriteAncientBlocks(db, []*types.Block{block}, types.EncodeBlockReceiptLists([]types.Receipts{nil}), nil) if blob := ReadHeaderRLP(db, hash, number); len(blob) == 0 { t.Fatalf("no header returned") @@ -561,7 +561,7 @@ func BenchmarkWriteAncientBlocks(b *testing.B) { blocks := allBlocks[i : i+length] receipts := batchReceipts[:length] - writeSize, err := WriteAncientBlocks(db, blocks, types.EncodeBlockReceiptLists(receipts)) + writeSize, err := WriteAncientBlocks(db, blocks, types.EncodeBlockReceiptLists(receipts), nil) if err != nil { b.Fatal(err) } @@ -866,7 +866,7 @@ func TestHeadersRLPStorage(t *testing.T) { } receipts := make([]types.Receipts, 100) // Write first half to ancients - WriteAncientBlocks(db, chain[:50], types.EncodeBlockReceiptLists(receipts[:50])) + WriteAncientBlocks(db, chain[:50], types.EncodeBlockReceiptLists(receipts[:50]), nil) // Write second half to db for i := 50; i < 100; i++ { WriteCanonicalHash(db, chain[i].Hash(), chain[i].NumberU64()) diff --git a/core/rawdb/chain_freezer.go b/core/rawdb/chain_freezer.go index d33f7ce33d..f7d3c75343 100644 --- a/core/rawdb/chain_freezer.go +++ b/core/rawdb/chain_freezer.go @@ -327,6 +327,7 @@ 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 := ReadBALRLP(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) @@ -340,6 +341,9 @@ 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 71c78d506b..5d19bd5b36 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...))) + rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), types.EncodeBlockReceiptLists(append([]types.Receipts{{}}, receipts...)), nil) // 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) + rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), encReceipts, nil) // 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) + rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), encReceipts, nil) // Index the initial blocks from ancient store indexer := &txIndexer{