tx_list.go 19 KB

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