tx_pool_test.go 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. // Copyright 2015 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. "crypto/ecdsa"
  19. "math/big"
  20. "math/rand"
  21. "testing"
  22. "time"
  23. "github.com/ethereum/go-ethereum/common"
  24. "github.com/ethereum/go-ethereum/core/state"
  25. "github.com/ethereum/go-ethereum/core/types"
  26. "github.com/ethereum/go-ethereum/crypto"
  27. "github.com/ethereum/go-ethereum/ethdb"
  28. "github.com/ethereum/go-ethereum/event"
  29. "github.com/ethereum/go-ethereum/params"
  30. )
  31. func transaction(nonce uint64, gaslimit *big.Int, key *ecdsa.PrivateKey) *types.Transaction {
  32. tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(100), gaslimit, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  33. return tx
  34. }
  35. func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
  36. db, _ := ethdb.NewMemDatabase()
  37. statedb, _ := state.New(common.Hash{}, db)
  38. key, _ := crypto.GenerateKey()
  39. newPool := NewTxPool(testChainConfig(), new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
  40. newPool.resetState()
  41. return newPool, key
  42. }
  43. func deriveSender(tx *types.Transaction) (common.Address, error) {
  44. return types.Sender(types.HomesteadSigner{}, tx)
  45. }
  46. // This test simulates a scenario where a new block is imported during a
  47. // state reset and tests whether the pending state is in sync with the
  48. // block head event that initiated the resetState().
  49. func TestStateChangeDuringPoolReset(t *testing.T) {
  50. var (
  51. db, _ = ethdb.NewMemDatabase()
  52. key, _ = crypto.GenerateKey()
  53. address = crypto.PubkeyToAddress(key.PublicKey)
  54. mux = new(event.TypeMux)
  55. statedb, _ = state.New(common.Hash{}, db)
  56. trigger = false
  57. )
  58. // setup pool with 2 transaction in it
  59. statedb.SetBalance(address, new(big.Int).SetUint64(params.Ether))
  60. tx0 := transaction(0, big.NewInt(100000), key)
  61. tx1 := transaction(1, big.NewInt(100000), key)
  62. // stateFunc is used multiple times to reset the pending state.
  63. // when simulate is true it will create a state that indicates
  64. // that tx0 and tx1 are included in the chain.
  65. stateFunc := func() (*state.StateDB, error) {
  66. // delay "state change" by one. The tx pool fetches the
  67. // state multiple times and by delaying it a bit we simulate
  68. // a state change between those fetches.
  69. stdb := statedb
  70. if trigger {
  71. statedb, _ = state.New(common.Hash{}, db)
  72. // simulate that the new head block included tx0 and tx1
  73. statedb.SetNonce(address, 2)
  74. statedb.SetBalance(address, new(big.Int).SetUint64(params.Ether))
  75. trigger = false
  76. }
  77. return stdb, nil
  78. }
  79. gasLimitFunc := func() *big.Int { return big.NewInt(1000000000) }
  80. txpool := NewTxPool(testChainConfig(), mux, stateFunc, gasLimitFunc)
  81. txpool.resetState()
  82. nonce := txpool.State().GetNonce(address)
  83. if nonce != 0 {
  84. t.Fatalf("Invalid nonce, want 0, got %d", nonce)
  85. }
  86. txpool.AddBatch(types.Transactions{tx0, tx1})
  87. nonce = txpool.State().GetNonce(address)
  88. if nonce != 2 {
  89. t.Fatalf("Invalid nonce, want 2, got %d", nonce)
  90. }
  91. // trigger state change in the background
  92. trigger = true
  93. txpool.resetState()
  94. pendingTx, err := txpool.Pending()
  95. if err != nil {
  96. t.Fatalf("Could not fetch pending transactions: %v", err)
  97. }
  98. for addr, txs := range pendingTx {
  99. t.Logf("%0x: %d\n", addr, len(txs))
  100. }
  101. nonce = txpool.State().GetNonce(address)
  102. if nonce != 2 {
  103. t.Fatalf("Invalid nonce, want 2, got %d", nonce)
  104. }
  105. }
  106. func TestInvalidTransactions(t *testing.T) {
  107. pool, key := setupTxPool()
  108. tx := transaction(0, big.NewInt(100), key)
  109. from, _ := deriveSender(tx)
  110. currentState, _ := pool.currentState()
  111. currentState.AddBalance(from, big.NewInt(1))
  112. if err := pool.Add(tx); err != ErrInsufficientFunds {
  113. t.Error("expected", ErrInsufficientFunds)
  114. }
  115. balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(tx.Gas(), tx.GasPrice()))
  116. currentState.AddBalance(from, balance)
  117. if err := pool.Add(tx); err != ErrIntrinsicGas {
  118. t.Error("expected", ErrIntrinsicGas, "got", err)
  119. }
  120. currentState.SetNonce(from, 1)
  121. currentState.AddBalance(from, big.NewInt(0xffffffffffffff))
  122. tx = transaction(0, big.NewInt(100000), key)
  123. if err := pool.Add(tx); err != ErrNonce {
  124. t.Error("expected", ErrNonce)
  125. }
  126. tx = transaction(1, big.NewInt(100000), key)
  127. pool.minGasPrice = big.NewInt(1000)
  128. if err := pool.Add(tx); err != ErrCheap {
  129. t.Error("expected", ErrCheap, "got", err)
  130. }
  131. pool.SetLocal(tx)
  132. if err := pool.Add(tx); err != nil {
  133. t.Error("expected", nil, "got", err)
  134. }
  135. }
  136. func TestTransactionQueue(t *testing.T) {
  137. pool, key := setupTxPool()
  138. tx := transaction(0, big.NewInt(100), key)
  139. from, _ := deriveSender(tx)
  140. currentState, _ := pool.currentState()
  141. currentState.AddBalance(from, big.NewInt(1000))
  142. pool.resetState()
  143. pool.enqueueTx(tx.Hash(), tx)
  144. pool.promoteExecutables(currentState)
  145. if len(pool.pending) != 1 {
  146. t.Error("expected valid txs to be 1 is", len(pool.pending))
  147. }
  148. tx = transaction(1, big.NewInt(100), key)
  149. from, _ = deriveSender(tx)
  150. currentState.SetNonce(from, 2)
  151. pool.enqueueTx(tx.Hash(), tx)
  152. pool.promoteExecutables(currentState)
  153. if _, ok := pool.pending[from].txs.items[tx.Nonce()]; ok {
  154. t.Error("expected transaction to be in tx pool")
  155. }
  156. if len(pool.queue) > 0 {
  157. t.Error("expected transaction queue to be empty. is", len(pool.queue))
  158. }
  159. pool, key = setupTxPool()
  160. tx1 := transaction(0, big.NewInt(100), key)
  161. tx2 := transaction(10, big.NewInt(100), key)
  162. tx3 := transaction(11, big.NewInt(100), key)
  163. from, _ = deriveSender(tx1)
  164. currentState, _ = pool.currentState()
  165. currentState.AddBalance(from, big.NewInt(1000))
  166. pool.resetState()
  167. pool.enqueueTx(tx1.Hash(), tx1)
  168. pool.enqueueTx(tx2.Hash(), tx2)
  169. pool.enqueueTx(tx3.Hash(), tx3)
  170. pool.promoteExecutables(currentState)
  171. if len(pool.pending) != 1 {
  172. t.Error("expected tx pool to be 1, got", len(pool.pending))
  173. }
  174. if pool.queue[from].Len() != 2 {
  175. t.Error("expected len(queue) == 2, got", pool.queue[from].Len())
  176. }
  177. }
  178. func TestRemoveTx(t *testing.T) {
  179. pool, key := setupTxPool()
  180. tx := transaction(0, big.NewInt(100), key)
  181. from, _ := deriveSender(tx)
  182. currentState, _ := pool.currentState()
  183. currentState.AddBalance(from, big.NewInt(1))
  184. pool.enqueueTx(tx.Hash(), tx)
  185. pool.promoteTx(from, tx.Hash(), tx)
  186. if len(pool.queue) != 1 {
  187. t.Error("expected queue to be 1, got", len(pool.queue))
  188. }
  189. if len(pool.pending) != 1 {
  190. t.Error("expected pending to be 1, got", len(pool.pending))
  191. }
  192. pool.Remove(tx.Hash())
  193. if len(pool.queue) > 0 {
  194. t.Error("expected queue to be 0, got", len(pool.queue))
  195. }
  196. if len(pool.pending) > 0 {
  197. t.Error("expected pending to be 0, got", len(pool.pending))
  198. }
  199. }
  200. func TestNegativeValue(t *testing.T) {
  201. pool, key := setupTxPool()
  202. tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), big.NewInt(100), big.NewInt(1), nil), types.HomesteadSigner{}, key)
  203. from, _ := deriveSender(tx)
  204. currentState, _ := pool.currentState()
  205. currentState.AddBalance(from, big.NewInt(1))
  206. if err := pool.Add(tx); err != ErrNegativeValue {
  207. t.Error("expected", ErrNegativeValue, "got", err)
  208. }
  209. }
  210. func TestTransactionChainFork(t *testing.T) {
  211. pool, key := setupTxPool()
  212. addr := crypto.PubkeyToAddress(key.PublicKey)
  213. resetState := func() {
  214. db, _ := ethdb.NewMemDatabase()
  215. statedb, _ := state.New(common.Hash{}, db)
  216. pool.currentState = func() (*state.StateDB, error) { return statedb, nil }
  217. currentState, _ := pool.currentState()
  218. currentState.AddBalance(addr, big.NewInt(100000000000000))
  219. pool.resetState()
  220. }
  221. resetState()
  222. tx := transaction(0, big.NewInt(100000), key)
  223. if err := pool.add(tx); err != nil {
  224. t.Error("didn't expect error", err)
  225. }
  226. pool.RemoveBatch([]*types.Transaction{tx})
  227. // reset the pool's internal state
  228. resetState()
  229. if err := pool.add(tx); err != nil {
  230. t.Error("didn't expect error", err)
  231. }
  232. }
  233. func TestTransactionDoubleNonce(t *testing.T) {
  234. pool, key := setupTxPool()
  235. addr := crypto.PubkeyToAddress(key.PublicKey)
  236. resetState := func() {
  237. db, _ := ethdb.NewMemDatabase()
  238. statedb, _ := state.New(common.Hash{}, db)
  239. pool.currentState = func() (*state.StateDB, error) { return statedb, nil }
  240. currentState, _ := pool.currentState()
  241. currentState.AddBalance(addr, big.NewInt(100000000000000))
  242. pool.resetState()
  243. }
  244. resetState()
  245. signer := types.HomesteadSigner{}
  246. tx1, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(100000), big.NewInt(1), nil), signer, key)
  247. tx2, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(1000000), big.NewInt(2), nil), signer, key)
  248. tx3, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(1000000), big.NewInt(1), nil), signer, key)
  249. // Add the first two transaction, ensure higher priced stays only
  250. if err := pool.add(tx1); err != nil {
  251. t.Error("didn't expect error", err)
  252. }
  253. if err := pool.add(tx2); err != nil {
  254. t.Error("didn't expect error", err)
  255. }
  256. state, _ := pool.currentState()
  257. pool.promoteExecutables(state)
  258. if pool.pending[addr].Len() != 1 {
  259. t.Error("expected 1 pending transactions, got", pool.pending[addr].Len())
  260. }
  261. if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() {
  262. t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash())
  263. }
  264. // Add the thid transaction and ensure it's not saved (smaller price)
  265. if err := pool.add(tx3); err != nil {
  266. t.Error("didn't expect error", err)
  267. }
  268. pool.promoteExecutables(state)
  269. if pool.pending[addr].Len() != 1 {
  270. t.Error("expected 1 pending transactions, got", pool.pending[addr].Len())
  271. }
  272. if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() {
  273. t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash())
  274. }
  275. // Ensure the total transaction count is correct
  276. if len(pool.all) != 1 {
  277. t.Error("expected 1 total transactions, got", len(pool.all))
  278. }
  279. }
  280. func TestMissingNonce(t *testing.T) {
  281. pool, key := setupTxPool()
  282. addr := crypto.PubkeyToAddress(key.PublicKey)
  283. currentState, _ := pool.currentState()
  284. currentState.AddBalance(addr, big.NewInt(100000000000000))
  285. tx := transaction(1, big.NewInt(100000), key)
  286. if err := pool.add(tx); err != nil {
  287. t.Error("didn't expect error", err)
  288. }
  289. if len(pool.pending) != 0 {
  290. t.Error("expected 0 pending transactions, got", len(pool.pending))
  291. }
  292. if pool.queue[addr].Len() != 1 {
  293. t.Error("expected 1 queued transaction, got", pool.queue[addr].Len())
  294. }
  295. if len(pool.all) != 1 {
  296. t.Error("expected 1 total transactions, got", len(pool.all))
  297. }
  298. }
  299. func TestNonceRecovery(t *testing.T) {
  300. const n = 10
  301. pool, key := setupTxPool()
  302. addr := crypto.PubkeyToAddress(key.PublicKey)
  303. currentState, _ := pool.currentState()
  304. currentState.SetNonce(addr, n)
  305. currentState.AddBalance(addr, big.NewInt(100000000000000))
  306. pool.resetState()
  307. tx := transaction(n, big.NewInt(100000), key)
  308. if err := pool.Add(tx); err != nil {
  309. t.Error(err)
  310. }
  311. // simulate some weird re-order of transactions and missing nonce(s)
  312. currentState.SetNonce(addr, n-1)
  313. pool.resetState()
  314. if fn := pool.pendingState.GetNonce(addr); fn != n+1 {
  315. t.Errorf("expected nonce to be %d, got %d", n+1, fn)
  316. }
  317. }
  318. func TestRemovedTxEvent(t *testing.T) {
  319. pool, key := setupTxPool()
  320. tx := transaction(0, big.NewInt(1000000), key)
  321. from, _ := deriveSender(tx)
  322. currentState, _ := pool.currentState()
  323. currentState.AddBalance(from, big.NewInt(1000000000000))
  324. pool.resetState()
  325. pool.eventMux.Post(RemovedTransactionEvent{types.Transactions{tx}})
  326. pool.eventMux.Post(ChainHeadEvent{nil})
  327. if pool.pending[from].Len() != 1 {
  328. t.Error("expected 1 pending tx, got", pool.pending[from].Len())
  329. }
  330. if len(pool.all) != 1 {
  331. t.Error("expected 1 total transactions, got", len(pool.all))
  332. }
  333. }
  334. // Tests that if an account runs out of funds, any pending and queued transactions
  335. // are dropped.
  336. func TestTransactionDropping(t *testing.T) {
  337. // Create a test account and fund it
  338. pool, key := setupTxPool()
  339. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  340. state, _ := pool.currentState()
  341. state.AddBalance(account, big.NewInt(1000))
  342. // Add some pending and some queued transactions
  343. var (
  344. tx0 = transaction(0, big.NewInt(100), key)
  345. tx1 = transaction(1, big.NewInt(200), key)
  346. tx10 = transaction(10, big.NewInt(100), key)
  347. tx11 = transaction(11, big.NewInt(200), key)
  348. )
  349. pool.promoteTx(account, tx0.Hash(), tx0)
  350. pool.promoteTx(account, tx1.Hash(), tx1)
  351. pool.enqueueTx(tx10.Hash(), tx10)
  352. pool.enqueueTx(tx11.Hash(), tx11)
  353. // Check that pre and post validations leave the pool as is
  354. if pool.pending[account].Len() != 2 {
  355. t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 2)
  356. }
  357. if pool.queue[account].Len() != 2 {
  358. t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 2)
  359. }
  360. if len(pool.all) != 4 {
  361. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 4)
  362. }
  363. pool.resetState()
  364. if pool.pending[account].Len() != 2 {
  365. t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 2)
  366. }
  367. if pool.queue[account].Len() != 2 {
  368. t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 2)
  369. }
  370. if len(pool.all) != 4 {
  371. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 4)
  372. }
  373. // Reduce the balance of the account, and check that invalidated transactions are dropped
  374. state.AddBalance(account, big.NewInt(-750))
  375. pool.resetState()
  376. if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok {
  377. t.Errorf("funded pending transaction missing: %v", tx0)
  378. }
  379. if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; ok {
  380. t.Errorf("out-of-fund pending transaction present: %v", tx1)
  381. }
  382. if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok {
  383. t.Errorf("funded queued transaction missing: %v", tx10)
  384. }
  385. if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; ok {
  386. t.Errorf("out-of-fund queued transaction present: %v", tx11)
  387. }
  388. if len(pool.all) != 2 {
  389. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 2)
  390. }
  391. }
  392. // Tests that if a transaction is dropped from the current pending pool (e.g. out
  393. // of fund), all consecutive (still valid, but not executable) transactions are
  394. // postponed back into the future queue to prevent broadcasting them.
  395. func TestTransactionPostponing(t *testing.T) {
  396. // Create a test account and fund it
  397. pool, key := setupTxPool()
  398. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  399. state, _ := pool.currentState()
  400. state.AddBalance(account, big.NewInt(1000))
  401. // Add a batch consecutive pending transactions for validation
  402. txns := []*types.Transaction{}
  403. for i := 0; i < 100; i++ {
  404. var tx *types.Transaction
  405. if i%2 == 0 {
  406. tx = transaction(uint64(i), big.NewInt(100), key)
  407. } else {
  408. tx = transaction(uint64(i), big.NewInt(500), key)
  409. }
  410. pool.promoteTx(account, tx.Hash(), tx)
  411. txns = append(txns, tx)
  412. }
  413. // Check that pre and post validations leave the pool as is
  414. if pool.pending[account].Len() != len(txns) {
  415. t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), len(txns))
  416. }
  417. if len(pool.queue) != 0 {
  418. t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 0)
  419. }
  420. if len(pool.all) != len(txns) {
  421. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txns))
  422. }
  423. pool.resetState()
  424. if pool.pending[account].Len() != len(txns) {
  425. t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), len(txns))
  426. }
  427. if len(pool.queue) != 0 {
  428. t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 0)
  429. }
  430. if len(pool.all) != len(txns) {
  431. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txns))
  432. }
  433. // Reduce the balance of the account, and check that transactions are reorganised
  434. state.AddBalance(account, big.NewInt(-750))
  435. pool.resetState()
  436. if _, ok := pool.pending[account].txs.items[txns[0].Nonce()]; !ok {
  437. t.Errorf("tx %d: valid and funded transaction missing from pending pool: %v", 0, txns[0])
  438. }
  439. if _, ok := pool.queue[account].txs.items[txns[0].Nonce()]; ok {
  440. t.Errorf("tx %d: valid and funded transaction present in future queue: %v", 0, txns[0])
  441. }
  442. for i, tx := range txns[1:] {
  443. if i%2 == 1 {
  444. if _, ok := pool.pending[account].txs.items[tx.Nonce()]; ok {
  445. t.Errorf("tx %d: valid but future transaction present in pending pool: %v", i+1, tx)
  446. }
  447. if _, ok := pool.queue[account].txs.items[tx.Nonce()]; !ok {
  448. t.Errorf("tx %d: valid but future transaction missing from future queue: %v", i+1, tx)
  449. }
  450. } else {
  451. if _, ok := pool.pending[account].txs.items[tx.Nonce()]; ok {
  452. t.Errorf("tx %d: out-of-fund transaction present in pending pool: %v", i+1, tx)
  453. }
  454. if _, ok := pool.queue[account].txs.items[tx.Nonce()]; ok {
  455. t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", i+1, tx)
  456. }
  457. }
  458. }
  459. if len(pool.all) != len(txns)/2 {
  460. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txns)/2)
  461. }
  462. }
  463. // Tests that if the transaction count belonging to a single account goes above
  464. // some threshold, the higher transactions are dropped to prevent DOS attacks.
  465. func TestTransactionQueueAccountLimiting(t *testing.T) {
  466. // Create a test account and fund it
  467. pool, key := setupTxPool()
  468. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  469. state, _ := pool.currentState()
  470. state.AddBalance(account, big.NewInt(1000000))
  471. pool.resetState()
  472. // Keep queuing up transactions and make sure all above a limit are dropped
  473. for i := uint64(1); i <= maxQueuedPerAccount+5; i++ {
  474. if err := pool.Add(transaction(i, big.NewInt(100000), key)); err != nil {
  475. t.Fatalf("tx %d: failed to add transaction: %v", i, err)
  476. }
  477. if len(pool.pending) != 0 {
  478. t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, len(pool.pending), 0)
  479. }
  480. if i <= maxQueuedPerAccount {
  481. if pool.queue[account].Len() != int(i) {
  482. t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), i)
  483. }
  484. } else {
  485. if pool.queue[account].Len() != int(maxQueuedPerAccount) {
  486. t.Errorf("tx %d: queue limit mismatch: have %d, want %d", i, pool.queue[account].Len(), maxQueuedPerAccount)
  487. }
  488. }
  489. }
  490. if len(pool.all) != int(maxQueuedPerAccount) {
  491. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), maxQueuedPerAccount)
  492. }
  493. }
  494. // Tests that if the transaction count belonging to multiple accounts go above
  495. // some threshold, the higher transactions are dropped to prevent DOS attacks.
  496. func TestTransactionQueueGlobalLimiting(t *testing.T) {
  497. // Reduce the queue limits to shorten test time
  498. defer func(old uint64) { maxQueuedInTotal = old }(maxQueuedInTotal)
  499. maxQueuedInTotal = maxQueuedPerAccount * 3
  500. // Create the pool to test the limit enforcement with
  501. db, _ := ethdb.NewMemDatabase()
  502. statedb, _ := state.New(common.Hash{}, db)
  503. pool := NewTxPool(testChainConfig(), new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
  504. pool.resetState()
  505. // Create a number of test accounts and fund them
  506. state, _ := pool.currentState()
  507. keys := make([]*ecdsa.PrivateKey, 5)
  508. for i := 0; i < len(keys); i++ {
  509. keys[i], _ = crypto.GenerateKey()
  510. state.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  511. }
  512. // Generate and queue a batch of transactions
  513. nonces := make(map[common.Address]uint64)
  514. txs := make(types.Transactions, 0, 3*maxQueuedInTotal)
  515. for len(txs) < cap(txs) {
  516. key := keys[rand.Intn(len(keys))]
  517. addr := crypto.PubkeyToAddress(key.PublicKey)
  518. txs = append(txs, transaction(nonces[addr]+1, big.NewInt(100000), key))
  519. nonces[addr]++
  520. }
  521. // Import the batch and verify that limits have been enforced
  522. pool.AddBatch(txs)
  523. queued := 0
  524. for addr, list := range pool.queue {
  525. if list.Len() > int(maxQueuedPerAccount) {
  526. t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), maxQueuedPerAccount)
  527. }
  528. queued += list.Len()
  529. }
  530. if queued > int(maxQueuedInTotal) {
  531. t.Fatalf("total transactions overflow allowance: %d > %d", queued, maxQueuedInTotal)
  532. }
  533. }
  534. // Tests that if an account remains idle for a prolonged amount of time, any
  535. // non-executable transactions queued up are dropped to prevent wasting resources
  536. // on shuffling them around.
  537. func TestTransactionQueueTimeLimiting(t *testing.T) {
  538. // Reduce the queue limits to shorten test time
  539. defer func(old time.Duration) { maxQueuedLifetime = old }(maxQueuedLifetime)
  540. defer func(old time.Duration) { evictionInterval = old }(evictionInterval)
  541. maxQueuedLifetime = time.Second
  542. evictionInterval = time.Second
  543. // Create a test account and fund it
  544. pool, key := setupTxPool()
  545. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  546. state, _ := pool.currentState()
  547. state.AddBalance(account, big.NewInt(1000000))
  548. // Queue up a batch of transactions
  549. for i := uint64(1); i <= maxQueuedPerAccount; i++ {
  550. if err := pool.Add(transaction(i, big.NewInt(100000), key)); err != nil {
  551. t.Fatalf("tx %d: failed to add transaction: %v", i, err)
  552. }
  553. }
  554. // Wait until at least two expiration cycles hit and make sure the transactions are gone
  555. time.Sleep(2 * evictionInterval)
  556. if len(pool.queue) > 0 {
  557. t.Fatalf("old transactions remained after eviction")
  558. }
  559. }
  560. // Tests that even if the transaction count belonging to a single account goes
  561. // above some threshold, as long as the transactions are executable, they are
  562. // accepted.
  563. func TestTransactionPendingLimiting(t *testing.T) {
  564. // Create a test account and fund it
  565. pool, key := setupTxPool()
  566. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  567. state, _ := pool.currentState()
  568. state.AddBalance(account, big.NewInt(1000000))
  569. pool.resetState()
  570. // Keep queuing up transactions and make sure all above a limit are dropped
  571. for i := uint64(0); i < maxQueuedPerAccount+5; i++ {
  572. if err := pool.Add(transaction(i, big.NewInt(100000), key)); err != nil {
  573. t.Fatalf("tx %d: failed to add transaction: %v", i, err)
  574. }
  575. if pool.pending[account].Len() != int(i)+1 {
  576. t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, pool.pending[account].Len(), i+1)
  577. }
  578. if len(pool.queue) != 0 {
  579. t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), 0)
  580. }
  581. }
  582. if len(pool.all) != int(maxQueuedPerAccount+5) {
  583. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), maxQueuedPerAccount+5)
  584. }
  585. }
  586. // Tests that the transaction limits are enforced the same way irrelevant whether
  587. // the transactions are added one by one or in batches.
  588. func TestTransactionQueueLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 1) }
  589. func TestTransactionPendingLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 0) }
  590. func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
  591. // Add a batch of transactions to a pool one by one
  592. pool1, key1 := setupTxPool()
  593. account1, _ := deriveSender(transaction(0, big.NewInt(0), key1))
  594. state1, _ := pool1.currentState()
  595. state1.AddBalance(account1, big.NewInt(1000000))
  596. for i := uint64(0); i < maxQueuedPerAccount+5; i++ {
  597. if err := pool1.Add(transaction(origin+i, big.NewInt(100000), key1)); err != nil {
  598. t.Fatalf("tx %d: failed to add transaction: %v", i, err)
  599. }
  600. }
  601. // Add a batch of transactions to a pool in one big batch
  602. pool2, key2 := setupTxPool()
  603. account2, _ := deriveSender(transaction(0, big.NewInt(0), key2))
  604. state2, _ := pool2.currentState()
  605. state2.AddBalance(account2, big.NewInt(1000000))
  606. txns := []*types.Transaction{}
  607. for i := uint64(0); i < maxQueuedPerAccount+5; i++ {
  608. txns = append(txns, transaction(origin+i, big.NewInt(100000), key2))
  609. }
  610. pool2.AddBatch(txns)
  611. // Ensure the batch optimization honors the same pool mechanics
  612. if len(pool1.pending) != len(pool2.pending) {
  613. t.Errorf("pending transaction count mismatch: one-by-one algo: %d, batch algo: %d", len(pool1.pending), len(pool2.pending))
  614. }
  615. if len(pool1.queue) != len(pool2.queue) {
  616. t.Errorf("queued transaction count mismatch: one-by-one algo: %d, batch algo: %d", len(pool1.queue), len(pool2.queue))
  617. }
  618. if len(pool1.all) != len(pool2.all) {
  619. t.Errorf("total transaction count mismatch: one-by-one algo %d, batch algo %d", len(pool1.all), len(pool2.all))
  620. }
  621. }
  622. // Tests that if the transaction count belonging to multiple accounts go above
  623. // some hard threshold, the higher transactions are dropped to prevent DOS
  624. // attacks.
  625. func TestTransactionPendingGlobalLimiting(t *testing.T) {
  626. // Reduce the queue limits to shorten test time
  627. defer func(old uint64) { maxPendingTotal = old }(maxPendingTotal)
  628. maxPendingTotal = minPendingPerAccount * 10
  629. // Create the pool to test the limit enforcement with
  630. db, _ := ethdb.NewMemDatabase()
  631. statedb, _ := state.New(common.Hash{}, db)
  632. pool := NewTxPool(testChainConfig(), new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
  633. pool.resetState()
  634. // Create a number of test accounts and fund them
  635. state, _ := pool.currentState()
  636. keys := make([]*ecdsa.PrivateKey, 5)
  637. for i := 0; i < len(keys); i++ {
  638. keys[i], _ = crypto.GenerateKey()
  639. state.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  640. }
  641. // Generate and queue a batch of transactions
  642. nonces := make(map[common.Address]uint64)
  643. txs := types.Transactions{}
  644. for _, key := range keys {
  645. addr := crypto.PubkeyToAddress(key.PublicKey)
  646. for j := 0; j < int(maxPendingTotal)/len(keys)*2; j++ {
  647. txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key))
  648. nonces[addr]++
  649. }
  650. }
  651. // Import the batch and verify that limits have been enforced
  652. pool.AddBatch(txs)
  653. pending := 0
  654. for _, list := range pool.pending {
  655. pending += list.Len()
  656. }
  657. if pending > int(maxPendingTotal) {
  658. t.Fatalf("total pending transactions overflow allowance: %d > %d", pending, maxPendingTotal)
  659. }
  660. }
  661. // Tests that if the transaction count belonging to multiple accounts go above
  662. // some hard threshold, if they are under the minimum guaranteed slot count then
  663. // the transactions are still kept.
  664. func TestTransactionPendingMinimumAllowance(t *testing.T) {
  665. // Reduce the queue limits to shorten test time
  666. defer func(old uint64) { maxPendingTotal = old }(maxPendingTotal)
  667. maxPendingTotal = 0
  668. // Create the pool to test the limit enforcement with
  669. db, _ := ethdb.NewMemDatabase()
  670. statedb, _ := state.New(common.Hash{}, db)
  671. pool := NewTxPool(testChainConfig(), new(event.TypeMux), func() (*state.StateDB, error) { return statedb, nil }, func() *big.Int { return big.NewInt(1000000) })
  672. pool.resetState()
  673. // Create a number of test accounts and fund them
  674. state, _ := pool.currentState()
  675. keys := make([]*ecdsa.PrivateKey, 5)
  676. for i := 0; i < len(keys); i++ {
  677. keys[i], _ = crypto.GenerateKey()
  678. state.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  679. }
  680. // Generate and queue a batch of transactions
  681. nonces := make(map[common.Address]uint64)
  682. txs := types.Transactions{}
  683. for _, key := range keys {
  684. addr := crypto.PubkeyToAddress(key.PublicKey)
  685. for j := 0; j < int(minPendingPerAccount)*2; j++ {
  686. txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key))
  687. nonces[addr]++
  688. }
  689. }
  690. // Import the batch and verify that limits have been enforced
  691. pool.AddBatch(txs)
  692. for addr, list := range pool.pending {
  693. if list.Len() != int(minPendingPerAccount) {
  694. t.Errorf("addr %x: total pending transactions mismatch: have %d, want %d", addr, list.Len(), minPendingPerAccount)
  695. }
  696. }
  697. }
  698. // Benchmarks the speed of validating the contents of the pending queue of the
  699. // transaction pool.
  700. func BenchmarkPendingDemotion100(b *testing.B) { benchmarkPendingDemotion(b, 100) }
  701. func BenchmarkPendingDemotion1000(b *testing.B) { benchmarkPendingDemotion(b, 1000) }
  702. func BenchmarkPendingDemotion10000(b *testing.B) { benchmarkPendingDemotion(b, 10000) }
  703. func benchmarkPendingDemotion(b *testing.B, size int) {
  704. // Add a batch of transactions to a pool one by one
  705. pool, key := setupTxPool()
  706. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  707. state, _ := pool.currentState()
  708. state.AddBalance(account, big.NewInt(1000000))
  709. for i := 0; i < size; i++ {
  710. tx := transaction(uint64(i), big.NewInt(100000), key)
  711. pool.promoteTx(account, tx.Hash(), tx)
  712. }
  713. // Benchmark the speed of pool validation
  714. b.ResetTimer()
  715. for i := 0; i < b.N; i++ {
  716. pool.demoteUnexecutables(state)
  717. }
  718. }
  719. // Benchmarks the speed of scheduling the contents of the future queue of the
  720. // transaction pool.
  721. func BenchmarkFuturePromotion100(b *testing.B) { benchmarkFuturePromotion(b, 100) }
  722. func BenchmarkFuturePromotion1000(b *testing.B) { benchmarkFuturePromotion(b, 1000) }
  723. func BenchmarkFuturePromotion10000(b *testing.B) { benchmarkFuturePromotion(b, 10000) }
  724. func benchmarkFuturePromotion(b *testing.B, size int) {
  725. // Add a batch of transactions to a pool one by one
  726. pool, key := setupTxPool()
  727. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  728. state, _ := pool.currentState()
  729. state.AddBalance(account, big.NewInt(1000000))
  730. for i := 0; i < size; i++ {
  731. tx := transaction(uint64(1+i), big.NewInt(100000), key)
  732. pool.enqueueTx(tx.Hash(), tx)
  733. }
  734. // Benchmark the speed of pool validation
  735. b.ResetTimer()
  736. for i := 0; i < b.N; i++ {
  737. pool.promoteExecutables(state)
  738. }
  739. }
  740. // Benchmarks the speed of iterative transaction insertion.
  741. func BenchmarkPoolInsert(b *testing.B) {
  742. // Generate a batch of transactions to enqueue into the pool
  743. pool, key := setupTxPool()
  744. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  745. state, _ := pool.currentState()
  746. state.AddBalance(account, big.NewInt(1000000))
  747. txs := make(types.Transactions, b.N)
  748. for i := 0; i < b.N; i++ {
  749. txs[i] = transaction(uint64(i), big.NewInt(100000), key)
  750. }
  751. // Benchmark importing the transactions into the queue
  752. b.ResetTimer()
  753. for _, tx := range txs {
  754. pool.Add(tx)
  755. }
  756. }
  757. // Benchmarks the speed of batched transaction insertion.
  758. func BenchmarkPoolBatchInsert100(b *testing.B) { benchmarkPoolBatchInsert(b, 100) }
  759. func BenchmarkPoolBatchInsert1000(b *testing.B) { benchmarkPoolBatchInsert(b, 1000) }
  760. func BenchmarkPoolBatchInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 10000) }
  761. func benchmarkPoolBatchInsert(b *testing.B, size int) {
  762. // Generate a batch of transactions to enqueue into the pool
  763. pool, key := setupTxPool()
  764. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  765. state, _ := pool.currentState()
  766. state.AddBalance(account, big.NewInt(1000000))
  767. batches := make([]types.Transactions, b.N)
  768. for i := 0; i < b.N; i++ {
  769. batches[i] = make(types.Transactions, size)
  770. for j := 0; j < size; j++ {
  771. batches[i][j] = transaction(uint64(size*i+j), big.NewInt(100000), key)
  772. }
  773. }
  774. // Benchmark importing the transactions into the queue
  775. b.ResetTimer()
  776. for _, batch := range batches {
  777. pool.AddBatch(batch)
  778. }
  779. }