@@ -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/XinFinOrg/XDPoSChain/common"
@@ -487,9 +489,10 @@ func (h *priceHeap) Pop() interface{} {
487
489
// better candidates for inclusion while in other cases (at the top of the baseFee peak)
488
490
// the floating heap is better. When baseFee is decreasing they behave similarly.
489
491
type txPricedList struct {
490
- all * txLookup // Pointer to the map of all transactions
491
- urgent , floating priceHeap // Heaps of prices of all the stored **remote** transactions
492
- stales int // Number of stale price points to (re-heap trigger)
492
+ all * txLookup // Pointer to the map of all transactions
493
+ urgent , floating priceHeap // Heaps of prices of all the stored **remote** transactions
494
+ stales int64 // Number of stale price points to (re-heap trigger)
495
+ reheapMu sync.Mutex // Mutex asserts that only one routine is reheaping the list
493
496
}
494
497
495
498
const (
@@ -519,8 +522,8 @@ func (l *txPricedList) Put(tx *types.Transaction, local bool) {
519
522
// the heap if a large enough ratio of transactions go stale.
520
523
func (l * txPricedList ) Removed (count int ) {
521
524
// Bump the stale counter, but exit if still too low (< 25%)
522
- l . stales += count
523
- if l . stales <= (len (l .urgent .list )+ len (l .floating .list ))/ 4 {
525
+ stales := atomic . AddInt64 ( & l . stales , int64 ( count ))
526
+ if int ( stales ) <= (len (l .urgent .list )+ len (l .floating .list ))/ 4 {
524
527
return
525
528
}
526
529
// Seems we've reached a critical number of stale transactions, reheap
@@ -544,7 +547,7 @@ func (l *txPricedList) underpricedFor(h *priceHeap, tx *types.Transaction) bool
544
547
for len (h .list ) > 0 {
545
548
head := h .list [0 ]
546
549
if l .all .GetRemote (head .Hash ()) == nil { // Removed or migrated
547
- l .stales --
550
+ atomic . AddInt64 ( & l .stales , - 1 )
548
551
heap .Pop (h )
549
552
continue
550
553
}
@@ -570,7 +573,7 @@ func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool)
570
573
// Discard stale transactions if found during cleanup
571
574
tx := heap .Pop (& l .urgent ).(* types.Transaction )
572
575
if l .all .GetRemote (tx .Hash ()) == nil { // Removed or migrated
573
- l .stales --
576
+ atomic . AddInt64 ( & l .stales , - 1 )
574
577
continue
575
578
}
576
579
// Non stale transaction found, move to floating heap
@@ -583,7 +586,7 @@ func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool)
583
586
// Discard stale transactions if found during cleanup
584
587
tx := heap .Pop (& l .floating ).(* types.Transaction )
585
588
if l .all .GetRemote (tx .Hash ()) == nil { // Removed or migrated
586
- l .stales --
589
+ atomic . AddInt64 ( & l .stales , - 1 )
587
590
continue
588
591
}
589
592
// Non stale transaction found, discard it
@@ -603,8 +606,10 @@ func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool)
603
606
604
607
// Reheap forcibly rebuilds the heap based on the current remote transaction set.
605
608
func (l * txPricedList ) Reheap () {
609
+ l .reheapMu .Lock ()
610
+ defer l .reheapMu .Unlock ()
606
611
start := time .Now ()
607
- l .stales = 0
612
+ atomic . StoreInt64 ( & l .stales , 0 )
608
613
l .urgent .list = make ([]* types.Transaction , 0 , l .all .RemoteCount ())
609
614
l .all .Range (func (hash common.Hash , tx * types.Transaction , local bool ) bool {
610
615
l .urgent .list = append (l .urgent .list , tx )
0 commit comments