diff --git a/cmd/faucet/rate_limiter.go b/cmd/faucet/rate_limiter.go index e490c55470..bd2b2b6750 100644 --- a/cmd/faucet/rate_limiter.go +++ b/cmd/faucet/rate_limiter.go @@ -1,25 +1,20 @@ package main import ( - lru "github.com/hashicorp/golang-lru" + "github.com/ethereum/go-ethereum/common/lru" "golang.org/x/time/rate" ) type IPRateLimiter struct { - ips *lru.Cache // LRU cache to store IP addresses and their associated rate limiters - r rate.Limit // the rate limit, e.g., 5 requests per second - b int // the burst size, e.g., allowing a burst of 10 requests at once. The rate limiter gets into action + ips *lru.Cache[string, *rate.Limiter] // LRU cache to store IP addresses and their associated rate limiters + r rate.Limit // the rate limit, e.g., 5 requests per second + b int // the burst size, e.g., allowing a burst of 10 requests at once. The rate limiter gets into action // only after this number exceeds } func NewIPRateLimiter(r rate.Limit, b int, size int) (*IPRateLimiter, error) { - cache, err := lru.New(size) - if err != nil { - return nil, err - } - i := &IPRateLimiter{ - ips: cache, + ips: lru.NewCache[string, *rate.Limiter](size), r: r, b: b, } @@ -37,7 +32,7 @@ func (i *IPRateLimiter) addIP(ip string) *rate.Limiter { func (i *IPRateLimiter) GetLimiter(ip string) *rate.Limiter { if limiter, exists := i.ips.Get(ip); exists { - return limiter.(*rate.Limiter) + return limiter } return i.addIP(ip) diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index ce59858007..f93b3e48d4 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -15,7 +15,7 @@ import ( "sync" "time" - lru "github.com/hashicorp/golang-lru" + "github.com/ethereum/go-ethereum/common/lru" "github.com/holiman/uint256" "github.com/prysmaticlabs/prysm/v5/crypto/bls" "github.com/willf/bitset" @@ -196,11 +196,11 @@ func isToSystemContract(to common.Address) bool { } // ecrecover extracts the Ethereum account address from a signed header. -func ecrecover(header *types.Header, sigCache *lru.ARCCache, chainId *big.Int) (common.Address, error) { +func ecrecover(header *types.Header, sigCache *lru.Cache[common.Hash, common.Address], chainId *big.Int) (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 { @@ -240,9 +240,9 @@ type Parlia struct { genesisHash common.Hash db ethdb.Database // Database to store and retrieve snapshot checkpoints - recentSnaps *lru.ARCCache // Snapshots for recent block to speed up - signatures *lru.ARCCache // Signatures of recent blocks to speed up mining - recentHeaders *lru.ARCCache // + recentSnaps *lru.Cache[common.Hash, *Snapshot] // Snapshots for recent block to speed up + signatures *lru.Cache[common.Hash, common.Address] // Signatures of recent blocks to speed up mining + recentHeaders *lru.Cache[string, common.Hash] // Recent headers to check for double signing: key includes block number and miner. value is the block header // If same key's value already exists for different block header roots then double sign is detected @@ -276,19 +276,6 @@ func New( parliaConfig := chainConfig.Parlia log.Info("Parlia", "chainConfig", chainConfig) - // Allocate the snapshot caches and create the engine - recentSnaps, err := lru.NewARC(inMemorySnapshots) - if err != nil { - panic(err) - } - signatures, err := lru.NewARC(inMemorySignatures) - if err != nil { - panic(err) - } - recentHeaders, err := lru.NewARC(inMemoryHeaders) - if err != nil { - panic(err) - } vABIBeforeLuban, err := abi.JSON(strings.NewReader(validatorSetABIBeforeLuban)) if err != nil { panic(err) @@ -311,9 +298,9 @@ func New( genesisHash: genesisHash, db: db, ethAPI: ethAPI, - recentSnaps: recentSnaps, - recentHeaders: recentHeaders, - signatures: signatures, + recentSnaps: lru.NewCache[common.Hash, *Snapshot](inMemorySnapshots), + recentHeaders: lru.NewCache[string, common.Hash](inMemoryHeaders), + signatures: lru.NewCache[common.Hash, common.Address](inMemorySignatures), validatorSetABIBeforeLuban: vABIBeforeLuban, validatorSetABI: vABI, slashABI: sABI, @@ -760,7 +747,7 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash for snap == nil { // If an in-memory snapshot was found, use that if s, ok := p.recentSnaps.Get(hash); ok { - snap = s.(*Snapshot) + snap = s break } @@ -950,7 +937,7 @@ func (p *Parlia) verifySeal(chain consensus.ChainHeaderReader, header *types.Hea if ok && preHash != header.Hash() { doubleSignCounter.Inc(1) log.Warn("DoubleSign detected", " block", header.Number, " miner", header.Coinbase, - "hash1", preHash.(common.Hash), "hash2", header.Hash()) + "hash1", preHash, "hash2", header.Hash()) } else { p.recentHeaders.Add(key, header.Hash()) } diff --git a/consensus/parlia/snapshot.go b/consensus/parlia/snapshot.go index d5df7abd43..477098fa85 100644 --- a/consensus/parlia/snapshot.go +++ b/consensus/parlia/snapshot.go @@ -25,9 +25,8 @@ import ( "math" "sort" - lru "github.com/hashicorp/golang-lru" - "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" @@ -40,7 +39,7 @@ import ( type Snapshot struct { config *params.ParliaConfig // Consensus engine parameters to fine tune behavior ethAPI *ethapi.BlockChainAPI - sigCache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover + sigCache *lru.Cache[common.Hash, common.Address] // 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 @@ -63,7 +62,7 @@ type ValidatorInfo struct { // the genesis block. func newSnapshot( config *params.ParliaConfig, - sigCache *lru.ARCCache, + sigCache *lru.Cache[common.Hash, common.Address], number uint64, hash common.Hash, validators []common.Address, @@ -112,7 +111,7 @@ func (s validatorsAscending) Less(i, j int) bool { return bytes.Compare(s[i][:], func (s validatorsAscending) Swap(i, j int) { s[i], s[j] = s[j], s[i] } // loadSnapshot loads an existing snapshot from the database. -func loadSnapshot(config *params.ParliaConfig, sigCache *lru.ARCCache, db ethdb.Database, hash common.Hash, ethAPI *ethapi.BlockChainAPI) (*Snapshot, error) { +func loadSnapshot(config *params.ParliaConfig, sigCache *lru.Cache[common.Hash, common.Address], db ethdb.Database, hash common.Hash, ethAPI *ethapi.BlockChainAPI) (*Snapshot, error) { blob, err := db.Get(append([]byte("parlia-"), hash[:]...)) if err != nil { return nil, err diff --git a/core/blockchain.go b/core/blockchain.go index c056e8539f..6a497a7f08 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -56,7 +56,6 @@ import ( "github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb/hashdb" "github.com/ethereum/go-ethereum/triedb/pathdb" - exlru "github.com/hashicorp/golang-lru" "golang.org/x/crypto/sha3" ) @@ -319,9 +318,9 @@ type BlockChain struct { futureBlocks *lru.Cache[common.Hash, *types.Block] // trusted diff layers - diffLayerCache *exlru.Cache // Cache for the diffLayers - diffLayerChanCache *exlru.Cache // Cache for the difflayer channel - diffQueue *prque.Prque[int64, *types.DiffLayer] // A Priority queue to store recent diff layer + diffLayerCache *lru.Cache[common.Hash, *types.DiffLayer] // Cache for the diffLayers + diffLayerChanCache *lru.Cache[common.Hash, chan struct{}] // Cache for the difflayer channel + diffQueue *prque.Prque[int64, *types.DiffLayer] // A Priority queue to store recent diff layer diffQueueBuffer chan *types.DiffLayer diffLayerFreezerBlockLimit uint64 @@ -357,9 +356,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis "triesInMemory", cacheConfig.TriesInMemory, "scheme", cacheConfig.StateScheme) } - diffLayerCache, _ := exlru.New(diffLayerCacheLimit) - diffLayerChanCache, _ := exlru.New(diffLayerCacheLimit) - // Open trie database with provided config enableVerkle, err := EnableVerkleAtGenesis(db, genesis) if err != nil { @@ -404,8 +400,8 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis blockStatsCache: lru.NewCache[common.Hash, *BlockStats](blockCacheLimit), txLookupCache: lru.NewCache[common.Hash, txLookup](txLookupCacheLimit), futureBlocks: lru.NewCache[common.Hash, *types.Block](maxFutureBlocks), - diffLayerCache: diffLayerCache, - diffLayerChanCache: diffLayerChanCache, + diffLayerCache: lru.NewCache[common.Hash, *types.DiffLayer](diffLayerCacheLimit), + diffLayerChanCache: lru.NewCache[common.Hash, chan struct{}](diffLayerCacheLimit), engine: engine, vmConfig: vmConfig, diffQueue: prque.New[int64, *types.DiffLayer](nil), @@ -674,10 +670,6 @@ func (bc *BlockChain) cacheDiffLayer(diffLayer *types.DiffLayer, diffLayerCh cha sort.Sort(&diffLayer.Storages[index]) } - if bc.diffLayerCache.Len() >= diffLayerCacheLimit { - bc.diffLayerCache.RemoveOldest() - } - bc.diffLayerCache.Add(diffLayer.BlockHash, diffLayer) close(diffLayerCh) @@ -1836,9 +1828,6 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. diffLayer.Number = block.NumberU64() diffLayerCh := make(chan struct{}) - if bc.diffLayerChanCache.Len() >= diffLayerCacheLimit { - bc.diffLayerChanCache.RemoveOldest() - } bc.diffLayerChanCache.Add(diffLayer.BlockHash, diffLayerCh) go bc.cacheDiffLayer(diffLayer, diffLayerCh) @@ -3275,12 +3264,11 @@ func (bc *BlockChain) GetVerifyResult(blockNumber uint64, blockHash common.Hash, } func (bc *BlockChain) GetTrustedDiffLayer(blockHash common.Hash) *types.DiffLayer { - var diff *types.DiffLayer if cached, ok := bc.diffLayerCache.Get(blockHash); ok { - diff = cached.(*types.DiffLayer) - return diff + return cached } + var diff *types.DiffLayer diffStore := bc.db.DiffStore() if diffStore != nil { diff = rawdb.ReadDiffLayer(diffStore, blockHash) diff --git a/core/monitor/malicious_vote_monitor.go b/core/monitor/malicious_vote_monitor.go index 43dc4d4243..7a669d6326 100644 --- a/core/monitor/malicious_vote_monitor.go +++ b/core/monitor/malicious_vote_monitor.go @@ -3,10 +3,10 @@ package monitor import ( "encoding/json" + "github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" - lru "github.com/hashicorp/golang-lru" ) // follow define in core/vote @@ -25,24 +25,19 @@ var ( // 1. monitor whether there are bugs in the voting mechanism, so add metrics to observe it. // 2. do malicious vote slashing. TODO type MaliciousVoteMonitor struct { - curVotes map[types.BLSPublicKey]*lru.Cache + curVotes map[types.BLSPublicKey]*lru.Cache[uint64, *types.VoteEnvelope] } func NewMaliciousVoteMonitor() *MaliciousVoteMonitor { return &MaliciousVoteMonitor{ - curVotes: make(map[types.BLSPublicKey]*lru.Cache, 21), // mainnet config + curVotes: make(map[types.BLSPublicKey]*lru.Cache[uint64, *types.VoteEnvelope], 21), // mainnet config } } func (m *MaliciousVoteMonitor) ConflictDetect(newVote *types.VoteEnvelope, pendingBlockNumber uint64) bool { // get votes for specified VoteAddress if _, ok := m.curVotes[newVote.VoteAddress]; !ok { - voteDataBuffer, err := lru.New(maxSizeOfRecentEntry) - if err != nil { - log.Error("MaliciousVoteMonitor new lru failed", "err", err) - return false - } - m.curVotes[newVote.VoteAddress] = voteDataBuffer + m.curVotes[newVote.VoteAddress] = lru.NewCache[uint64, *types.VoteEnvelope](maxSizeOfRecentEntry) } voteDataBuffer := m.curVotes[newVote.VoteAddress] sourceNumber, targetNumber := newVote.Data.SourceNumber, newVote.Data.TargetNumber @@ -67,16 +62,16 @@ func (m *MaliciousVoteMonitor) ConflictDetect(newVote *types.VoteEnvelope, pendi continue } maliciousVote := false - if blockNumber == targetNumber && voteEnvelope.(*types.VoteEnvelope).Data.Hash() != newVoteHash { + if blockNumber == targetNumber && voteEnvelope.Data.Hash() != newVoteHash { violateRule1Counter.Inc(1) maliciousVote = true - } else if (blockNumber < targetNumber && voteEnvelope.(*types.VoteEnvelope).Data.SourceNumber > sourceNumber) || - (blockNumber > targetNumber && voteEnvelope.(*types.VoteEnvelope).Data.SourceNumber < sourceNumber) { + } else if (blockNumber < targetNumber && voteEnvelope.Data.SourceNumber > sourceNumber) || + (blockNumber > targetNumber && voteEnvelope.Data.SourceNumber < sourceNumber) { violateRule2Counter.Inc(1) maliciousVote = true } if maliciousVote { - evidence := types.NewSlashIndicatorFinalityEvidenceWrapper(voteEnvelope.(*types.VoteEnvelope), newVote) + evidence := types.NewSlashIndicatorFinalityEvidenceWrapper(voteEnvelope, newVote) if evidence != nil { if evidenceJson, err := json.Marshal(evidence); err == nil { log.Warn("MaliciousVote", "evidence", string(evidenceJson)) diff --git a/core/remote_state_verifier.go b/core/remote_state_verifier.go index 9754f96f35..1a54423f83 100644 --- a/core/remote_state_verifier.go +++ b/core/remote_state_verifier.go @@ -7,9 +7,8 @@ import ( "sync" "time" - lru "github.com/hashicorp/golang-lru" - "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" @@ -48,7 +47,7 @@ type remoteVerifyManager struct { taskLock sync.RWMutex tasks map[common.Hash]*verifyTask peers verifyPeers - verifiedCache *lru.Cache + verifiedCache *lru.Cache[common.Hash, bool] allowInsecure bool // Subscription @@ -61,7 +60,7 @@ type remoteVerifyManager struct { } func NewVerifyManager(blockchain *BlockChain, peers verifyPeers, allowInsecure bool) (*remoteVerifyManager, error) { - verifiedCache, _ := lru.New(verifiedCacheSize) + verifiedCache := lru.NewCache[common.Hash, bool](verifiedCacheSize) block := blockchain.CurrentBlock() if block == nil { return nil, ErrCurrentBlockNotFound @@ -178,7 +177,7 @@ func (vm *remoteVerifyManager) NewBlockVerifyTask(header *types.Header) { var diffLayer *types.DiffLayer if cached, ok := vm.bc.diffLayerChanCache.Get(hash); ok { - diffLayerCh := cached.(chan struct{}) + diffLayerCh := cached <-diffLayerCh diffLayer = vm.bc.GetTrustedDiffLayer(hash) } @@ -203,9 +202,6 @@ func (vm *remoteVerifyManager) NewBlockVerifyTask(header *types.Header) { } func (vm *remoteVerifyManager) cacheBlockVerified(hash common.Hash) { - if vm.verifiedCache.Len() >= verifiedCacheSize { - vm.verifiedCache.RemoveOldest() - } vm.verifiedCache.Add(hash, true) } diff --git a/core/vm/contract.go b/core/vm/contract.go index 59845af8c9..2496dd1efa 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -18,16 +18,16 @@ package vm import ( "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/metrics" - lru "github.com/hashicorp/golang-lru" "github.com/holiman/uint256" ) const codeBitmapCacheSize = 2000 var ( - codeBitmapCache, _ = lru.New(codeBitmapCacheSize) + codeBitmapCache = lru.NewCache[common.Hash, bitvec](codeBitmapCacheSize) contractCodeBitmapHitMeter = metrics.NewRegisteredMeter("vm/contract/code/bitmap/hit", nil) contractCodeBitmapMissMeter = metrics.NewRegisteredMeter("vm/contract/code/bitmap/miss", nil) @@ -106,7 +106,7 @@ func (c *Contract) isCode(udest uint64) bool { if !exist { if cached, ok := codeBitmapCache.Get(c.CodeHash); ok { contractCodeBitmapHitMeter.Mark(1) - analysis = cached.(bitvec) + analysis = cached } else { // Do the analysis and save in parent context // We do not need to store it in c.analysis diff --git a/core/vote/vote_journal.go b/core/vote/vote_journal.go index 2b8cc19218..9f7f042e5d 100644 --- a/core/vote/vote_journal.go +++ b/core/vote/vote_journal.go @@ -3,9 +3,9 @@ package vote import ( "encoding/json" - lru "github.com/hashicorp/golang-lru" "github.com/tidwall/wal" + "github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" @@ -21,7 +21,7 @@ type VoteJournal struct { walLog *wal.Log - voteDataBuffer *lru.Cache + voteDataBuffer *lru.Cache[uint64, *types.VoteData] } var voteJournalErrorCounter = metrics.NewRegisteredCounter("voteJournal/error", nil) @@ -36,11 +36,6 @@ func NewVoteJournal(filePath string) (*VoteJournal, error) { return nil, err } - voteDataBuffer, err := lru.New(maxSizeOfRecentEntry) - if err != nil { - return nil, err - } - firstIndex, err := walLog.FirstIndex() if err != nil { log.Error("Failed to get first index of votes journal", "err", err) @@ -53,18 +48,18 @@ func NewVoteJournal(filePath string) (*VoteJournal, error) { } voteJournal := &VoteJournal{ - journalPath: filePath, - walLog: walLog, + journalPath: filePath, + walLog: walLog, + voteDataBuffer: lru.NewCache[uint64, *types.VoteData](maxSizeOfRecentEntry), } // Reload all voteData from journal to lru memory everytime node reboot. for index := firstIndex; index <= lastIndex; index++ { if voteEnvelop, err := voteJournal.ReadVote(index); err == nil && voteEnvelop != nil { voteData := voteEnvelop.Data - voteDataBuffer.Add(voteData.TargetNumber, voteData) + voteJournal.voteDataBuffer.Add(voteData.TargetNumber, voteData) } } - voteJournal.voteDataBuffer = voteDataBuffer return voteJournal, nil } diff --git a/core/vote/vote_manager.go b/core/vote/vote_manager.go index e1effef60f..cf5da97502 100644 --- a/core/vote/vote_manager.go +++ b/core/vote/vote_manager.go @@ -295,9 +295,9 @@ func (voteManager *VoteManager) UnderRules(header *types.Header) (bool, uint64, log.Error("Failed to get voteData info from LRU cache.") continue } - if voteData.(*types.VoteData).SourceNumber > sourceNumber { + if voteData.SourceNumber > sourceNumber { log.Debug(fmt.Sprintf("error: cur vote %d-->%d is across the span of other votes %d-->%d", - sourceNumber, targetNumber, voteData.(*types.VoteData).SourceNumber, voteData.(*types.VoteData).TargetNumber)) + sourceNumber, targetNumber, voteData.SourceNumber, voteData.TargetNumber)) return false, 0, common.Hash{} } } @@ -309,9 +309,9 @@ func (voteManager *VoteManager) UnderRules(header *types.Header) (bool, uint64, log.Error("Failed to get voteData info from LRU cache.") continue } - if voteData.(*types.VoteData).SourceNumber < sourceNumber { + if voteData.SourceNumber < sourceNumber { log.Debug(fmt.Sprintf("error: cur vote %d-->%d is within the span of other votes %d-->%d", - sourceNumber, targetNumber, voteData.(*types.VoteData).SourceNumber, voteData.(*types.VoteData).TargetNumber)) + sourceNumber, targetNumber, voteData.SourceNumber, voteData.TargetNumber)) return false, 0, common.Hash{} } } diff --git a/go.mod b/go.mod index 9652af49ed..c36e491e1a 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,6 @@ require ( github.com/gorilla/websocket v1.5.3 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/billy v0.0.0-20240216141850-2abb0c79d3c4 github.com/holiman/bloomfilter/v2 v2.0.3 github.com/holiman/uint256 v1.3.2 @@ -163,6 +162,7 @@ require ( github.com/gtank/merlin v0.1.1 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e // indirect github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect diff --git a/miner/worker.go b/miner/worker.go index fcdb1a9bdd..29cedf17f5 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -25,10 +25,10 @@ import ( "time" mapset "github.com/deckarep/golang-set/v2" - lru "github.com/hashicorp/golang-lru" "github.com/holiman/uint256" "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/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" @@ -250,11 +250,10 @@ type worker struct { skipSealHook func(*task) bool // Method to decide whether skipping the sealing. fullTaskHook func() // Method to call before pushing the full sealing task. resubmitHook func(time.Duration, time.Duration) // Method to call upon updating resubmitting interval. - recentMinedBlocks *lru.Cache + recentMinedBlocks *lru.Cache[uint64, []common.Hash] } func newWorker(config *minerconfig.Config, engine consensus.Engine, eth Backend, mux *event.TypeMux, init bool) *worker { - recentMinedBlocks, _ := lru.New(recentMinedCacheLimit) chainConfig := eth.BlockChain().Config() worker := &worker{ prefetcher: core.NewStatePrefetcher(chainConfig, eth.BlockChain().HeadChain()), @@ -276,7 +275,7 @@ func newWorker(config *minerconfig.Config, engine consensus.Engine, eth Backend, startCh: make(chan struct{}, 1), exitCh: make(chan struct{}), resubmitIntervalCh: make(chan time.Duration), - recentMinedBlocks: recentMinedBlocks, + recentMinedBlocks: lru.NewCache[uint64, []common.Hash](recentMinedCacheLimit), } // Subscribe events for blockchain worker.chainHeadSub = eth.BlockChain().SubscribeChainHeadEvent(worker.chainHeadCh) @@ -639,7 +638,7 @@ func (w *worker) resultLoop() { if prev, ok := w.recentMinedBlocks.Get(block.NumberU64()); ok { doubleSign := false - prevParents, _ := prev.([]common.Hash) + prevParents := prev for _, prevParent := range prevParents { if prevParent == block.ParentHash() { log.Error("Reject Double Sign!!", "block", block.NumberU64(),