github.com/theQRL/go-zond@v0.2.1/core/txpool/legacypool/list.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package legacypool
    18  
    19  import (
    20  	"container/heap"
    21  	"math"
    22  	"math/big"
    23  	"slices"
    24  	"sort"
    25  	"sync"
    26  	"sync/atomic"
    27  	"time"
    28  
    29  	"github.com/theQRL/go-zond/common"
    30  	"github.com/theQRL/go-zond/core/types"
    31  )
    32  
    33  // nonceHeap is a heap.Interface implementation over 64bit unsigned integers for
    34  // retrieving sorted transactions from the possibly gapped future queue.
    35  type nonceHeap []uint64
    36  
    37  func (h nonceHeap) Len() int           { return len(h) }
    38  func (h nonceHeap) Less(i, j int) bool { return h[i] < h[j] }
    39  func (h nonceHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
    40  
    41  func (h *nonceHeap) Push(x interface{}) {
    42  	*h = append(*h, x.(uint64))
    43  }
    44  
    45  func (h *nonceHeap) Pop() interface{} {
    46  	old := *h
    47  	n := len(old)
    48  	x := old[n-1]
    49  	old[n-1] = 0
    50  	*h = old[0 : n-1]
    51  	return x
    52  }
    53  
    54  // sortedMap is a nonce->transaction hash map with a heap based index to allow
    55  // iterating over the contents in a nonce-incrementing way.
    56  type sortedMap struct {
    57  	items   map[uint64]*types.Transaction // Hash map storing the transaction data
    58  	index   *nonceHeap                    // Heap of nonces of all the stored transactions (non-strict mode)
    59  	cache   types.Transactions            // Cache of the transactions already sorted
    60  	cacheMu sync.Mutex                    // Mutex covering the cache
    61  }
    62  
    63  // newSortedMap creates a new nonce-sorted transaction map.
    64  func newSortedMap() *sortedMap {
    65  	return &sortedMap{
    66  		items: make(map[uint64]*types.Transaction),
    67  		index: new(nonceHeap),
    68  	}
    69  }
    70  
    71  // Get retrieves the current transactions associated with the given nonce.
    72  func (m *sortedMap) Get(nonce uint64) *types.Transaction {
    73  	return m.items[nonce]
    74  }
    75  
    76  // Put inserts a new transaction into the map, also updating the map's nonce
    77  // index. If a transaction already exists with the same nonce, it's overwritten.
    78  func (m *sortedMap) Put(tx *types.Transaction) {
    79  	nonce := tx.Nonce()
    80  	if m.items[nonce] == nil {
    81  		heap.Push(m.index, nonce)
    82  	}
    83  	m.cacheMu.Lock()
    84  	m.items[nonce], m.cache = tx, nil
    85  	m.cacheMu.Unlock()
    86  }
    87  
    88  // Forward removes all transactions from the map with a nonce lower than the
    89  // provided threshold. Every removed transaction is returned for any post-removal
    90  // maintenance.
    91  func (m *sortedMap) Forward(threshold uint64) types.Transactions {
    92  	var removed types.Transactions
    93  
    94  	// Pop off heap items until the threshold is reached
    95  	for m.index.Len() > 0 && (*m.index)[0] < threshold {
    96  		nonce := heap.Pop(m.index).(uint64)
    97  		removed = append(removed, m.items[nonce])
    98  		delete(m.items, nonce)
    99  	}
   100  	// If we had a cached order, shift the front
   101  	m.cacheMu.Lock()
   102  	if m.cache != nil {
   103  		m.cache = m.cache[len(removed):]
   104  	}
   105  	m.cacheMu.Unlock()
   106  	return removed
   107  }
   108  
   109  // Filter iterates over the list of transactions and removes all of them for which
   110  // the specified function evaluates to true.
   111  // Filter, as opposed to 'filter', re-initialises the heap after the operation is done.
   112  // If you want to do several consecutive filterings, it's therefore better to first
   113  // do a .filter(func1) followed by .Filter(func2) or reheap()
   114  func (m *sortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions {
   115  	removed := m.filter(filter)
   116  	// If transactions were removed, the heap and cache are ruined
   117  	if len(removed) > 0 {
   118  		m.reheap()
   119  	}
   120  	return removed
   121  }
   122  
   123  func (m *sortedMap) reheap() {
   124  	*m.index = make([]uint64, 0, len(m.items))
   125  	for nonce := range m.items {
   126  		*m.index = append(*m.index, nonce)
   127  	}
   128  	heap.Init(m.index)
   129  	m.cacheMu.Lock()
   130  	m.cache = nil
   131  	m.cacheMu.Unlock()
   132  }
   133  
   134  // filter is identical to Filter, but **does not** regenerate the heap. This method
   135  // should only be used if followed immediately by a call to Filter or reheap()
   136  func (m *sortedMap) filter(filter func(*types.Transaction) bool) types.Transactions {
   137  	var removed types.Transactions
   138  
   139  	// Collect all the transactions to filter out
   140  	for nonce, tx := range m.items {
   141  		if filter(tx) {
   142  			removed = append(removed, tx)
   143  			delete(m.items, nonce)
   144  		}
   145  	}
   146  	if len(removed) > 0 {
   147  		m.cacheMu.Lock()
   148  		m.cache = nil
   149  		m.cacheMu.Unlock()
   150  	}
   151  	return removed
   152  }
   153  
   154  // Cap places a hard limit on the number of items, returning all transactions
   155  // exceeding that limit.
   156  func (m *sortedMap) Cap(threshold int) types.Transactions {
   157  	// Short circuit if the number of items is under the limit
   158  	if len(m.items) <= threshold {
   159  		return nil
   160  	}
   161  	// Otherwise gather and drop the highest nonce'd transactions
   162  	var drops types.Transactions
   163  
   164  	slices.Sort(*m.index)
   165  	for size := len(m.items); size > threshold; size-- {
   166  		drops = append(drops, m.items[(*m.index)[size-1]])
   167  		delete(m.items, (*m.index)[size-1])
   168  	}
   169  	*m.index = (*m.index)[:threshold]
   170  	// The sorted m.index slice is still a valid heap, so there is no need to
   171  	// reheap after deleting tail items.
   172  
   173  	// If we had a cache, shift the back
   174  	m.cacheMu.Lock()
   175  	if m.cache != nil {
   176  		m.cache = m.cache[:len(m.cache)-len(drops)]
   177  	}
   178  	m.cacheMu.Unlock()
   179  	return drops
   180  }
   181  
   182  // Remove deletes a transaction from the maintained map, returning whether the
   183  // transaction was found.
   184  func (m *sortedMap) Remove(nonce uint64) bool {
   185  	// Short circuit if no transaction is present
   186  	_, ok := m.items[nonce]
   187  	if !ok {
   188  		return false
   189  	}
   190  	// Otherwise delete the transaction and fix the heap index
   191  	for i := 0; i < m.index.Len(); i++ {
   192  		if (*m.index)[i] == nonce {
   193  			heap.Remove(m.index, i)
   194  			break
   195  		}
   196  	}
   197  	delete(m.items, nonce)
   198  	m.cacheMu.Lock()
   199  	m.cache = nil
   200  	m.cacheMu.Unlock()
   201  
   202  	return true
   203  }
   204  
   205  // Ready retrieves a sequentially increasing list of transactions starting at the
   206  // provided nonce that is ready for processing. The returned transactions will be
   207  // removed from the list.
   208  //
   209  // Note, all transactions with nonces lower than start will also be returned to
   210  // prevent getting into an invalid state. This is not something that should ever
   211  // happen but better to be self correcting than failing!
   212  func (m *sortedMap) Ready(start uint64) types.Transactions {
   213  	// Short circuit if no transactions are available
   214  	if m.index.Len() == 0 || (*m.index)[0] > start {
   215  		return nil
   216  	}
   217  	// Otherwise start accumulating incremental transactions
   218  	var ready types.Transactions
   219  	for next := (*m.index)[0]; m.index.Len() > 0 && (*m.index)[0] == next; next++ {
   220  		ready = append(ready, m.items[next])
   221  		delete(m.items, next)
   222  		heap.Pop(m.index)
   223  	}
   224  	m.cacheMu.Lock()
   225  	m.cache = nil
   226  	m.cacheMu.Unlock()
   227  
   228  	return ready
   229  }
   230  
   231  // Len returns the length of the transaction map.
   232  func (m *sortedMap) Len() int {
   233  	return len(m.items)
   234  }
   235  
   236  func (m *sortedMap) flatten() types.Transactions {
   237  	m.cacheMu.Lock()
   238  	defer m.cacheMu.Unlock()
   239  	// If the sorting was not cached yet, create and cache it
   240  	if m.cache == nil {
   241  		m.cache = make(types.Transactions, 0, len(m.items))
   242  		for _, tx := range m.items {
   243  			m.cache = append(m.cache, tx)
   244  		}
   245  		sort.Sort(types.TxByNonce(m.cache))
   246  	}
   247  	return m.cache
   248  }
   249  
   250  // Flatten creates a nonce-sorted slice of transactions based on the loosely
   251  // sorted internal representation. The result of the sorting is cached in case
   252  // it's requested again before any modifications are made to the contents.
   253  func (m *sortedMap) Flatten() types.Transactions {
   254  	cache := m.flatten()
   255  	// Copy the cache to prevent accidental modification
   256  	txs := make(types.Transactions, len(cache))
   257  	copy(txs, cache)
   258  	return txs
   259  }
   260  
   261  // LastElement returns the last element of a flattened list, thus, the
   262  // transaction with the highest nonce
   263  func (m *sortedMap) LastElement() *types.Transaction {
   264  	cache := m.flatten()
   265  	return cache[len(cache)-1]
   266  }
   267  
   268  // list is a "list" of transactions belonging to an account, sorted by account
   269  // nonce. The same type can be used both for storing contiguous transactions for
   270  // the executable/pending queue; and for storing gapped transactions for the non-
   271  // executable/future queue, with minor behavioral changes.
   272  type list struct {
   273  	strict bool       // Whether nonces are strictly continuous or not
   274  	txs    *sortedMap // Heap indexed sorted hash map of the transactions
   275  
   276  	costcap   *big.Int // Price of the highest costing transaction (reset only if exceeds balance)
   277  	gascap    uint64   // Gas limit of the highest spending transaction (reset only if exceeds block limit)
   278  	totalcost *big.Int // Total cost of all transactions in the list
   279  }
   280  
   281  // newList create a new transaction list for maintaining nonce-indexable fast,
   282  // gapped, sortable transaction lists.
   283  func newList(strict bool) *list {
   284  	return &list{
   285  		strict:    strict,
   286  		txs:       newSortedMap(),
   287  		costcap:   new(big.Int),
   288  		totalcost: new(big.Int),
   289  	}
   290  }
   291  
   292  // Contains returns whether the  list contains a transaction
   293  // with the provided nonce.
   294  func (l *list) Contains(nonce uint64) bool {
   295  	return l.txs.Get(nonce) != nil
   296  }
   297  
   298  // Add tries to insert a new transaction into the list, returning whether the
   299  // transaction was accepted, and if yes, any previous transaction it replaced.
   300  //
   301  // If the new transaction is accepted into the list, the lists' cost and gas
   302  // thresholds are also potentially updated.
   303  func (l *list) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transaction) {
   304  	// If there's an older better transaction, abort
   305  	old := l.txs.Get(tx.Nonce())
   306  	if old != nil {
   307  		if old.GasFeeCapCmp(tx) >= 0 || old.GasTipCapCmp(tx) >= 0 {
   308  			return false, nil
   309  		}
   310  		// thresholdFeeCap = oldFC  * (100 + priceBump) / 100
   311  		a := big.NewInt(100 + int64(priceBump))
   312  		aFeeCap := new(big.Int).Mul(a, old.GasFeeCap())
   313  		aTip := a.Mul(a, old.GasTipCap())
   314  
   315  		// thresholdTip    = oldTip * (100 + priceBump) / 100
   316  		b := big.NewInt(100)
   317  		thresholdFeeCap := aFeeCap.Div(aFeeCap, b)
   318  		thresholdTip := aTip.Div(aTip, b)
   319  
   320  		// We have to ensure that both the new fee cap and tip are higher than the
   321  		// old ones as well as checking the percentage threshold to ensure that
   322  		// this is accurate for low (Wei-level) gas price replacements.
   323  		if tx.GasFeeCapIntCmp(thresholdFeeCap) < 0 || tx.GasTipCapIntCmp(thresholdTip) < 0 {
   324  			return false, nil
   325  		}
   326  		// Old is being replaced, subtract old cost
   327  		l.subTotalCost([]*types.Transaction{old})
   328  	}
   329  	// Add new tx cost to totalcost
   330  	l.totalcost.Add(l.totalcost, tx.Cost())
   331  	// Otherwise overwrite the old transaction with the current one
   332  	l.txs.Put(tx)
   333  	if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 {
   334  		l.costcap = cost
   335  	}
   336  	if gas := tx.Gas(); l.gascap < gas {
   337  		l.gascap = gas
   338  	}
   339  	return true, old
   340  }
   341  
   342  // Forward removes all transactions from the list with a nonce lower than the
   343  // provided threshold. Every removed transaction is returned for any post-removal
   344  // maintenance.
   345  func (l *list) Forward(threshold uint64) types.Transactions {
   346  	txs := l.txs.Forward(threshold)
   347  	l.subTotalCost(txs)
   348  	return txs
   349  }
   350  
   351  // Filter removes all transactions from the list with a cost or gas limit higher
   352  // than the provided thresholds. Every removed transaction is returned for any
   353  // post-removal maintenance. Strict-mode invalidated transactions are also
   354  // returned.
   355  //
   356  // This method uses the cached costcap and gascap to quickly decide if there's even
   357  // a point in calculating all the costs or if the balance covers all. If the threshold
   358  // is lower than the costgas cap, the caps will be reset to a new high after removing
   359  // the newly invalidated transactions.
   360  func (l *list) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions, types.Transactions) {
   361  	// If all transactions are below the threshold, short circuit
   362  	if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit {
   363  		return nil, nil
   364  	}
   365  	l.costcap = new(big.Int).Set(costLimit) // Lower the caps to the thresholds
   366  	l.gascap = gasLimit
   367  
   368  	// Filter out all the transactions above the account's funds
   369  	removed := l.txs.Filter(func(tx *types.Transaction) bool {
   370  		return tx.Gas() > gasLimit || tx.Cost().Cmp(costLimit) > 0
   371  	})
   372  
   373  	if len(removed) == 0 {
   374  		return nil, nil
   375  	}
   376  	var invalids types.Transactions
   377  	// If the list was strict, filter anything above the lowest nonce
   378  	if l.strict {
   379  		lowest := uint64(math.MaxUint64)
   380  		for _, tx := range removed {
   381  			if nonce := tx.Nonce(); lowest > nonce {
   382  				lowest = nonce
   383  			}
   384  		}
   385  		invalids = l.txs.filter(func(tx *types.Transaction) bool { return tx.Nonce() > lowest })
   386  	}
   387  	// Reset total cost
   388  	l.subTotalCost(removed)
   389  	l.subTotalCost(invalids)
   390  	l.txs.reheap()
   391  	return removed, invalids
   392  }
   393  
   394  // Cap places a hard limit on the number of items, returning all transactions
   395  // exceeding that limit.
   396  func (l *list) Cap(threshold int) types.Transactions {
   397  	txs := l.txs.Cap(threshold)
   398  	l.subTotalCost(txs)
   399  	return txs
   400  }
   401  
   402  // Remove deletes a transaction from the maintained list, returning whether the
   403  // transaction was found, and also returning any transaction invalidated due to
   404  // the deletion (strict mode only).
   405  func (l *list) Remove(tx *types.Transaction) (bool, types.Transactions) {
   406  	// Remove the transaction from the set
   407  	nonce := tx.Nonce()
   408  	if removed := l.txs.Remove(nonce); !removed {
   409  		return false, nil
   410  	}
   411  	l.subTotalCost([]*types.Transaction{tx})
   412  	// In strict mode, filter out non-executable transactions
   413  	if l.strict {
   414  		txs := l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > nonce })
   415  		l.subTotalCost(txs)
   416  		return true, txs
   417  	}
   418  	return true, nil
   419  }
   420  
   421  // Ready retrieves a sequentially increasing list of transactions starting at the
   422  // provided nonce that is ready for processing. The returned transactions will be
   423  // removed from the list.
   424  //
   425  // Note, all transactions with nonces lower than start will also be returned to
   426  // prevent getting into an invalid state. This is not something that should ever
   427  // happen but better to be self correcting than failing!
   428  func (l *list) Ready(start uint64) types.Transactions {
   429  	txs := l.txs.Ready(start)
   430  	l.subTotalCost(txs)
   431  	return txs
   432  }
   433  
   434  // Len returns the length of the transaction list.
   435  func (l *list) Len() int {
   436  	return l.txs.Len()
   437  }
   438  
   439  // Empty returns whether the list of transactions is empty or not.
   440  func (l *list) Empty() bool {
   441  	return l.Len() == 0
   442  }
   443  
   444  // Flatten creates a nonce-sorted slice of transactions based on the loosely
   445  // sorted internal representation. The result of the sorting is cached in case
   446  // it's requested again before any modifications are made to the contents.
   447  func (l *list) Flatten() types.Transactions {
   448  	return l.txs.Flatten()
   449  }
   450  
   451  // LastElement returns the last element of a flattened list, thus, the
   452  // transaction with the highest nonce
   453  func (l *list) LastElement() *types.Transaction {
   454  	return l.txs.LastElement()
   455  }
   456  
   457  // subTotalCost subtracts the cost of the given transactions from the
   458  // total cost of all transactions.
   459  func (l *list) subTotalCost(txs []*types.Transaction) {
   460  	for _, tx := range txs {
   461  		l.totalcost.Sub(l.totalcost, tx.Cost())
   462  	}
   463  }
   464  
   465  // priceHeap is a heap.Interface implementation over transactions for retrieving
   466  // price-sorted transactions to discard when the pool fills up. If baseFee is set
   467  // then the heap is sorted based on the effective tip based on the given base fee.
   468  // If baseFee is nil then the sorting is based on gasFeeCap.
   469  type priceHeap struct {
   470  	baseFee *big.Int // heap should always be re-sorted after baseFee is changed
   471  	list    []*types.Transaction
   472  }
   473  
   474  func (h *priceHeap) Len() int      { return len(h.list) }
   475  func (h *priceHeap) Swap(i, j int) { h.list[i], h.list[j] = h.list[j], h.list[i] }
   476  
   477  func (h *priceHeap) Less(i, j int) bool {
   478  	switch h.cmp(h.list[i], h.list[j]) {
   479  	case -1:
   480  		return true
   481  	case 1:
   482  		return false
   483  	default:
   484  		return h.list[i].Nonce() > h.list[j].Nonce()
   485  	}
   486  }
   487  
   488  func (h *priceHeap) cmp(a, b *types.Transaction) int {
   489  	if h.baseFee != nil {
   490  		// Compare effective tips if baseFee is specified
   491  		if c := a.EffectiveGasTipCmp(b, h.baseFee); c != 0 {
   492  			return c
   493  		}
   494  	}
   495  	// Compare fee caps if baseFee is not specified or effective tips are equal
   496  	if c := a.GasFeeCapCmp(b); c != 0 {
   497  		return c
   498  	}
   499  	// Compare tips if effective tips and fee caps are equal
   500  	return a.GasTipCapCmp(b)
   501  }
   502  
   503  func (h *priceHeap) Push(x interface{}) {
   504  	tx := x.(*types.Transaction)
   505  	h.list = append(h.list, tx)
   506  }
   507  
   508  func (h *priceHeap) Pop() interface{} {
   509  	old := h.list
   510  	n := len(old)
   511  	x := old[n-1]
   512  	old[n-1] = nil
   513  	h.list = old[0 : n-1]
   514  	return x
   515  }
   516  
   517  // pricedList is a price-sorted heap to allow operating on transactions pool
   518  // contents in a price-incrementing way. It's built upon the all transactions
   519  // in txpool but only interested in the remote part. It means only remote transactions
   520  // will be considered for tracking, sorting, eviction, etc.
   521  //
   522  // Two heaps are used for sorting: the urgent heap (based on effective tip in the next
   523  // block) and the floating heap (based on gasFeeCap). Always the bigger heap is chosen for
   524  // eviction. Transactions evicted from the urgent heap are first demoted into the floating heap.
   525  // In some cases (during a congestion, when blocks are full) the urgent heap can provide
   526  // better candidates for inclusion while in other cases (at the top of the baseFee peak)
   527  // the floating heap is better. When baseFee is decreasing they behave similarly.
   528  type pricedList struct {
   529  	// Number of stale price points to (re-heap trigger).
   530  	stales atomic.Int64
   531  
   532  	all              *lookup    // Pointer to the map of all transactions
   533  	urgent, floating priceHeap  // Heaps of prices of all the stored **remote** transactions
   534  	reheapMu         sync.Mutex // Mutex asserts that only one routine is reheaping the list
   535  }
   536  
   537  const (
   538  	// urgentRatio : floatingRatio is the capacity ratio of the two queues
   539  	urgentRatio   = 4
   540  	floatingRatio = 1
   541  )
   542  
   543  // newPricedList creates a new price-sorted transaction heap.
   544  func newPricedList(all *lookup) *pricedList {
   545  	return &pricedList{
   546  		all: all,
   547  	}
   548  }
   549  
   550  // Put inserts a new transaction into the heap.
   551  func (l *pricedList) Put(tx *types.Transaction, local bool) {
   552  	if local {
   553  		return
   554  	}
   555  	// Insert every new transaction to the urgent heap first; Discard will balance the heaps
   556  	heap.Push(&l.urgent, tx)
   557  }
   558  
   559  // Removed notifies the prices transaction list that an old transaction dropped
   560  // from the pool. The list will just keep a counter of stale objects and update
   561  // the heap if a large enough ratio of transactions go stale.
   562  func (l *pricedList) Removed(count int) {
   563  	// Bump the stale counter, but exit if still too low (< 25%)
   564  	stales := l.stales.Add(int64(count))
   565  	if int(stales) <= (len(l.urgent.list)+len(l.floating.list))/4 {
   566  		return
   567  	}
   568  	// Seems we've reached a critical number of stale transactions, reheap
   569  	l.Reheap()
   570  }
   571  
   572  // Underpriced checks whether a transaction is cheaper than (or as cheap as) the
   573  // lowest priced (remote) transaction currently being tracked.
   574  func (l *pricedList) Underpriced(tx *types.Transaction) bool {
   575  	// Note: with two queues, being underpriced is defined as being worse than the worst item
   576  	// in all non-empty queues if there is any. If both queues are empty then nothing is underpriced.
   577  	return (l.underpricedFor(&l.urgent, tx) || len(l.urgent.list) == 0) &&
   578  		(l.underpricedFor(&l.floating, tx) || len(l.floating.list) == 0) &&
   579  		(len(l.urgent.list) != 0 || len(l.floating.list) != 0)
   580  }
   581  
   582  // underpricedFor checks whether a transaction is cheaper than (or as cheap as) the
   583  // lowest priced (remote) transaction in the given heap.
   584  func (l *pricedList) underpricedFor(h *priceHeap, tx *types.Transaction) bool {
   585  	// Discard stale price points if found at the heap start
   586  	for len(h.list) > 0 {
   587  		head := h.list[0]
   588  		if l.all.GetRemote(head.Hash()) == nil { // Removed or migrated
   589  			l.stales.Add(-1)
   590  			heap.Pop(h)
   591  			continue
   592  		}
   593  		break
   594  	}
   595  	// Check if the transaction is underpriced or not
   596  	if len(h.list) == 0 {
   597  		return false // There is no remote transaction at all.
   598  	}
   599  	// If the remote transaction is even cheaper than the
   600  	// cheapest one tracked locally, reject it.
   601  	return h.cmp(h.list[0], tx) >= 0
   602  }
   603  
   604  // Discard finds a number of most underpriced transactions, removes them from the
   605  // priced list and returns them for further removal from the entire pool.
   606  // If noPending is set to true, we will only consider the floating list
   607  //
   608  // Note local transaction won't be considered for eviction.
   609  func (l *pricedList) Discard(slots int, force bool) (types.Transactions, bool) {
   610  	drop := make(types.Transactions, 0, slots) // Remote underpriced transactions to drop
   611  	for slots > 0 {
   612  		if len(l.urgent.list)*floatingRatio > len(l.floating.list)*urgentRatio {
   613  			// Discard stale transactions if found during cleanup
   614  			tx := heap.Pop(&l.urgent).(*types.Transaction)
   615  			if l.all.GetRemote(tx.Hash()) == nil { // Removed or migrated
   616  				l.stales.Add(-1)
   617  				continue
   618  			}
   619  			// Non stale transaction found, move to floating heap
   620  			heap.Push(&l.floating, tx)
   621  		} else {
   622  			if len(l.floating.list) == 0 {
   623  				// Stop if both heaps are empty
   624  				break
   625  			}
   626  			// Discard stale transactions if found during cleanup
   627  			tx := heap.Pop(&l.floating).(*types.Transaction)
   628  			if l.all.GetRemote(tx.Hash()) == nil { // Removed or migrated
   629  				l.stales.Add(-1)
   630  				continue
   631  			}
   632  			// Non stale transaction found, discard it
   633  			drop = append(drop, tx)
   634  			slots -= numSlots(tx)
   635  		}
   636  	}
   637  	// If we still can't make enough room for the new transaction
   638  	if slots > 0 && !force {
   639  		for _, tx := range drop {
   640  			heap.Push(&l.urgent, tx)
   641  		}
   642  		return nil, false
   643  	}
   644  	return drop, true
   645  }
   646  
   647  // Reheap forcibly rebuilds the heap based on the current remote transaction set.
   648  func (l *pricedList) Reheap() {
   649  	l.reheapMu.Lock()
   650  	defer l.reheapMu.Unlock()
   651  	start := time.Now()
   652  	l.stales.Store(0)
   653  	l.urgent.list = make([]*types.Transaction, 0, l.all.RemoteCount())
   654  	l.all.Range(func(hash common.Hash, tx *types.Transaction, local bool) bool {
   655  		l.urgent.list = append(l.urgent.list, tx)
   656  		return true
   657  	}, false, true) // Only iterate remotes
   658  	heap.Init(&l.urgent)
   659  
   660  	// balance out the two heaps by moving the worse half of transactions into the
   661  	// floating heap
   662  	// Note: Discard would also do this before the first eviction but Reheap can do
   663  	// is more efficiently. Also, Underpriced would work suboptimally the first time
   664  	// if the floating queue was empty.
   665  	floatingCount := len(l.urgent.list) * floatingRatio / (urgentRatio + floatingRatio)
   666  	l.floating.list = make([]*types.Transaction, floatingCount)
   667  	for i := 0; i < floatingCount; i++ {
   668  		l.floating.list[i] = heap.Pop(&l.urgent).(*types.Transaction)
   669  	}
   670  	heap.Init(&l.floating)
   671  	reheapTimer.Update(time.Since(start))
   672  }
   673  
   674  // SetBaseFee updates the base fee and triggers a re-heap. Note that Removed is not
   675  // necessary to call right before SetBaseFee when processing a new block.
   676  func (l *pricedList) SetBaseFee(baseFee *big.Int) {
   677  	l.urgent.baseFee = baseFee
   678  	l.Reheap()
   679  }