@@ -21,6 +21,8 @@ import (
2121 "math"
2222 "math/big"
2323 "sort"
24+ "sync"
25+ "sync/atomic"
2426 "time"
2527
2628 "github.com/ethereum/go-ethereum/common"
@@ -478,9 +480,10 @@ func (h *priceHeap) Pop() interface{} {
478480// better candidates for inclusion while in other cases (at the top of the baseFee peak)
479481// the floating heap is better. When baseFee is decreasing they behave similarly.
480482type txPricedList struct {
481- all * txLookup // Pointer to the map of all transactions
482- urgent , floating priceHeap // Heaps of prices of all the stored **remote** transactions
483- stales int // Number of stale price points to (re-heap trigger)
483+ all * txLookup // Pointer to the map of all transactions
484+ urgent , floating priceHeap // Heaps of prices of all the stored **remote** transactions
485+ stales int64 // Number of stale price points to (re-heap trigger)
486+ reheapMu sync.Mutex // Mutex asserts that only one routine is reheaping the list
484487}
485488
486489const (
@@ -510,8 +513,8 @@ func (l *txPricedList) Put(tx *types.Transaction, local bool) {
510513// the heap if a large enough ratio of transactions go stale.
511514func (l * txPricedList ) Removed (count int ) {
512515 // Bump the stale counter, but exit if still too low (< 25%)
513- l . stales += count
514- if l . stales <= (len (l .urgent .list )+ len (l .floating .list ))/ 4 {
516+ stales := atomic . AddInt64 ( & l . stales , int64 ( count ))
517+ if int ( stales ) <= (len (l .urgent .list )+ len (l .floating .list ))/ 4 {
515518 return
516519 }
517520 // Seems we've reached a critical number of stale transactions, reheap
@@ -535,7 +538,7 @@ func (l *txPricedList) underpricedFor(h *priceHeap, tx *types.Transaction) bool
535538 for len (h .list ) > 0 {
536539 head := h .list [0 ]
537540 if l .all .GetRemote (head .Hash ()) == nil { // Removed or migrated
538- l .stales --
541+ atomic . AddInt64 ( & l .stales , - 1 )
539542 heap .Pop (h )
540543 continue
541544 }
@@ -561,7 +564,7 @@ func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool)
561564 // Discard stale transactions if found during cleanup
562565 tx := heap .Pop (& l .urgent ).(* types.Transaction )
563566 if l .all .GetRemote (tx .Hash ()) == nil { // Removed or migrated
564- l .stales --
567+ atomic . AddInt64 ( & l .stales , - 1 )
565568 continue
566569 }
567570 // Non stale transaction found, move to floating heap
@@ -574,7 +577,7 @@ func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool)
574577 // Discard stale transactions if found during cleanup
575578 tx := heap .Pop (& l .floating ).(* types.Transaction )
576579 if l .all .GetRemote (tx .Hash ()) == nil { // Removed or migrated
577- l .stales --
580+ atomic . AddInt64 ( & l .stales , - 1 )
578581 continue
579582 }
580583 // Non stale transaction found, discard it
@@ -594,8 +597,10 @@ func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool)
594597
595598// Reheap forcibly rebuilds the heap based on the current remote transaction set.
596599func (l * txPricedList ) Reheap () {
600+ l .reheapMu .Lock ()
601+ defer l .reheapMu .Unlock ()
597602 start := time .Now ()
598- l .stales = 0
603+ atomic . StoreInt64 ( & l .stales , 0 )
599604 l .urgent .list = make ([]* types.Transaction , 0 , l .all .RemoteCount ())
600605 l .all .Range (func (hash common.Hash , tx * types.Transaction , local bool ) bool {
601606 l .urgent .list = append (l .urgent .list , tx )
0 commit comments