aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Schneider <ryanleeschneider@gmail.com>2018-09-30 04:53:31 +0800
committerFelix Lange <fjl@users.noreply.github.com>2018-09-30 04:53:31 +0800
commitb69942befeb9f1af55cad0f91953bdaea2ea3efb (patch)
tree0a2e4253e4ab715ae42f272009446cb1a75ba9e9
parent86ec213076ac52a7b427a0fb25994bfb4e78720b (diff)
downloaddexon-b69942befeb9f1af55cad0f91953bdaea2ea3efb.tar.gz
dexon-b69942befeb9f1af55cad0f91953bdaea2ea3efb.tar.zst
dexon-b69942befeb9f1af55cad0f91953bdaea2ea3efb.zip
core, internal/ethapi: add and use LRU cache for receipts (#17610)
-rw-r--r--core/blockchain.go24
-rw-r--r--eth/api_backend.go12
2 files changed, 20 insertions, 16 deletions
diff --git a/core/blockchain.go b/core/blockchain.go
index fe961e0c4..f4a818f4c 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -55,6 +55,7 @@ var (
const (
bodyCacheLimit = 256
blockCacheLimit = 256
+ receiptsCacheLimit = 32
maxFutureBlocks = 256
maxTimeFutureBlocks = 30
badBlockLimit = 10
@@ -111,11 +112,12 @@ type BlockChain struct {
currentBlock atomic.Value // Current head of the block chain
currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!)
- stateCache state.Database // State database to reuse between imports (contains state cache)
- bodyCache *lru.Cache // Cache for the most recent block bodies
- bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format
- blockCache *lru.Cache // Cache for the most recent entire blocks
- futureBlocks *lru.Cache // future blocks are blocks added for later processing
+ stateCache state.Database // State database to reuse between imports (contains state cache)
+ 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
+ blockCache *lru.Cache // Cache for the most recent entire blocks
+ futureBlocks *lru.Cache // future blocks are blocks added for later processing
quit chan struct{} // blockchain quit channel
running int32 // running must be called atomically
@@ -144,6 +146,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
}
bodyCache, _ := lru.New(bodyCacheLimit)
bodyRLPCache, _ := lru.New(bodyCacheLimit)
+ receiptsCache, _ := lru.New(receiptsCacheLimit)
blockCache, _ := lru.New(blockCacheLimit)
futureBlocks, _ := lru.New(maxFutureBlocks)
badBlocks, _ := lru.New(badBlockLimit)
@@ -158,6 +161,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
shouldPreserve: shouldPreserve,
bodyCache: bodyCache,
bodyRLPCache: bodyRLPCache,
+ receiptsCache: receiptsCache,
blockCache: blockCache,
futureBlocks: futureBlocks,
engine: engine,
@@ -280,6 +284,7 @@ func (bc *BlockChain) SetHead(head uint64) error {
// Clear out any stale content from the caches
bc.bodyCache.Purge()
bc.bodyRLPCache.Purge()
+ bc.receiptsCache.Purge()
bc.blockCache.Purge()
bc.futureBlocks.Purge()
@@ -603,11 +608,18 @@ func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
// GetReceiptsByHash retrieves the receipts for all transactions in a given block.
func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
+ if receipts, ok := bc.receiptsCache.Get(hash); ok {
+ return receipts.(types.Receipts)
+ }
+
number := rawdb.ReadHeaderNumber(bc.db, hash)
if number == nil {
return nil
}
- return rawdb.ReadReceipts(bc.db, hash, *number)
+
+ receipts := rawdb.ReadReceipts(bc.db, hash, *number)
+ bc.receiptsCache.Add(hash, receipts)
+ return receipts
}
// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
diff --git a/eth/api_backend.go b/eth/api_backend.go
index 03f6012d7..8748d444f 100644
--- a/eth/api_backend.go
+++ b/eth/api_backend.go
@@ -25,7 +25,6 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
@@ -107,18 +106,11 @@ func (b *EthAPIBackend) GetBlock(ctx context.Context, hash common.Hash) (*types.
}
func (b *EthAPIBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
- if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil {
- return rawdb.ReadReceipts(b.eth.chainDb, hash, *number), nil
- }
- return nil, nil
+ return b.eth.blockchain.GetReceiptsByHash(hash), nil
}
func (b *EthAPIBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
- number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash)
- if number == nil {
- return nil, nil
- }
- receipts := rawdb.ReadReceipts(b.eth.chainDb, hash, *number)
+ receipts := b.eth.blockchain.GetReceiptsByHash(hash)
if receipts == nil {
return nil, nil
}