github.com/etherite/go-etherite@v0.0.0-20171015192807-5f4dd87b2f6e/core/tx_pool_test.go (about)

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