1
0
Fork 0
forked from forks/go-ethereum

core/filtermaps: do not derive full receipts during rendering (#31716)

This changes the filtermaps to only pull up the raw receipts, not the
derived receipts which saves a lot of allocations.

During normal execution this will reduce the allocations of the whole
geth node by ~15%.
This commit is contained in:
Marius van der Wijden 2025-04-30 09:23:08 +02:00 committed by GitHub
parent 21341f6c0b
commit 7612872761
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 38 additions and 2 deletions

View file

@ -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 {

View file

@ -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
@ -102,10 +103,23 @@ 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)
}
// 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 nil
}
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()

View file

@ -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) {

View file

@ -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)
}

View file

@ -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