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