cache.go 1.93 KB
Newer Older
1 2 3 4 5 6
package l1

import (
	"github.com/ethereum-optimism/optimism/op-node/eth"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
7
	"github.com/hashicorp/golang-lru/v2/simplelru"
8 9
)

10 11 12
// Cache size is quite high as retrieving data from the pre-image oracle can be quite expensive
const cacheSize = 2000

13 14 15
// CachingOracle is an implementation of Oracle that delegates to another implementation, adding caching of all results
type CachingOracle struct {
	oracle Oracle
16 17 18
	blocks *simplelru.LRU[common.Hash, eth.BlockInfo]
	txs    *simplelru.LRU[common.Hash, types.Transactions]
	rcpts  *simplelru.LRU[common.Hash, types.Receipts]
19 20 21
}

func NewCachingOracle(oracle Oracle) *CachingOracle {
22 23 24
	blockLRU, _ := simplelru.NewLRU[common.Hash, eth.BlockInfo](cacheSize, nil)
	txsLRU, _ := simplelru.NewLRU[common.Hash, types.Transactions](cacheSize, nil)
	rcptsLRU, _ := simplelru.NewLRU[common.Hash, types.Receipts](cacheSize, nil)
25 26
	return &CachingOracle{
		oracle: oracle,
27 28 29
		blocks: blockLRU,
		txs:    txsLRU,
		rcpts:  rcptsLRU,
30 31 32
	}
}

33 34
func (o *CachingOracle) HeaderByBlockHash(blockHash common.Hash) eth.BlockInfo {
	block, ok := o.blocks.Get(blockHash)
35 36 37 38
	if ok {
		return block
	}
	block = o.oracle.HeaderByBlockHash(blockHash)
39
	o.blocks.Add(blockHash, block)
40 41 42
	return block
}

43 44
func (o *CachingOracle) TransactionsByBlockHash(blockHash common.Hash) (eth.BlockInfo, types.Transactions) {
	txs, ok := o.txs.Get(blockHash)
45 46 47 48
	if ok {
		return o.HeaderByBlockHash(blockHash), txs
	}
	block, txs := o.oracle.TransactionsByBlockHash(blockHash)
49 50
	o.blocks.Add(blockHash, block)
	o.txs.Add(blockHash, txs)
51 52 53
	return block, txs
}

54 55
func (o *CachingOracle) ReceiptsByBlockHash(blockHash common.Hash) (eth.BlockInfo, types.Receipts) {
	rcpts, ok := o.rcpts.Get(blockHash)
56 57 58 59
	if ok {
		return o.HeaderByBlockHash(blockHash), rcpts
	}
	block, rcpts := o.oracle.ReceiptsByBlockHash(blockHash)
60 61
	o.blocks.Add(blockHash, block)
	o.rcpts.Add(blockHash, rcpts)
62 63
	return block, rcpts
}