@@ -21,6 +21,8 @@ import (
21
21
"math"
22
22
"math/big"
23
23
"sort"
24
+ "sync"
25
+ "sync/atomic"
24
26
"time"
25
27
26
28
"github.com/ethereum/go-ethereum/common"
@@ -478,9 +480,10 @@ func (h *priceHeap) Pop() interface{} {
478
480
// better candidates for inclusion while in other cases (at the top of the baseFee peak)
479
481
// the floating heap is better. When baseFee is decreasing they behave similarly.
480
482
type 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
484
487
}
485
488
486
489
const (
@@ -510,8 +513,8 @@ func (l *txPricedList) Put(tx *types.Transaction, local bool) {
510
513
// the heap if a large enough ratio of transactions go stale.
511
514
func (l * txPricedList ) Removed (count int ) {
512
515
// 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 {
515
518
return
516
519
}
517
520
// 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
535
538
for len (h .list ) > 0 {
536
539
head := h .list [0 ]
537
540
if l .all .GetRemote (head .Hash ()) == nil { // Removed or migrated
538
- l .stales --
541
+ atomic . AddInt64 ( & l .stales , - 1 )
539
542
heap .Pop (h )
540
543
continue
541
544
}
@@ -561,7 +564,7 @@ func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool)
561
564
// Discard stale transactions if found during cleanup
562
565
tx := heap .Pop (& l .urgent ).(* types.Transaction )
563
566
if l .all .GetRemote (tx .Hash ()) == nil { // Removed or migrated
564
- l .stales --
567
+ atomic . AddInt64 ( & l .stales , - 1 )
565
568
continue
566
569
}
567
570
// Non stale transaction found, move to floating heap
@@ -574,7 +577,7 @@ func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool)
574
577
// Discard stale transactions if found during cleanup
575
578
tx := heap .Pop (& l .floating ).(* types.Transaction )
576
579
if l .all .GetRemote (tx .Hash ()) == nil { // Removed or migrated
577
- l .stales --
580
+ atomic . AddInt64 ( & l .stales , - 1 )
578
581
continue
579
582
}
580
583
// Non stale transaction found, discard it
@@ -594,8 +597,10 @@ func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool)
594
597
595
598
// Reheap forcibly rebuilds the heap based on the current remote transaction set.
596
599
func (l * txPricedList ) Reheap () {
600
+ l .reheapMu .Lock ()
601
+ defer l .reheapMu .Unlock ()
597
602
start := time .Now ()
598
- l .stales = 0
603
+ atomic . StoreInt64 ( & l .stales , 0 )
599
604
l .urgent .list = make ([]* types.Transaction , 0 , l .all .RemoteCount ())
600
605
l .all .Range (func (hash common.Hash , tx * types.Transaction , local bool ) bool {
601
606
l .urgent .list = append (l .urgent .list , tx )
0 commit comments