Skip to content

Commit 444efa9

Browse files
committed
core: cache raw receipts of new heads separately
1 parent 0c5200b commit 444efa9

File tree

3 files changed

+31
-36
lines changed

3 files changed

+31
-36
lines changed

core/blockchain.go

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,24 +1616,8 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
16161616
blockBatch := bc.db.NewBatch()
16171617
rawdb.WriteBlock(blockBatch, block)
16181618
blockHash := block.Hash()
1619-
bc.blockCache.Add(blockHash, block)
16201619
rawdb.WriteReceipts(blockBatch, blockHash, block.NumberU64(), receipts)
1621-
if receipts != nil {
1622-
// ensure that receipts are cached in the exact same format as when reconstructed from database.
1623-
for _, receipt := range receipts {
1624-
if receipt.Logs == nil {
1625-
receipt.Logs = []*types.Log{}
1626-
}
1627-
}
1628-
var blobGasPrice *big.Int
1629-
if block.ExcessBlobGas() != nil {
1630-
blobGasPrice = eip4844.CalcBlobFee(bc.chainConfig, block.Header())
1631-
}
1632-
types.Receipts(receipts).DeriveFields(bc.chainConfig, blockHash, block.NumberU64(), block.Time(), block.BaseFee(), blobGasPrice, block.Transactions())
1633-
bc.receiptsCache.Add(blockHash, receipts)
1634-
} else {
1635-
bc.receiptsCache.Add(blockHash, []*types.Receipt{})
1636-
}
1620+
bc.indexServers.cacheRawReceipts(blockHash, receipts)
16371621
rawdb.WritePreimages(blockBatch, statedb.Preimages())
16381622
if err := blockBatch.Write(); err != nil {
16391623
log.Crit("Failed to write block into disk", "err", err)

core/blockchain_reader.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -266,14 +266,6 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
266266
if !ok {
267267
return nil
268268
}
269-
return bc.GetReceipts(hash, number)
270-
}
271-
272-
// GetReceipts retrieves the receipts for all transactions in a given block.
273-
func (bc *BlockChain) GetReceipts(hash common.Hash, number uint64) types.Receipts {
274-
if receipts, ok := bc.receiptsCache.Get(hash); ok {
275-
return receipts
276-
}
277269
header := bc.GetHeader(hash, number)
278270
if header == nil {
279271
return nil

core/index_server.go

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,17 @@ import (
2222
"time"
2323

2424
"github.com/ethereum/go-ethereum/common"
25+
"github.com/ethereum/go-ethereum/common/lru"
2526
"github.com/ethereum/go-ethereum/core/types"
2627
"github.com/ethereum/go-ethereum/log"
2728
)
2829

2930
const (
30-
busyDelay = time.Second // indexer status polling frequency when not ready
31-
maxHistoricPrefetch = 16 // size of block data pre-fetch queue
32-
logFrequency = time.Second * 20 // log info frequency during long indexing/unindexing process
33-
headLogDelay = time.Second // head indexing log info delay (do not log if finished faster)
31+
busyDelay = time.Second // indexer status polling frequency when not ready
32+
maxHistoricPrefetch = 16 // size of block data pre-fetch queue
33+
rawReceiptsCacheSize = 8
34+
logFrequency = time.Second * 20 // log info frequency during long indexing/unindexing process
35+
headLogDelay = time.Second // head indexing log info delay (do not log if finished faster)
3436
)
3537

3638
type Indexer interface {
@@ -76,9 +78,10 @@ type Indexer interface {
7678
// indexServers operates as a part of BlockChain and can serve multiple chain
7779
// indexers that implement the Indexer interface.
7880
type indexServers struct {
79-
lock sync.Mutex
80-
servers []*indexServer
81-
chain *BlockChain
81+
lock sync.Mutex
82+
servers []*indexServer
83+
chain *BlockChain
84+
rawReceiptsCache *lru.Cache[common.Hash, []*types.Receipt]
8285

8386
lastHead *types.Header
8487
lastHeadReceipts types.Receipts
@@ -96,6 +99,7 @@ func (f *indexServers) init(chain *BlockChain) {
9699
f.chain = chain
97100
f.lastHead = chain.CurrentBlock()
98101
f.closeCh = make(chan struct{})
102+
f.rawReceiptsCache = lru.NewCache[common.Hash, []*types.Receipt](rawReceiptsCacheSize)
99103
}
100104

101105
// stop shuts down all registered Indexers and their serving goroutines.
@@ -135,15 +139,24 @@ func (f *indexServers) register(indexer Indexer, name string) {
135139
go server.historicSendLoop()
136140
}
137141

142+
func (f *indexServers) cacheRawReceipts(blockHash common.Hash, blockReceipts types.Receipts) {
143+
f.rawReceiptsCache.Add(blockHash, blockReceipts)
144+
}
145+
138146
// broadcast sends a new head block to all registered Indexer instances.
139147
func (f *indexServers) broadcast(header *types.Header) {
140148
f.lock.Lock()
141149
defer f.lock.Unlock()
142150

143-
blockReceipts := f.chain.GetReceipts(header.Hash(), header.Number.Uint64())
151+
blockHash := header.Hash()
152+
blockReceipts, _ := f.rawReceiptsCache.Get(blockHash)
144153
if blockReceipts == nil {
145-
log.Error("Receipts belonging to new head are missing", "number", header.Number, "hash", header.Hash())
146-
return
154+
blockReceipts = f.chain.GetRawReceipts(blockHash, header.Number.Uint64())
155+
if blockReceipts == nil {
156+
log.Error("Receipts belonging to new head are missing", "number", header.Number, "hash", header.Hash())
157+
return
158+
}
159+
f.rawReceiptsCache.Add(blockHash, blockReceipts)
147160
}
148161
f.lastHead, f.lastHeadReceipts = header, blockReceipts
149162
for _, server := range f.servers {
@@ -499,7 +512,13 @@ func (s *indexServer) historicReadLoop() {
499512
// Send next item to the queue.
500513
bd := blockData{blockNumber: sendRange.First(), revertCount: status.revertCount}
501514
if bd.header = s.parent.chain.GetHeaderByNumber(bd.blockNumber); bd.header != nil {
502-
bd.receipts = s.parent.chain.GetReceipts(bd.header.Hash(), bd.blockNumber)
515+
blockHash := bd.header.Hash()
516+
bd.receipts, _ = s.parent.rawReceiptsCache.Get(blockHash)
517+
if bd.receipts == nil {
518+
bd.receipts = s.parent.chain.GetRawReceipts(blockHash, bd.blockNumber)
519+
// Note: we do not cache historical receipts because typically
520+
// each indexer requests them at different times.
521+
}
503522
}
504523
// Note that a response with missing block data is still sent in case of
505524
// a read error, signaling to the sender logic that something is missing.

0 commit comments

Comments
 (0)