From 73b1ff2cd4d89f399dfd7bf59393baad97e03b80 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Fri, 25 Apr 2025 17:34:50 +0200 Subject: [PATCH 1/2] core/filtermaps: do not derive full receipts during rendering --- core/blockchain_reader.go | 8 ++++++++ core/filtermaps/chain_view.go | 12 ++++++++++++ core/filtermaps/indexer_test.go | 7 +++++++ core/filtermaps/map_renderer.go | 4 ++-- eth/filters/filter_system_test.go | 7 +++++++ 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index a8c2e26d18b..b4ba5d9fd88 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -234,6 +234,14 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts { return receipts } +func (bc *BlockChain) GetRawReceiptsByHash(hash common.Hash) types.Receipts { + number := rawdb.ReadHeaderNumber(bc.db, hash) + if number == nil { + return nil + } + return rawdb.ReadRawReceipts(bc.db, hash, *number) +} + // GetUnclesInChain retrieves all the uncles from a given block backwards until // a specific distance is reached. func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header { diff --git a/core/filtermaps/chain_view.go b/core/filtermaps/chain_view.go index aa74f3901a4..2cc87670a79 100644 --- a/core/filtermaps/chain_view.go +++ b/core/filtermaps/chain_view.go @@ -29,6 +29,7 @@ type blockchain interface { GetHeader(hash common.Hash, number uint64) *types.Header GetCanonicalHash(number uint64) common.Hash GetReceiptsByHash(hash common.Hash) types.Receipts + GetRawReceiptsByHash(hash common.Hash) types.Receipts } // ChainView represents an immutable view of a chain with a block id and a set @@ -106,6 +107,17 @@ func (cv *ChainView) Receipts(number uint64) types.Receipts { return cv.chain.GetReceiptsByHash(blockHash) } +// RawReceipts returns the set of receipts belonging to the block at the given +// block number. Does not derive the fields of the receipts, should only be +// used during creation of the filter maps, please use cv.Receipts during querying. +func (cv *ChainView) RawReceipts(number uint64) types.Receipts { + blockHash := cv.BlockHash(number) + if blockHash == (common.Hash{}) { + log.Error("Chain view: block hash unavailable", "number", number, "head", cv.headNumber) + } + return cv.chain.GetRawReceiptsByHash(blockHash) +} + // SharedRange returns the block range shared by two chain views. func (cv *ChainView) SharedRange(cv2 *ChainView) common.Range[uint64] { cv.lock.Lock() diff --git a/core/filtermaps/indexer_test.go b/core/filtermaps/indexer_test.go index e60130ba4bd..2782b2cbe6b 100644 --- a/core/filtermaps/indexer_test.go +++ b/core/filtermaps/indexer_test.go @@ -515,6 +515,13 @@ func (tc *testChain) GetReceiptsByHash(hash common.Hash) types.Receipts { return tc.receipts[hash] } +func (tc *testChain) GetRawReceiptsByHash(hash common.Hash) types.Receipts { + tc.lock.RLock() + defer tc.lock.RUnlock() + + return tc.receipts[hash] +} + func (tc *testChain) addBlocks(count, maxTxPerBlock, maxLogsPerReceipt, maxTopicsPerLog int, random bool) { tc.lock.Lock() blockGen := func(i int, gen *core.BlockGen) { diff --git a/core/filtermaps/map_renderer.go b/core/filtermaps/map_renderer.go index f59a01c032a..74baec6a1a5 100644 --- a/core/filtermaps/map_renderer.go +++ b/core/filtermaps/map_renderer.go @@ -693,7 +693,7 @@ func (f *FilterMaps) newLogIteratorFromMapBoundary(mapIndex uint32, startBlock, return nil, fmt.Errorf("iterator entry point %d after target chain head block %d", startBlock, f.targetView.HeadNumber()) } // get block receipts - receipts := f.targetView.Receipts(startBlock) + receipts := f.targetView.RawReceipts(startBlock) if receipts == nil { return nil, fmt.Errorf("receipts not found for start block %d", startBlock) } @@ -760,7 +760,7 @@ func (l *logIterator) next() error { if l.delimiter { l.delimiter = false l.blockNumber++ - l.receipts = l.chainView.Receipts(l.blockNumber) + l.receipts = l.chainView.RawReceipts(l.blockNumber) if l.receipts == nil { return fmt.Errorf("receipts not found for block %d", l.blockNumber) } diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index fa5d4fe8973..122bdaeda42 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -80,6 +80,13 @@ func (b *testBackend) GetReceiptsByHash(hash common.Hash) types.Receipts { return r } +func (b *testBackend) GetRawReceiptsByHash(hash common.Hash) types.Receipts { + if number := rawdb.ReadHeaderNumber(b.db, hash); number != nil { + return rawdb.ReadRawReceipts(b.db, hash, *number) + } + return nil +} + func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) { var ( hash common.Hash From 7c59af10444f4df758a69c99fe62d883396cbb44 Mon Sep 17 00:00:00 2001 From: Gary Rong Date: Wed, 30 Apr 2025 11:19:58 +0800 Subject: [PATCH 2/2] core/filtermaps: polish --- core/filtermaps/chain_view.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/filtermaps/chain_view.go b/core/filtermaps/chain_view.go index 2cc87670a79..63df2cfb6d2 100644 --- a/core/filtermaps/chain_view.go +++ b/core/filtermaps/chain_view.go @@ -103,6 +103,7 @@ func (cv *ChainView) Receipts(number uint64) types.Receipts { blockHash := cv.BlockHash(number) if blockHash == (common.Hash{}) { log.Error("Chain view: block hash unavailable", "number", number, "head", cv.headNumber) + return nil } return cv.chain.GetReceiptsByHash(blockHash) } @@ -114,6 +115,7 @@ func (cv *ChainView) RawReceipts(number uint64) types.Receipts { blockHash := cv.BlockHash(number) if blockHash == (common.Hash{}) { log.Error("Chain view: block hash unavailable", "number", number, "head", cv.headNumber) + return nil } return cv.chain.GetRawReceiptsByHash(blockHash) }