tx_list.go 22 KB

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