github.com/MetalBlockchain/subnet-evm@v0.4.9/core/tx_list.go (about)

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