From 59f11516840bd86925bcd187837f54681c60f431 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Mon, 1 Aug 2022 16:13:43 +0200 Subject: [PATCH] core,eth: cache logs in blockchain --- core/blockchain.go | 5 +++++ core/blockchain_reader.go | 17 +++++++++++++++++ eth/api_backend.go | 12 +----------- eth/filters/filter.go | 4 ++++ 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 506034b539a76..22f6a97b1c11d 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -88,6 +88,7 @@ const ( bodyCacheLimit = 256 blockCacheLimit = 256 receiptsCacheLimit = 32 + logsCacheLimit = 32 txLookupCacheLimit = 1024 maxFutureBlocks = 256 maxTimeFutureBlocks = 30 @@ -198,6 +199,7 @@ type BlockChain struct { bodyCache *lru.Cache // Cache for the most recent block bodies bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format receiptsCache *lru.Cache // Cache for the most recent receipts per block + logsCache *lru.Cache // Cache for the most recent logs per block blockCache *lru.Cache // Cache for the most recent entire blocks txLookupCache *lru.Cache // Cache for the most recent transaction lookup data. futureBlocks *lru.Cache // future blocks are blocks added for later processing @@ -225,6 +227,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par bodyCache, _ := lru.New(bodyCacheLimit) bodyRLPCache, _ := lru.New(bodyCacheLimit) receiptsCache, _ := lru.New(receiptsCacheLimit) + logsCache, _ := lru.New(logsCacheLimit) blockCache, _ := lru.New(blockCacheLimit) txLookupCache, _ := lru.New(txLookupCacheLimit) futureBlocks, _ := lru.New(maxFutureBlocks) @@ -244,6 +247,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par bodyCache: bodyCache, bodyRLPCache: bodyRLPCache, receiptsCache: receiptsCache, + logsCache: logsCache, blockCache: blockCache, txLookupCache: txLookupCache, futureBlocks: futureBlocks, @@ -681,6 +685,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, root common.Hash, repair bo bc.bodyCache.Purge() bc.bodyRLPCache.Purge() bc.receiptsCache.Purge() + bc.logsCache.Purge() bc.blockCache.Purge() bc.txLookupCache.Purge() bc.futureBlocks.Purge() diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index 96e9f80b6aac3..dc3fd5b22df87 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -222,6 +222,23 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts { return receipts } +// GetLogsByHash retrieves the logs for all transactions in a given block. +func (bc *BlockChain) GetLogsByHash(hash common.Hash) [][]*types.Log { + if logs, ok := bc.logsCache.Get(hash); ok { + return logs.([][]*types.Log) + } + number := rawdb.ReadHeaderNumber(bc.db, hash) + if number == nil { + return nil + } + logs := rawdb.ReadLogs(bc.db, hash, *number, bc.chainConfig) + if logs == nil { + return nil + } + bc.logsCache.Add(hash, logs) + return logs +} + // 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/eth/api_backend.go b/eth/api_backend.go index 1d8ba8ea5cae0..eb312e89d8c91 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -19,7 +19,6 @@ package eth import ( "context" "errors" - "fmt" "math/big" "time" @@ -203,16 +202,7 @@ func (b *EthAPIBackend) GetReceipts(ctx context.Context, hash common.Hash) (type } func (b *EthAPIBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { - db := b.eth.ChainDb() - number := rawdb.ReadHeaderNumber(db, hash) - if number == nil { - return nil, fmt.Errorf("failed to get block number for hash %#x", hash) - } - logs := rawdb.ReadLogs(db, hash, *number, b.eth.blockchain.Config()) - if logs == nil { - return nil, fmt.Errorf("failed to get logs for block #%d (0x%s)", *number, hash.TerminalString()) - } - return logs, nil + return b.eth.blockchain.GetLogsByHash(hash), nil } func (b *EthAPIBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int { diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 9ff7ab7f55e1e..b009b90b5b0f6 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -19,6 +19,7 @@ package filters import ( "context" "errors" + "fmt" "math/big" "github.com/ethereum/go-ethereum/common" @@ -266,6 +267,9 @@ func (f *Filter) checkMatches(ctx context.Context, header *types.Header) (logs [ if err != nil { return nil, err } + if logsList == nil { + return nil, fmt.Errorf("failed to get logs for block #%d (0x%s)", header.Number.Uint64(), header.Hash().TerminalString()) + } var unfiltered []*types.Log for _, logs := range logsList { unfiltered = append(unfiltered, logs...)