From f56bf0846328e9ae50d8f24ede967d2f1166cd0a Mon Sep 17 00:00:00 2001 From: Ilya Mikheev <54912776+JkLondon@users.noreply.github.com> Date: Wed, 18 Dec 2024 08:18:33 +0100 Subject: [PATCH] cache tx granularity (#13134) closes #13088 Not really sure about 2 caches conception but like it --------- Co-authored-by: JkLondon --- turbo/jsonrpc/eth_receipts.go | 7 +++-- turbo/jsonrpc/receipts/receipts_generator.go | 28 +++++++++++++++++--- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/turbo/jsonrpc/eth_receipts.go b/turbo/jsonrpc/eth_receipts.go index 4c41d7a8a67..04a5fceeb7a 100644 --- a/turbo/jsonrpc/eth_receipts.go +++ b/turbo/jsonrpc/eth_receipts.go @@ -55,6 +55,10 @@ func (api *BaseAPI) getReceipt(ctx context.Context, cc *chain.Config, tx kv.Temp return api.receiptsGenerator.GetReceipt(ctx, cc, tx, block, index, txNum) } +func (api *BaseAPI) getCachedReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, bool) { + return api.receiptsGenerator.GetCachedReceipt(ctx, hash) +} + func (api *BaseAPI) getCachedReceipts(ctx context.Context, hash common.Hash) (types.Receipts, bool) { return api.receiptsGenerator.GetCachedReceipts(ctx, hash) } @@ -463,7 +467,7 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, txnHash common.Ha } } - if txn == nil && chainConfig.Bor != nil { + if txn == nil && chainConfig.Bor != nil { //TODO: add tx gran here to. receipts, err := api.getReceipts(ctx, tx, block) if err != nil { return nil, fmt.Errorf("getReceipts error: %w", err) @@ -501,7 +505,6 @@ func (api *APIImpl) GetBlockReceipts(ctx context.Context, numberOrHash rpc.Block return nil, err } defer tx.Rollback() - blockNum, blockHash, _, err := rpchelper.GetBlockNumber(ctx, numberOrHash, tx, api._blockReader, api.filters) if err != nil { return nil, err diff --git a/turbo/jsonrpc/receipts/receipts_generator.go b/turbo/jsonrpc/receipts/receipts_generator.go index 4dc0dd19446..9a580abe9f7 100644 --- a/turbo/jsonrpc/receipts/receipts_generator.go +++ b/turbo/jsonrpc/receipts/receipts_generator.go @@ -24,7 +24,9 @@ import ( type Generator struct { receiptsCache *lru.Cache[common.Hash, types.Receipts] + receiptCache *lru.Cache[common.Hash, *types.Receipt] receiptsCacheTrace bool + receiptCacheTrace bool blockReader services.FullBlockReader engine consensus.EngineReader @@ -46,7 +48,12 @@ var ( ) func NewGenerator(blockReader services.FullBlockReader, engine consensus.EngineReader) *Generator { - receiptsCache, err := lru.New[common.Hash, types.Receipts](receiptsCacheLimit) + receiptsCache, err := lru.New[common.Hash, types.Receipts](receiptsCacheLimit) //TODO: is handling both of them a good idea though...? + if err != nil { + panic(err) + } + + receiptCache, err := lru.New[common.Hash, *types.Receipt](receiptsCacheLimit * 1000) // think they should be connected in some of that way if err != nil { panic(err) } @@ -56,6 +63,8 @@ func NewGenerator(blockReader services.FullBlockReader, engine consensus.EngineR blockReader: blockReader, engine: engine, receiptsCacheTrace: receiptsCacheTrace, + receiptCacheTrace: receiptsCacheTrace, + receiptCache: receiptCache, } } @@ -71,6 +80,10 @@ func (g *Generator) GetCachedReceipts(ctx context.Context, blockHash common.Hash return g.receiptsCache.Get(blockHash) } +func (g *Generator) GetCachedReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, bool) { + return g.receiptCache.Get(hash) +} + func (g *Generator) PrepareEnv(ctx context.Context, block *types.Block, cfg *chain.Config, tx kv.TemporalTx, txIndex int) (*ReceiptEnv, error) { txNumsReader := rawdbv3.TxNums.WithCustomReadTxNumFunc(freezeblocks.ReadTxNumFuncFromBlockReader(ctx, g.blockReader)) ibs, _, _, _, _, err := transactions.ComputeBlockContext(ctx, g.engine, block.HeaderNoCopy(), cfg, g.blockReader, txNumsReader, tx, txIndex) @@ -103,11 +116,19 @@ func (g *Generator) PrepareEnv(ctx context.Context, block *types.Block, cfg *cha }, nil } -func (g *Generator) addToCache(header *types.Header, receipts types.Receipts) { +func (g *Generator) addToCacheReceipts(header *types.Header, receipts types.Receipts) { g.receiptsCache.Add(header.Hash(), receipts.Copy()) // .Copy() helps pprof to attribute memory to cache - instead of evm (where it was allocated). } +func (g *Generator) addToCacheReceipt(hash common.Hash, receipt *types.Receipt) { + g.receiptCache.Add(hash, receipt.Copy()) // .Copy() helps pprof to attribute memory to cache - instead of evm (where it was allocated). +} + func (g *Generator) GetReceipt(ctx context.Context, cfg *chain.Config, tx kv.TemporalTx, block *types.Block, index int, txNum uint64) (*types.Receipt, error) { + if receipt, ok := g.receiptCache.Get(block.Transactions()[index].Hash()); ok { + return receipt, nil + } + if receipts, ok := g.receiptsCache.Get(block.Hash()); ok && len(receipts) > index { return receipts[index], nil } @@ -137,6 +158,7 @@ func (g *Generator) GetReceipt(ctx context.Context, cfg *chain.Config, tx kv.Tem receipt.Logs[i].Index = uint(firstLogIndex + uint32(i)) } + g.addToCacheReceipt(receipt.TxHash, receipt) return receipt, nil } @@ -162,6 +184,6 @@ func (g *Generator) GetReceipts(ctx context.Context, cfg *chain.Config, tx kv.Te receipts[i] = receipt } - g.addToCache(block.HeaderNoCopy(), receipts) + g.addToCacheReceipts(block.HeaderNoCopy(), receipts) return receipts, nil }