@@ -24,8 +24,8 @@ import (
2424 "sort"
2525 "time"
2626
27- mapset "github.com/deckarep/golang-set/v2"
2827 "github.com/ethereum/go-ethereum/common"
28+ "github.com/ethereum/go-ethereum/common/lru"
2929 "github.com/ethereum/go-ethereum/common/mclock"
3030 "github.com/ethereum/go-ethereum/core/txpool"
3131 "github.com/ethereum/go-ethereum/core/types"
@@ -53,6 +53,9 @@ const (
5353 // re-request them.
5454 maxTxUnderpricedSetSize = 32768
5555
56+ // maxTxUnderpricedTimeout is the max time a transaction should be stuck in the underpriced set.
57+ maxTxUnderpricedTimeout = int64 (5 * time .Minute )
58+
5659 // txArriveTimeout is the time allowance before an announced transaction is
5760 // explicitly requested.
5861 txArriveTimeout = 500 * time .Millisecond
@@ -148,7 +151,7 @@ type TxFetcher struct {
148151 drop chan * txDrop
149152 quit chan struct {}
150153
151- underpriced mapset. Set [common.Hash ] // Transactions discarded as too cheap (don't re-fetch)
154+ underpriced * lru. Cache [common.Hash , int64 ] // Transactions discarded as too cheap (don't re-fetch)
152155
153156 // Stage 1: Waiting lists for newly discovered transactions that might be
154157 // broadcast without needing explicit request/reply round trips.
@@ -202,7 +205,7 @@ func NewTxFetcherForTests(
202205 fetching : make (map [common.Hash ]string ),
203206 requests : make (map [string ]* txRequest ),
204207 alternates : make (map [common.Hash ]map [string ]struct {}),
205- underpriced : mapset . NewSet [common.Hash ]( ),
208+ underpriced : lru. NewCache [common.Hash , int64 ]( maxTxUnderpricedSetSize ),
206209 hasTx : hasTx ,
207210 addTxs : addTxs ,
208211 fetchTxs : fetchTxs ,
@@ -223,17 +226,16 @@ func (f *TxFetcher) Notify(peer string, hashes []common.Hash) error {
223226 // still valuable to check here because it runs concurrent to the internal
224227 // loop, so anything caught here is time saved internally.
225228 var (
226- unknowns = make ([]common.Hash , 0 , len (hashes ))
227- duplicate , underpriced int64
229+ unknowns = make ([]common.Hash , 0 , len (hashes ))
230+ duplicate int64
231+ underpriced int64
228232 )
229233 for _ , hash := range hashes {
230234 switch {
231235 case f .hasTx (hash ):
232236 duplicate ++
233-
234- case f .underpriced .Contains (hash ):
237+ case f .isKnownUnderpriced (hash ):
235238 underpriced ++
236-
237239 default :
238240 unknowns = append (unknowns , hash )
239241 }
@@ -245,10 +247,7 @@ func (f *TxFetcher) Notify(peer string, hashes []common.Hash) error {
245247 if len (unknowns ) == 0 {
246248 return nil
247249 }
248- announce := & txAnnounce {
249- origin : peer ,
250- hashes : unknowns ,
251- }
250+ announce := & txAnnounce {origin : peer , hashes : unknowns }
252251 select {
253252 case f .notify <- announce :
254253 return nil
@@ -257,6 +256,16 @@ func (f *TxFetcher) Notify(peer string, hashes []common.Hash) error {
257256 }
258257}
259258
259+ // isKnownUnderpriced reports whether a transaction hash was recently found to be underpriced.
260+ func (f * TxFetcher ) isKnownUnderpriced (hash common.Hash ) bool {
261+ prevTime , ok := f .underpriced .Peek (hash )
262+ if ok && prevTime + maxTxUnderpricedTimeout < time .Now ().Unix () {
263+ f .underpriced .Remove (hash )
264+ return false
265+ }
266+ return ok
267+ }
268+
260269// Enqueue imports a batch of received transaction into the transaction pool
261270// and the fetcher. This method may be called by both transaction broadcasts and
262271// direct request replies. The differentiation is important so the fetcher can
@@ -300,10 +309,7 @@ func (f *TxFetcher) Enqueue(peer string, txs []*types.Transaction, direct bool)
300309 // Avoid re-request this transaction when we receive another
301310 // announcement.
302311 if errors .Is (err , txpool .ErrUnderpriced ) || errors .Is (err , txpool .ErrReplaceUnderpriced ) {
303- for f .underpriced .Cardinality () >= maxTxUnderpricedSetSize {
304- f .underpriced .Pop ()
305- }
306- f .underpriced .Add (batch [j ].Hash ())
312+ f .underpriced .Add (batch [j ].Hash (), batch [j ].Time ().Unix ())
307313 }
308314 // Track a few interesting failure types
309315 switch {
0 commit comments