all: remove remaining uses of untyped golang-lru (#26194)
This commit is contained in:
parent
c3b42683b3
commit
12df45662a
@ -34,7 +34,7 @@ type cacheItem[K any, V any] struct {
|
|||||||
|
|
||||||
// NewBasicLRU creates a new LRU cache.
|
// NewBasicLRU creates a new LRU cache.
|
||||||
func NewBasicLRU[K comparable, V any](capacity int) BasicLRU[K, V] {
|
func NewBasicLRU[K comparable, V any](capacity int) BasicLRU[K, V] {
|
||||||
if capacity < 0 {
|
if capacity <= 0 {
|
||||||
capacity = 1
|
capacity = 1
|
||||||
}
|
}
|
||||||
c := BasicLRU[K, V]{
|
c := BasicLRU[K, V]{
|
||||||
|
@ -30,6 +30,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
lru "github.com/ethereum/go-ethereum/common/lru"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
@ -41,7 +42,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
"golang.org/x/crypto/sha3"
|
"golang.org/x/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -143,11 +143,11 @@ var (
|
|||||||
type SignerFn func(signer accounts.Account, mimeType string, message []byte) ([]byte, error)
|
type SignerFn func(signer accounts.Account, mimeType string, message []byte) ([]byte, error)
|
||||||
|
|
||||||
// ecrecover extracts the Ethereum account address from a signed header.
|
// ecrecover extracts the Ethereum account address from a signed header.
|
||||||
func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
|
func ecrecover(header *types.Header, sigcache *sigLRU) (common.Address, error) {
|
||||||
// If the signature's already cached, return that
|
// If the signature's already cached, return that
|
||||||
hash := header.Hash()
|
hash := header.Hash()
|
||||||
if address, known := sigcache.Get(hash); known {
|
if address, known := sigcache.Get(hash); known {
|
||||||
return address.(common.Address), nil
|
return address, nil
|
||||||
}
|
}
|
||||||
// Retrieve the signature from the header extra-data
|
// Retrieve the signature from the header extra-data
|
||||||
if len(header.Extra) < extraSeal {
|
if len(header.Extra) < extraSeal {
|
||||||
@ -173,8 +173,8 @@ type Clique struct {
|
|||||||
config *params.CliqueConfig // Consensus engine configuration parameters
|
config *params.CliqueConfig // Consensus engine configuration parameters
|
||||||
db ethdb.Database // Database to store and retrieve snapshot checkpoints
|
db ethdb.Database // Database to store and retrieve snapshot checkpoints
|
||||||
|
|
||||||
recents *lru.ARCCache // Snapshots for recent block to speed up reorgs
|
recents *lru.Cache[common.Hash, *Snapshot] // Snapshots for recent block to speed up reorgs
|
||||||
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
|
signatures *sigLRU // Signatures of recent blocks to speed up mining
|
||||||
|
|
||||||
proposals map[common.Address]bool // Current list of proposals we are pushing
|
proposals map[common.Address]bool // Current list of proposals we are pushing
|
||||||
|
|
||||||
@ -195,8 +195,8 @@ func New(config *params.CliqueConfig, db ethdb.Database) *Clique {
|
|||||||
conf.Epoch = epochLength
|
conf.Epoch = epochLength
|
||||||
}
|
}
|
||||||
// Allocate the snapshot caches and create the engine
|
// Allocate the snapshot caches and create the engine
|
||||||
recents, _ := lru.NewARC(inmemorySnapshots)
|
recents := lru.NewCache[common.Hash, *Snapshot](inmemorySnapshots)
|
||||||
signatures, _ := lru.NewARC(inmemorySignatures)
|
signatures := lru.NewCache[common.Hash, common.Address](inmemorySignatures)
|
||||||
|
|
||||||
return &Clique{
|
return &Clique{
|
||||||
config: &conf,
|
config: &conf,
|
||||||
@ -375,7 +375,7 @@ func (c *Clique) snapshot(chain consensus.ChainHeaderReader, number uint64, hash
|
|||||||
for snap == nil {
|
for snap == nil {
|
||||||
// If an in-memory snapshot was found, use that
|
// If an in-memory snapshot was found, use that
|
||||||
if s, ok := c.recents.Get(hash); ok {
|
if s, ok := c.recents.Get(hash); ok {
|
||||||
snap = s.(*Snapshot)
|
snap = s
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// If an on-disk checkpoint snapshot can be found, use that
|
// If an on-disk checkpoint snapshot can be found, use that
|
||||||
|
@ -23,12 +23,12 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/lru"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Vote represents a single vote that an authorized signer made to modify the
|
// Vote represents a single vote that an authorized signer made to modify the
|
||||||
@ -47,10 +47,12 @@ type Tally struct {
|
|||||||
Votes int `json:"votes"` // Number of votes until now wanting to pass the proposal
|
Votes int `json:"votes"` // Number of votes until now wanting to pass the proposal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type sigLRU = lru.Cache[common.Hash, common.Address]
|
||||||
|
|
||||||
// Snapshot is the state of the authorization voting at a given point in time.
|
// Snapshot is the state of the authorization voting at a given point in time.
|
||||||
type Snapshot struct {
|
type Snapshot struct {
|
||||||
config *params.CliqueConfig // Consensus engine parameters to fine tune behavior
|
config *params.CliqueConfig // Consensus engine parameters to fine tune behavior
|
||||||
sigcache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover
|
sigcache *sigLRU // Cache of recent block signatures to speed up ecrecover
|
||||||
|
|
||||||
Number uint64 `json:"number"` // Block number where the snapshot was created
|
Number uint64 `json:"number"` // Block number where the snapshot was created
|
||||||
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
|
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
|
||||||
@ -70,7 +72,7 @@ func (s signersAscending) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|||||||
// newSnapshot creates a new snapshot with the specified startup parameters. This
|
// newSnapshot creates a new snapshot with the specified startup parameters. This
|
||||||
// method does not initialize the set of recent signers, so only ever use if for
|
// method does not initialize the set of recent signers, so only ever use if for
|
||||||
// the genesis block.
|
// the genesis block.
|
||||||
func newSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, number uint64, hash common.Hash, signers []common.Address) *Snapshot {
|
func newSnapshot(config *params.CliqueConfig, sigcache *sigLRU, number uint64, hash common.Hash, signers []common.Address) *Snapshot {
|
||||||
snap := &Snapshot{
|
snap := &Snapshot{
|
||||||
config: config,
|
config: config,
|
||||||
sigcache: sigcache,
|
sigcache: sigcache,
|
||||||
@ -87,7 +89,7 @@ func newSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, number uin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// loadSnapshot loads an existing snapshot from the database.
|
// loadSnapshot loads an existing snapshot from the database.
|
||||||
func loadSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, db ethdb.Database, hash common.Hash) (*Snapshot, error) {
|
func loadSnapshot(config *params.CliqueConfig, sigcache *sigLRU, db ethdb.Database, hash common.Hash) (*Snapshot, error) {
|
||||||
blob, err := db.Get(append(rawdb.CliqueSnapshotPrefix, hash[:]...))
|
blob, err := db.Get(append(rawdb.CliqueSnapshotPrefix, hash[:]...))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -34,11 +34,11 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/edsrzf/mmap-go"
|
"github.com/edsrzf/mmap-go"
|
||||||
|
lrupkg "github.com/ethereum/go-ethereum/common/lru"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/hashicorp/golang-lru/simplelru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrInvalidDumpMagic = errors.New("invalid dump magic")
|
var ErrInvalidDumpMagic = errors.New("invalid dump magic")
|
||||||
@ -165,34 +165,45 @@ func memoryMapAndGenerate(path string, size uint64, lock bool, generator func(bu
|
|||||||
return memoryMap(path, lock)
|
return memoryMap(path, lock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type cacheOrDataset interface {
|
||||||
|
*cache | *dataset
|
||||||
|
}
|
||||||
|
|
||||||
// lru tracks caches or datasets by their last use time, keeping at most N of them.
|
// lru tracks caches or datasets by their last use time, keeping at most N of them.
|
||||||
type lru struct {
|
type lru[T cacheOrDataset] struct {
|
||||||
what string
|
what string
|
||||||
new func(epoch uint64) interface{}
|
new func(epoch uint64) T
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
// Items are kept in a LRU cache, but there is a special case:
|
// Items are kept in a LRU cache, but there is a special case:
|
||||||
// We always keep an item for (highest seen epoch) + 1 as the 'future item'.
|
// We always keep an item for (highest seen epoch) + 1 as the 'future item'.
|
||||||
cache *simplelru.LRU
|
cache lrupkg.BasicLRU[uint64, T]
|
||||||
future uint64
|
future uint64
|
||||||
futureItem interface{}
|
futureItem T
|
||||||
}
|
}
|
||||||
|
|
||||||
// newlru create a new least-recently-used cache for either the verification caches
|
// newlru create a new least-recently-used cache for either the verification caches
|
||||||
// or the mining datasets.
|
// or the mining datasets.
|
||||||
func newlru(what string, maxItems int, new func(epoch uint64) interface{}) *lru {
|
func newlru[T cacheOrDataset](maxItems int, new func(epoch uint64) T) *lru[T] {
|
||||||
if maxItems <= 0 {
|
var what string
|
||||||
maxItems = 1
|
switch any(T(nil)).(type) {
|
||||||
|
case *cache:
|
||||||
|
what = "cache"
|
||||||
|
case *dataset:
|
||||||
|
what = "dataset"
|
||||||
|
default:
|
||||||
|
panic("unknown type")
|
||||||
|
}
|
||||||
|
return &lru[T]{
|
||||||
|
what: what,
|
||||||
|
new: new,
|
||||||
|
cache: lrupkg.NewBasicLRU[uint64, T](maxItems),
|
||||||
}
|
}
|
||||||
cache, _ := simplelru.NewLRU(maxItems, func(key, value interface{}) {
|
|
||||||
log.Trace("Evicted ethash "+what, "epoch", key)
|
|
||||||
})
|
|
||||||
return &lru{what: what, new: new, cache: cache}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get retrieves or creates an item for the given epoch. The first return value is always
|
// get retrieves or creates an item for the given epoch. The first return value is always
|
||||||
// non-nil. The second return value is non-nil if lru thinks that an item will be useful in
|
// non-nil. The second return value is non-nil if lru thinks that an item will be useful in
|
||||||
// the near future.
|
// the near future.
|
||||||
func (lru *lru) get(epoch uint64) (item, future interface{}) {
|
func (lru *lru[T]) get(epoch uint64) (item, future T) {
|
||||||
lru.mu.Lock()
|
lru.mu.Lock()
|
||||||
defer lru.mu.Unlock()
|
defer lru.mu.Unlock()
|
||||||
|
|
||||||
@ -226,9 +237,8 @@ type cache struct {
|
|||||||
once sync.Once // Ensures the cache is generated only once
|
once sync.Once // Ensures the cache is generated only once
|
||||||
}
|
}
|
||||||
|
|
||||||
// newCache creates a new ethash verification cache and returns it as a plain Go
|
// newCache creates a new ethash verification cache.
|
||||||
// interface to be usable in an LRU cache.
|
func newCache(epoch uint64) *cache {
|
||||||
func newCache(epoch uint64) interface{} {
|
|
||||||
return &cache{epoch: epoch}
|
return &cache{epoch: epoch}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +318,7 @@ type dataset struct {
|
|||||||
|
|
||||||
// newDataset creates a new ethash mining dataset and returns it as a plain Go
|
// newDataset creates a new ethash mining dataset and returns it as a plain Go
|
||||||
// interface to be usable in an LRU cache.
|
// interface to be usable in an LRU cache.
|
||||||
func newDataset(epoch uint64) interface{} {
|
func newDataset(epoch uint64) *dataset {
|
||||||
return &dataset{epoch: epoch}
|
return &dataset{epoch: epoch}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,8 +449,8 @@ type Config struct {
|
|||||||
type Ethash struct {
|
type Ethash struct {
|
||||||
config Config
|
config Config
|
||||||
|
|
||||||
caches *lru // In memory caches to avoid regenerating too often
|
caches *lru[*cache] // In memory caches to avoid regenerating too often
|
||||||
datasets *lru // In memory datasets to avoid regenerating too often
|
datasets *lru[*dataset] // In memory datasets to avoid regenerating too often
|
||||||
|
|
||||||
// Mining related fields
|
// Mining related fields
|
||||||
rand *rand.Rand // Properly seeded random source for nonces
|
rand *rand.Rand // Properly seeded random source for nonces
|
||||||
@ -477,8 +487,8 @@ func New(config Config, notify []string, noverify bool) *Ethash {
|
|||||||
}
|
}
|
||||||
ethash := &Ethash{
|
ethash := &Ethash{
|
||||||
config: config,
|
config: config,
|
||||||
caches: newlru("cache", config.CachesInMem, newCache),
|
caches: newlru(config.CachesInMem, newCache),
|
||||||
datasets: newlru("dataset", config.DatasetsInMem, newDataset),
|
datasets: newlru(config.DatasetsInMem, newDataset),
|
||||||
update: make(chan struct{}),
|
update: make(chan struct{}),
|
||||||
hashrate: metrics.NewMeterForced(),
|
hashrate: metrics.NewMeterForced(),
|
||||||
}
|
}
|
||||||
@ -573,15 +583,13 @@ func (ethash *Ethash) StopRemoteSealer() error {
|
|||||||
// stored on disk, and finally generating one if none can be found.
|
// stored on disk, and finally generating one if none can be found.
|
||||||
func (ethash *Ethash) cache(block uint64) *cache {
|
func (ethash *Ethash) cache(block uint64) *cache {
|
||||||
epoch := block / epochLength
|
epoch := block / epochLength
|
||||||
currentI, futureI := ethash.caches.get(epoch)
|
current, future := ethash.caches.get(epoch)
|
||||||
current := currentI.(*cache)
|
|
||||||
|
|
||||||
// Wait for generation finish.
|
// Wait for generation finish.
|
||||||
current.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.CachesLockMmap, ethash.config.PowMode == ModeTest)
|
current.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.CachesLockMmap, ethash.config.PowMode == ModeTest)
|
||||||
|
|
||||||
// If we need a new future cache, now's a good time to regenerate it.
|
// If we need a new future cache, now's a good time to regenerate it.
|
||||||
if futureI != nil {
|
if future != nil {
|
||||||
future := futureI.(*cache)
|
|
||||||
go future.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.CachesLockMmap, ethash.config.PowMode == ModeTest)
|
go future.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.CachesLockMmap, ethash.config.PowMode == ModeTest)
|
||||||
}
|
}
|
||||||
return current
|
return current
|
||||||
@ -596,25 +604,20 @@ func (ethash *Ethash) cache(block uint64) *cache {
|
|||||||
func (ethash *Ethash) dataset(block uint64, async bool) *dataset {
|
func (ethash *Ethash) dataset(block uint64, async bool) *dataset {
|
||||||
// Retrieve the requested ethash dataset
|
// Retrieve the requested ethash dataset
|
||||||
epoch := block / epochLength
|
epoch := block / epochLength
|
||||||
currentI, futureI := ethash.datasets.get(epoch)
|
current, future := ethash.datasets.get(epoch)
|
||||||
current := currentI.(*dataset)
|
|
||||||
|
|
||||||
// If async is specified, generate everything in a background thread
|
// If async is specified, generate everything in a background thread
|
||||||
if async && !current.generated() {
|
if async && !current.generated() {
|
||||||
go func() {
|
go func() {
|
||||||
current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.DatasetsLockMmap, ethash.config.PowMode == ModeTest)
|
current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.DatasetsLockMmap, ethash.config.PowMode == ModeTest)
|
||||||
|
if future != nil {
|
||||||
if futureI != nil {
|
|
||||||
future := futureI.(*dataset)
|
|
||||||
future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.DatasetsLockMmap, ethash.config.PowMode == ModeTest)
|
future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.DatasetsLockMmap, ethash.config.PowMode == ModeTest)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
} else {
|
} else {
|
||||||
// Either blocking generation was requested, or already done
|
// Either blocking generation was requested, or already done
|
||||||
current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.DatasetsLockMmap, ethash.config.PowMode == ModeTest)
|
current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.DatasetsLockMmap, ethash.config.PowMode == ModeTest)
|
||||||
|
if future != nil {
|
||||||
if futureI != nil {
|
|
||||||
future := futureI.(*dataset)
|
|
||||||
go future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.DatasetsLockMmap, ethash.config.PowMode == ModeTest)
|
go future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.DatasetsLockMmap, ethash.config.PowMode == ModeTest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
go.mod
1
go.mod
@ -33,7 +33,6 @@ require (
|
|||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
github.com/graph-gophers/graphql-go v1.3.0
|
github.com/graph-gophers/graphql-go v1.3.0
|
||||||
github.com/hashicorp/go-bexpr v0.1.10
|
github.com/hashicorp/go-bexpr v0.1.10
|
||||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d
|
|
||||||
github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e
|
github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e
|
||||||
github.com/holiman/bloomfilter/v2 v2.0.3
|
github.com/holiman/bloomfilter/v2 v2.0.3
|
||||||
github.com/holiman/uint256 v1.2.0
|
github.com/holiman/uint256 v1.2.0
|
||||||
|
1
go.sum
1
go.sum
@ -226,7 +226,6 @@ github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpx
|
|||||||
github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=
|
github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||||
github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw=
|
github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw=
|
||||||
github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU=
|
github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU=
|
||||||
|
@ -22,13 +22,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/lru"
|
||||||
"github.com/ethereum/go-ethereum/common/mclock"
|
"github.com/ethereum/go-ethereum/common/mclock"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/les/utils"
|
"github.com/ethereum/go-ethereum/les/utils"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -57,7 +57,7 @@ var (
|
|||||||
|
|
||||||
type nodeDB struct {
|
type nodeDB struct {
|
||||||
db ethdb.KeyValueStore
|
db ethdb.KeyValueStore
|
||||||
cache *lru.Cache
|
cache *lru.Cache[string, utils.ExpiredValue]
|
||||||
auxbuf []byte // 37-byte auxiliary buffer for key encoding
|
auxbuf []byte // 37-byte auxiliary buffer for key encoding
|
||||||
verbuf [2]byte // 2-byte auxiliary buffer for db version
|
verbuf [2]byte // 2-byte auxiliary buffer for db version
|
||||||
evictCallBack func(mclock.AbsTime, bool, utils.ExpiredValue) bool // Callback to determine whether the balance can be evicted.
|
evictCallBack func(mclock.AbsTime, bool, utils.ExpiredValue) bool // Callback to determine whether the balance can be evicted.
|
||||||
@ -67,10 +67,9 @@ type nodeDB struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newNodeDB(db ethdb.KeyValueStore, clock mclock.Clock) *nodeDB {
|
func newNodeDB(db ethdb.KeyValueStore, clock mclock.Clock) *nodeDB {
|
||||||
cache, _ := lru.New(balanceCacheLimit)
|
|
||||||
ndb := &nodeDB{
|
ndb := &nodeDB{
|
||||||
db: db,
|
db: db,
|
||||||
cache: cache,
|
cache: lru.NewCache[string, utils.ExpiredValue](balanceCacheLimit),
|
||||||
auxbuf: make([]byte, 37),
|
auxbuf: make([]byte, 37),
|
||||||
clock: clock,
|
clock: clock,
|
||||||
closeCh: make(chan struct{}),
|
closeCh: make(chan struct{}),
|
||||||
@ -125,8 +124,9 @@ func (db *nodeDB) getOrNewBalance(id []byte, neg bool) utils.ExpiredValue {
|
|||||||
key := db.key(id, neg)
|
key := db.key(id, neg)
|
||||||
item, exist := db.cache.Get(string(key))
|
item, exist := db.cache.Get(string(key))
|
||||||
if exist {
|
if exist {
|
||||||
return item.(utils.ExpiredValue)
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
var b utils.ExpiredValue
|
var b utils.ExpiredValue
|
||||||
enc, err := db.db.Get(key)
|
enc, err := db.db.Get(key)
|
||||||
if err != nil || len(enc) == 0 {
|
if err != nil || len(enc) == 0 {
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/lru"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
@ -37,7 +38,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -61,9 +61,9 @@ type LightChain struct {
|
|||||||
genesisBlock *types.Block
|
genesisBlock *types.Block
|
||||||
forker *core.ForkChoice
|
forker *core.ForkChoice
|
||||||
|
|
||||||
bodyCache *lru.Cache // Cache for the most recent block bodies
|
bodyCache *lru.Cache[common.Hash, *types.Body]
|
||||||
bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format
|
bodyRLPCache *lru.Cache[common.Hash, rlp.RawValue]
|
||||||
blockCache *lru.Cache // Cache for the most recent entire blocks
|
blockCache *lru.Cache[common.Hash, *types.Block]
|
||||||
|
|
||||||
chainmu sync.RWMutex // protects header inserts
|
chainmu sync.RWMutex // protects header inserts
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
@ -79,18 +79,14 @@ type LightChain struct {
|
|||||||
// available in the database. It initialises the default Ethereum header
|
// available in the database. It initialises the default Ethereum header
|
||||||
// validator.
|
// validator.
|
||||||
func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.Engine, checkpoint *params.TrustedCheckpoint) (*LightChain, error) {
|
func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.Engine, checkpoint *params.TrustedCheckpoint) (*LightChain, error) {
|
||||||
bodyCache, _ := lru.New(bodyCacheLimit)
|
|
||||||
bodyRLPCache, _ := lru.New(bodyCacheLimit)
|
|
||||||
blockCache, _ := lru.New(blockCacheLimit)
|
|
||||||
|
|
||||||
bc := &LightChain{
|
bc := &LightChain{
|
||||||
chainDb: odr.Database(),
|
chainDb: odr.Database(),
|
||||||
indexerConfig: odr.IndexerConfig(),
|
indexerConfig: odr.IndexerConfig(),
|
||||||
odr: odr,
|
odr: odr,
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
bodyCache: bodyCache,
|
bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit),
|
||||||
bodyRLPCache: bodyRLPCache,
|
bodyRLPCache: lru.NewCache[common.Hash, rlp.RawValue](bodyCacheLimit),
|
||||||
blockCache: blockCache,
|
blockCache: lru.NewCache[common.Hash, *types.Block](blockCacheLimit),
|
||||||
engine: engine,
|
engine: engine,
|
||||||
}
|
}
|
||||||
bc.forker = core.NewForkChoice(bc, nil)
|
bc.forker = core.NewForkChoice(bc, nil)
|
||||||
@ -233,8 +229,7 @@ func (lc *LightChain) StateCache() state.Database {
|
|||||||
func (lc *LightChain) GetBody(ctx context.Context, hash common.Hash) (*types.Body, error) {
|
func (lc *LightChain) GetBody(ctx context.Context, hash common.Hash) (*types.Body, error) {
|
||||||
// Short circuit if the body's already in the cache, retrieve otherwise
|
// Short circuit if the body's already in the cache, retrieve otherwise
|
||||||
if cached, ok := lc.bodyCache.Get(hash); ok {
|
if cached, ok := lc.bodyCache.Get(hash); ok {
|
||||||
body := cached.(*types.Body)
|
return cached, nil
|
||||||
return body, nil
|
|
||||||
}
|
}
|
||||||
number := lc.hc.GetBlockNumber(hash)
|
number := lc.hc.GetBlockNumber(hash)
|
||||||
if number == nil {
|
if number == nil {
|
||||||
@ -254,7 +249,7 @@ func (lc *LightChain) GetBody(ctx context.Context, hash common.Hash) (*types.Bod
|
|||||||
func (lc *LightChain) GetBodyRLP(ctx context.Context, hash common.Hash) (rlp.RawValue, error) {
|
func (lc *LightChain) GetBodyRLP(ctx context.Context, hash common.Hash) (rlp.RawValue, error) {
|
||||||
// Short circuit if the body's already in the cache, retrieve otherwise
|
// Short circuit if the body's already in the cache, retrieve otherwise
|
||||||
if cached, ok := lc.bodyRLPCache.Get(hash); ok {
|
if cached, ok := lc.bodyRLPCache.Get(hash); ok {
|
||||||
return cached.(rlp.RawValue), nil
|
return cached, nil
|
||||||
}
|
}
|
||||||
number := lc.hc.GetBlockNumber(hash)
|
number := lc.hc.GetBlockNumber(hash)
|
||||||
if number == nil {
|
if number == nil {
|
||||||
@ -281,7 +276,7 @@ func (lc *LightChain) HasBlock(hash common.Hash, number uint64) bool {
|
|||||||
func (lc *LightChain) GetBlock(ctx context.Context, hash common.Hash, number uint64) (*types.Block, error) {
|
func (lc *LightChain) GetBlock(ctx context.Context, hash common.Hash, number uint64) (*types.Block, error) {
|
||||||
// Short circuit if the block's already in the cache, retrieve otherwise
|
// Short circuit if the block's already in the cache, retrieve otherwise
|
||||||
if block, ok := lc.blockCache.Get(hash); ok {
|
if block, ok := lc.blockCache.Get(hash); ok {
|
||||||
return block.(*types.Block), nil
|
return block, nil
|
||||||
}
|
}
|
||||||
block, err := GetBlock(ctx, lc.odr, hash, number)
|
block, err := GetBlock(ctx, lc.odr, hash, number)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user