@@ -21,6 +21,8 @@ import (
2121 "math"
2222 "math/big"
2323 "sort"
24+ "sync"
25+ "sync/atomic"
2426
2527 "github.com/XinFinOrg/XDPoSChain/common"
2628 "github.com/XinFinOrg/XDPoSChain/core/types"
@@ -450,9 +452,10 @@ func (h *priceHeap) Pop() interface{} {
450452// in txpool but only interested in the remote part. It means only remote transactions
451453// will be considered for tracking, sorting, eviction, etc.
452454type txPricedList struct {
453- all * txLookup // Pointer to the map of all transactions
454- remotes * priceHeap // Heap of prices of all the stored **remote** transactions
455- stales int // Number of stale price points to (re-heap trigger)
455+ all * txLookup // Pointer to the map of all transactions
456+ remotes * priceHeap // Heap of prices of all the stored **remote** transactions
457+ stales int64 // Number of stale price points to (re-heap trigger)
458+ reheapMu sync.Mutex // Mutex asserts that only one routine is reheaping the list
456459}
457460
458461// newTxPricedList creates a new price-sorted transaction heap.
@@ -476,8 +479,8 @@ func (l *txPricedList) Put(tx *types.Transaction, local bool) {
476479// the heap if a large enough ratio of transactions go stale.
477480func (l * txPricedList ) Removed (count int ) {
478481 // Bump the stale counter, but exit if still too low (< 25%)
479- l . stales += count
480- if l . stales <= len (* l .remotes )/ 4 {
482+ stales := atomic . AddInt64 ( & l . stales , int64 ( count ))
483+ if int ( stales ) <= len (* l .remotes )/ 4 {
481484 return
482485 }
483486 // Seems we've reached a critical number of stale transactions, reheap
@@ -515,7 +518,7 @@ func (l *txPricedList) Underpriced(tx *types.Transaction) bool {
515518 for len (* l .remotes ) > 0 {
516519 head := []* types.Transaction (* l .remotes )[0 ]
517520 if l .all .GetRemote (head .Hash ()) == nil { // Removed or migrated
518- l .stales --
521+ atomic . AddInt64 ( & l .stales , - 1 )
519522 heap .Pop (l .remotes )
520523 continue
521524 }
@@ -541,7 +544,7 @@ func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool)
541544 // Discard stale transactions if found during cleanup
542545 tx := heap .Pop (l .remotes ).(* types.Transaction )
543546 if l .all .GetRemote (tx .Hash ()) == nil { // Removed or migrated
544- l .stales --
547+ atomic . AddInt64 ( & l .stales , - 1 )
545548 continue
546549 }
547550 // Non stale transaction found, discard it
@@ -560,9 +563,12 @@ func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool)
560563
561564// Reheap forcibly rebuilds the heap based on the current remote transaction set.
562565func (l * txPricedList ) Reheap () {
566+ l .reheapMu .Lock ()
567+ defer l .reheapMu .Unlock ()
563568 reheap := make (priceHeap , 0 , l .all .RemoteCount ())
564569
565- l .stales , l .remotes = 0 , & reheap
570+ atomic .StoreInt64 (& l .stales , 0 )
571+ l .remotes = & reheap
566572 l .all .Range (func (hash common.Hash , tx * types.Transaction , local bool ) bool {
567573 * l .remotes = append (* l .remotes , tx )
568574 return true
0 commit comments