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