@@ -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
2930const (
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
3638type 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.
7880type 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.
139147func (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