tx_pool_test.go 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479
  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. "fmt"
  20. "io/ioutil"
  21. "math/big"
  22. "math/rand"
  23. "os"
  24. "testing"
  25. "time"
  26. "github.com/ethereum/go-ethereum/common"
  27. "github.com/ethereum/go-ethereum/core/state"
  28. "github.com/ethereum/go-ethereum/core/types"
  29. "github.com/ethereum/go-ethereum/crypto"
  30. "github.com/ethereum/go-ethereum/ethdb"
  31. "github.com/ethereum/go-ethereum/event"
  32. "github.com/ethereum/go-ethereum/params"
  33. )
  34. // testTxPoolConfig is a transaction pool configuration without stateful disk
  35. // sideeffects used during testing.
  36. var testTxPoolConfig TxPoolConfig
  37. func init() {
  38. testTxPoolConfig = DefaultTxPoolConfig
  39. testTxPoolConfig.Journal = ""
  40. }
  41. type testBlockChain struct {
  42. statedb *state.StateDB
  43. gasLimit *big.Int
  44. chainHeadFeed *event.Feed
  45. }
  46. func (bc *testBlockChain) CurrentHeader() *types.Header {
  47. return &types.Header{
  48. GasLimit: bc.gasLimit,
  49. }
  50. }
  51. func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription {
  52. return bc.chainHeadFeed.Subscribe(ch)
  53. }
  54. func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
  55. return types.NewBlock(bc.CurrentHeader(), nil, nil, nil)
  56. }
  57. func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) {
  58. return bc.statedb, nil
  59. }
  60. func transaction(nonce uint64, gaslimit *big.Int, key *ecdsa.PrivateKey) *types.Transaction {
  61. return pricedTransaction(nonce, gaslimit, big.NewInt(1), key)
  62. }
  63. func pricedTransaction(nonce uint64, gaslimit, gasprice *big.Int, key *ecdsa.PrivateKey) *types.Transaction {
  64. tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(100), gaslimit, gasprice, nil), types.HomesteadSigner{}, key)
  65. return tx
  66. }
  67. func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
  68. db, _ := ethdb.NewMemDatabase()
  69. statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
  70. blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  71. key, _ := crypto.GenerateKey()
  72. pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
  73. return pool, key
  74. }
  75. // validateTxPoolInternals checks various consistency invariants within the pool.
  76. func validateTxPoolInternals(pool *TxPool) error {
  77. pool.mu.RLock()
  78. defer pool.mu.RUnlock()
  79. // Ensure the total transaction set is consistent with pending + queued
  80. pending, queued := pool.stats()
  81. if total := len(pool.all); total != pending+queued {
  82. return fmt.Errorf("total transaction count %d != %d pending + %d queued", total, pending, queued)
  83. }
  84. if priced := pool.priced.items.Len() - pool.priced.stales; priced != pending+queued {
  85. return fmt.Errorf("total priced transaction count %d != %d pending + %d queued", priced, pending, queued)
  86. }
  87. // Ensure the next nonce to assign is the correct one
  88. for addr, txs := range pool.pending {
  89. // Find the last transaction
  90. var last uint64
  91. for nonce, _ := range txs.txs.items {
  92. if last < nonce {
  93. last = nonce
  94. }
  95. }
  96. if nonce := pool.pendingState.GetNonce(addr); nonce != last+1 {
  97. return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1)
  98. }
  99. }
  100. return nil
  101. }
  102. func deriveSender(tx *types.Transaction) (common.Address, error) {
  103. return types.Sender(types.HomesteadSigner{}, tx)
  104. }
  105. type testChain struct {
  106. *testBlockChain
  107. address common.Address
  108. trigger *bool
  109. }
  110. // testChain.State() is used multiple times to reset the pending state.
  111. // when simulate is true it will create a state that indicates
  112. // that tx0 and tx1 are included in the chain.
  113. func (c *testChain) State() (*state.StateDB, error) {
  114. // delay "state change" by one. The tx pool fetches the
  115. // state multiple times and by delaying it a bit we simulate
  116. // a state change between those fetches.
  117. stdb := c.statedb
  118. if *c.trigger {
  119. db, _ := ethdb.NewMemDatabase()
  120. c.statedb, _ = state.New(common.Hash{}, state.NewDatabase(db))
  121. // simulate that the new head block included tx0 and tx1
  122. c.statedb.SetNonce(c.address, 2)
  123. c.statedb.SetBalance(c.address, new(big.Int).SetUint64(params.Ether))
  124. *c.trigger = false
  125. }
  126. return stdb, nil
  127. }
  128. // This test simulates a scenario where a new block is imported during a
  129. // state reset and tests whether the pending state is in sync with the
  130. // block head event that initiated the resetState().
  131. func TestStateChangeDuringPoolReset(t *testing.T) {
  132. var (
  133. db, _ = ethdb.NewMemDatabase()
  134. key, _ = crypto.GenerateKey()
  135. address = crypto.PubkeyToAddress(key.PublicKey)
  136. statedb, _ = state.New(common.Hash{}, state.NewDatabase(db))
  137. trigger = false
  138. )
  139. // setup pool with 2 transaction in it
  140. statedb.SetBalance(address, new(big.Int).SetUint64(params.Ether))
  141. blockchain := &testChain{&testBlockChain{statedb, big.NewInt(1000000000), new(event.Feed)}, address, &trigger}
  142. tx0 := transaction(0, big.NewInt(100000), key)
  143. tx1 := transaction(1, big.NewInt(100000), key)
  144. pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
  145. defer pool.Stop()
  146. nonce := pool.State().GetNonce(address)
  147. if nonce != 0 {
  148. t.Fatalf("Invalid nonce, want 0, got %d", nonce)
  149. }
  150. pool.AddRemotes(types.Transactions{tx0, tx1})
  151. nonce = pool.State().GetNonce(address)
  152. if nonce != 2 {
  153. t.Fatalf("Invalid nonce, want 2, got %d", nonce)
  154. }
  155. // trigger state change in the background
  156. trigger = true
  157. pool.lockedReset(nil, nil)
  158. pendingTx, err := pool.Pending()
  159. if err != nil {
  160. t.Fatalf("Could not fetch pending transactions: %v", err)
  161. }
  162. for addr, txs := range pendingTx {
  163. t.Logf("%0x: %d\n", addr, len(txs))
  164. }
  165. nonce = pool.State().GetNonce(address)
  166. if nonce != 2 {
  167. t.Fatalf("Invalid nonce, want 2, got %d", nonce)
  168. }
  169. }
  170. func TestInvalidTransactions(t *testing.T) {
  171. pool, key := setupTxPool()
  172. defer pool.Stop()
  173. tx := transaction(0, big.NewInt(100), key)
  174. from, _ := deriveSender(tx)
  175. pool.currentState.AddBalance(from, big.NewInt(1))
  176. if err := pool.AddRemote(tx); err != ErrInsufficientFunds {
  177. t.Error("expected", ErrInsufficientFunds)
  178. }
  179. balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(tx.Gas(), tx.GasPrice()))
  180. pool.currentState.AddBalance(from, balance)
  181. if err := pool.AddRemote(tx); err != ErrIntrinsicGas {
  182. t.Error("expected", ErrIntrinsicGas, "got", err)
  183. }
  184. pool.currentState.SetNonce(from, 1)
  185. pool.currentState.AddBalance(from, big.NewInt(0xffffffffffffff))
  186. tx = transaction(0, big.NewInt(100000), key)
  187. if err := pool.AddRemote(tx); err != ErrNonceTooLow {
  188. t.Error("expected", ErrNonceTooLow)
  189. }
  190. tx = transaction(1, big.NewInt(100000), key)
  191. pool.gasPrice = big.NewInt(1000)
  192. if err := pool.AddRemote(tx); err != ErrUnderpriced {
  193. t.Error("expected", ErrUnderpriced, "got", err)
  194. }
  195. if err := pool.AddLocal(tx); err != nil {
  196. t.Error("expected", nil, "got", err)
  197. }
  198. }
  199. func TestTransactionQueue(t *testing.T) {
  200. pool, key := setupTxPool()
  201. defer pool.Stop()
  202. tx := transaction(0, big.NewInt(100), key)
  203. from, _ := deriveSender(tx)
  204. pool.currentState.AddBalance(from, big.NewInt(1000))
  205. pool.lockedReset(nil, nil)
  206. pool.enqueueTx(tx.Hash(), tx)
  207. pool.promoteExecutables([]common.Address{from})
  208. if len(pool.pending) != 1 {
  209. t.Error("expected valid txs to be 1 is", len(pool.pending))
  210. }
  211. tx = transaction(1, big.NewInt(100), key)
  212. from, _ = deriveSender(tx)
  213. pool.currentState.SetNonce(from, 2)
  214. pool.enqueueTx(tx.Hash(), tx)
  215. pool.promoteExecutables([]common.Address{from})
  216. if _, ok := pool.pending[from].txs.items[tx.Nonce()]; ok {
  217. t.Error("expected transaction to be in tx pool")
  218. }
  219. if len(pool.queue) > 0 {
  220. t.Error("expected transaction queue to be empty. is", len(pool.queue))
  221. }
  222. pool, key = setupTxPool()
  223. defer pool.Stop()
  224. tx1 := transaction(0, big.NewInt(100), key)
  225. tx2 := transaction(10, big.NewInt(100), key)
  226. tx3 := transaction(11, big.NewInt(100), key)
  227. from, _ = deriveSender(tx1)
  228. pool.currentState.AddBalance(from, big.NewInt(1000))
  229. pool.lockedReset(nil, nil)
  230. pool.enqueueTx(tx1.Hash(), tx1)
  231. pool.enqueueTx(tx2.Hash(), tx2)
  232. pool.enqueueTx(tx3.Hash(), tx3)
  233. pool.promoteExecutables([]common.Address{from})
  234. if len(pool.pending) != 1 {
  235. t.Error("expected tx pool to be 1, got", len(pool.pending))
  236. }
  237. if pool.queue[from].Len() != 2 {
  238. t.Error("expected len(queue) == 2, got", pool.queue[from].Len())
  239. }
  240. }
  241. func TestNegativeValue(t *testing.T) {
  242. pool, key := setupTxPool()
  243. defer pool.Stop()
  244. tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), big.NewInt(100), big.NewInt(1), nil), types.HomesteadSigner{}, key)
  245. from, _ := deriveSender(tx)
  246. pool.currentState.AddBalance(from, big.NewInt(1))
  247. if err := pool.AddRemote(tx); err != ErrNegativeValue {
  248. t.Error("expected", ErrNegativeValue, "got", err)
  249. }
  250. }
  251. func TestTransactionChainFork(t *testing.T) {
  252. pool, key := setupTxPool()
  253. defer pool.Stop()
  254. addr := crypto.PubkeyToAddress(key.PublicKey)
  255. resetState := func() {
  256. db, _ := ethdb.NewMemDatabase()
  257. statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
  258. statedb.AddBalance(addr, big.NewInt(100000000000000))
  259. pool.chain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  260. pool.lockedReset(nil, nil)
  261. }
  262. resetState()
  263. tx := transaction(0, big.NewInt(100000), key)
  264. if _, err := pool.add(tx, false); err != nil {
  265. t.Error("didn't expect error", err)
  266. }
  267. pool.removeTx(tx.Hash())
  268. // reset the pool's internal state
  269. resetState()
  270. if _, err := pool.add(tx, false); err != nil {
  271. t.Error("didn't expect error", err)
  272. }
  273. }
  274. func TestTransactionDoubleNonce(t *testing.T) {
  275. pool, key := setupTxPool()
  276. defer pool.Stop()
  277. addr := crypto.PubkeyToAddress(key.PublicKey)
  278. resetState := func() {
  279. db, _ := ethdb.NewMemDatabase()
  280. statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
  281. statedb.AddBalance(addr, big.NewInt(100000000000000))
  282. pool.chain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  283. pool.lockedReset(nil, nil)
  284. }
  285. resetState()
  286. signer := types.HomesteadSigner{}
  287. tx1, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(100000), big.NewInt(1), nil), signer, key)
  288. tx2, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(1000000), big.NewInt(2), nil), signer, key)
  289. tx3, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), big.NewInt(1000000), big.NewInt(1), nil), signer, key)
  290. // Add the first two transaction, ensure higher priced stays only
  291. if replace, err := pool.add(tx1, false); err != nil || replace {
  292. t.Errorf("first transaction insert failed (%v) or reported replacement (%v)", err, replace)
  293. }
  294. if replace, err := pool.add(tx2, false); err != nil || !replace {
  295. t.Errorf("second transaction insert failed (%v) or not reported replacement (%v)", err, replace)
  296. }
  297. pool.promoteExecutables([]common.Address{addr})
  298. if pool.pending[addr].Len() != 1 {
  299. t.Error("expected 1 pending transactions, got", pool.pending[addr].Len())
  300. }
  301. if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() {
  302. t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash())
  303. }
  304. // Add the third transaction and ensure it's not saved (smaller price)
  305. pool.add(tx3, false)
  306. pool.promoteExecutables([]common.Address{addr})
  307. if pool.pending[addr].Len() != 1 {
  308. t.Error("expected 1 pending transactions, got", pool.pending[addr].Len())
  309. }
  310. if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() {
  311. t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash())
  312. }
  313. // Ensure the total transaction count is correct
  314. if len(pool.all) != 1 {
  315. t.Error("expected 1 total transactions, got", len(pool.all))
  316. }
  317. }
  318. func TestMissingNonce(t *testing.T) {
  319. pool, key := setupTxPool()
  320. defer pool.Stop()
  321. addr := crypto.PubkeyToAddress(key.PublicKey)
  322. pool.currentState.AddBalance(addr, big.NewInt(100000000000000))
  323. tx := transaction(1, big.NewInt(100000), key)
  324. if _, err := pool.add(tx, false); err != nil {
  325. t.Error("didn't expect error", err)
  326. }
  327. if len(pool.pending) != 0 {
  328. t.Error("expected 0 pending transactions, got", len(pool.pending))
  329. }
  330. if pool.queue[addr].Len() != 1 {
  331. t.Error("expected 1 queued transaction, got", pool.queue[addr].Len())
  332. }
  333. if len(pool.all) != 1 {
  334. t.Error("expected 1 total transactions, got", len(pool.all))
  335. }
  336. }
  337. func TestTransactionNonceRecovery(t *testing.T) {
  338. const n = 10
  339. pool, key := setupTxPool()
  340. defer pool.Stop()
  341. addr := crypto.PubkeyToAddress(key.PublicKey)
  342. pool.currentState.SetNonce(addr, n)
  343. pool.currentState.AddBalance(addr, big.NewInt(100000000000000))
  344. pool.lockedReset(nil, nil)
  345. tx := transaction(n, big.NewInt(100000), key)
  346. if err := pool.AddRemote(tx); err != nil {
  347. t.Error(err)
  348. }
  349. // simulate some weird re-order of transactions and missing nonce(s)
  350. pool.currentState.SetNonce(addr, n-1)
  351. pool.lockedReset(nil, nil)
  352. if fn := pool.pendingState.GetNonce(addr); fn != n-1 {
  353. t.Errorf("expected nonce to be %d, got %d", n-1, fn)
  354. }
  355. }
  356. // Tests that if an account runs out of funds, any pending and queued transactions
  357. // are dropped.
  358. func TestTransactionDropping(t *testing.T) {
  359. // Create a test account and fund it
  360. pool, key := setupTxPool()
  361. defer pool.Stop()
  362. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  363. pool.currentState.AddBalance(account, big.NewInt(1000))
  364. // Add some pending and some queued transactions
  365. var (
  366. tx0 = transaction(0, big.NewInt(100), key)
  367. tx1 = transaction(1, big.NewInt(200), key)
  368. tx2 = transaction(2, big.NewInt(300), key)
  369. tx10 = transaction(10, big.NewInt(100), key)
  370. tx11 = transaction(11, big.NewInt(200), key)
  371. tx12 = transaction(12, big.NewInt(300), key)
  372. )
  373. pool.promoteTx(account, tx0.Hash(), tx0)
  374. pool.promoteTx(account, tx1.Hash(), tx1)
  375. pool.promoteTx(account, tx2.Hash(), tx2)
  376. pool.enqueueTx(tx10.Hash(), tx10)
  377. pool.enqueueTx(tx11.Hash(), tx11)
  378. pool.enqueueTx(tx12.Hash(), tx12)
  379. // Check that pre and post validations leave the pool as is
  380. if pool.pending[account].Len() != 3 {
  381. t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3)
  382. }
  383. if pool.queue[account].Len() != 3 {
  384. t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3)
  385. }
  386. if len(pool.all) != 6 {
  387. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 6)
  388. }
  389. pool.lockedReset(nil, nil)
  390. if pool.pending[account].Len() != 3 {
  391. t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3)
  392. }
  393. if pool.queue[account].Len() != 3 {
  394. t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3)
  395. }
  396. if len(pool.all) != 6 {
  397. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 6)
  398. }
  399. // Reduce the balance of the account, and check that invalidated transactions are dropped
  400. pool.currentState.AddBalance(account, big.NewInt(-650))
  401. pool.lockedReset(nil, nil)
  402. if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok {
  403. t.Errorf("funded pending transaction missing: %v", tx0)
  404. }
  405. if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; !ok {
  406. t.Errorf("funded pending transaction missing: %v", tx0)
  407. }
  408. if _, ok := pool.pending[account].txs.items[tx2.Nonce()]; ok {
  409. t.Errorf("out-of-fund pending transaction present: %v", tx1)
  410. }
  411. if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok {
  412. t.Errorf("funded queued transaction missing: %v", tx10)
  413. }
  414. if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; !ok {
  415. t.Errorf("funded queued transaction missing: %v", tx10)
  416. }
  417. if _, ok := pool.queue[account].txs.items[tx12.Nonce()]; ok {
  418. t.Errorf("out-of-fund queued transaction present: %v", tx11)
  419. }
  420. if len(pool.all) != 4 {
  421. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 4)
  422. }
  423. // Reduce the block gas limit, check that invalidated transactions are dropped
  424. pool.chain.(*testBlockChain).gasLimit = big.NewInt(100)
  425. pool.lockedReset(nil, nil)
  426. if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok {
  427. t.Errorf("funded pending transaction missing: %v", tx0)
  428. }
  429. if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; ok {
  430. t.Errorf("over-gased pending transaction present: %v", tx1)
  431. }
  432. if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok {
  433. t.Errorf("funded queued transaction missing: %v", tx10)
  434. }
  435. if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; ok {
  436. t.Errorf("over-gased queued transaction present: %v", tx11)
  437. }
  438. if len(pool.all) != 2 {
  439. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 2)
  440. }
  441. }
  442. // Tests that if a transaction is dropped from the current pending pool (e.g. out
  443. // of fund), all consecutive (still valid, but not executable) transactions are
  444. // postponed back into the future queue to prevent broadcasting them.
  445. func TestTransactionPostponing(t *testing.T) {
  446. // Create a test account and fund it
  447. pool, key := setupTxPool()
  448. defer pool.Stop()
  449. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  450. pool.currentState.AddBalance(account, big.NewInt(1000))
  451. // Add a batch consecutive pending transactions for validation
  452. txns := []*types.Transaction{}
  453. for i := 0; i < 100; i++ {
  454. var tx *types.Transaction
  455. if i%2 == 0 {
  456. tx = transaction(uint64(i), big.NewInt(100), key)
  457. } else {
  458. tx = transaction(uint64(i), big.NewInt(500), key)
  459. }
  460. pool.promoteTx(account, tx.Hash(), tx)
  461. txns = append(txns, tx)
  462. }
  463. // Check that pre and post validations leave the pool as is
  464. if pool.pending[account].Len() != len(txns) {
  465. t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), len(txns))
  466. }
  467. if len(pool.queue) != 0 {
  468. t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 0)
  469. }
  470. if len(pool.all) != len(txns) {
  471. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txns))
  472. }
  473. pool.lockedReset(nil, nil)
  474. if pool.pending[account].Len() != len(txns) {
  475. t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), len(txns))
  476. }
  477. if len(pool.queue) != 0 {
  478. t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 0)
  479. }
  480. if len(pool.all) != len(txns) {
  481. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txns))
  482. }
  483. // Reduce the balance of the account, and check that transactions are reorganised
  484. pool.currentState.AddBalance(account, big.NewInt(-750))
  485. pool.lockedReset(nil, nil)
  486. if _, ok := pool.pending[account].txs.items[txns[0].Nonce()]; !ok {
  487. t.Errorf("tx %d: valid and funded transaction missing from pending pool: %v", 0, txns[0])
  488. }
  489. if _, ok := pool.queue[account].txs.items[txns[0].Nonce()]; ok {
  490. t.Errorf("tx %d: valid and funded transaction present in future queue: %v", 0, txns[0])
  491. }
  492. for i, tx := range txns[1:] {
  493. if i%2 == 1 {
  494. if _, ok := pool.pending[account].txs.items[tx.Nonce()]; ok {
  495. t.Errorf("tx %d: valid but future transaction present in pending pool: %v", i+1, tx)
  496. }
  497. if _, ok := pool.queue[account].txs.items[tx.Nonce()]; !ok {
  498. t.Errorf("tx %d: valid but future transaction missing from future queue: %v", i+1, tx)
  499. }
  500. } else {
  501. if _, ok := pool.pending[account].txs.items[tx.Nonce()]; ok {
  502. t.Errorf("tx %d: out-of-fund transaction present in pending pool: %v", i+1, tx)
  503. }
  504. if _, ok := pool.queue[account].txs.items[tx.Nonce()]; ok {
  505. t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", i+1, tx)
  506. }
  507. }
  508. }
  509. if len(pool.all) != len(txns)/2 {
  510. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txns)/2)
  511. }
  512. }
  513. // Tests that if the transaction count belonging to a single account goes above
  514. // some threshold, the higher transactions are dropped to prevent DOS attacks.
  515. func TestTransactionQueueAccountLimiting(t *testing.T) {
  516. // Create a test account and fund it
  517. pool, key := setupTxPool()
  518. defer pool.Stop()
  519. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  520. pool.currentState.AddBalance(account, big.NewInt(1000000))
  521. // Keep queuing up transactions and make sure all above a limit are dropped
  522. for i := uint64(1); i <= testTxPoolConfig.AccountQueue+5; i++ {
  523. if err := pool.AddRemote(transaction(i, big.NewInt(100000), key)); err != nil {
  524. t.Fatalf("tx %d: failed to add transaction: %v", i, err)
  525. }
  526. if len(pool.pending) != 0 {
  527. t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, len(pool.pending), 0)
  528. }
  529. if i <= testTxPoolConfig.AccountQueue {
  530. if pool.queue[account].Len() != int(i) {
  531. t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), i)
  532. }
  533. } else {
  534. if pool.queue[account].Len() != int(testTxPoolConfig.AccountQueue) {
  535. t.Errorf("tx %d: queue limit mismatch: have %d, want %d", i, pool.queue[account].Len(), testTxPoolConfig.AccountQueue)
  536. }
  537. }
  538. }
  539. if len(pool.all) != int(testTxPoolConfig.AccountQueue) {
  540. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), testTxPoolConfig.AccountQueue)
  541. }
  542. }
  543. // Tests that if the transaction count belonging to multiple accounts go above
  544. // some threshold, the higher transactions are dropped to prevent DOS attacks.
  545. //
  546. // This logic should not hold for local transactions, unless the local tracking
  547. // mechanism is disabled.
  548. func TestTransactionQueueGlobalLimiting(t *testing.T) {
  549. testTransactionQueueGlobalLimiting(t, false)
  550. }
  551. func TestTransactionQueueGlobalLimitingNoLocals(t *testing.T) {
  552. testTransactionQueueGlobalLimiting(t, true)
  553. }
  554. func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) {
  555. // Create the pool to test the limit enforcement with
  556. db, _ := ethdb.NewMemDatabase()
  557. statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
  558. blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  559. config := testTxPoolConfig
  560. config.NoLocals = nolocals
  561. config.GlobalQueue = config.AccountQueue*3 - 1 // reduce the queue limits to shorten test time (-1 to make it non divisible)
  562. pool := NewTxPool(config, params.TestChainConfig, blockchain)
  563. defer pool.Stop()
  564. // Create a number of test accounts and fund them (last one will be the local)
  565. keys := make([]*ecdsa.PrivateKey, 5)
  566. for i := 0; i < len(keys); i++ {
  567. keys[i], _ = crypto.GenerateKey()
  568. pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  569. }
  570. local := keys[len(keys)-1]
  571. // Generate and queue a batch of transactions
  572. nonces := make(map[common.Address]uint64)
  573. txs := make(types.Transactions, 0, 3*config.GlobalQueue)
  574. for len(txs) < cap(txs) {
  575. key := keys[rand.Intn(len(keys)-1)] // skip adding transactions with the local account
  576. addr := crypto.PubkeyToAddress(key.PublicKey)
  577. txs = append(txs, transaction(nonces[addr]+1, big.NewInt(100000), key))
  578. nonces[addr]++
  579. }
  580. // Import the batch and verify that limits have been enforced
  581. pool.AddRemotes(txs)
  582. queued := 0
  583. for addr, list := range pool.queue {
  584. if list.Len() > int(config.AccountQueue) {
  585. t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue)
  586. }
  587. queued += list.Len()
  588. }
  589. if queued > int(config.GlobalQueue) {
  590. t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue)
  591. }
  592. // Generate a batch of transactions from the local account and import them
  593. txs = txs[:0]
  594. for i := uint64(0); i < 3*config.GlobalQueue; i++ {
  595. txs = append(txs, transaction(i+1, big.NewInt(100000), local))
  596. }
  597. pool.AddLocals(txs)
  598. // If locals are disabled, the previous eviction algorithm should apply here too
  599. if nolocals {
  600. queued := 0
  601. for addr, list := range pool.queue {
  602. if list.Len() > int(config.AccountQueue) {
  603. t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue)
  604. }
  605. queued += list.Len()
  606. }
  607. if queued > int(config.GlobalQueue) {
  608. t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue)
  609. }
  610. } else {
  611. // Local exemptions are enabled, make sure the local account owned the queue
  612. if len(pool.queue) != 1 {
  613. t.Errorf("multiple accounts in queue: have %v, want %v", len(pool.queue), 1)
  614. }
  615. // Also ensure no local transactions are ever dropped, even if above global limits
  616. if queued := pool.queue[crypto.PubkeyToAddress(local.PublicKey)].Len(); uint64(queued) != 3*config.GlobalQueue {
  617. t.Fatalf("local account queued transaction count mismatch: have %v, want %v", queued, 3*config.GlobalQueue)
  618. }
  619. }
  620. }
  621. // Tests that if an account remains idle for a prolonged amount of time, any
  622. // non-executable transactions queued up are dropped to prevent wasting resources
  623. // on shuffling them around.
  624. //
  625. // This logic should not hold for local transactions, unless the local tracking
  626. // mechanism is disabled.
  627. func TestTransactionQueueTimeLimiting(t *testing.T) { testTransactionQueueTimeLimiting(t, false) }
  628. func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) { testTransactionQueueTimeLimiting(t, true) }
  629. func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
  630. // Reduce the eviction interval to a testable amount
  631. defer func(old time.Duration) { evictionInterval = old }(evictionInterval)
  632. evictionInterval = time.Second
  633. // Create the pool to test the non-expiration enforcement
  634. db, _ := ethdb.NewMemDatabase()
  635. statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
  636. blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  637. config := testTxPoolConfig
  638. config.Lifetime = time.Second
  639. config.NoLocals = nolocals
  640. pool := NewTxPool(config, params.TestChainConfig, blockchain)
  641. defer pool.Stop()
  642. // Create two test accounts to ensure remotes expire but locals do not
  643. local, _ := crypto.GenerateKey()
  644. remote, _ := crypto.GenerateKey()
  645. pool.currentState.AddBalance(crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000))
  646. pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000))
  647. // Add the two transactions and ensure they both are queued up
  648. if err := pool.AddLocal(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), local)); err != nil {
  649. t.Fatalf("failed to add local transaction: %v", err)
  650. }
  651. if err := pool.AddRemote(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), remote)); err != nil {
  652. t.Fatalf("failed to add remote transaction: %v", err)
  653. }
  654. pending, queued := pool.Stats()
  655. if pending != 0 {
  656. t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
  657. }
  658. if queued != 2 {
  659. t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
  660. }
  661. if err := validateTxPoolInternals(pool); err != nil {
  662. t.Fatalf("pool internal state corrupted: %v", err)
  663. }
  664. // Wait a bit for eviction to run and clean up any leftovers, and ensure only the local remains
  665. time.Sleep(2 * config.Lifetime)
  666. pending, queued = pool.Stats()
  667. if pending != 0 {
  668. t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
  669. }
  670. if nolocals {
  671. if queued != 0 {
  672. t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  673. }
  674. } else {
  675. if queued != 1 {
  676. t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
  677. }
  678. }
  679. if err := validateTxPoolInternals(pool); err != nil {
  680. t.Fatalf("pool internal state corrupted: %v", err)
  681. }
  682. }
  683. // Tests that even if the transaction count belonging to a single account goes
  684. // above some threshold, as long as the transactions are executable, they are
  685. // accepted.
  686. func TestTransactionPendingLimiting(t *testing.T) {
  687. // Create a test account and fund it
  688. pool, key := setupTxPool()
  689. defer pool.Stop()
  690. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  691. pool.currentState.AddBalance(account, big.NewInt(1000000))
  692. // Keep queuing up transactions and make sure all above a limit are dropped
  693. for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ {
  694. if err := pool.AddRemote(transaction(i, big.NewInt(100000), key)); err != nil {
  695. t.Fatalf("tx %d: failed to add transaction: %v", i, err)
  696. }
  697. if pool.pending[account].Len() != int(i)+1 {
  698. t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, pool.pending[account].Len(), i+1)
  699. }
  700. if len(pool.queue) != 0 {
  701. t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), 0)
  702. }
  703. }
  704. if len(pool.all) != int(testTxPoolConfig.AccountQueue+5) {
  705. t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), testTxPoolConfig.AccountQueue+5)
  706. }
  707. }
  708. // Tests that the transaction limits are enforced the same way irrelevant whether
  709. // the transactions are added one by one or in batches.
  710. func TestTransactionQueueLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 1) }
  711. func TestTransactionPendingLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 0) }
  712. func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
  713. // Add a batch of transactions to a pool one by one
  714. pool1, key1 := setupTxPool()
  715. defer pool1.Stop()
  716. account1, _ := deriveSender(transaction(0, big.NewInt(0), key1))
  717. pool1.currentState.AddBalance(account1, big.NewInt(1000000))
  718. for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ {
  719. if err := pool1.AddRemote(transaction(origin+i, big.NewInt(100000), key1)); err != nil {
  720. t.Fatalf("tx %d: failed to add transaction: %v", i, err)
  721. }
  722. }
  723. // Add a batch of transactions to a pool in one big batch
  724. pool2, key2 := setupTxPool()
  725. defer pool2.Stop()
  726. account2, _ := deriveSender(transaction(0, big.NewInt(0), key2))
  727. pool2.currentState.AddBalance(account2, big.NewInt(1000000))
  728. txns := []*types.Transaction{}
  729. for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ {
  730. txns = append(txns, transaction(origin+i, big.NewInt(100000), key2))
  731. }
  732. pool2.AddRemotes(txns)
  733. // Ensure the batch optimization honors the same pool mechanics
  734. if len(pool1.pending) != len(pool2.pending) {
  735. t.Errorf("pending transaction count mismatch: one-by-one algo: %d, batch algo: %d", len(pool1.pending), len(pool2.pending))
  736. }
  737. if len(pool1.queue) != len(pool2.queue) {
  738. t.Errorf("queued transaction count mismatch: one-by-one algo: %d, batch algo: %d", len(pool1.queue), len(pool2.queue))
  739. }
  740. if len(pool1.all) != len(pool2.all) {
  741. t.Errorf("total transaction count mismatch: one-by-one algo %d, batch algo %d", len(pool1.all), len(pool2.all))
  742. }
  743. if err := validateTxPoolInternals(pool1); err != nil {
  744. t.Errorf("pool 1 internal state corrupted: %v", err)
  745. }
  746. if err := validateTxPoolInternals(pool2); err != nil {
  747. t.Errorf("pool 2 internal state corrupted: %v", err)
  748. }
  749. }
  750. // Tests that if the transaction count belonging to multiple accounts go above
  751. // some hard threshold, the higher transactions are dropped to prevent DOS
  752. // attacks.
  753. func TestTransactionPendingGlobalLimiting(t *testing.T) {
  754. // Create the pool to test the limit enforcement with
  755. db, _ := ethdb.NewMemDatabase()
  756. statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
  757. blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  758. config := testTxPoolConfig
  759. config.GlobalSlots = config.AccountSlots * 10
  760. pool := NewTxPool(config, params.TestChainConfig, blockchain)
  761. defer pool.Stop()
  762. // Create a number of test accounts and fund them
  763. keys := make([]*ecdsa.PrivateKey, 5)
  764. for i := 0; i < len(keys); i++ {
  765. keys[i], _ = crypto.GenerateKey()
  766. pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  767. }
  768. // Generate and queue a batch of transactions
  769. nonces := make(map[common.Address]uint64)
  770. txs := types.Transactions{}
  771. for _, key := range keys {
  772. addr := crypto.PubkeyToAddress(key.PublicKey)
  773. for j := 0; j < int(config.GlobalSlots)/len(keys)*2; j++ {
  774. txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key))
  775. nonces[addr]++
  776. }
  777. }
  778. // Import the batch and verify that limits have been enforced
  779. pool.AddRemotes(txs)
  780. pending := 0
  781. for _, list := range pool.pending {
  782. pending += list.Len()
  783. }
  784. if pending > int(config.GlobalSlots) {
  785. t.Fatalf("total pending transactions overflow allowance: %d > %d", pending, config.GlobalSlots)
  786. }
  787. if err := validateTxPoolInternals(pool); err != nil {
  788. t.Fatalf("pool internal state corrupted: %v", err)
  789. }
  790. }
  791. // Tests that if transactions start being capped, transactions are also removed from 'all'
  792. func TestTransactionCapClearsFromAll(t *testing.T) {
  793. // Create the pool to test the limit enforcement with
  794. db, _ := ethdb.NewMemDatabase()
  795. statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
  796. blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  797. config := testTxPoolConfig
  798. config.AccountSlots = 2
  799. config.AccountQueue = 2
  800. config.GlobalSlots = 8
  801. pool := NewTxPool(config, params.TestChainConfig, blockchain)
  802. defer pool.Stop()
  803. // Create a number of test accounts and fund them
  804. key, _ := crypto.GenerateKey()
  805. addr := crypto.PubkeyToAddress(key.PublicKey)
  806. pool.currentState.AddBalance(addr, big.NewInt(1000000))
  807. txs := types.Transactions{}
  808. for j := 0; j < int(config.GlobalSlots)*2; j++ {
  809. txs = append(txs, transaction(uint64(j), big.NewInt(100000), key))
  810. }
  811. // Import the batch and verify that limits have been enforced
  812. pool.AddRemotes(txs)
  813. if err := validateTxPoolInternals(pool); err != nil {
  814. t.Fatalf("pool internal state corrupted: %v", err)
  815. }
  816. }
  817. // Tests that if the transaction count belonging to multiple accounts go above
  818. // some hard threshold, if they are under the minimum guaranteed slot count then
  819. // the transactions are still kept.
  820. func TestTransactionPendingMinimumAllowance(t *testing.T) {
  821. // Create the pool to test the limit enforcement with
  822. db, _ := ethdb.NewMemDatabase()
  823. statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
  824. blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  825. config := testTxPoolConfig
  826. config.GlobalSlots = 0
  827. pool := NewTxPool(config, params.TestChainConfig, blockchain)
  828. defer pool.Stop()
  829. // Create a number of test accounts and fund them
  830. keys := make([]*ecdsa.PrivateKey, 5)
  831. for i := 0; i < len(keys); i++ {
  832. keys[i], _ = crypto.GenerateKey()
  833. pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  834. }
  835. // Generate and queue a batch of transactions
  836. nonces := make(map[common.Address]uint64)
  837. txs := types.Transactions{}
  838. for _, key := range keys {
  839. addr := crypto.PubkeyToAddress(key.PublicKey)
  840. for j := 0; j < int(config.AccountSlots)*2; j++ {
  841. txs = append(txs, transaction(nonces[addr], big.NewInt(100000), key))
  842. nonces[addr]++
  843. }
  844. }
  845. // Import the batch and verify that limits have been enforced
  846. pool.AddRemotes(txs)
  847. for addr, list := range pool.pending {
  848. if list.Len() != int(config.AccountSlots) {
  849. t.Errorf("addr %x: total pending transactions mismatch: have %d, want %d", addr, list.Len(), config.AccountSlots)
  850. }
  851. }
  852. if err := validateTxPoolInternals(pool); err != nil {
  853. t.Fatalf("pool internal state corrupted: %v", err)
  854. }
  855. }
  856. // Tests that setting the transaction pool gas price to a higher value correctly
  857. // discards everything cheaper than that and moves any gapped transactions back
  858. // from the pending pool to the queue.
  859. //
  860. // Note, local transactions are never allowed to be dropped.
  861. func TestTransactionPoolRepricing(t *testing.T) {
  862. // Create the pool to test the pricing enforcement with
  863. db, _ := ethdb.NewMemDatabase()
  864. statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
  865. blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  866. pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
  867. defer pool.Stop()
  868. // Create a number of test accounts and fund them
  869. keys := make([]*ecdsa.PrivateKey, 3)
  870. for i := 0; i < len(keys); i++ {
  871. keys[i], _ = crypto.GenerateKey()
  872. pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  873. }
  874. // Generate and queue a batch of transactions, both pending and queued
  875. txs := types.Transactions{}
  876. txs = append(txs, pricedTransaction(0, big.NewInt(100000), big.NewInt(2), keys[0]))
  877. txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(1), keys[0]))
  878. txs = append(txs, pricedTransaction(2, big.NewInt(100000), big.NewInt(2), keys[0]))
  879. txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(2), keys[1]))
  880. txs = append(txs, pricedTransaction(2, big.NewInt(100000), big.NewInt(1), keys[1]))
  881. txs = append(txs, pricedTransaction(3, big.NewInt(100000), big.NewInt(2), keys[1]))
  882. ltx := pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[2])
  883. // Import the batch and that both pending and queued transactions match up
  884. pool.AddRemotes(txs)
  885. pool.AddLocal(ltx)
  886. pending, queued := pool.Stats()
  887. if pending != 4 {
  888. t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 4)
  889. }
  890. if queued != 3 {
  891. t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3)
  892. }
  893. if err := validateTxPoolInternals(pool); err != nil {
  894. t.Fatalf("pool internal state corrupted: %v", err)
  895. }
  896. // Reprice the pool and check that underpriced transactions get dropped
  897. pool.SetGasPrice(big.NewInt(2))
  898. pending, queued = pool.Stats()
  899. if pending != 2 {
  900. t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
  901. }
  902. if queued != 3 {
  903. t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3)
  904. }
  905. if err := validateTxPoolInternals(pool); err != nil {
  906. t.Fatalf("pool internal state corrupted: %v", err)
  907. }
  908. // Check that we can't add the old transactions back
  909. if err := pool.AddRemote(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), keys[0])); err != ErrUnderpriced {
  910. t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
  911. }
  912. if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(1), keys[1])); err != ErrUnderpriced {
  913. t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
  914. }
  915. if err := validateTxPoolInternals(pool); err != nil {
  916. t.Fatalf("pool internal state corrupted: %v", err)
  917. }
  918. // However we can add local underpriced transactions
  919. tx := pricedTransaction(1, big.NewInt(100000), big.NewInt(1), keys[2])
  920. if err := pool.AddLocal(tx); err != nil {
  921. t.Fatalf("failed to add underpriced local transaction: %v", err)
  922. }
  923. if pending, _ = pool.Stats(); pending != 3 {
  924. t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
  925. }
  926. if err := validateTxPoolInternals(pool); err != nil {
  927. t.Fatalf("pool internal state corrupted: %v", err)
  928. }
  929. }
  930. // Tests that setting the transaction pool gas price to a higher value does not
  931. // remove local transactions.
  932. func TestTransactionPoolRepricingKeepsLocals(t *testing.T) {
  933. // Create the pool to test the pricing enforcement with
  934. db, _ := ethdb.NewMemDatabase()
  935. statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
  936. blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  937. pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
  938. defer pool.Stop()
  939. // Create a number of test accounts and fund them
  940. keys := make([]*ecdsa.PrivateKey, 3)
  941. for i := 0; i < len(keys); i++ {
  942. keys[i], _ = crypto.GenerateKey()
  943. pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000*1000000))
  944. }
  945. // Create transaction (both pending and queued) with a linearly growing gasprice
  946. for i := uint64(0); i < 500; i++ {
  947. // Add pending
  948. p_tx := pricedTransaction(i, big.NewInt(100000), big.NewInt(int64(i)), keys[2])
  949. if err := pool.AddLocal(p_tx); err != nil {
  950. t.Fatal(err)
  951. }
  952. // Add queued
  953. q_tx := pricedTransaction(i+501, big.NewInt(100000), big.NewInt(int64(i)), keys[2])
  954. if err := pool.AddLocal(q_tx); err != nil {
  955. t.Fatal(err)
  956. }
  957. }
  958. pending, queued := pool.Stats()
  959. expPending, expQueued := 500, 500
  960. validate := func() {
  961. pending, queued = pool.Stats()
  962. if pending != expPending {
  963. t.Fatalf("pending transactions mismatched: have %d, want %d", pending, expPending)
  964. }
  965. if queued != expQueued {
  966. t.Fatalf("queued transactions mismatched: have %d, want %d", queued, expQueued)
  967. }
  968. if err := validateTxPoolInternals(pool); err != nil {
  969. t.Fatalf("pool internal state corrupted: %v", err)
  970. }
  971. }
  972. validate()
  973. // Reprice the pool and check that nothing is dropped
  974. pool.SetGasPrice(big.NewInt(2))
  975. validate()
  976. pool.SetGasPrice(big.NewInt(2))
  977. pool.SetGasPrice(big.NewInt(4))
  978. pool.SetGasPrice(big.NewInt(8))
  979. pool.SetGasPrice(big.NewInt(100))
  980. validate()
  981. }
  982. // Tests that when the pool reaches its global transaction limit, underpriced
  983. // transactions are gradually shifted out for more expensive ones and any gapped
  984. // pending transactions are moved into te queue.
  985. //
  986. // Note, local transactions are never allowed to be dropped.
  987. func TestTransactionPoolUnderpricing(t *testing.T) {
  988. // Create the pool to test the pricing enforcement with
  989. db, _ := ethdb.NewMemDatabase()
  990. statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
  991. blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  992. config := testTxPoolConfig
  993. config.GlobalSlots = 2
  994. config.GlobalQueue = 2
  995. pool := NewTxPool(config, params.TestChainConfig, blockchain)
  996. defer pool.Stop()
  997. // Create a number of test accounts and fund them
  998. keys := make([]*ecdsa.PrivateKey, 3)
  999. for i := 0; i < len(keys); i++ {
  1000. keys[i], _ = crypto.GenerateKey()
  1001. pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  1002. }
  1003. // Generate and queue a batch of transactions, both pending and queued
  1004. txs := types.Transactions{}
  1005. txs = append(txs, pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[0]))
  1006. txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(2), keys[0]))
  1007. txs = append(txs, pricedTransaction(1, big.NewInt(100000), big.NewInt(1), keys[1]))
  1008. ltx := pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[2])
  1009. // Import the batch and that both pending and queued transactions match up
  1010. pool.AddRemotes(txs)
  1011. pool.AddLocal(ltx)
  1012. pending, queued := pool.Stats()
  1013. if pending != 3 {
  1014. t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
  1015. }
  1016. if queued != 1 {
  1017. t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
  1018. }
  1019. if err := validateTxPoolInternals(pool); err != nil {
  1020. t.Fatalf("pool internal state corrupted: %v", err)
  1021. }
  1022. // Ensure that adding an underpriced transaction on block limit fails
  1023. if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), keys[1])); err != ErrUnderpriced {
  1024. t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
  1025. }
  1026. // Ensure that adding high priced transactions drops cheap ones, but not own
  1027. if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(3), keys[1])); err != nil {
  1028. t.Fatalf("failed to add well priced transaction: %v", err)
  1029. }
  1030. if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(4), keys[1])); err != nil {
  1031. t.Fatalf("failed to add well priced transaction: %v", err)
  1032. }
  1033. if err := pool.AddRemote(pricedTransaction(3, big.NewInt(100000), big.NewInt(5), keys[1])); err != nil {
  1034. t.Fatalf("failed to add well priced transaction: %v", err)
  1035. }
  1036. pending, queued = pool.Stats()
  1037. if pending != 2 {
  1038. t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
  1039. }
  1040. if queued != 2 {
  1041. t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
  1042. }
  1043. if err := validateTxPoolInternals(pool); err != nil {
  1044. t.Fatalf("pool internal state corrupted: %v", err)
  1045. }
  1046. // Ensure that adding local transactions can push out even higher priced ones
  1047. tx := pricedTransaction(1, big.NewInt(100000), big.NewInt(0), keys[2])
  1048. if err := pool.AddLocal(tx); err != nil {
  1049. t.Fatalf("failed to add underpriced local transaction: %v", err)
  1050. }
  1051. pending, queued = pool.Stats()
  1052. if pending != 2 {
  1053. t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
  1054. }
  1055. if queued != 2 {
  1056. t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
  1057. }
  1058. if err := validateTxPoolInternals(pool); err != nil {
  1059. t.Fatalf("pool internal state corrupted: %v", err)
  1060. }
  1061. }
  1062. // Tests that the pool rejects replacement transactions that don't meet the minimum
  1063. // price bump required.
  1064. func TestTransactionReplacement(t *testing.T) {
  1065. // Create the pool to test the pricing enforcement with
  1066. db, _ := ethdb.NewMemDatabase()
  1067. statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
  1068. blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  1069. pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
  1070. defer pool.Stop()
  1071. // Create a test account to add transactions with
  1072. key, _ := crypto.GenerateKey()
  1073. pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000))
  1074. // Add pending transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too)
  1075. price := int64(100)
  1076. threshold := (price * (100 + int64(testTxPoolConfig.PriceBump))) / 100
  1077. if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), key)); err != nil {
  1078. t.Fatalf("failed to add original cheap pending transaction: %v", err)
  1079. }
  1080. if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100001), big.NewInt(1), key)); err != ErrReplaceUnderpriced {
  1081. t.Fatalf("original cheap pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced)
  1082. }
  1083. if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(2), key)); err != nil {
  1084. t.Fatalf("failed to replace original cheap pending transaction: %v", err)
  1085. }
  1086. if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(price), key)); err != nil {
  1087. t.Fatalf("failed to add original proper pending transaction: %v", err)
  1088. }
  1089. if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(threshold), key)); err != ErrReplaceUnderpriced {
  1090. t.Fatalf("original proper pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced)
  1091. }
  1092. if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(threshold+1), key)); err != nil {
  1093. t.Fatalf("failed to replace original proper pending transaction: %v", err)
  1094. }
  1095. // Add queued transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too)
  1096. if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(1), key)); err != nil {
  1097. t.Fatalf("failed to add original queued transaction: %v", err)
  1098. }
  1099. if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100001), big.NewInt(1), key)); err != ErrReplaceUnderpriced {
  1100. t.Fatalf("original queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced)
  1101. }
  1102. if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(2), key)); err != nil {
  1103. t.Fatalf("failed to replace original queued transaction: %v", err)
  1104. }
  1105. if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(price), key)); err != nil {
  1106. t.Fatalf("failed to add original queued transaction: %v", err)
  1107. }
  1108. if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100001), big.NewInt(threshold), key)); err != ErrReplaceUnderpriced {
  1109. t.Fatalf("original queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced)
  1110. }
  1111. if err := pool.AddRemote(pricedTransaction(2, big.NewInt(100000), big.NewInt(threshold+1), key)); err != nil {
  1112. t.Fatalf("failed to replace original queued transaction: %v", err)
  1113. }
  1114. if err := validateTxPoolInternals(pool); err != nil {
  1115. t.Fatalf("pool internal state corrupted: %v", err)
  1116. }
  1117. }
  1118. // Tests that local transactions are journaled to disk, but remote transactions
  1119. // get discarded between restarts.
  1120. func TestTransactionJournaling(t *testing.T) { testTransactionJournaling(t, false) }
  1121. func TestTransactionJournalingNoLocals(t *testing.T) { testTransactionJournaling(t, true) }
  1122. func testTransactionJournaling(t *testing.T, nolocals bool) {
  1123. // Create a temporary file for the journal
  1124. file, err := ioutil.TempFile("", "")
  1125. if err != nil {
  1126. t.Fatalf("failed to create temporary journal: %v", err)
  1127. }
  1128. journal := file.Name()
  1129. defer os.Remove(journal)
  1130. // Clean up the temporary file, we only need the path for now
  1131. file.Close()
  1132. os.Remove(journal)
  1133. // Create the original pool to inject transaction into the journal
  1134. db, _ := ethdb.NewMemDatabase()
  1135. statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
  1136. blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  1137. config := testTxPoolConfig
  1138. config.NoLocals = nolocals
  1139. config.Journal = journal
  1140. config.Rejournal = time.Second
  1141. pool := NewTxPool(config, params.TestChainConfig, blockchain)
  1142. // Create two test accounts to ensure remotes expire but locals do not
  1143. local, _ := crypto.GenerateKey()
  1144. remote, _ := crypto.GenerateKey()
  1145. pool.currentState.AddBalance(crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000))
  1146. pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000))
  1147. // Add three local and a remote transactions and ensure they are queued up
  1148. if err := pool.AddLocal(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), local)); err != nil {
  1149. t.Fatalf("failed to add local transaction: %v", err)
  1150. }
  1151. if err := pool.AddLocal(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), local)); err != nil {
  1152. t.Fatalf("failed to add local transaction: %v", err)
  1153. }
  1154. if err := pool.AddLocal(pricedTransaction(2, big.NewInt(100000), big.NewInt(1), local)); err != nil {
  1155. t.Fatalf("failed to add local transaction: %v", err)
  1156. }
  1157. if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), remote)); err != nil {
  1158. t.Fatalf("failed to add remote transaction: %v", err)
  1159. }
  1160. pending, queued := pool.Stats()
  1161. if pending != 4 {
  1162. t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 4)
  1163. }
  1164. if queued != 0 {
  1165. t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  1166. }
  1167. if err := validateTxPoolInternals(pool); err != nil {
  1168. t.Fatalf("pool internal state corrupted: %v", err)
  1169. }
  1170. // Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive
  1171. pool.Stop()
  1172. statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
  1173. blockchain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  1174. pool = NewTxPool(config, params.TestChainConfig, blockchain)
  1175. pending, queued = pool.Stats()
  1176. if queued != 0 {
  1177. t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  1178. }
  1179. if nolocals {
  1180. if pending != 0 {
  1181. t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
  1182. }
  1183. } else {
  1184. if pending != 2 {
  1185. t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
  1186. }
  1187. }
  1188. if err := validateTxPoolInternals(pool); err != nil {
  1189. t.Fatalf("pool internal state corrupted: %v", err)
  1190. }
  1191. // Bump the nonce temporarily and ensure the newly invalidated transaction is removed
  1192. statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2)
  1193. pool.lockedReset(nil, nil)
  1194. time.Sleep(2 * config.Rejournal)
  1195. pool.Stop()
  1196. statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
  1197. blockchain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
  1198. pool = NewTxPool(config, params.TestChainConfig, blockchain)
  1199. pending, queued = pool.Stats()
  1200. if pending != 0 {
  1201. t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
  1202. }
  1203. if nolocals {
  1204. if queued != 0 {
  1205. t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  1206. }
  1207. } else {
  1208. if queued != 1 {
  1209. t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
  1210. }
  1211. }
  1212. if err := validateTxPoolInternals(pool); err != nil {
  1213. t.Fatalf("pool internal state corrupted: %v", err)
  1214. }
  1215. pool.Stop()
  1216. }
  1217. // Benchmarks the speed of validating the contents of the pending queue of the
  1218. // transaction pool.
  1219. func BenchmarkPendingDemotion100(b *testing.B) { benchmarkPendingDemotion(b, 100) }
  1220. func BenchmarkPendingDemotion1000(b *testing.B) { benchmarkPendingDemotion(b, 1000) }
  1221. func BenchmarkPendingDemotion10000(b *testing.B) { benchmarkPendingDemotion(b, 10000) }
  1222. func benchmarkPendingDemotion(b *testing.B, size int) {
  1223. // Add a batch of transactions to a pool one by one
  1224. pool, key := setupTxPool()
  1225. defer pool.Stop()
  1226. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  1227. pool.currentState.AddBalance(account, big.NewInt(1000000))
  1228. for i := 0; i < size; i++ {
  1229. tx := transaction(uint64(i), big.NewInt(100000), key)
  1230. pool.promoteTx(account, tx.Hash(), tx)
  1231. }
  1232. // Benchmark the speed of pool validation
  1233. b.ResetTimer()
  1234. for i := 0; i < b.N; i++ {
  1235. pool.demoteUnexecutables()
  1236. }
  1237. }
  1238. // Benchmarks the speed of scheduling the contents of the future queue of the
  1239. // transaction pool.
  1240. func BenchmarkFuturePromotion100(b *testing.B) { benchmarkFuturePromotion(b, 100) }
  1241. func BenchmarkFuturePromotion1000(b *testing.B) { benchmarkFuturePromotion(b, 1000) }
  1242. func BenchmarkFuturePromotion10000(b *testing.B) { benchmarkFuturePromotion(b, 10000) }
  1243. func benchmarkFuturePromotion(b *testing.B, size int) {
  1244. // Add a batch of transactions to a pool one by one
  1245. pool, key := setupTxPool()
  1246. defer pool.Stop()
  1247. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  1248. pool.currentState.AddBalance(account, big.NewInt(1000000))
  1249. for i := 0; i < size; i++ {
  1250. tx := transaction(uint64(1+i), big.NewInt(100000), key)
  1251. pool.enqueueTx(tx.Hash(), tx)
  1252. }
  1253. // Benchmark the speed of pool validation
  1254. b.ResetTimer()
  1255. for i := 0; i < b.N; i++ {
  1256. pool.promoteExecutables(nil)
  1257. }
  1258. }
  1259. // Benchmarks the speed of iterative transaction insertion.
  1260. func BenchmarkPoolInsert(b *testing.B) {
  1261. // Generate a batch of transactions to enqueue into the pool
  1262. pool, key := setupTxPool()
  1263. defer pool.Stop()
  1264. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  1265. pool.currentState.AddBalance(account, big.NewInt(1000000))
  1266. txs := make(types.Transactions, b.N)
  1267. for i := 0; i < b.N; i++ {
  1268. txs[i] = transaction(uint64(i), big.NewInt(100000), key)
  1269. }
  1270. // Benchmark importing the transactions into the queue
  1271. b.ResetTimer()
  1272. for _, tx := range txs {
  1273. pool.AddRemote(tx)
  1274. }
  1275. }
  1276. // Benchmarks the speed of batched transaction insertion.
  1277. func BenchmarkPoolBatchInsert100(b *testing.B) { benchmarkPoolBatchInsert(b, 100) }
  1278. func BenchmarkPoolBatchInsert1000(b *testing.B) { benchmarkPoolBatchInsert(b, 1000) }
  1279. func BenchmarkPoolBatchInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 10000) }
  1280. func benchmarkPoolBatchInsert(b *testing.B, size int) {
  1281. // Generate a batch of transactions to enqueue into the pool
  1282. pool, key := setupTxPool()
  1283. defer pool.Stop()
  1284. account, _ := deriveSender(transaction(0, big.NewInt(0), key))
  1285. pool.currentState.AddBalance(account, big.NewInt(1000000))
  1286. batches := make([]types.Transactions, b.N)
  1287. for i := 0; i < b.N; i++ {
  1288. batches[i] = make(types.Transactions, size)
  1289. for j := 0; j < size; j++ {
  1290. batches[i][j] = transaction(uint64(size*i+j), big.NewInt(100000), key)
  1291. }
  1292. }
  1293. // Benchmark importing the transactions into the queue
  1294. b.ResetTimer()
  1295. for _, batch := range batches {
  1296. pool.AddRemotes(batch)
  1297. }
  1298. }