tx_list.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  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. "github.com/ethereum/go-ethereum/core/types"
  23. )
  24. // nonceHeap is a heap.Interface implementation over 64bit unsigned integers for
  25. // retrieving sorted transactions from the possibly gapped future queue.
  26. type nonceHeap []uint64
  27. func (h nonceHeap) Len() int { return len(h) }
  28. func (h nonceHeap) Less(i, j int) bool { return h[i] < h[j] }
  29. func (h nonceHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
  30. func (h *nonceHeap) Push(x interface{}) {
  31. *h = append(*h, x.(uint64))
  32. }
  33. func (h *nonceHeap) Pop() interface{} {
  34. old := *h
  35. n := len(old)
  36. x := old[n-1]
  37. *h = old[0 : n-1]
  38. return x
  39. }
  40. // txSortedMap is a nonce->transaction hash map with a heap based index to allow
  41. // iterating over the contents in a nonce-incrementing way.
  42. type txSortedMap struct {
  43. items map[uint64]*types.Transaction // Hash map storing the transaction data
  44. index *nonceHeap // Heap of nonces of all the stored transactions (non-strict mode)
  45. cache types.Transactions // Cache of the transactions already sorted
  46. }
  47. // newTxSortedMap creates a new sorted transaction map.
  48. func newTxSortedMap() *txSortedMap {
  49. return &txSortedMap{
  50. items: make(map[uint64]*types.Transaction),
  51. index: &nonceHeap{},
  52. }
  53. }
  54. // Get retrieves the current transactions associated with the given nonce.
  55. func (m *txSortedMap) Get(nonce uint64) *types.Transaction {
  56. return m.items[nonce]
  57. }
  58. // Put inserts a new transaction into the map, also updating the map's nonce
  59. // index. If a transaction already exists with the same nonce, it's overwritten.
  60. func (m *txSortedMap) Put(tx *types.Transaction) {
  61. nonce := tx.Nonce()
  62. if m.items[nonce] == nil {
  63. heap.Push(m.index, nonce)
  64. }
  65. m.items[nonce], m.cache = tx, nil
  66. }
  67. // Forward removes all transactions from the map with a nonce lower than the
  68. // provided threshold. Every removed transaction is returned for any post-removal
  69. // maintenance.
  70. func (m *txSortedMap) Forward(threshold uint64) types.Transactions {
  71. var removed types.Transactions
  72. // Pop off heap items until the threshold is reached
  73. for m.index.Len() > 0 && (*m.index)[0] < threshold {
  74. nonce := heap.Pop(m.index).(uint64)
  75. removed = append(removed, m.items[nonce])
  76. delete(m.items, nonce)
  77. }
  78. // If we had a cached order, shift the front
  79. if m.cache != nil {
  80. m.cache = m.cache[len(removed):]
  81. }
  82. return removed
  83. }
  84. // Filter iterates over the list of transactions and removes all of them for which
  85. // the specified function evaluates to true.
  86. func (m *txSortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions {
  87. var removed types.Transactions
  88. // Collect all the transactions to filter out
  89. for nonce, tx := range m.items {
  90. if filter(tx) {
  91. removed = append(removed, tx)
  92. delete(m.items, nonce)
  93. }
  94. }
  95. // If transactions were removed, the heap and cache are ruined
  96. if len(removed) > 0 {
  97. *m.index = make([]uint64, 0, len(m.items))
  98. for nonce, _ := range m.items {
  99. *m.index = append(*m.index, nonce)
  100. }
  101. heap.Init(m.index)
  102. m.cache = nil
  103. }
  104. return removed
  105. }
  106. // Cap places a hard limit on the number of items, returning all transactions
  107. // exceeding that limit.
  108. func (m *txSortedMap) Cap(threshold int) types.Transactions {
  109. // Short circuit if the number of items is under the limit
  110. if len(m.items) <= threshold {
  111. return nil
  112. }
  113. // Otherwise gather and drop the highest nonce'd transactions
  114. var drops types.Transactions
  115. sort.Sort(*m.index)
  116. for size := len(m.items); size > threshold; size-- {
  117. drops = append(drops, m.items[(*m.index)[size-1]])
  118. delete(m.items, (*m.index)[size-1])
  119. }
  120. *m.index = (*m.index)[:threshold]
  121. heap.Init(m.index)
  122. // If we had a cache, shift the back
  123. if m.cache != nil {
  124. m.cache = m.cache[:len(m.cache)-len(drops)]
  125. }
  126. return drops
  127. }
  128. // Remove deletes a transaction from the maintained map, returning whether the
  129. // transaction was found.
  130. func (m *txSortedMap) Remove(nonce uint64) bool {
  131. // Short circuit if no transaction is present
  132. _, ok := m.items[nonce]
  133. if !ok {
  134. return false
  135. }
  136. // Otherwise delete the transaction and fix the heap index
  137. for i := 0; i < m.index.Len(); i++ {
  138. if (*m.index)[i] == nonce {
  139. heap.Remove(m.index, i)
  140. break
  141. }
  142. }
  143. delete(m.items, nonce)
  144. m.cache = nil
  145. return true
  146. }
  147. // Ready retrieves a sequentially increasing list of transactions starting at the
  148. // provided nonce that is ready for processing. The returned transactions will be
  149. // removed from the list.
  150. //
  151. // Note, all transactions with nonces lower than start will also be returned to
  152. // prevent getting into and invalid state. This is not something that should ever
  153. // happen but better to be self correcting than failing!
  154. func (m *txSortedMap) Ready(start uint64) types.Transactions {
  155. // Short circuit if no transactions are available
  156. if m.index.Len() == 0 || (*m.index)[0] > start {
  157. return nil
  158. }
  159. // Otherwise start accumulating incremental transactions
  160. var ready types.Transactions
  161. for next := (*m.index)[0]; m.index.Len() > 0 && (*m.index)[0] == next; next++ {
  162. ready = append(ready, m.items[next])
  163. delete(m.items, next)
  164. heap.Pop(m.index)
  165. }
  166. m.cache = nil
  167. return ready
  168. }
  169. // Len returns the length of the transaction map.
  170. func (m *txSortedMap) Len() int {
  171. return len(m.items)
  172. }
  173. // Flatten creates a nonce-sorted slice of transactions based on the loosely
  174. // sorted internal representation. The result of the sorting is cached in case
  175. // it's requested again before any modifications are made to the contents.
  176. func (m *txSortedMap) Flatten() types.Transactions {
  177. // If the sorting was not cached yet, create and cache it
  178. if m.cache == nil {
  179. m.cache = make(types.Transactions, 0, len(m.items))
  180. for _, tx := range m.items {
  181. m.cache = append(m.cache, tx)
  182. }
  183. sort.Sort(types.TxByNonce(m.cache))
  184. }
  185. // Copy the cache to prevent accidental modifications
  186. txs := make(types.Transactions, len(m.cache))
  187. copy(txs, m.cache)
  188. return txs
  189. }
  190. // txList is a "list" of transactions belonging to an account, sorted by account
  191. // nonce. The same type can be used both for storing contiguous transactions for
  192. // the executable/pending queue; and for storing gapped transactions for the non-
  193. // executable/future queue, with minor behavoiral changes.
  194. type txList struct {
  195. strict bool // Whether nonces are strictly continuous or not
  196. txs *txSortedMap // Heap indexed sorted hash map of the transactions
  197. costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance)
  198. }
  199. // newTxList create a new transaction list for maintaining nonce-indexable fast,
  200. // gapped, sortable transaction lists.
  201. func newTxList(strict bool) *txList {
  202. return &txList{
  203. strict: strict,
  204. txs: newTxSortedMap(),
  205. costcap: new(big.Int),
  206. }
  207. }
  208. // Add tries to insert a new transaction into the list, returning whether the
  209. // transaction was accepted, and if yes, any previous transaction it replaced.
  210. //
  211. // If the new transaction is accepted into the list, the lists' cost threshold
  212. // is also potentially updated.
  213. func (l *txList) Add(tx *types.Transaction) (bool, *types.Transaction) {
  214. // If there's an older better transaction, abort
  215. old := l.txs.Get(tx.Nonce())
  216. if old != nil && old.GasPrice().Cmp(tx.GasPrice()) >= 0 {
  217. return false, nil
  218. }
  219. // Otherwise overwrite the old transaction with the current one
  220. l.txs.Put(tx)
  221. if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 {
  222. l.costcap = cost
  223. }
  224. return true, old
  225. }
  226. // Forward removes all transactions from the list with a nonce lower than the
  227. // provided threshold. Every removed transaction is returned for any post-removal
  228. // maintenance.
  229. func (l *txList) Forward(threshold uint64) types.Transactions {
  230. return l.txs.Forward(threshold)
  231. }
  232. // Filter removes all transactions from the list with a cost higher than the
  233. // provided threshold. Every removed transaction is returned for any post-removal
  234. // maintenance. Strict-mode invalidated transactions are also returned.
  235. //
  236. // This method uses the cached costcap to quickly decide if there's even a point
  237. // in calculating all the costs or if the balance covers all. If the threshold is
  238. // lower than the costcap, the costcap will be reset to a new high after removing
  239. // expensive the too transactions.
  240. func (l *txList) Filter(threshold *big.Int) (types.Transactions, types.Transactions) {
  241. // If all transactions are below the threshold, short circuit
  242. if l.costcap.Cmp(threshold) <= 0 {
  243. return nil, nil
  244. }
  245. l.costcap = new(big.Int).Set(threshold) // Lower the cap to the threshold
  246. // Filter out all the transactions above the account's funds
  247. removed := l.txs.Filter(func(tx *types.Transaction) bool { return tx.Cost().Cmp(threshold) > 0 })
  248. // If the list was strict, filter anything above the lowest nonce
  249. var invalids types.Transactions
  250. if l.strict && len(removed) > 0 {
  251. lowest := uint64(math.MaxUint64)
  252. for _, tx := range removed {
  253. if nonce := tx.Nonce(); lowest > nonce {
  254. lowest = nonce
  255. }
  256. }
  257. invalids = l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > lowest })
  258. }
  259. return removed, invalids
  260. }
  261. // Cap places a hard limit on the number of items, returning all transactions
  262. // exceeding that limit.
  263. func (l *txList) Cap(threshold int) types.Transactions {
  264. return l.txs.Cap(threshold)
  265. }
  266. // Remove deletes a transaction from the maintained list, returning whether the
  267. // transaction was found, and also returning any transaction invalidated due to
  268. // the deletion (strict mode only).
  269. func (l *txList) Remove(tx *types.Transaction) (bool, types.Transactions) {
  270. // Remove the transaction from the set
  271. nonce := tx.Nonce()
  272. if removed := l.txs.Remove(nonce); !removed {
  273. return false, nil
  274. }
  275. // In strict mode, filter out non-executable transactions
  276. if l.strict {
  277. return true, l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > nonce })
  278. }
  279. return true, nil
  280. }
  281. // Ready retrieves a sequentially increasing list of transactions starting at the
  282. // provided nonce that is ready for processing. The returned transactions will be
  283. // removed from the list.
  284. //
  285. // Note, all transactions with nonces lower than start will also be returned to
  286. // prevent getting into and invalid state. This is not something that should ever
  287. // happen but better to be self correcting than failing!
  288. func (l *txList) Ready(start uint64) types.Transactions {
  289. return l.txs.Ready(start)
  290. }
  291. // Len returns the length of the transaction list.
  292. func (l *txList) Len() int {
  293. return l.txs.Len()
  294. }
  295. // Empty returns whether the list of transactions is empty or not.
  296. func (l *txList) Empty() bool {
  297. return l.Len() == 0
  298. }
  299. // Flatten creates a nonce-sorted slice of transactions based on the loosely
  300. // sorted internal representation. The result of the sorting is cached in case
  301. // it's requested again before any modifications are made to the contents.
  302. func (l *txList) Flatten() types.Transactions {
  303. return l.txs.Flatten()
  304. }