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