Skip to content

Commit

Permalink
all: remove remaining uses of untyped golang-lru (ethereum#26194)
Browse files Browse the repository at this point in the history
  • Loading branch information
fjl authored Nov 17, 2022
1 parent c3b4268 commit 12df456
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 68 deletions.
2 changes: 1 addition & 1 deletion common/lru/basiclru.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type cacheItem[K any, V any] struct {

// NewBasicLRU creates a new LRU cache.
func NewBasicLRU[K comparable, V any](capacity int) BasicLRU[K, V] {
if capacity < 0 {
if capacity <= 0 {
capacity = 1
}
c := BasicLRU[K, V]{
Expand Down
16 changes: 8 additions & 8 deletions consensus/clique/clique.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"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/misc"
"github.com/ethereum/go-ethereum/core/state"
Expand All @@ -41,7 +42,6 @@ import (
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/trie"
lru "github.com/hashicorp/golang-lru"
"golang.org/x/crypto/sha3"
)

Expand Down Expand Up @@ -143,11 +143,11 @@ var (
type SignerFn func(signer accounts.Account, mimeType string, message []byte) ([]byte, error)

// 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
hash := header.Hash()
if address, known := sigcache.Get(hash); known {
return address.(common.Address), nil
return address, nil
}
// Retrieve the signature from the header extra-data
if len(header.Extra) < extraSeal {
Expand All @@ -173,8 +173,8 @@ type Clique struct {
config *params.CliqueConfig // Consensus engine configuration parameters
db ethdb.Database // Database to store and retrieve snapshot checkpoints

recents *lru.ARCCache // Snapshots for recent block to speed up reorgs
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
recents *lru.Cache[common.Hash, *Snapshot] // Snapshots for recent block to speed up reorgs
signatures *sigLRU // Signatures of recent blocks to speed up mining

proposals map[common.Address]bool // Current list of proposals we are pushing

Expand All @@ -195,8 +195,8 @@ func New(config *params.CliqueConfig, db ethdb.Database) *Clique {
conf.Epoch = epochLength
}
// Allocate the snapshot caches and create the engine
recents, _ := lru.NewARC(inmemorySnapshots)
signatures, _ := lru.NewARC(inmemorySignatures)
recents := lru.NewCache[common.Hash, *Snapshot](inmemorySnapshots)
signatures := lru.NewCache[common.Hash, common.Address](inmemorySignatures)

return &Clique{
config: &conf,
Expand Down Expand Up @@ -375,7 +375,7 @@ func (c *Clique) snapshot(chain consensus.ChainHeaderReader, number uint64, hash
for snap == nil {
// If an in-memory snapshot was found, use that
if s, ok := c.recents.Get(hash); ok {
snap = s.(*Snapshot)
snap = s
break
}
// If an on-disk checkpoint snapshot can be found, use that
Expand Down
10 changes: 6 additions & 4 deletions consensus/clique/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ import (
"time"

"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/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"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
Expand All @@ -47,10 +47,12 @@ type Tally struct {
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.
type Snapshot struct {
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
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
Expand All @@ -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
// method does not initialize the set of recent signers, so only ever use if for
// 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{
config: config,
sigcache: sigcache,
Expand All @@ -87,7 +89,7 @@ func newSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, number uin
}

// 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[:]...))
if err != nil {
return nil, err
Expand Down
69 changes: 36 additions & 33 deletions consensus/ethash/ethash.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ import (
"unsafe"

"github.com/edsrzf/mmap-go"
lrupkg "github.com/ethereum/go-ethereum/common/lru"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/rpc"
"github.com/hashicorp/golang-lru/simplelru"
)

var ErrInvalidDumpMagic = errors.New("invalid dump magic")
Expand Down Expand Up @@ -165,34 +165,45 @@ func memoryMapAndGenerate(path string, size uint64, lock bool, generator func(bu
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.
type lru struct {
type lru[T cacheOrDataset] struct {
what string
new func(epoch uint64) interface{}
new func(epoch uint64) T
mu sync.Mutex
// 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'.
cache *simplelru.LRU
cache lrupkg.BasicLRU[uint64, T]
future uint64
futureItem interface{}
futureItem T
}

// newlru create a new least-recently-used cache for either the verification caches
// or the mining datasets.
func newlru(what string, maxItems int, new func(epoch uint64) interface{}) *lru {
if maxItems <= 0 {
maxItems = 1
func newlru[T cacheOrDataset](maxItems int, new func(epoch uint64) T) *lru[T] {
var what string
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
// non-nil. The second return value is non-nil if lru thinks that an item will be useful in
// 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()
defer lru.mu.Unlock()

Expand Down Expand Up @@ -226,9 +237,8 @@ type cache struct {
once sync.Once // Ensures the cache is generated only once
}

// newCache creates a new ethash verification cache and returns it as a plain Go
// interface to be usable in an LRU cache.
func newCache(epoch uint64) interface{} {
// newCache creates a new ethash verification cache.
func newCache(epoch uint64) *cache {
return &cache{epoch: epoch}
}

Expand Down Expand Up @@ -308,7 +318,7 @@ type dataset struct {

// newDataset creates a new ethash mining dataset and returns it as a plain Go
// interface to be usable in an LRU cache.
func newDataset(epoch uint64) interface{} {
func newDataset(epoch uint64) *dataset {
return &dataset{epoch: epoch}
}

Expand Down Expand Up @@ -439,8 +449,8 @@ type Config struct {
type Ethash struct {
config Config

caches *lru // In memory caches to avoid regenerating too often
datasets *lru // In memory datasets to avoid regenerating too often
caches *lru[*cache] // In memory caches to avoid regenerating too often
datasets *lru[*dataset] // In memory datasets to avoid regenerating too often

// Mining related fields
rand *rand.Rand // Properly seeded random source for nonces
Expand Down Expand Up @@ -477,8 +487,8 @@ func New(config Config, notify []string, noverify bool) *Ethash {
}
ethash := &Ethash{
config: config,
caches: newlru("cache", config.CachesInMem, newCache),
datasets: newlru("dataset", config.DatasetsInMem, newDataset),
caches: newlru(config.CachesInMem, newCache),
datasets: newlru(config.DatasetsInMem, newDataset),
update: make(chan struct{}),
hashrate: metrics.NewMeterForced(),
}
Expand Down Expand Up @@ -573,15 +583,13 @@ func (ethash *Ethash) StopRemoteSealer() error {
// stored on disk, and finally generating one if none can be found.
func (ethash *Ethash) cache(block uint64) *cache {
epoch := block / epochLength
currentI, futureI := ethash.caches.get(epoch)
current := currentI.(*cache)
current, future := ethash.caches.get(epoch)

// Wait for generation finish.
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 futureI != nil {
future := futureI.(*cache)
if future != nil {
go future.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.CachesLockMmap, ethash.config.PowMode == ModeTest)
}
return current
Expand All @@ -596,25 +604,20 @@ func (ethash *Ethash) cache(block uint64) *cache {
func (ethash *Ethash) dataset(block uint64, async bool) *dataset {
// Retrieve the requested ethash dataset
epoch := block / epochLength
currentI, futureI := ethash.datasets.get(epoch)
current := currentI.(*dataset)
current, future := ethash.datasets.get(epoch)

// If async is specified, generate everything in a background thread
if async && !current.generated() {
go func() {
current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.DatasetsLockMmap, ethash.config.PowMode == ModeTest)

if futureI != nil {
future := futureI.(*dataset)
if future != nil {
future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.DatasetsLockMmap, ethash.config.PowMode == ModeTest)
}
}()
} else {
// Either blocking generation was requested, or already done
current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.DatasetsLockMmap, ethash.config.PowMode == ModeTest)

if futureI != nil {
future := futureI.(*dataset)
if future != nil {
go future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.DatasetsLockMmap, ethash.config.PowMode == ModeTest)
}
}
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ require (
github.com/gorilla/websocket v1.4.2
github.com/graph-gophers/graphql-go v1.3.0
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/bloomfilter/v2 v2.0.3
github.com/holiman/uint256 v1.2.0
Expand Down
1 change: 0 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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/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.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/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=
Expand Down
10 changes: 5 additions & 5 deletions les/vflux/server/clientdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ import (
"time"

"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/ethdb"
"github.com/ethereum/go-ethereum/les/utils"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/rlp"
lru "github.com/hashicorp/golang-lru"
)

const (
Expand Down Expand Up @@ -57,7 +57,7 @@ var (

type nodeDB struct {
db ethdb.KeyValueStore
cache *lru.Cache
cache *lru.Cache[string, utils.ExpiredValue]
auxbuf []byte // 37-byte auxiliary buffer for key encoding
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.
Expand All @@ -67,10 +67,9 @@ type nodeDB struct {
}

func newNodeDB(db ethdb.KeyValueStore, clock mclock.Clock) *nodeDB {
cache, _ := lru.New(balanceCacheLimit)
ndb := &nodeDB{
db: db,
cache: cache,
cache: lru.NewCache[string, utils.ExpiredValue](balanceCacheLimit),
auxbuf: make([]byte, 37),
clock: clock,
closeCh: make(chan struct{}),
Expand Down Expand Up @@ -125,8 +124,9 @@ func (db *nodeDB) getOrNewBalance(id []byte, neg bool) utils.ExpiredValue {
key := db.key(id, neg)
item, exist := db.cache.Get(string(key))
if exist {
return item.(utils.ExpiredValue)
return item
}

var b utils.ExpiredValue
enc, err := db.db.Get(key)
if err != nil || len(enc) == 0 {
Expand Down
Loading

0 comments on commit 12df456

Please sign in to comment.