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

import (
4 5
	"github.com/hashicorp/golang-lru/v2/simplelru"

6 7
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
8 9

	"github.com/ethereum-optimism/optimism/op-service/eth"
10 11
)

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

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

func NewCachingOracle(oracle Oracle) *CachingOracle {
24 25 26
	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)
27 28
	return &CachingOracle{
		oracle: oracle,
29 30 31
		blocks: blockLRU,
		txs:    txsLRU,
		rcpts:  rcptsLRU,
32 33 34
	}
}

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

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

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