cache.go 1.62 KB
Newer Older
1 2 3 4 5
package l2

import (
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
6
	"github.com/hashicorp/golang-lru/v2/simplelru"
7 8
)

9 10 11
// blockCacheSize should be set large enough to handle the pipeline reset process of walking back from L2 head to find
// the L1 origin that is old enough to start buffering channel data from.
const blockCacheSize = 3_000
12 13 14
const nodeCacheSize = 100_000
const codeCacheSize = 10_000

15 16
type CachingOracle struct {
	oracle Oracle
17 18 19
	blocks *simplelru.LRU[common.Hash, *types.Block]
	nodes  *simplelru.LRU[common.Hash, []byte]
	codes  *simplelru.LRU[common.Hash, []byte]
20 21 22
}

func NewCachingOracle(oracle Oracle) *CachingOracle {
23 24 25
	blockLRU, _ := simplelru.NewLRU[common.Hash, *types.Block](blockCacheSize, nil)
	nodeLRU, _ := simplelru.NewLRU[common.Hash, []byte](nodeCacheSize, nil)
	codeLRU, _ := simplelru.NewLRU[common.Hash, []byte](codeCacheSize, nil)
26 27
	return &CachingOracle{
		oracle: oracle,
28 29 30
		blocks: blockLRU,
		nodes:  nodeLRU,
		codes:  codeLRU,
31 32 33
	}
}

34 35
func (o *CachingOracle) NodeByHash(nodeHash common.Hash) []byte {
	node, ok := o.nodes.Get(nodeHash)
36 37 38 39
	if ok {
		return node
	}
	node = o.oracle.NodeByHash(nodeHash)
40
	o.nodes.Add(nodeHash, node)
41 42 43
	return node
}

44 45
func (o *CachingOracle) CodeByHash(codeHash common.Hash) []byte {
	code, ok := o.codes.Get(codeHash)
46 47 48 49
	if ok {
		return code
	}
	code = o.oracle.CodeByHash(codeHash)
50
	o.codes.Add(codeHash, code)
51 52 53
	return code
}

54 55
func (o *CachingOracle) BlockByHash(blockHash common.Hash) *types.Block {
	block, ok := o.blocks.Get(blockHash)
56 57 58 59
	if ok {
		return block
	}
	block = o.oracle.BlockByHash(blockHash)
60
	o.blocks.Add(blockHash, block)
61 62
	return block
}