github.com/dim4egster/coreth@v0.10.2/core/tx_pool_test.go (about)

     1  // (c) 2019-2021, Ava Labs, Inc.
     2  //
     3  // This file is a derived work, based on the go-ethereum library whose original
     4  // notices appear below.
     5  //
     6  // It is distributed under a license compatible with the licensing terms of the
     7  // original code from which it is derived.
     8  //
     9  // Much love to the original authors for their work.
    10  // **********
    11  // Copyright 2015 The go-ethereum Authors
    12  // This file is part of the go-ethereum library.
    13  //
    14  // The go-ethereum library is free software: you can redistribute it and/or modify
    15  // it under the terms of the GNU Lesser General Public License as published by
    16  // the Free Software Foundation, either version 3 of the License, or
    17  // (at your option) any later version.
    18  //
    19  // The go-ethereum library is distributed in the hope that it will be useful,
    20  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    21  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    22  // GNU Lesser General Public License for more details.
    23  //
    24  // You should have received a copy of the GNU Lesser General Public License
    25  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    26  
    27  package core
    28  
    29  import (
    30  	"crypto/ecdsa"
    31  	"errors"
    32  	"fmt"
    33  	"math/big"
    34  	"math/rand"
    35  	"os"
    36  	"strings"
    37  	"sync"
    38  	"testing"
    39  	"time"
    40  
    41  	"github.com/dim4egster/coreth/core/rawdb"
    42  	"github.com/dim4egster/coreth/core/state"
    43  	"github.com/dim4egster/coreth/core/types"
    44  	"github.com/dim4egster/coreth/params"
    45  	"github.com/dim4egster/coreth/trie"
    46  	"github.com/ethereum/go-ethereum/common"
    47  	"github.com/ethereum/go-ethereum/crypto"
    48  	"github.com/ethereum/go-ethereum/event"
    49  )
    50  
    51  var (
    52  	// testTxPoolConfig is a transaction pool configuration without stateful disk
    53  	// sideeffects used during testing.
    54  	testTxPoolConfig TxPoolConfig
    55  
    56  	// eip1559Config is a chain config with EIP-1559 enabled at block 0.
    57  	eip1559Config *params.ChainConfig
    58  )
    59  
    60  func init() {
    61  	testTxPoolConfig = DefaultTxPoolConfig
    62  	testTxPoolConfig.Journal = ""
    63  
    64  	cpy := *params.TestChainConfig
    65  	eip1559Config = &cpy
    66  	eip1559Config.ApricotPhase2BlockTimestamp = common.Big0
    67  	eip1559Config.ApricotPhase3BlockTimestamp = common.Big0
    68  }
    69  
    70  type testBlockChain struct {
    71  	statedb       *state.StateDB
    72  	gasLimit      uint64
    73  	chainHeadFeed *event.Feed
    74  	lock          sync.Mutex
    75  }
    76  
    77  func newTestBlockchain(statedb *state.StateDB, gasLimit uint64, chainHeadFeed *event.Feed) *testBlockChain {
    78  	return &testBlockChain{
    79  		statedb:       statedb,
    80  		gasLimit:      gasLimit,
    81  		chainHeadFeed: chainHeadFeed,
    82  	}
    83  }
    84  
    85  func (bc *testBlockChain) reset(statedb *state.StateDB, gasLimit uint64, chainHeadFeed *event.Feed) {
    86  	bc.lock.Lock()
    87  	defer bc.lock.Unlock()
    88  
    89  	bc.statedb = statedb
    90  	bc.gasLimit = gasLimit
    91  	bc.chainHeadFeed = chainHeadFeed
    92  }
    93  
    94  func (bc *testBlockChain) CurrentBlock() *types.Block {
    95  	bc.lock.Lock()
    96  	defer bc.lock.Unlock()
    97  
    98  	return types.NewBlock(&types.Header{
    99  		GasLimit: bc.gasLimit,
   100  	}, nil, nil, nil, trie.NewStackTrie(nil), nil, true)
   101  }
   102  
   103  func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
   104  	return bc.CurrentBlock()
   105  }
   106  
   107  func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) {
   108  	bc.lock.Lock()
   109  	defer bc.lock.Unlock()
   110  
   111  	return bc.statedb, nil
   112  }
   113  
   114  func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription {
   115  	bc.lock.Lock()
   116  	defer bc.lock.Unlock()
   117  
   118  	return bc.chainHeadFeed.Subscribe(ch)
   119  }
   120  
   121  func (bc *testBlockChain) SenderCacher() *TxSenderCacher {
   122  	return newTxSenderCacher(1)
   123  }
   124  
   125  func transaction(nonce uint64, gaslimit uint64, key *ecdsa.PrivateKey) *types.Transaction {
   126  	return pricedTransaction(nonce, gaslimit, big.NewInt(1), key)
   127  }
   128  
   129  func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey) *types.Transaction {
   130  	tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(100), gaslimit, gasprice, nil), types.HomesteadSigner{}, key)
   131  	return tx
   132  }
   133  
   134  func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey, bytes uint64) *types.Transaction {
   135  	data := make([]byte, bytes)
   136  	rand.Read(data)
   137  
   138  	tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(0), gaslimit, gasprice, data), types.HomesteadSigner{}, key)
   139  	return tx
   140  }
   141  
   142  func dynamicFeeTx(nonce uint64, gaslimit uint64, gasFee *big.Int, tip *big.Int, key *ecdsa.PrivateKey) *types.Transaction {
   143  	tx, _ := types.SignNewTx(key, types.LatestSignerForChainID(params.TestChainConfig.ChainID), &types.DynamicFeeTx{
   144  		ChainID:    params.TestChainConfig.ChainID,
   145  		Nonce:      nonce,
   146  		GasTipCap:  tip,
   147  		GasFeeCap:  gasFee,
   148  		Gas:        gaslimit,
   149  		To:         &common.Address{},
   150  		Value:      big.NewInt(100),
   151  		Data:       nil,
   152  		AccessList: nil,
   153  	})
   154  	return tx
   155  }
   156  
   157  func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
   158  	return setupTxPoolWithConfig(params.TestChainConfig)
   159  }
   160  
   161  func setupTxPoolWithConfig(config *params.ChainConfig) (*TxPool, *ecdsa.PrivateKey) {
   162  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
   163  	blockchain := newTestBlockchain(statedb, 10000000, new(event.Feed))
   164  
   165  	key, _ := crypto.GenerateKey()
   166  	pool := NewTxPool(testTxPoolConfig, config, blockchain)
   167  
   168  	// wait for the pool to initialize
   169  	<-pool.initDoneCh
   170  	return pool, key
   171  }
   172  
   173  // validateTxPoolInternals checks various consistency invariants within the pool.
   174  func validateTxPoolInternals(pool *TxPool) error {
   175  	pool.mu.RLock()
   176  	defer pool.mu.RUnlock()
   177  
   178  	// Ensure the total transaction set is consistent with pending + queued
   179  	pending, queued := pool.stats()
   180  	if total := pool.all.Count(); total != pending+queued {
   181  		return fmt.Errorf("total transaction count %d != %d pending + %d queued", total, pending, queued)
   182  	}
   183  	pool.priced.Reheap()
   184  	priced, remote := pool.priced.urgent.Len()+pool.priced.floating.Len(), pool.all.RemoteCount()
   185  	if priced != remote {
   186  		return fmt.Errorf("total priced transaction count %d != %d", priced, remote)
   187  	}
   188  	// Ensure the next nonce to assign is the correct one
   189  	for addr, txs := range pool.pending {
   190  		// Find the last transaction
   191  		var last uint64
   192  		for nonce := range txs.txs.items {
   193  			if last < nonce {
   194  				last = nonce
   195  			}
   196  		}
   197  		if nonce := pool.pendingNonces.get(addr); nonce != last+1 {
   198  			return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1)
   199  		}
   200  	}
   201  	return nil
   202  }
   203  
   204  // validateEvents checks that the correct number of transaction addition events
   205  // were fired on the pool's event feed.
   206  func validateEvents(events chan NewTxsEvent, count int) error {
   207  	var received []*types.Transaction
   208  
   209  	for len(received) < count {
   210  		select {
   211  		case ev := <-events:
   212  			received = append(received, ev.Txs...)
   213  		case <-time.After(10 * time.Second):
   214  			return fmt.Errorf("event #%d not fired", len(received))
   215  		}
   216  	}
   217  	if len(received) > count {
   218  		return fmt.Errorf("more than %d events fired: %v", count, received[count:])
   219  	}
   220  	select {
   221  	case ev := <-events:
   222  		return fmt.Errorf("more than %d events fired: %v", count, ev.Txs)
   223  
   224  	case <-time.After(50 * time.Millisecond):
   225  		// This branch should be "default", but it's a data race between goroutines,
   226  		// reading the event channel and pushing into it, so better wait a bit ensuring
   227  		// really nothing gets injected.
   228  	}
   229  	return nil
   230  }
   231  
   232  func deriveSender(tx *types.Transaction) (common.Address, error) {
   233  	return types.Sender(types.HomesteadSigner{}, tx)
   234  }
   235  
   236  type testChain struct {
   237  	*testBlockChain
   238  	address common.Address
   239  	trigger *bool
   240  }
   241  
   242  // testChain.State() is used multiple times to reset the pending state.
   243  // when simulate is true it will create a state that indicates
   244  // that tx0 and tx1 are included in the chain.
   245  func (c *testChain) State() (*state.StateDB, error) {
   246  	// delay "state change" by one. The tx pool fetches the
   247  	// state multiple times and by delaying it a bit we simulate
   248  	// a state change between those fetches.
   249  	stdb := c.statedb
   250  	if *c.trigger {
   251  		c.statedb, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
   252  		// simulate that the new head block included tx0 and tx1
   253  		c.statedb.SetNonce(c.address, 2)
   254  		c.statedb.SetBalance(c.address, new(big.Int).SetUint64(params.Ether))
   255  		*c.trigger = false
   256  	}
   257  	return stdb, nil
   258  }
   259  
   260  // This test simulates a scenario where a new block is imported during a
   261  // state reset and tests whether the pending state is in sync with the
   262  // block head event that initiated the resetState().
   263  func TestStateChangeDuringTransactionPoolReset(t *testing.T) {
   264  	t.Parallel()
   265  
   266  	var (
   267  		key, _     = crypto.GenerateKey()
   268  		address    = crypto.PubkeyToAddress(key.PublicKey)
   269  		statedb, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
   270  		trigger    = false
   271  	)
   272  
   273  	// setup pool with 2 transaction in it
   274  	statedb.SetBalance(address, new(big.Int).SetUint64(params.Ether))
   275  	blockchain := &testChain{newTestBlockchain(statedb, 1000000000, new(event.Feed)), address, &trigger}
   276  
   277  	tx0 := transaction(0, 100000, key)
   278  	tx1 := transaction(1, 100000, key)
   279  
   280  	pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
   281  	defer pool.Stop()
   282  
   283  	nonce := pool.Nonce(address)
   284  	if nonce != 0 {
   285  		t.Fatalf("Invalid nonce, want 0, got %d", nonce)
   286  	}
   287  
   288  	pool.AddRemotesSync([]*types.Transaction{tx0, tx1})
   289  
   290  	nonce = pool.Nonce(address)
   291  	if nonce != 2 {
   292  		t.Fatalf("Invalid nonce, want 2, got %d", nonce)
   293  	}
   294  
   295  	// trigger state change in the background
   296  	trigger = true
   297  	<-pool.requestReset(nil, nil)
   298  
   299  	nonce = pool.Nonce(address)
   300  	if nonce != 2 {
   301  		t.Fatalf("Invalid nonce, want 2, got %d", nonce)
   302  	}
   303  }
   304  
   305  func testAddBalance(pool *TxPool, addr common.Address, amount *big.Int) {
   306  	pool.mu.Lock()
   307  	pool.currentState.AddBalance(addr, amount)
   308  	pool.mu.Unlock()
   309  }
   310  
   311  func testSetNonce(pool *TxPool, addr common.Address, nonce uint64) {
   312  	pool.mu.Lock()
   313  	pool.currentState.SetNonce(addr, nonce)
   314  	pool.mu.Unlock()
   315  }
   316  
   317  func TestInvalidTransactions(t *testing.T) {
   318  	t.Parallel()
   319  
   320  	pool, key := setupTxPool()
   321  	defer pool.Stop()
   322  
   323  	tx := transaction(0, 100, key)
   324  	from, _ := deriveSender(tx)
   325  
   326  	testAddBalance(pool, from, big.NewInt(1))
   327  	if err := pool.AddRemote(tx); !errors.Is(err, ErrInsufficientFunds) {
   328  		t.Error("expected", ErrInsufficientFunds)
   329  	}
   330  
   331  	balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(new(big.Int).SetUint64(tx.Gas()), tx.GasPrice()))
   332  	testAddBalance(pool, from, balance)
   333  	if err := pool.AddRemote(tx); !errors.Is(err, ErrIntrinsicGas) {
   334  		t.Error("expected", ErrIntrinsicGas, "got", err)
   335  	}
   336  
   337  	testSetNonce(pool, from, 1)
   338  	testAddBalance(pool, from, big.NewInt(0xffffffffffffff))
   339  	tx = transaction(0, 100000, key)
   340  	if err := pool.AddRemote(tx); !errors.Is(err, ErrNonceTooLow) {
   341  		t.Error("expected", ErrNonceTooLow)
   342  	}
   343  
   344  	tx = transaction(1, 100000, key)
   345  	pool.gasPrice = big.NewInt(1000)
   346  	if err := pool.AddRemote(tx); !strings.Contains(err.Error(), ErrUnderpriced.Error()) {
   347  		t.Error("expected error to contain", ErrUnderpriced, "got", err)
   348  	}
   349  	if err := pool.AddLocal(tx); err != nil {
   350  		t.Error("expected", nil, "got", err)
   351  	}
   352  }
   353  
   354  func TestTransactionQueue(t *testing.T) {
   355  	t.Parallel()
   356  
   357  	pool, key := setupTxPool()
   358  	defer pool.Stop()
   359  
   360  	tx := transaction(0, 100, key)
   361  	from, _ := deriveSender(tx)
   362  	testAddBalance(pool, from, big.NewInt(1000))
   363  	<-pool.requestReset(nil, nil)
   364  
   365  	pool.enqueueTx(tx.Hash(), tx, false, true)
   366  	<-pool.requestPromoteExecutables(newAccountSet(pool.signer, from))
   367  	if len(pool.pending) != 1 {
   368  		t.Error("expected valid txs to be 1 is", len(pool.pending))
   369  	}
   370  
   371  	tx = transaction(1, 100, key)
   372  	from, _ = deriveSender(tx)
   373  	testSetNonce(pool, from, 2)
   374  	pool.enqueueTx(tx.Hash(), tx, false, true)
   375  
   376  	<-pool.requestPromoteExecutables(newAccountSet(pool.signer, from))
   377  	if _, ok := pool.pending[from].txs.items[tx.Nonce()]; ok {
   378  		t.Error("expected transaction to be in tx pool")
   379  	}
   380  	if len(pool.queue) > 0 {
   381  		t.Error("expected transaction queue to be empty. is", len(pool.queue))
   382  	}
   383  }
   384  
   385  func TestTransactionQueue2(t *testing.T) {
   386  	t.Parallel()
   387  
   388  	pool, key := setupTxPool()
   389  	defer pool.Stop()
   390  
   391  	tx1 := transaction(0, 100, key)
   392  	tx2 := transaction(10, 100, key)
   393  	tx3 := transaction(11, 100, key)
   394  	from, _ := deriveSender(tx1)
   395  	testAddBalance(pool, from, big.NewInt(1000))
   396  	pool.reset(nil, nil)
   397  
   398  	pool.enqueueTx(tx1.Hash(), tx1, false, true)
   399  	pool.enqueueTx(tx2.Hash(), tx2, false, true)
   400  	pool.enqueueTx(tx3.Hash(), tx3, false, true)
   401  
   402  	pool.promoteExecutables([]common.Address{from})
   403  	if len(pool.pending) != 1 {
   404  		t.Error("expected pending length to be 1, got", len(pool.pending))
   405  	}
   406  	if pool.queue[from].Len() != 2 {
   407  		t.Error("expected len(queue) == 2, got", pool.queue[from].Len())
   408  	}
   409  }
   410  
   411  func TestTransactionNegativeValue(t *testing.T) {
   412  	t.Parallel()
   413  
   414  	pool, key := setupTxPool()
   415  	defer pool.Stop()
   416  
   417  	tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), 100, big.NewInt(1), nil), types.HomesteadSigner{}, key)
   418  	from, _ := deriveSender(tx)
   419  	testAddBalance(pool, from, big.NewInt(1))
   420  	if err := pool.AddRemote(tx); err != ErrNegativeValue {
   421  		t.Error("expected", ErrNegativeValue, "got", err)
   422  	}
   423  }
   424  
   425  func TestTransactionTipAboveFeeCap(t *testing.T) {
   426  	t.Parallel()
   427  
   428  	pool, key := setupTxPoolWithConfig(eip1559Config)
   429  	defer pool.Stop()
   430  
   431  	tx := dynamicFeeTx(0, 100, big.NewInt(1), big.NewInt(2), key)
   432  
   433  	if err := pool.AddRemote(tx); err != ErrTipAboveFeeCap {
   434  		t.Error("expected", ErrTipAboveFeeCap, "got", err)
   435  	}
   436  }
   437  
   438  func TestTransactionVeryHighValues(t *testing.T) {
   439  	t.Parallel()
   440  
   441  	pool, key := setupTxPoolWithConfig(eip1559Config)
   442  	defer pool.Stop()
   443  
   444  	veryBigNumber := big.NewInt(1)
   445  	veryBigNumber.Lsh(veryBigNumber, 300)
   446  
   447  	tx := dynamicFeeTx(0, 100, big.NewInt(1), veryBigNumber, key)
   448  	if err := pool.AddRemote(tx); err != ErrTipVeryHigh {
   449  		t.Error("expected", ErrTipVeryHigh, "got", err)
   450  	}
   451  
   452  	tx2 := dynamicFeeTx(0, 100, veryBigNumber, big.NewInt(1), key)
   453  	if err := pool.AddRemote(tx2); err != ErrFeeCapVeryHigh {
   454  		t.Error("expected", ErrFeeCapVeryHigh, "got", err)
   455  	}
   456  }
   457  
   458  func TestTransactionChainFork(t *testing.T) {
   459  	t.Parallel()
   460  
   461  	pool, key := setupTxPool()
   462  	defer pool.Stop()
   463  
   464  	addr := crypto.PubkeyToAddress(key.PublicKey)
   465  	resetState := func() {
   466  		statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
   467  		statedb.AddBalance(addr, big.NewInt(100000000000000))
   468  
   469  		pool.chain.(*testBlockChain).reset(statedb, 1000000, new(event.Feed))
   470  		<-pool.requestReset(nil, nil)
   471  	}
   472  	resetState()
   473  
   474  	tx := transaction(0, 100000, key)
   475  	if _, err := pool.add(tx, false); err != nil {
   476  		t.Error("didn't expect error", err)
   477  	}
   478  	pool.removeTx(tx.Hash(), true)
   479  
   480  	// reset the pool's internal state
   481  	resetState()
   482  	if _, err := pool.add(tx, false); err != nil {
   483  		t.Error("didn't expect error", err)
   484  	}
   485  }
   486  
   487  func TestTransactionDoubleNonce(t *testing.T) {
   488  	t.Parallel()
   489  
   490  	pool, key := setupTxPool()
   491  	defer pool.Stop()
   492  
   493  	addr := crypto.PubkeyToAddress(key.PublicKey)
   494  	resetState := func() {
   495  		statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
   496  		statedb.AddBalance(addr, big.NewInt(100000000000000))
   497  
   498  		pool.chain.(*testBlockChain).reset(statedb, 1000000, new(event.Feed))
   499  		<-pool.requestReset(nil, nil)
   500  	}
   501  	resetState()
   502  
   503  	signer := types.HomesteadSigner{}
   504  	tx1, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 100000, big.NewInt(1), nil), signer, key)
   505  	tx2, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(2), nil), signer, key)
   506  	tx3, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(1), nil), signer, key)
   507  
   508  	// Add the first two transaction, ensure higher priced stays only
   509  	if replace, err := pool.add(tx1, false); err != nil || replace {
   510  		t.Errorf("first transaction insert failed (%v) or reported replacement (%v)", err, replace)
   511  	}
   512  	if replace, err := pool.add(tx2, false); err != nil || !replace {
   513  		t.Errorf("second transaction insert failed (%v) or not reported replacement (%v)", err, replace)
   514  	}
   515  	<-pool.requestPromoteExecutables(newAccountSet(signer, addr))
   516  	if pool.pending[addr].Len() != 1 {
   517  		t.Error("expected 1 pending transactions, got", pool.pending[addr].Len())
   518  	}
   519  	if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() {
   520  		t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash())
   521  	}
   522  
   523  	// Add the third transaction and ensure it's not saved (smaller price)
   524  	pool.add(tx3, false)
   525  	<-pool.requestPromoteExecutables(newAccountSet(signer, addr))
   526  	if pool.pending[addr].Len() != 1 {
   527  		t.Error("expected 1 pending transactions, got", pool.pending[addr].Len())
   528  	}
   529  	if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() {
   530  		t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash())
   531  	}
   532  	// Ensure the total transaction count is correct
   533  	if pool.all.Count() != 1 {
   534  		t.Error("expected 1 total transactions, got", pool.all.Count())
   535  	}
   536  }
   537  
   538  func TestTransactionMissingNonce(t *testing.T) {
   539  	t.Parallel()
   540  
   541  	pool, key := setupTxPool()
   542  	defer pool.Stop()
   543  
   544  	addr := crypto.PubkeyToAddress(key.PublicKey)
   545  	testAddBalance(pool, addr, big.NewInt(100000000000000))
   546  	tx := transaction(1, 100000, key)
   547  	if _, err := pool.add(tx, false); err != nil {
   548  		t.Error("didn't expect error", err)
   549  	}
   550  	if len(pool.pending) != 0 {
   551  		t.Error("expected 0 pending transactions, got", len(pool.pending))
   552  	}
   553  	if pool.queue[addr].Len() != 1 {
   554  		t.Error("expected 1 queued transaction, got", pool.queue[addr].Len())
   555  	}
   556  	if pool.all.Count() != 1 {
   557  		t.Error("expected 1 total transactions, got", pool.all.Count())
   558  	}
   559  }
   560  
   561  func TestTransactionNonceRecovery(t *testing.T) {
   562  	t.Parallel()
   563  
   564  	const n = 10
   565  	pool, key := setupTxPool()
   566  	defer pool.Stop()
   567  
   568  	addr := crypto.PubkeyToAddress(key.PublicKey)
   569  	testSetNonce(pool, addr, n)
   570  	testAddBalance(pool, addr, big.NewInt(100000000000000))
   571  	<-pool.requestReset(nil, nil)
   572  
   573  	tx := transaction(n, 100000, key)
   574  	if err := pool.AddRemote(tx); err != nil {
   575  		t.Error(err)
   576  	}
   577  	// simulate some weird re-order of transactions and missing nonce(s)
   578  	testSetNonce(pool, addr, n-1)
   579  	<-pool.requestReset(nil, nil)
   580  	if fn := pool.Nonce(addr); fn != n-1 {
   581  		t.Errorf("expected nonce to be %d, got %d", n-1, fn)
   582  	}
   583  }
   584  
   585  // Tests that if an account runs out of funds, any pending and queued transactions
   586  // are dropped.
   587  func TestTransactionDropping(t *testing.T) {
   588  	t.Parallel()
   589  
   590  	// Create a test account and fund it
   591  	pool, key := setupTxPool()
   592  	defer pool.Stop()
   593  
   594  	account := crypto.PubkeyToAddress(key.PublicKey)
   595  	testAddBalance(pool, account, big.NewInt(1000))
   596  
   597  	// Add some pending and some queued transactions
   598  	var (
   599  		tx0  = transaction(0, 100, key)
   600  		tx1  = transaction(1, 200, key)
   601  		tx2  = transaction(2, 300, key)
   602  		tx10 = transaction(10, 100, key)
   603  		tx11 = transaction(11, 200, key)
   604  		tx12 = transaction(12, 300, key)
   605  	)
   606  	pool.all.Add(tx0, false)
   607  	pool.priced.Put(tx0, false)
   608  	pool.promoteTx(account, tx0.Hash(), tx0)
   609  
   610  	pool.all.Add(tx1, false)
   611  	pool.priced.Put(tx1, false)
   612  	pool.promoteTx(account, tx1.Hash(), tx1)
   613  
   614  	pool.all.Add(tx2, false)
   615  	pool.priced.Put(tx2, false)
   616  	pool.promoteTx(account, tx2.Hash(), tx2)
   617  
   618  	pool.enqueueTx(tx10.Hash(), tx10, false, true)
   619  	pool.enqueueTx(tx11.Hash(), tx11, false, true)
   620  	pool.enqueueTx(tx12.Hash(), tx12, false, true)
   621  
   622  	// Check that pre and post validations leave the pool as is
   623  	if pool.pending[account].Len() != 3 {
   624  		t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3)
   625  	}
   626  	if pool.queue[account].Len() != 3 {
   627  		t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3)
   628  	}
   629  	if pool.all.Count() != 6 {
   630  		t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 6)
   631  	}
   632  	<-pool.requestReset(nil, nil)
   633  	if pool.pending[account].Len() != 3 {
   634  		t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3)
   635  	}
   636  	if pool.queue[account].Len() != 3 {
   637  		t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3)
   638  	}
   639  	if pool.all.Count() != 6 {
   640  		t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 6)
   641  	}
   642  	// Reduce the balance of the account, and check that invalidated transactions are dropped
   643  	testAddBalance(pool, account, big.NewInt(-650))
   644  	<-pool.requestReset(nil, nil)
   645  
   646  	if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok {
   647  		t.Errorf("funded pending transaction missing: %v", tx0)
   648  	}
   649  	if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; !ok {
   650  		t.Errorf("funded pending transaction missing: %v", tx0)
   651  	}
   652  	if _, ok := pool.pending[account].txs.items[tx2.Nonce()]; ok {
   653  		t.Errorf("out-of-fund pending transaction present: %v", tx1)
   654  	}
   655  	if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok {
   656  		t.Errorf("funded queued transaction missing: %v", tx10)
   657  	}
   658  	if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; !ok {
   659  		t.Errorf("funded queued transaction missing: %v", tx10)
   660  	}
   661  	if _, ok := pool.queue[account].txs.items[tx12.Nonce()]; ok {
   662  		t.Errorf("out-of-fund queued transaction present: %v", tx11)
   663  	}
   664  	if pool.all.Count() != 4 {
   665  		t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 4)
   666  	}
   667  	// Reduce the block gas limit, check that invalidated transactions are dropped
   668  	tbc := pool.chain.(*testBlockChain)
   669  	tbc.reset(tbc.statedb, 100, tbc.chainHeadFeed)
   670  	<-pool.requestReset(nil, nil)
   671  
   672  	if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok {
   673  		t.Errorf("funded pending transaction missing: %v", tx0)
   674  	}
   675  	if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; ok {
   676  		t.Errorf("over-gased pending transaction present: %v", tx1)
   677  	}
   678  	if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok {
   679  		t.Errorf("funded queued transaction missing: %v", tx10)
   680  	}
   681  	if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; ok {
   682  		t.Errorf("over-gased queued transaction present: %v", tx11)
   683  	}
   684  	if pool.all.Count() != 2 {
   685  		t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 2)
   686  	}
   687  }
   688  
   689  // Tests that if a transaction is dropped from the current pending pool (e.g. out
   690  // of fund), all consecutive (still valid, but not executable) transactions are
   691  // postponed back into the future queue to prevent broadcasting them.
   692  func TestTransactionPostponing(t *testing.T) {
   693  	t.Parallel()
   694  
   695  	// Create the pool to test the postponing with
   696  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
   697  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
   698  
   699  	pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
   700  	defer pool.Stop()
   701  
   702  	// Create two test accounts to produce different gap profiles with
   703  	keys := make([]*ecdsa.PrivateKey, 2)
   704  	accs := make([]common.Address, len(keys))
   705  
   706  	for i := 0; i < len(keys); i++ {
   707  		keys[i], _ = crypto.GenerateKey()
   708  		accs[i] = crypto.PubkeyToAddress(keys[i].PublicKey)
   709  
   710  		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(50100))
   711  	}
   712  	// Add a batch consecutive pending transactions for validation
   713  	txs := []*types.Transaction{}
   714  	for i, key := range keys {
   715  		for j := 0; j < 100; j++ {
   716  			var tx *types.Transaction
   717  			if (i+j)%2 == 0 {
   718  				tx = transaction(uint64(j), 25000, key)
   719  			} else {
   720  				tx = transaction(uint64(j), 50000, key)
   721  			}
   722  			txs = append(txs, tx)
   723  		}
   724  	}
   725  	for i, err := range pool.AddRemotesSync(txs) {
   726  		if err != nil {
   727  			t.Fatalf("tx %d: failed to add transactions: %v", i, err)
   728  		}
   729  	}
   730  	// Check that pre and post validations leave the pool as is
   731  	if pending := pool.pending[accs[0]].Len() + pool.pending[accs[1]].Len(); pending != len(txs) {
   732  		t.Errorf("pending transaction mismatch: have %d, want %d", pending, len(txs))
   733  	}
   734  	if len(pool.queue) != 0 {
   735  		t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue), 0)
   736  	}
   737  	if pool.all.Count() != len(txs) {
   738  		t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs))
   739  	}
   740  	<-pool.requestReset(nil, nil)
   741  	if pending := pool.pending[accs[0]].Len() + pool.pending[accs[1]].Len(); pending != len(txs) {
   742  		t.Errorf("pending transaction mismatch: have %d, want %d", pending, len(txs))
   743  	}
   744  	if len(pool.queue) != 0 {
   745  		t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue), 0)
   746  	}
   747  	if pool.all.Count() != len(txs) {
   748  		t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs))
   749  	}
   750  	// Reduce the balance of the account, and check that transactions are reorganised
   751  	for _, addr := range accs {
   752  		testAddBalance(pool, addr, big.NewInt(-1))
   753  	}
   754  	<-pool.requestReset(nil, nil)
   755  
   756  	// The first account's first transaction remains valid, check that subsequent
   757  	// ones are either filtered out, or queued up for later.
   758  	if _, ok := pool.pending[accs[0]].txs.items[txs[0].Nonce()]; !ok {
   759  		t.Errorf("tx %d: valid and funded transaction missing from pending pool: %v", 0, txs[0])
   760  	}
   761  	if _, ok := pool.queue[accs[0]].txs.items[txs[0].Nonce()]; ok {
   762  		t.Errorf("tx %d: valid and funded transaction present in future queue: %v", 0, txs[0])
   763  	}
   764  	for i, tx := range txs[1:100] {
   765  		if i%2 == 1 {
   766  			if _, ok := pool.pending[accs[0]].txs.items[tx.Nonce()]; ok {
   767  				t.Errorf("tx %d: valid but future transaction present in pending pool: %v", i+1, tx)
   768  			}
   769  			if _, ok := pool.queue[accs[0]].txs.items[tx.Nonce()]; !ok {
   770  				t.Errorf("tx %d: valid but future transaction missing from future queue: %v", i+1, tx)
   771  			}
   772  		} else {
   773  			if _, ok := pool.pending[accs[0]].txs.items[tx.Nonce()]; ok {
   774  				t.Errorf("tx %d: out-of-fund transaction present in pending pool: %v", i+1, tx)
   775  			}
   776  			if _, ok := pool.queue[accs[0]].txs.items[tx.Nonce()]; ok {
   777  				t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", i+1, tx)
   778  			}
   779  		}
   780  	}
   781  	// The second account's first transaction got invalid, check that all transactions
   782  	// are either filtered out, or queued up for later.
   783  	if pool.pending[accs[1]] != nil {
   784  		t.Errorf("invalidated account still has pending transactions")
   785  	}
   786  	for i, tx := range txs[100:] {
   787  		if i%2 == 1 {
   788  			if _, ok := pool.queue[accs[1]].txs.items[tx.Nonce()]; !ok {
   789  				t.Errorf("tx %d: valid but future transaction missing from future queue: %v", 100+i, tx)
   790  			}
   791  		} else {
   792  			if _, ok := pool.queue[accs[1]].txs.items[tx.Nonce()]; ok {
   793  				t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", 100+i, tx)
   794  			}
   795  		}
   796  	}
   797  	if pool.all.Count() != len(txs)/2 {
   798  		t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)/2)
   799  	}
   800  }
   801  
   802  // Tests that if the transaction pool has both executable and non-executable
   803  // transactions from an origin account, filling the nonce gap moves all queued
   804  // ones into the pending pool.
   805  func TestTransactionGapFilling(t *testing.T) {
   806  	t.Parallel()
   807  
   808  	// Create a test account and fund it
   809  	pool, key := setupTxPool()
   810  	defer pool.Stop()
   811  
   812  	account := crypto.PubkeyToAddress(key.PublicKey)
   813  	testAddBalance(pool, account, big.NewInt(1000000))
   814  
   815  	// Keep track of transaction events to ensure all executables get announced
   816  	events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5)
   817  	sub := pool.txFeed.Subscribe(events)
   818  	defer sub.Unsubscribe()
   819  
   820  	// Create a pending and a queued transaction with a nonce-gap in between
   821  	pool.AddRemotesSync([]*types.Transaction{
   822  		transaction(0, 100000, key),
   823  		transaction(2, 100000, key),
   824  	})
   825  	pending, queued := pool.Stats()
   826  	if pending != 1 {
   827  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 1)
   828  	}
   829  	if queued != 1 {
   830  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
   831  	}
   832  	if err := validateEvents(events, 1); err != nil {
   833  		t.Fatalf("original event firing failed: %v", err)
   834  	}
   835  	if err := validateTxPoolInternals(pool); err != nil {
   836  		t.Fatalf("pool internal state corrupted: %v", err)
   837  	}
   838  	// Fill the nonce gap and ensure all transactions become pending
   839  	if err := pool.addRemoteSync(transaction(1, 100000, key)); err != nil {
   840  		t.Fatalf("failed to add gapped transaction: %v", err)
   841  	}
   842  	pending, queued = pool.Stats()
   843  	if pending != 3 {
   844  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
   845  	}
   846  	if queued != 0 {
   847  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
   848  	}
   849  	if err := validateEvents(events, 2); err != nil {
   850  		t.Fatalf("gap-filling event firing failed: %v", err)
   851  	}
   852  	if err := validateTxPoolInternals(pool); err != nil {
   853  		t.Fatalf("pool internal state corrupted: %v", err)
   854  	}
   855  }
   856  
   857  // Tests that if the transaction count belonging to a single account goes above
   858  // some threshold, the higher transactions are dropped to prevent DOS attacks.
   859  func TestTransactionQueueAccountLimiting(t *testing.T) {
   860  	t.Parallel()
   861  
   862  	// Create a test account and fund it
   863  	pool, key := setupTxPool()
   864  	defer pool.Stop()
   865  
   866  	account := crypto.PubkeyToAddress(key.PublicKey)
   867  	testAddBalance(pool, account, big.NewInt(1000000))
   868  
   869  	// Keep queuing up transactions and make sure all above a limit are dropped
   870  	for i := uint64(1); i <= testTxPoolConfig.AccountQueue+5; i++ {
   871  		if err := pool.addRemoteSync(transaction(i, 100000, key)); err != nil {
   872  			t.Fatalf("tx %d: failed to add transaction: %v", i, err)
   873  		}
   874  		if len(pool.pending) != 0 {
   875  			t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, len(pool.pending), 0)
   876  		}
   877  		if i <= testTxPoolConfig.AccountQueue {
   878  			if pool.queue[account].Len() != int(i) {
   879  				t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), i)
   880  			}
   881  		} else {
   882  			if pool.queue[account].Len() != int(testTxPoolConfig.AccountQueue) {
   883  				t.Errorf("tx %d: queue limit mismatch: have %d, want %d", i, pool.queue[account].Len(), testTxPoolConfig.AccountQueue)
   884  			}
   885  		}
   886  	}
   887  	if pool.all.Count() != int(testTxPoolConfig.AccountQueue) {
   888  		t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), testTxPoolConfig.AccountQueue)
   889  	}
   890  }
   891  
   892  // Tests that if the transaction count belonging to multiple accounts go above
   893  // some threshold, the higher transactions are dropped to prevent DOS attacks.
   894  //
   895  // This logic should not hold for local transactions, unless the local tracking
   896  // mechanism is disabled.
   897  func TestTransactionQueueGlobalLimiting(t *testing.T) {
   898  	testTransactionQueueGlobalLimiting(t, false)
   899  }
   900  func TestTransactionQueueGlobalLimitingNoLocals(t *testing.T) {
   901  	testTransactionQueueGlobalLimiting(t, true)
   902  }
   903  
   904  func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) {
   905  	t.Parallel()
   906  
   907  	// Create the pool to test the limit enforcement with
   908  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
   909  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
   910  
   911  	config := testTxPoolConfig
   912  	config.NoLocals = nolocals
   913  	config.GlobalQueue = config.AccountQueue*3 - 1 // reduce the queue limits to shorten test time (-1 to make it non divisible)
   914  
   915  	pool := NewTxPool(config, params.TestChainConfig, blockchain)
   916  	defer pool.Stop()
   917  
   918  	// Create a number of test accounts and fund them (last one will be the local)
   919  	keys := make([]*ecdsa.PrivateKey, 5)
   920  	for i := 0; i < len(keys); i++ {
   921  		keys[i], _ = crypto.GenerateKey()
   922  		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
   923  	}
   924  	local := keys[len(keys)-1]
   925  
   926  	// Generate and queue a batch of transactions
   927  	nonces := make(map[common.Address]uint64)
   928  
   929  	txs := make(types.Transactions, 0, 3*config.GlobalQueue)
   930  	for len(txs) < cap(txs) {
   931  		key := keys[rand.Intn(len(keys)-1)] // skip adding transactions with the local account
   932  		addr := crypto.PubkeyToAddress(key.PublicKey)
   933  
   934  		txs = append(txs, transaction(nonces[addr]+1, 100000, key))
   935  		nonces[addr]++
   936  	}
   937  	// Import the batch and verify that limits have been enforced
   938  	pool.AddRemotesSync(txs)
   939  
   940  	queued := 0
   941  	for addr, list := range pool.queue {
   942  		if list.Len() > int(config.AccountQueue) {
   943  			t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue)
   944  		}
   945  		queued += list.Len()
   946  	}
   947  	if queued > int(config.GlobalQueue) {
   948  		t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue)
   949  	}
   950  	// Generate a batch of transactions from the local account and import them
   951  	txs = txs[:0]
   952  	for i := uint64(0); i < 3*config.GlobalQueue; i++ {
   953  		txs = append(txs, transaction(i+1, 100000, local))
   954  	}
   955  	pool.AddLocals(txs)
   956  
   957  	// If locals are disabled, the previous eviction algorithm should apply here too
   958  	if nolocals {
   959  		queued := 0
   960  		for addr, list := range pool.queue {
   961  			if list.Len() > int(config.AccountQueue) {
   962  				t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue)
   963  			}
   964  			queued += list.Len()
   965  		}
   966  		if queued > int(config.GlobalQueue) {
   967  			t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue)
   968  		}
   969  	} else {
   970  		// Local exemptions are enabled, make sure the local account owned the queue
   971  		if len(pool.queue) != 1 {
   972  			t.Errorf("multiple accounts in queue: have %v, want %v", len(pool.queue), 1)
   973  		}
   974  		// Also ensure no local transactions are ever dropped, even if above global limits
   975  		if queued := pool.queue[crypto.PubkeyToAddress(local.PublicKey)].Len(); uint64(queued) != 3*config.GlobalQueue {
   976  			t.Fatalf("local account queued transaction count mismatch: have %v, want %v", queued, 3*config.GlobalQueue)
   977  		}
   978  	}
   979  }
   980  
   981  // Tests that if an account remains idle for a prolonged amount of time, any
   982  // non-executable transactions queued up are dropped to prevent wasting resources
   983  // on shuffling them around.
   984  //
   985  // This logic should not hold for local transactions, unless the local tracking
   986  // mechanism is disabled.
   987  func TestTransactionQueueTimeLimiting(t *testing.T) {
   988  	testTransactionQueueTimeLimiting(t, false)
   989  }
   990  func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) {
   991  	testTransactionQueueTimeLimiting(t, true)
   992  }
   993  
   994  func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
   995  	// Reduce the eviction interval to a testable amount
   996  	defer func(old time.Duration) { evictionInterval = old }(evictionInterval)
   997  	evictionInterval = time.Millisecond * 100
   998  
   999  	// Create the pool to test the non-expiration enforcement
  1000  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
  1001  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
  1002  
  1003  	config := testTxPoolConfig
  1004  	config.Lifetime = time.Second
  1005  	config.NoLocals = nolocals
  1006  
  1007  	pool := NewTxPool(config, params.TestChainConfig, blockchain)
  1008  	defer pool.Stop()
  1009  
  1010  	// Create two test accounts to ensure remotes expire but locals do not
  1011  	local, _ := crypto.GenerateKey()
  1012  	remote, _ := crypto.GenerateKey()
  1013  
  1014  	testAddBalance(pool, crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000))
  1015  	testAddBalance(pool, crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000))
  1016  
  1017  	// Add the two transactions and ensure they both are queued up
  1018  	if err := pool.AddLocal(pricedTransaction(1, 100000, big.NewInt(1), local)); err != nil {
  1019  		t.Fatalf("failed to add local transaction: %v", err)
  1020  	}
  1021  	if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(1), remote)); err != nil {
  1022  		t.Fatalf("failed to add remote transaction: %v", err)
  1023  	}
  1024  	pending, queued := pool.Stats()
  1025  	if pending != 0 {
  1026  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
  1027  	}
  1028  	if queued != 2 {
  1029  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
  1030  	}
  1031  	if err := validateTxPoolInternals(pool); err != nil {
  1032  		t.Fatalf("pool internal state corrupted: %v", err)
  1033  	}
  1034  
  1035  	// Allow the eviction interval to run
  1036  	time.Sleep(2 * evictionInterval)
  1037  
  1038  	// Transactions should not be evicted from the queue yet since lifetime duration has not passed
  1039  	pending, queued = pool.Stats()
  1040  	if pending != 0 {
  1041  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
  1042  	}
  1043  	if queued != 2 {
  1044  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
  1045  	}
  1046  	if err := validateTxPoolInternals(pool); err != nil {
  1047  		t.Fatalf("pool internal state corrupted: %v", err)
  1048  	}
  1049  
  1050  	// Wait a bit for eviction to run and clean up any leftovers, and ensure only the local remains
  1051  	time.Sleep(2 * config.Lifetime)
  1052  
  1053  	pending, queued = pool.Stats()
  1054  	if pending != 0 {
  1055  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
  1056  	}
  1057  	if nolocals {
  1058  		if queued != 0 {
  1059  			t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  1060  		}
  1061  	} else {
  1062  		if queued != 1 {
  1063  			t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
  1064  		}
  1065  	}
  1066  	if err := validateTxPoolInternals(pool); err != nil {
  1067  		t.Fatalf("pool internal state corrupted: %v", err)
  1068  	}
  1069  
  1070  	// remove current transactions and increase nonce to prepare for a reset and cleanup
  1071  	statedb.SetNonce(crypto.PubkeyToAddress(remote.PublicKey), 2)
  1072  	statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2)
  1073  	<-pool.requestReset(nil, nil)
  1074  
  1075  	// make sure queue, pending are cleared
  1076  	pending, queued = pool.Stats()
  1077  	if pending != 0 {
  1078  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
  1079  	}
  1080  	if queued != 0 {
  1081  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  1082  	}
  1083  	if err := validateTxPoolInternals(pool); err != nil {
  1084  		t.Fatalf("pool internal state corrupted: %v", err)
  1085  	}
  1086  
  1087  	// Queue gapped transactions
  1088  	if err := pool.AddLocal(pricedTransaction(4, 100000, big.NewInt(1), local)); err != nil {
  1089  		t.Fatalf("failed to add remote transaction: %v", err)
  1090  	}
  1091  	if err := pool.addRemoteSync(pricedTransaction(4, 100000, big.NewInt(1), remote)); err != nil {
  1092  		t.Fatalf("failed to add remote transaction: %v", err)
  1093  	}
  1094  	time.Sleep(5 * evictionInterval) // A half lifetime pass
  1095  
  1096  	// Queue executable transactions, the life cycle should be restarted.
  1097  	if err := pool.AddLocal(pricedTransaction(2, 100000, big.NewInt(1), local)); err != nil {
  1098  		t.Fatalf("failed to add remote transaction: %v", err)
  1099  	}
  1100  	if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), remote)); err != nil {
  1101  		t.Fatalf("failed to add remote transaction: %v", err)
  1102  	}
  1103  	time.Sleep(6 * evictionInterval)
  1104  
  1105  	// All gapped transactions shouldn't be kicked out
  1106  	pending, queued = pool.Stats()
  1107  	if pending != 2 {
  1108  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
  1109  	}
  1110  	if queued != 2 {
  1111  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3)
  1112  	}
  1113  	if err := validateTxPoolInternals(pool); err != nil {
  1114  		t.Fatalf("pool internal state corrupted: %v", err)
  1115  	}
  1116  
  1117  	// The whole life time pass after last promotion, kick out stale transactions
  1118  	time.Sleep(2 * config.Lifetime)
  1119  	pending, queued = pool.Stats()
  1120  	if pending != 2 {
  1121  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
  1122  	}
  1123  	if nolocals {
  1124  		if queued != 0 {
  1125  			t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  1126  		}
  1127  	} else {
  1128  		if queued != 1 {
  1129  			t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
  1130  		}
  1131  	}
  1132  	if err := validateTxPoolInternals(pool); err != nil {
  1133  		t.Fatalf("pool internal state corrupted: %v", err)
  1134  	}
  1135  }
  1136  
  1137  // Tests that even if the transaction count belonging to a single account goes
  1138  // above some threshold, as long as the transactions are executable, they are
  1139  // accepted.
  1140  func TestTransactionPendingLimiting(t *testing.T) {
  1141  	t.Parallel()
  1142  
  1143  	// Create a test account and fund it
  1144  	pool, key := setupTxPool()
  1145  	defer pool.Stop()
  1146  
  1147  	account := crypto.PubkeyToAddress(key.PublicKey)
  1148  	testAddBalance(pool, account, big.NewInt(1000000))
  1149  
  1150  	// Keep track of transaction events to ensure all executables get announced
  1151  	events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5)
  1152  	sub := pool.txFeed.Subscribe(events)
  1153  	defer sub.Unsubscribe()
  1154  
  1155  	// Keep queuing up transactions and make sure all above a limit are dropped
  1156  	for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ {
  1157  		if err := pool.addRemoteSync(transaction(i, 100000, key)); err != nil {
  1158  			t.Fatalf("tx %d: failed to add transaction: %v", i, err)
  1159  		}
  1160  		if pool.pending[account].Len() != int(i)+1 {
  1161  			t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, pool.pending[account].Len(), i+1)
  1162  		}
  1163  		if len(pool.queue) != 0 {
  1164  			t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), 0)
  1165  		}
  1166  	}
  1167  	if pool.all.Count() != int(testTxPoolConfig.AccountQueue+5) {
  1168  		t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), testTxPoolConfig.AccountQueue+5)
  1169  	}
  1170  	if err := validateEvents(events, int(testTxPoolConfig.AccountQueue+5)); err != nil {
  1171  		t.Fatalf("event firing failed: %v", err)
  1172  	}
  1173  	if err := validateTxPoolInternals(pool); err != nil {
  1174  		t.Fatalf("pool internal state corrupted: %v", err)
  1175  	}
  1176  }
  1177  
  1178  // Tests that if the transaction count belonging to multiple accounts go above
  1179  // some hard threshold, the higher transactions are dropped to prevent DOS
  1180  // attacks.
  1181  func TestTransactionPendingGlobalLimiting(t *testing.T) {
  1182  	t.Parallel()
  1183  
  1184  	// Create the pool to test the limit enforcement with
  1185  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
  1186  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
  1187  
  1188  	config := testTxPoolConfig
  1189  	config.GlobalSlots = config.AccountSlots * 10
  1190  
  1191  	pool := NewTxPool(config, params.TestChainConfig, blockchain)
  1192  	defer pool.Stop()
  1193  
  1194  	// Create a number of test accounts and fund them
  1195  	keys := make([]*ecdsa.PrivateKey, 5)
  1196  	for i := 0; i < len(keys); i++ {
  1197  		keys[i], _ = crypto.GenerateKey()
  1198  		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  1199  	}
  1200  	// Generate and queue a batch of transactions
  1201  	nonces := make(map[common.Address]uint64)
  1202  
  1203  	txs := types.Transactions{}
  1204  	for _, key := range keys {
  1205  		addr := crypto.PubkeyToAddress(key.PublicKey)
  1206  		for j := 0; j < int(config.GlobalSlots)/len(keys)*2; j++ {
  1207  			txs = append(txs, transaction(nonces[addr], 100000, key))
  1208  			nonces[addr]++
  1209  		}
  1210  	}
  1211  	// Import the batch and verify that limits have been enforced
  1212  	pool.AddRemotesSync(txs)
  1213  
  1214  	pending := 0
  1215  	for _, list := range pool.pending {
  1216  		pending += list.Len()
  1217  	}
  1218  	if pending > int(config.GlobalSlots) {
  1219  		t.Fatalf("total pending transactions overflow allowance: %d > %d", pending, config.GlobalSlots)
  1220  	}
  1221  	if err := validateTxPoolInternals(pool); err != nil {
  1222  		t.Fatalf("pool internal state corrupted: %v", err)
  1223  	}
  1224  }
  1225  
  1226  // Test the limit on transaction size is enforced correctly.
  1227  // This test verifies every transaction having allowed size
  1228  // is added to the pool, and longer transactions are rejected.
  1229  func TestTransactionAllowedTxSize(t *testing.T) {
  1230  	t.Parallel()
  1231  
  1232  	// Create a test account and fund it
  1233  	pool, key := setupTxPool()
  1234  	defer pool.Stop()
  1235  
  1236  	account := crypto.PubkeyToAddress(key.PublicKey)
  1237  	testAddBalance(pool, account, big.NewInt(1000000000))
  1238  
  1239  	// Compute maximal data size for transactions (lower bound).
  1240  	//
  1241  	// It is assumed the fields in the transaction (except of the data) are:
  1242  	//   - nonce     <= 32 bytes
  1243  	//   - gasPrice  <= 32 bytes
  1244  	//   - gasLimit  <= 32 bytes
  1245  	//   - recipient == 20 bytes
  1246  	//   - value     <= 32 bytes
  1247  	//   - signature == 65 bytes
  1248  	// All those fields are summed up to at most 213 bytes.
  1249  	baseSize := uint64(213)
  1250  	dataSize := txMaxSize - baseSize
  1251  
  1252  	// Try adding a transaction with maximal allowed size
  1253  	tx := pricedDataTransaction(0, pool.currentMaxGas, big.NewInt(1), key, dataSize)
  1254  	if err := pool.addRemoteSync(tx); err != nil {
  1255  		t.Fatalf("failed to add transaction of size %d, close to maximal: %v", int(tx.Size()), err)
  1256  	}
  1257  	// Try adding a transaction with random allowed size
  1258  	if err := pool.addRemoteSync(pricedDataTransaction(1, pool.currentMaxGas, big.NewInt(1), key, uint64(rand.Intn(int(dataSize))))); err != nil {
  1259  		t.Fatalf("failed to add transaction of random allowed size: %v", err)
  1260  	}
  1261  	// Try adding a transaction of minimal not allowed size
  1262  	if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentMaxGas, big.NewInt(1), key, txMaxSize)); err == nil {
  1263  		t.Fatalf("expected rejection on slightly oversize transaction")
  1264  	}
  1265  	// Try adding a transaction of random not allowed size
  1266  	if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentMaxGas, big.NewInt(1), key, dataSize+1+uint64(rand.Intn(10*txMaxSize)))); err == nil {
  1267  		t.Fatalf("expected rejection on oversize transaction")
  1268  	}
  1269  	// Run some sanity checks on the pool internals
  1270  	pending, queued := pool.Stats()
  1271  	if pending != 2 {
  1272  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
  1273  	}
  1274  	if queued != 0 {
  1275  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  1276  	}
  1277  	if err := validateTxPoolInternals(pool); err != nil {
  1278  		t.Fatalf("pool internal state corrupted: %v", err)
  1279  	}
  1280  }
  1281  
  1282  // Tests that if transactions start being capped, transactions are also removed from 'all'
  1283  func TestTransactionCapClearsFromAll(t *testing.T) {
  1284  	t.Parallel()
  1285  
  1286  	// Create the pool to test the limit enforcement with
  1287  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
  1288  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
  1289  
  1290  	config := testTxPoolConfig
  1291  	config.AccountSlots = 2
  1292  	config.AccountQueue = 2
  1293  	config.GlobalSlots = 8
  1294  
  1295  	pool := NewTxPool(config, params.TestChainConfig, blockchain)
  1296  	defer pool.Stop()
  1297  
  1298  	// Create a number of test accounts and fund them
  1299  	key, _ := crypto.GenerateKey()
  1300  	addr := crypto.PubkeyToAddress(key.PublicKey)
  1301  	testAddBalance(pool, addr, big.NewInt(1000000))
  1302  
  1303  	txs := types.Transactions{}
  1304  	for j := 0; j < int(config.GlobalSlots)*2; j++ {
  1305  		txs = append(txs, transaction(uint64(j), 100000, key))
  1306  	}
  1307  	// Import the batch and verify that limits have been enforced
  1308  	pool.AddRemotes(txs)
  1309  	if err := validateTxPoolInternals(pool); err != nil {
  1310  		t.Fatalf("pool internal state corrupted: %v", err)
  1311  	}
  1312  }
  1313  
  1314  // Tests that if the transaction count belonging to multiple accounts go above
  1315  // some hard threshold, if they are under the minimum guaranteed slot count then
  1316  // the transactions are still kept.
  1317  func TestTransactionPendingMinimumAllowance(t *testing.T) {
  1318  	t.Parallel()
  1319  
  1320  	// Create the pool to test the limit enforcement with
  1321  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
  1322  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
  1323  
  1324  	config := testTxPoolConfig
  1325  	config.GlobalSlots = 1
  1326  
  1327  	pool := NewTxPool(config, params.TestChainConfig, blockchain)
  1328  	defer pool.Stop()
  1329  
  1330  	// Create a number of test accounts and fund them
  1331  	keys := make([]*ecdsa.PrivateKey, 5)
  1332  	for i := 0; i < len(keys); i++ {
  1333  		keys[i], _ = crypto.GenerateKey()
  1334  		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  1335  	}
  1336  	// Generate and queue a batch of transactions
  1337  	nonces := make(map[common.Address]uint64)
  1338  
  1339  	txs := types.Transactions{}
  1340  	for _, key := range keys {
  1341  		addr := crypto.PubkeyToAddress(key.PublicKey)
  1342  		for j := 0; j < int(config.AccountSlots)*2; j++ {
  1343  			txs = append(txs, transaction(nonces[addr], 100000, key))
  1344  			nonces[addr]++
  1345  		}
  1346  	}
  1347  	// Import the batch and verify that limits have been enforced
  1348  	pool.AddRemotesSync(txs)
  1349  
  1350  	for addr, list := range pool.pending {
  1351  		if list.Len() != int(config.AccountSlots) {
  1352  			t.Errorf("addr %x: total pending transactions mismatch: have %d, want %d", addr, list.Len(), config.AccountSlots)
  1353  		}
  1354  	}
  1355  	if err := validateTxPoolInternals(pool); err != nil {
  1356  		t.Fatalf("pool internal state corrupted: %v", err)
  1357  	}
  1358  }
  1359  
  1360  // Tests that setting the transaction pool gas price to a higher value correctly
  1361  // discards everything cheaper than that and moves any gapped transactions back
  1362  // from the pending pool to the queue.
  1363  //
  1364  // Note, local transactions are never allowed to be dropped.
  1365  func TestTransactionPoolRepricing(t *testing.T) {
  1366  	t.Parallel()
  1367  
  1368  	// Create the pool to test the pricing enforcement with
  1369  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
  1370  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
  1371  
  1372  	pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
  1373  	defer pool.Stop()
  1374  
  1375  	// Keep track of transaction events to ensure all executables get announced
  1376  	events := make(chan NewTxsEvent, 32)
  1377  	sub := pool.txFeed.Subscribe(events)
  1378  	defer sub.Unsubscribe()
  1379  
  1380  	// Create a number of test accounts and fund them
  1381  	keys := make([]*ecdsa.PrivateKey, 4)
  1382  	for i := 0; i < len(keys); i++ {
  1383  		keys[i], _ = crypto.GenerateKey()
  1384  		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  1385  	}
  1386  	// Generate and queue a batch of transactions, both pending and queued
  1387  	txs := types.Transactions{}
  1388  
  1389  	txs = append(txs, pricedTransaction(0, 100000, big.NewInt(2), keys[0]))
  1390  	txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[0]))
  1391  	txs = append(txs, pricedTransaction(2, 100000, big.NewInt(2), keys[0]))
  1392  
  1393  	txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[1]))
  1394  	txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[1]))
  1395  	txs = append(txs, pricedTransaction(2, 100000, big.NewInt(2), keys[1]))
  1396  
  1397  	txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[2]))
  1398  	txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[2]))
  1399  	txs = append(txs, pricedTransaction(3, 100000, big.NewInt(2), keys[2]))
  1400  
  1401  	ltx := pricedTransaction(0, 100000, big.NewInt(1), keys[3])
  1402  
  1403  	// Import the batch and that both pending and queued transactions match up
  1404  	pool.AddRemotesSync(txs)
  1405  	pool.AddLocal(ltx)
  1406  
  1407  	pending, queued := pool.Stats()
  1408  	if pending != 7 {
  1409  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 7)
  1410  	}
  1411  	if queued != 3 {
  1412  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3)
  1413  	}
  1414  	if err := validateEvents(events, 7); err != nil {
  1415  		t.Fatalf("original event firing failed: %v", err)
  1416  	}
  1417  	if err := validateTxPoolInternals(pool); err != nil {
  1418  		t.Fatalf("pool internal state corrupted: %v", err)
  1419  	}
  1420  	// Reprice the pool and check that underpriced transactions get dropped
  1421  	pool.SetGasPrice(big.NewInt(2))
  1422  
  1423  	pending, queued = pool.Stats()
  1424  	if pending != 2 {
  1425  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
  1426  	}
  1427  	if queued != 5 {
  1428  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 5)
  1429  	}
  1430  	if err := validateEvents(events, 0); err != nil {
  1431  		t.Fatalf("reprice event firing failed: %v", err)
  1432  	}
  1433  	if err := validateTxPoolInternals(pool); err != nil {
  1434  		t.Fatalf("pool internal state corrupted: %v", err)
  1435  	}
  1436  	// Check that we can't add the old transactions back
  1437  	if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(1), keys[0])); !strings.Contains(err.Error(), ErrUnderpriced.Error()) {
  1438  		t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want error to conain %v", err, ErrUnderpriced)
  1439  	}
  1440  	if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); !strings.Contains(err.Error(), ErrUnderpriced.Error()) {
  1441  		t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want error to conain %v", err, ErrUnderpriced)
  1442  	}
  1443  	if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(1), keys[2])); !strings.Contains(err.Error(), ErrUnderpriced.Error()) {
  1444  		t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want error to conain %v", err, ErrUnderpriced)
  1445  	}
  1446  	if err := validateEvents(events, 0); err != nil {
  1447  		t.Fatalf("post-reprice event firing failed: %v", err)
  1448  	}
  1449  	if err := validateTxPoolInternals(pool); err != nil {
  1450  		t.Fatalf("pool internal state corrupted: %v", err)
  1451  	}
  1452  	// However we can add local underpriced transactions
  1453  	tx := pricedTransaction(1, 100000, big.NewInt(1), keys[3])
  1454  	if err := pool.AddLocal(tx); err != nil {
  1455  		t.Fatalf("failed to add underpriced local transaction: %v", err)
  1456  	}
  1457  	if pending, _ = pool.Stats(); pending != 3 {
  1458  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
  1459  	}
  1460  	if err := validateEvents(events, 1); err != nil {
  1461  		t.Fatalf("post-reprice local event firing failed: %v", err)
  1462  	}
  1463  	if err := validateTxPoolInternals(pool); err != nil {
  1464  		t.Fatalf("pool internal state corrupted: %v", err)
  1465  	}
  1466  	// And we can fill gaps with properly priced transactions
  1467  	if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(2), keys[0])); err != nil {
  1468  		t.Fatalf("failed to add pending transaction: %v", err)
  1469  	}
  1470  	if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(2), keys[1])); err != nil {
  1471  		t.Fatalf("failed to add pending transaction: %v", err)
  1472  	}
  1473  	if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(2), keys[2])); err != nil {
  1474  		t.Fatalf("failed to add queued transaction: %v", err)
  1475  	}
  1476  	if err := validateEvents(events, 5); err != nil {
  1477  		t.Fatalf("post-reprice event firing failed: %v", err)
  1478  	}
  1479  	if err := validateTxPoolInternals(pool); err != nil {
  1480  		t.Fatalf("pool internal state corrupted: %v", err)
  1481  	}
  1482  }
  1483  
  1484  // Tests that setting the transaction pool gas price to a higher value correctly
  1485  // discards everything cheaper (legacy & dynamic fee) than that and moves any
  1486  // gapped transactions back from the pending pool to the queue.
  1487  //
  1488  // Note, local transactions are never allowed to be dropped.
  1489  func TestTransactionPoolRepricingDynamicFee(t *testing.T) {
  1490  	t.Parallel()
  1491  
  1492  	// Create the pool to test the pricing enforcement with
  1493  	pool, _ := setupTxPoolWithConfig(eip1559Config)
  1494  	defer pool.Stop()
  1495  
  1496  	// Keep track of transaction events to ensure all executables get announced
  1497  	events := make(chan NewTxsEvent, 32)
  1498  	sub := pool.txFeed.Subscribe(events)
  1499  	defer sub.Unsubscribe()
  1500  
  1501  	// Create a number of test accounts and fund them
  1502  	keys := make([]*ecdsa.PrivateKey, 4)
  1503  	for i := 0; i < len(keys); i++ {
  1504  		keys[i], _ = crypto.GenerateKey()
  1505  		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  1506  	}
  1507  	// Generate and queue a batch of transactions, both pending and queued
  1508  	txs := types.Transactions{}
  1509  
  1510  	txs = append(txs, pricedTransaction(0, 100000, big.NewInt(2), keys[0]))
  1511  	txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[0]))
  1512  	txs = append(txs, pricedTransaction(2, 100000, big.NewInt(2), keys[0]))
  1513  
  1514  	txs = append(txs, dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[1]))
  1515  	txs = append(txs, dynamicFeeTx(1, 100000, big.NewInt(3), big.NewInt(2), keys[1]))
  1516  	txs = append(txs, dynamicFeeTx(2, 100000, big.NewInt(3), big.NewInt(2), keys[1]))
  1517  
  1518  	txs = append(txs, dynamicFeeTx(1, 100000, big.NewInt(2), big.NewInt(2), keys[2]))
  1519  	txs = append(txs, dynamicFeeTx(2, 100000, big.NewInt(1), big.NewInt(1), keys[2]))
  1520  	txs = append(txs, dynamicFeeTx(3, 100000, big.NewInt(2), big.NewInt(2), keys[2]))
  1521  
  1522  	ltx := dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[3])
  1523  
  1524  	// Import the batch and that both pending and queued transactions match up
  1525  	pool.AddRemotesSync(txs)
  1526  	pool.AddLocal(ltx)
  1527  
  1528  	pending, queued := pool.Stats()
  1529  	if pending != 7 {
  1530  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 7)
  1531  	}
  1532  	if queued != 3 {
  1533  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3)
  1534  	}
  1535  	if err := validateEvents(events, 7); err != nil {
  1536  		t.Fatalf("original event firing failed: %v", err)
  1537  	}
  1538  	if err := validateTxPoolInternals(pool); err != nil {
  1539  		t.Fatalf("pool internal state corrupted: %v", err)
  1540  	}
  1541  	// Reprice the pool and check that underpriced transactions get dropped
  1542  	pool.SetGasPrice(big.NewInt(2))
  1543  
  1544  	pending, queued = pool.Stats()
  1545  	if pending != 2 {
  1546  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
  1547  	}
  1548  	if queued != 5 {
  1549  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 5)
  1550  	}
  1551  	if err := validateEvents(events, 0); err != nil {
  1552  		t.Fatalf("reprice event firing failed: %v", err)
  1553  	}
  1554  	if err := validateTxPoolInternals(pool); err != nil {
  1555  		t.Fatalf("pool internal state corrupted: %v", err)
  1556  	}
  1557  	// Check that we can't add the old transactions back
  1558  	tx := pricedTransaction(1, 100000, big.NewInt(1), keys[0])
  1559  	if err := pool.AddRemote(tx); !strings.Contains(err.Error(), ErrUnderpriced.Error()) {
  1560  		t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
  1561  	}
  1562  	tx = dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[1])
  1563  	if err := pool.AddRemote(tx); !strings.Contains(err.Error(), ErrUnderpriced.Error()) {
  1564  		t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
  1565  	}
  1566  	tx = dynamicFeeTx(2, 100000, big.NewInt(1), big.NewInt(1), keys[2])
  1567  	if err := pool.AddRemote(tx); !strings.Contains(err.Error(), ErrUnderpriced.Error()) {
  1568  		t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
  1569  	}
  1570  	if err := validateEvents(events, 0); err != nil {
  1571  		t.Fatalf("post-reprice event firing failed: %v", err)
  1572  	}
  1573  	if err := validateTxPoolInternals(pool); err != nil {
  1574  		t.Fatalf("pool internal state corrupted: %v", err)
  1575  	}
  1576  	// However we can add local underpriced transactions
  1577  	tx = dynamicFeeTx(1, 100000, big.NewInt(1), big.NewInt(1), keys[3])
  1578  	if err := pool.AddLocal(tx); err != nil {
  1579  		t.Fatalf("failed to add underpriced local transaction: %v", err)
  1580  	}
  1581  	if pending, _ = pool.Stats(); pending != 3 {
  1582  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
  1583  	}
  1584  	if err := validateEvents(events, 1); err != nil {
  1585  		t.Fatalf("post-reprice local event firing failed: %v", err)
  1586  	}
  1587  	if err := validateTxPoolInternals(pool); err != nil {
  1588  		t.Fatalf("pool internal state corrupted: %v", err)
  1589  	}
  1590  	// And we can fill gaps with properly priced transactions
  1591  	tx = pricedTransaction(1, 100000, big.NewInt(2), keys[0])
  1592  	if err := pool.AddRemote(tx); err != nil {
  1593  		t.Fatalf("failed to add pending transaction: %v", err)
  1594  	}
  1595  	tx = dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), keys[1])
  1596  	if err := pool.AddRemote(tx); err != nil {
  1597  		t.Fatalf("failed to add pending transaction: %v", err)
  1598  	}
  1599  	tx = dynamicFeeTx(2, 100000, big.NewInt(2), big.NewInt(2), keys[2])
  1600  	if err := pool.AddRemote(tx); err != nil {
  1601  		t.Fatalf("failed to add queued transaction: %v", err)
  1602  	}
  1603  	if err := validateEvents(events, 5); err != nil {
  1604  		t.Fatalf("post-reprice event firing failed: %v", err)
  1605  	}
  1606  	if err := validateTxPoolInternals(pool); err != nil {
  1607  		t.Fatalf("pool internal state corrupted: %v", err)
  1608  	}
  1609  }
  1610  
  1611  // Tests that setting the transaction pool gas price to a higher value does not
  1612  // remove local transactions (legacy & dynamic fee).
  1613  func TestTransactionPoolRepricingKeepsLocals(t *testing.T) {
  1614  	t.Parallel()
  1615  
  1616  	// Create the pool to test the pricing enforcement with
  1617  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
  1618  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
  1619  
  1620  	pool := NewTxPool(testTxPoolConfig, eip1559Config, blockchain)
  1621  	defer pool.Stop()
  1622  
  1623  	// Create a number of test accounts and fund them
  1624  	keys := make([]*ecdsa.PrivateKey, 3)
  1625  	for i := 0; i < len(keys); i++ {
  1626  		keys[i], _ = crypto.GenerateKey()
  1627  		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000*1000000))
  1628  	}
  1629  	// Create transaction (both pending and queued) with a linearly growing gasprice
  1630  	for i := uint64(0); i < 500; i++ {
  1631  		// Add pending transaction.
  1632  		pendingTx := pricedTransaction(i, 100000, big.NewInt(int64(i)), keys[2])
  1633  		if err := pool.AddLocal(pendingTx); err != nil {
  1634  			t.Fatal(err)
  1635  		}
  1636  		// Add queued transaction.
  1637  		queuedTx := pricedTransaction(i+501, 100000, big.NewInt(int64(i)), keys[2])
  1638  		if err := pool.AddLocal(queuedTx); err != nil {
  1639  			t.Fatal(err)
  1640  		}
  1641  
  1642  		// Add pending dynamic fee transaction.
  1643  		pendingTx = dynamicFeeTx(i, 100000, big.NewInt(int64(i)+1), big.NewInt(int64(i)), keys[1])
  1644  		if err := pool.AddLocal(pendingTx); err != nil {
  1645  			t.Fatal(err)
  1646  		}
  1647  		// Add queued dynamic fee transaction.
  1648  		queuedTx = dynamicFeeTx(i+501, 100000, big.NewInt(int64(i)+1), big.NewInt(int64(i)), keys[1])
  1649  		if err := pool.AddLocal(queuedTx); err != nil {
  1650  			t.Fatal(err)
  1651  		}
  1652  	}
  1653  	pending, queued := pool.Stats()
  1654  	expPending, expQueued := 1000, 1000
  1655  	validate := func() {
  1656  		pending, queued = pool.Stats()
  1657  		if pending != expPending {
  1658  			t.Fatalf("pending transactions mismatched: have %d, want %d", pending, expPending)
  1659  		}
  1660  		if queued != expQueued {
  1661  			t.Fatalf("queued transactions mismatched: have %d, want %d", queued, expQueued)
  1662  		}
  1663  
  1664  		if err := validateTxPoolInternals(pool); err != nil {
  1665  			t.Fatalf("pool internal state corrupted: %v", err)
  1666  		}
  1667  	}
  1668  	validate()
  1669  
  1670  	// Reprice the pool and check that nothing is dropped
  1671  	pool.SetGasPrice(big.NewInt(2))
  1672  	validate()
  1673  
  1674  	pool.SetGasPrice(big.NewInt(2))
  1675  	pool.SetGasPrice(big.NewInt(4))
  1676  	pool.SetGasPrice(big.NewInt(8))
  1677  	pool.SetGasPrice(big.NewInt(100))
  1678  	validate()
  1679  }
  1680  
  1681  // Tests that when the pool reaches its global transaction limit, underpriced
  1682  // transactions are gradually shifted out for more expensive ones and any gapped
  1683  // pending transactions are moved into the queue.
  1684  //
  1685  // Note, local transactions are never allowed to be dropped.
  1686  func TestTransactionPoolUnderpricing(t *testing.T) {
  1687  	t.Parallel()
  1688  
  1689  	// Create the pool to test the pricing enforcement with
  1690  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
  1691  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
  1692  
  1693  	config := testTxPoolConfig
  1694  	config.GlobalSlots = 2
  1695  	config.GlobalQueue = 2
  1696  
  1697  	pool := NewTxPool(config, params.TestChainConfig, blockchain)
  1698  	defer pool.Stop()
  1699  
  1700  	// Keep track of transaction events to ensure all executables get announced
  1701  	events := make(chan NewTxsEvent, 32)
  1702  	sub := pool.txFeed.Subscribe(events)
  1703  	defer sub.Unsubscribe()
  1704  
  1705  	// Create a number of test accounts and fund them
  1706  	keys := make([]*ecdsa.PrivateKey, 4)
  1707  	for i := 0; i < len(keys); i++ {
  1708  		keys[i], _ = crypto.GenerateKey()
  1709  		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  1710  	}
  1711  	// Generate and queue a batch of transactions, both pending and queued
  1712  	txs := types.Transactions{}
  1713  
  1714  	txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[0]))
  1715  	txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[0]))
  1716  
  1717  	txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[1]))
  1718  
  1719  	ltx := pricedTransaction(0, 100000, big.NewInt(1), keys[2])
  1720  
  1721  	// Import the batch and that both pending and queued transactions match up
  1722  	pool.AddRemotesSync(txs)
  1723  	pool.AddLocal(ltx)
  1724  
  1725  	pending, queued := pool.Stats()
  1726  	if pending != 3 {
  1727  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
  1728  	}
  1729  	if queued != 1 {
  1730  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
  1731  	}
  1732  	if err := validateEvents(events, 3); err != nil {
  1733  		t.Fatalf("original event firing failed: %v", err)
  1734  	}
  1735  	if err := validateTxPoolInternals(pool); err != nil {
  1736  		t.Fatalf("pool internal state corrupted: %v", err)
  1737  	}
  1738  	// Ensure that adding an underpriced transaction on block limit fails
  1739  	if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); err != ErrUnderpriced {
  1740  		t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
  1741  	}
  1742  	// Ensure that adding high priced transactions drops cheap ones, but not own
  1743  	if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); err != nil { // +K1:0 => -K1:1 => Pend K0:0, K0:1, K1:0, K2:0; Que -
  1744  		t.Fatalf("failed to add well priced transaction: %v", err)
  1745  	}
  1746  	if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(4), keys[1])); err != nil { // +K1:2 => -K0:0 => Pend K1:0, K2:0; Que K0:1 K1:2
  1747  		t.Fatalf("failed to add well priced transaction: %v", err)
  1748  	}
  1749  	if err := pool.addRemoteSync(pricedTransaction(3, 100000, big.NewInt(5), keys[1])); err != nil { // +K1:3 => -K0:1 => Pend K1:0, K2:0; Que K1:2 K1:3
  1750  		t.Fatalf("failed to add well priced transaction: %v", err)
  1751  	}
  1752  	pending, queued = pool.Stats()
  1753  	if pending != 2 {
  1754  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
  1755  	}
  1756  	if queued != 2 {
  1757  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
  1758  	}
  1759  	if err := validateEvents(events, 1); err != nil {
  1760  		t.Fatalf("additional event firing failed: %v", err)
  1761  	}
  1762  	if err := validateTxPoolInternals(pool); err != nil {
  1763  		t.Fatalf("pool internal state corrupted: %v", err)
  1764  	}
  1765  	// Ensure that adding local transactions can push out even higher priced ones
  1766  	ltx = pricedTransaction(1, 100000, big.NewInt(0), keys[2])
  1767  	if err := pool.AddLocal(ltx); err != nil {
  1768  		t.Fatalf("failed to append underpriced local transaction: %v", err)
  1769  	}
  1770  	ltx = pricedTransaction(0, 100000, big.NewInt(0), keys[3])
  1771  	if err := pool.AddLocal(ltx); err != nil {
  1772  		t.Fatalf("failed to add new underpriced local transaction: %v", err)
  1773  	}
  1774  	pending, queued = pool.Stats()
  1775  	if pending != 3 {
  1776  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
  1777  	}
  1778  	if queued != 1 {
  1779  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
  1780  	}
  1781  	if err := validateEvents(events, 2); err != nil {
  1782  		t.Fatalf("local event firing failed: %v", err)
  1783  	}
  1784  	if err := validateTxPoolInternals(pool); err != nil {
  1785  		t.Fatalf("pool internal state corrupted: %v", err)
  1786  	}
  1787  }
  1788  
  1789  // Tests that more expensive transactions push out cheap ones from the pool, but
  1790  // without producing instability by creating gaps that start jumping transactions
  1791  // back and forth between queued/pending.
  1792  func TestTransactionPoolStableUnderpricing(t *testing.T) {
  1793  	t.Parallel()
  1794  
  1795  	// Create the pool to test the pricing enforcement with
  1796  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
  1797  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
  1798  
  1799  	config := testTxPoolConfig
  1800  	config.GlobalSlots = 128
  1801  	config.GlobalQueue = 0
  1802  
  1803  	pool := NewTxPool(config, params.TestChainConfig, blockchain)
  1804  	defer pool.Stop()
  1805  
  1806  	// Keep track of transaction events to ensure all executables get announced
  1807  	events := make(chan NewTxsEvent, 32)
  1808  	sub := pool.txFeed.Subscribe(events)
  1809  	defer sub.Unsubscribe()
  1810  
  1811  	// Create a number of test accounts and fund them
  1812  	keys := make([]*ecdsa.PrivateKey, 2)
  1813  	for i := 0; i < len(keys); i++ {
  1814  		keys[i], _ = crypto.GenerateKey()
  1815  		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  1816  	}
  1817  	// Fill up the entire queue with the same transaction price points
  1818  	txs := types.Transactions{}
  1819  	for i := uint64(0); i < config.GlobalSlots; i++ {
  1820  		txs = append(txs, pricedTransaction(i, 100000, big.NewInt(1), keys[0]))
  1821  	}
  1822  	pool.AddRemotesSync(txs)
  1823  
  1824  	pending, queued := pool.Stats()
  1825  	if pending != int(config.GlobalSlots) {
  1826  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, config.GlobalSlots)
  1827  	}
  1828  	if queued != 0 {
  1829  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  1830  	}
  1831  	if err := validateEvents(events, int(config.GlobalSlots)); err != nil {
  1832  		t.Fatalf("original event firing failed: %v", err)
  1833  	}
  1834  	if err := validateTxPoolInternals(pool); err != nil {
  1835  		t.Fatalf("pool internal state corrupted: %v", err)
  1836  	}
  1837  	// Ensure that adding high priced transactions drops a cheap, but doesn't produce a gap
  1838  	if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); err != nil {
  1839  		t.Fatalf("failed to add well priced transaction: %v", err)
  1840  	}
  1841  	pending, queued = pool.Stats()
  1842  	if pending != int(config.GlobalSlots) {
  1843  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, config.GlobalSlots)
  1844  	}
  1845  	if queued != 0 {
  1846  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  1847  	}
  1848  	if err := validateEvents(events, 1); err != nil {
  1849  		t.Fatalf("additional event firing failed: %v", err)
  1850  	}
  1851  	if err := validateTxPoolInternals(pool); err != nil {
  1852  		t.Fatalf("pool internal state corrupted: %v", err)
  1853  	}
  1854  }
  1855  
  1856  // Tests that when the pool reaches its global transaction limit, underpriced
  1857  // transactions (legacy & dynamic fee) are gradually shifted out for more
  1858  // expensive ones and any gapped pending transactions are moved into the queue.
  1859  //
  1860  // Note, local transactions are never allowed to be dropped.
  1861  func TestTransactionPoolUnderpricingDynamicFee(t *testing.T) {
  1862  	t.Parallel()
  1863  
  1864  	pool, _ := setupTxPoolWithConfig(eip1559Config)
  1865  	defer pool.Stop()
  1866  
  1867  	pool.config.GlobalSlots = 2
  1868  	pool.config.GlobalQueue = 2
  1869  
  1870  	// Keep track of transaction events to ensure all executables get announced
  1871  	events := make(chan NewTxsEvent, 32)
  1872  	sub := pool.txFeed.Subscribe(events)
  1873  	defer sub.Unsubscribe()
  1874  
  1875  	// Create a number of test accounts and fund them
  1876  	keys := make([]*ecdsa.PrivateKey, 4)
  1877  	for i := 0; i < len(keys); i++ {
  1878  		keys[i], _ = crypto.GenerateKey()
  1879  		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  1880  	}
  1881  
  1882  	// Generate and queue a batch of transactions, both pending and queued
  1883  	txs := types.Transactions{}
  1884  
  1885  	txs = append(txs, dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), keys[0]))
  1886  	txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[0]))
  1887  	txs = append(txs, dynamicFeeTx(1, 100000, big.NewInt(2), big.NewInt(1), keys[1]))
  1888  
  1889  	ltx := dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[2])
  1890  
  1891  	// Import the batch and that both pending and queued transactions match up
  1892  	pool.AddRemotesSync(txs) // Pend K0:0, K0:1; Que K1:1
  1893  	pool.AddLocal(ltx)       // +K2:0 => Pend K0:0, K0:1, K2:0; Que K1:1
  1894  
  1895  	pending, queued := pool.Stats()
  1896  	if pending != 3 {
  1897  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
  1898  	}
  1899  	if queued != 1 {
  1900  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
  1901  	}
  1902  	if err := validateEvents(events, 3); err != nil {
  1903  		t.Fatalf("original event firing failed: %v", err)
  1904  	}
  1905  	if err := validateTxPoolInternals(pool); err != nil {
  1906  		t.Fatalf("pool internal state corrupted: %v", err)
  1907  	}
  1908  
  1909  	// Ensure that adding an underpriced transaction fails
  1910  	tx := dynamicFeeTx(0, 100000, big.NewInt(2), big.NewInt(1), keys[1])
  1911  	if err := pool.addRemoteSync(tx); err != ErrUnderpriced { // Pend K0:0, K0:1, K2:0; Que K1:1
  1912  		t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
  1913  	}
  1914  
  1915  	// Ensure that adding high priced transactions drops cheap ones, but not own
  1916  	tx = pricedTransaction(0, 100000, big.NewInt(2), keys[1])
  1917  	if err := pool.addRemoteSync(tx); err != nil { // +K1:0, -K1:1 => Pend K0:0, K0:1, K1:0, K2:0; Que -
  1918  		t.Fatalf("failed to add well priced transaction: %v", err)
  1919  	}
  1920  
  1921  	tx = pricedTransaction(2, 100000, big.NewInt(3), keys[1])
  1922  	if err := pool.addRemoteSync(tx); err != nil { // +K1:2, -K0:1 => Pend K0:0 K1:0, K2:0; Que K1:2
  1923  		t.Fatalf("failed to add well priced transaction: %v", err)
  1924  	}
  1925  	tx = dynamicFeeTx(3, 100000, big.NewInt(4), big.NewInt(1), keys[1])
  1926  	if err := pool.addRemoteSync(tx); err != nil { // +K1:3, -K1:0 => Pend K0:0 K2:0; Que K1:2 K1:3
  1927  		t.Fatalf("failed to add well priced transaction: %v", err)
  1928  	}
  1929  	pending, queued = pool.Stats()
  1930  	if pending != 2 {
  1931  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
  1932  	}
  1933  	if queued != 2 {
  1934  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
  1935  	}
  1936  	if err := validateEvents(events, 1); err != nil {
  1937  		t.Fatalf("additional event firing failed: %v", err)
  1938  	}
  1939  	if err := validateTxPoolInternals(pool); err != nil {
  1940  		t.Fatalf("pool internal state corrupted: %v", err)
  1941  	}
  1942  	// Ensure that adding local transactions can push out even higher priced ones
  1943  	ltx = dynamicFeeTx(1, 100000, big.NewInt(0), big.NewInt(0), keys[2])
  1944  	if err := pool.AddLocal(ltx); err != nil {
  1945  		t.Fatalf("failed to append underpriced local transaction: %v", err)
  1946  	}
  1947  	ltx = dynamicFeeTx(0, 100000, big.NewInt(0), big.NewInt(0), keys[3])
  1948  	if err := pool.AddLocal(ltx); err != nil {
  1949  		t.Fatalf("failed to add new underpriced local transaction: %v", err)
  1950  	}
  1951  	pending, queued = pool.Stats()
  1952  	if pending != 3 {
  1953  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
  1954  	}
  1955  	if queued != 1 {
  1956  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
  1957  	}
  1958  	if err := validateEvents(events, 2); err != nil {
  1959  		t.Fatalf("local event firing failed: %v", err)
  1960  	}
  1961  	if err := validateTxPoolInternals(pool); err != nil {
  1962  		t.Fatalf("pool internal state corrupted: %v", err)
  1963  	}
  1964  }
  1965  
  1966  // Tests whether highest fee cap transaction is retained after a batch of high effective
  1967  // tip transactions are added and vice versa
  1968  func TestDualHeapEviction(t *testing.T) {
  1969  	t.Parallel()
  1970  
  1971  	pool, _ := setupTxPoolWithConfig(eip1559Config)
  1972  	defer pool.Stop()
  1973  
  1974  	pool.config.GlobalSlots = 10
  1975  	pool.config.GlobalQueue = 10
  1976  
  1977  	var (
  1978  		highTip, highCap *types.Transaction
  1979  		baseFee          int
  1980  	)
  1981  
  1982  	check := func(tx *types.Transaction, name string) {
  1983  		if pool.all.GetRemote(tx.Hash()) == nil {
  1984  			t.Fatalf("highest %s transaction evicted from the pool", name)
  1985  		}
  1986  	}
  1987  
  1988  	add := func(urgent bool) {
  1989  		for i := 0; i < 20; i++ {
  1990  			var tx *types.Transaction
  1991  			// Create a test accounts and fund it
  1992  			key, _ := crypto.GenerateKey()
  1993  			testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000000))
  1994  			if urgent {
  1995  				tx = dynamicFeeTx(0, 100000, big.NewInt(int64(baseFee+1+i)), big.NewInt(int64(1+i)), key)
  1996  				highTip = tx
  1997  			} else {
  1998  				tx = dynamicFeeTx(0, 100000, big.NewInt(int64(baseFee+200+i)), big.NewInt(1), key)
  1999  				highCap = tx
  2000  			}
  2001  			pool.AddRemotesSync([]*types.Transaction{tx})
  2002  		}
  2003  		pending, queued := pool.Stats()
  2004  		if pending+queued != 20 {
  2005  			t.Fatalf("transaction count mismatch: have %d, want %d", pending+queued, 10)
  2006  		}
  2007  	}
  2008  
  2009  	add(false)
  2010  	for baseFee = 0; baseFee <= 1000; baseFee += 100 {
  2011  		pool.mu.Lock()
  2012  		pool.priced.SetBaseFee(big.NewInt(int64(baseFee)))
  2013  		pool.mu.Unlock()
  2014  		add(true)
  2015  		check(highCap, "fee cap")
  2016  		add(false)
  2017  		check(highTip, "effective tip")
  2018  	}
  2019  
  2020  	if err := validateTxPoolInternals(pool); err != nil {
  2021  		t.Fatalf("pool internal state corrupted: %v", err)
  2022  	}
  2023  }
  2024  
  2025  // Tests that the pool rejects duplicate transactions.
  2026  func TestTransactionDeduplication(t *testing.T) {
  2027  	t.Parallel()
  2028  
  2029  	// Create the pool to test the pricing enforcement with
  2030  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
  2031  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
  2032  
  2033  	pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
  2034  	defer pool.Stop()
  2035  
  2036  	// Create a test account to add transactions with
  2037  	key, _ := crypto.GenerateKey()
  2038  	testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000))
  2039  
  2040  	// Create a batch of transactions and add a few of them
  2041  	txs := make([]*types.Transaction, 16)
  2042  	for i := 0; i < len(txs); i++ {
  2043  		txs[i] = pricedTransaction(uint64(i), 100000, big.NewInt(1), key)
  2044  	}
  2045  	var firsts []*types.Transaction
  2046  	for i := 0; i < len(txs); i += 2 {
  2047  		firsts = append(firsts, txs[i])
  2048  	}
  2049  	errs := pool.AddRemotesSync(firsts)
  2050  	if len(errs) != len(firsts) {
  2051  		t.Fatalf("first add mismatching result count: have %d, want %d", len(errs), len(firsts))
  2052  	}
  2053  	for i, err := range errs {
  2054  		if err != nil {
  2055  			t.Errorf("add %d failed: %v", i, err)
  2056  		}
  2057  	}
  2058  	pending, queued := pool.Stats()
  2059  	if pending != 1 {
  2060  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 1)
  2061  	}
  2062  	if queued != len(txs)/2-1 {
  2063  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, len(txs)/2-1)
  2064  	}
  2065  	// Try to add all of them now and ensure previous ones error out as knowns
  2066  	errs = pool.AddRemotesSync(txs)
  2067  	if len(errs) != len(txs) {
  2068  		t.Fatalf("all add mismatching result count: have %d, want %d", len(errs), len(txs))
  2069  	}
  2070  	for i, err := range errs {
  2071  		if i%2 == 0 && err == nil {
  2072  			t.Errorf("add %d succeeded, should have failed as known", i)
  2073  		}
  2074  		if i%2 == 1 && err != nil {
  2075  			t.Errorf("add %d failed: %v", i, err)
  2076  		}
  2077  	}
  2078  	pending, queued = pool.Stats()
  2079  	if pending != len(txs) {
  2080  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, len(txs))
  2081  	}
  2082  	if queued != 0 {
  2083  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  2084  	}
  2085  	if err := validateTxPoolInternals(pool); err != nil {
  2086  		t.Fatalf("pool internal state corrupted: %v", err)
  2087  	}
  2088  }
  2089  
  2090  // Tests that the pool rejects replacement transactions that don't meet the minimum
  2091  // price bump required.
  2092  func TestTransactionReplacement(t *testing.T) {
  2093  	t.Parallel()
  2094  
  2095  	// Create the pool to test the pricing enforcement with
  2096  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
  2097  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
  2098  
  2099  	pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
  2100  	defer pool.Stop()
  2101  
  2102  	// Keep track of transaction events to ensure all executables get announced
  2103  	events := make(chan NewTxsEvent, 32)
  2104  	sub := pool.txFeed.Subscribe(events)
  2105  	defer sub.Unsubscribe()
  2106  
  2107  	// Create a test account to add transactions with
  2108  	key, _ := crypto.GenerateKey()
  2109  	testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000))
  2110  
  2111  	// Add pending transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too)
  2112  	price := int64(100)
  2113  	threshold := (price * (100 + int64(testTxPoolConfig.PriceBump))) / 100
  2114  
  2115  	if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), key)); err != nil {
  2116  		t.Fatalf("failed to add original cheap pending transaction: %v", err)
  2117  	}
  2118  	if err := pool.AddRemote(pricedTransaction(0, 100001, big.NewInt(1), key)); err != ErrReplaceUnderpriced {
  2119  		t.Fatalf("original cheap pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced)
  2120  	}
  2121  	if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(2), key)); err != nil {
  2122  		t.Fatalf("failed to replace original cheap pending transaction: %v", err)
  2123  	}
  2124  	if err := validateEvents(events, 2); err != nil {
  2125  		t.Fatalf("cheap replacement event firing failed: %v", err)
  2126  	}
  2127  
  2128  	if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(price), key)); err != nil {
  2129  		t.Fatalf("failed to add original proper pending transaction: %v", err)
  2130  	}
  2131  	if err := pool.AddRemote(pricedTransaction(0, 100001, big.NewInt(threshold-1), key)); err != ErrReplaceUnderpriced {
  2132  		t.Fatalf("original proper pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced)
  2133  	}
  2134  	if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(threshold), key)); err != nil {
  2135  		t.Fatalf("failed to replace original proper pending transaction: %v", err)
  2136  	}
  2137  	if err := validateEvents(events, 2); err != nil {
  2138  		t.Fatalf("proper replacement event firing failed: %v", err)
  2139  	}
  2140  
  2141  	// Add queued transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too)
  2142  	if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(1), key)); err != nil {
  2143  		t.Fatalf("failed to add original cheap queued transaction: %v", err)
  2144  	}
  2145  	if err := pool.AddRemote(pricedTransaction(2, 100001, big.NewInt(1), key)); err != ErrReplaceUnderpriced {
  2146  		t.Fatalf("original cheap queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced)
  2147  	}
  2148  	if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(2), key)); err != nil {
  2149  		t.Fatalf("failed to replace original cheap queued transaction: %v", err)
  2150  	}
  2151  
  2152  	if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(price), key)); err != nil {
  2153  		t.Fatalf("failed to add original proper queued transaction: %v", err)
  2154  	}
  2155  	if err := pool.AddRemote(pricedTransaction(2, 100001, big.NewInt(threshold-1), key)); err != ErrReplaceUnderpriced {
  2156  		t.Fatalf("original proper queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced)
  2157  	}
  2158  	if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(threshold), key)); err != nil {
  2159  		t.Fatalf("failed to replace original proper queued transaction: %v", err)
  2160  	}
  2161  
  2162  	if err := validateEvents(events, 0); err != nil {
  2163  		t.Fatalf("queued replacement event firing failed: %v", err)
  2164  	}
  2165  	if err := validateTxPoolInternals(pool); err != nil {
  2166  		t.Fatalf("pool internal state corrupted: %v", err)
  2167  	}
  2168  }
  2169  
  2170  // Tests that the pool rejects replacement dynamic fee transactions that don't
  2171  // meet the minimum price bump required.
  2172  func TestTransactionReplacementDynamicFee(t *testing.T) {
  2173  	t.Parallel()
  2174  
  2175  	// Create the pool to test the pricing enforcement with
  2176  	pool, key := setupTxPoolWithConfig(eip1559Config)
  2177  	defer pool.Stop()
  2178  	testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000))
  2179  
  2180  	// Keep track of transaction events to ensure all executables get announced
  2181  	events := make(chan NewTxsEvent, 32)
  2182  	sub := pool.txFeed.Subscribe(events)
  2183  	defer sub.Unsubscribe()
  2184  
  2185  	// Add pending transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too)
  2186  	gasFeeCap := int64(100)
  2187  	feeCapThreshold := (gasFeeCap * (100 + int64(testTxPoolConfig.PriceBump))) / 100
  2188  	gasTipCap := int64(60)
  2189  	tipThreshold := (gasTipCap * (100 + int64(testTxPoolConfig.PriceBump))) / 100
  2190  
  2191  	// Run the following identical checks for both the pending and queue pools:
  2192  	//	1.  Send initial tx => accept
  2193  	//	2.  Don't bump tip or fee cap => discard
  2194  	//	3.  Bump both more than min => accept
  2195  	//	4.  Check events match expected (2 new executable txs during pending, 0 during queue)
  2196  	//	5.  Send new tx with larger tip and gasFeeCap => accept
  2197  	//	6.  Bump tip max allowed so it's still underpriced => discard
  2198  	//	7.  Bump fee cap max allowed so it's still underpriced => discard
  2199  	//	8.  Bump tip min for acceptance => discard
  2200  	//	9.  Bump feecap min for acceptance => discard
  2201  	//	10. Bump feecap and tip min for acceptance => accept
  2202  	//	11. Check events match expected (2 new executable txs during pending, 0 during queue)
  2203  	stages := []string{"pending", "queued"}
  2204  	for _, stage := range stages {
  2205  		// Since state is empty, 0 nonce txs are "executable" and can go
  2206  		// into pending immediately. 2 nonce txs are "happed
  2207  		nonce := uint64(0)
  2208  		if stage == "queued" {
  2209  			nonce = 2
  2210  		}
  2211  
  2212  		// 1.  Send initial tx => accept
  2213  		tx := dynamicFeeTx(nonce, 100000, big.NewInt(2), big.NewInt(1), key)
  2214  		if err := pool.addRemoteSync(tx); err != nil {
  2215  			t.Fatalf("failed to add original cheap %s transaction: %v", stage, err)
  2216  		}
  2217  		// 2.  Don't bump tip or feecap => discard
  2218  		tx = dynamicFeeTx(nonce, 100001, big.NewInt(2), big.NewInt(1), key)
  2219  		if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
  2220  			t.Fatalf("original cheap %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
  2221  		}
  2222  		// 3.  Bump both more than min => accept
  2223  		tx = dynamicFeeTx(nonce, 100000, big.NewInt(3), big.NewInt(2), key)
  2224  		if err := pool.AddRemote(tx); err != nil {
  2225  			t.Fatalf("failed to replace original cheap %s transaction: %v", stage, err)
  2226  		}
  2227  		// 4.  Check events match expected (2 new executable txs during pending, 0 during queue)
  2228  		count := 2
  2229  		if stage == "queued" {
  2230  			count = 0
  2231  		}
  2232  		if err := validateEvents(events, count); err != nil {
  2233  			t.Fatalf("cheap %s replacement event firing failed: %v", stage, err)
  2234  		}
  2235  		// 5.  Send new tx with larger tip and feeCap => accept
  2236  		tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(gasTipCap), key)
  2237  		if err := pool.addRemoteSync(tx); err != nil {
  2238  			t.Fatalf("failed to add original proper %s transaction: %v", stage, err)
  2239  		}
  2240  		// 6.  Bump tip max allowed so it's still underpriced => discard
  2241  		tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(tipThreshold-1), key)
  2242  		if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
  2243  			t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
  2244  		}
  2245  		// 7.  Bump fee cap max allowed so it's still underpriced => discard
  2246  		tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold-1), big.NewInt(gasTipCap), key)
  2247  		if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
  2248  			t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
  2249  		}
  2250  		// 8.  Bump tip min for acceptance => accept
  2251  		tx = dynamicFeeTx(nonce, 100000, big.NewInt(gasFeeCap), big.NewInt(tipThreshold), key)
  2252  		if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
  2253  			t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
  2254  		}
  2255  		// 9.  Bump fee cap min for acceptance => accept
  2256  		tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold), big.NewInt(gasTipCap), key)
  2257  		if err := pool.AddRemote(tx); err != ErrReplaceUnderpriced {
  2258  			t.Fatalf("original proper %s transaction replacement error mismatch: have %v, want %v", stage, err, ErrReplaceUnderpriced)
  2259  		}
  2260  		// 10. Check events match expected (3 new executable txs during pending, 0 during queue)
  2261  		tx = dynamicFeeTx(nonce, 100000, big.NewInt(feeCapThreshold), big.NewInt(tipThreshold), key)
  2262  		if err := pool.AddRemote(tx); err != nil {
  2263  			t.Fatalf("failed to replace original cheap %s transaction: %v", stage, err)
  2264  		}
  2265  		// 11. Check events match expected (3 new executable txs during pending, 0 during queue)
  2266  		count = 2
  2267  		if stage == "queued" {
  2268  			count = 0
  2269  		}
  2270  		if err := validateEvents(events, count); err != nil {
  2271  			t.Fatalf("replacement %s event firing failed: %v", stage, err)
  2272  		}
  2273  	}
  2274  
  2275  	if err := validateTxPoolInternals(pool); err != nil {
  2276  		t.Fatalf("pool internal state corrupted: %v", err)
  2277  	}
  2278  }
  2279  
  2280  // Tests that local transactions are journaled to disk, but remote transactions
  2281  // get discarded between restarts.
  2282  func TestTransactionJournaling(t *testing.T)         { testTransactionJournaling(t, false) }
  2283  func TestTransactionJournalingNoLocals(t *testing.T) { testTransactionJournaling(t, true) }
  2284  
  2285  func testTransactionJournaling(t *testing.T, nolocals bool) {
  2286  	t.Parallel()
  2287  
  2288  	// Create a temporary file for the journal
  2289  	file, err := os.CreateTemp("", "")
  2290  	if err != nil {
  2291  		t.Fatalf("failed to create temporary journal: %v", err)
  2292  	}
  2293  	journal := file.Name()
  2294  	defer os.Remove(journal)
  2295  
  2296  	// Clean up the temporary file, we only need the path for now
  2297  	file.Close()
  2298  	os.Remove(journal)
  2299  
  2300  	// Create the original pool to inject transaction into the journal
  2301  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
  2302  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
  2303  
  2304  	config := testTxPoolConfig
  2305  	config.NoLocals = nolocals
  2306  	config.Journal = journal
  2307  	config.Rejournal = time.Second
  2308  
  2309  	pool := NewTxPool(config, params.TestChainConfig, blockchain)
  2310  
  2311  	// Create two test accounts to ensure remotes expire but locals do not
  2312  	local, _ := crypto.GenerateKey()
  2313  	remote, _ := crypto.GenerateKey()
  2314  
  2315  	testAddBalance(pool, crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000))
  2316  	testAddBalance(pool, crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000))
  2317  
  2318  	// Add three local and a remote transactions and ensure they are queued up
  2319  	if err := pool.AddLocal(pricedTransaction(0, 100000, big.NewInt(1), local)); err != nil {
  2320  		t.Fatalf("failed to add local transaction: %v", err)
  2321  	}
  2322  	if err := pool.AddLocal(pricedTransaction(1, 100000, big.NewInt(1), local)); err != nil {
  2323  		t.Fatalf("failed to add local transaction: %v", err)
  2324  	}
  2325  	if err := pool.AddLocal(pricedTransaction(2, 100000, big.NewInt(1), local)); err != nil {
  2326  		t.Fatalf("failed to add local transaction: %v", err)
  2327  	}
  2328  	if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), remote)); err != nil {
  2329  		t.Fatalf("failed to add remote transaction: %v", err)
  2330  	}
  2331  	pending, queued := pool.Stats()
  2332  	if pending != 4 {
  2333  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 4)
  2334  	}
  2335  	if queued != 0 {
  2336  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  2337  	}
  2338  	if err := validateTxPoolInternals(pool); err != nil {
  2339  		t.Fatalf("pool internal state corrupted: %v", err)
  2340  	}
  2341  	// Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive
  2342  	pool.Stop()
  2343  	statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
  2344  	blockchain = newTestBlockchain(statedb, 1000000, new(event.Feed))
  2345  
  2346  	pool = NewTxPool(config, params.TestChainConfig, blockchain)
  2347  
  2348  	pending, queued = pool.Stats()
  2349  	if queued != 0 {
  2350  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  2351  	}
  2352  	if nolocals {
  2353  		if pending != 0 {
  2354  			t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
  2355  		}
  2356  	} else {
  2357  		if pending != 2 {
  2358  			t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
  2359  		}
  2360  	}
  2361  	if err := validateTxPoolInternals(pool); err != nil {
  2362  		t.Fatalf("pool internal state corrupted: %v", err)
  2363  	}
  2364  	// Bump the nonce temporarily and ensure the newly invalidated transaction is removed
  2365  	statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2)
  2366  	<-pool.requestReset(nil, nil)
  2367  	time.Sleep(2 * config.Rejournal)
  2368  	pool.Stop()
  2369  
  2370  	statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
  2371  	blockchain = newTestBlockchain(statedb, 1000000, new(event.Feed))
  2372  	pool = NewTxPool(config, params.TestChainConfig, blockchain)
  2373  
  2374  	pending, queued = pool.Stats()
  2375  	if pending != 0 {
  2376  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
  2377  	}
  2378  	if nolocals {
  2379  		if queued != 0 {
  2380  			t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
  2381  		}
  2382  	} else {
  2383  		if queued != 1 {
  2384  			t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
  2385  		}
  2386  	}
  2387  	if err := validateTxPoolInternals(pool); err != nil {
  2388  		t.Fatalf("pool internal state corrupted: %v", err)
  2389  	}
  2390  	pool.Stop()
  2391  }
  2392  
  2393  // TestTransactionStatusCheck tests that the pool can correctly retrieve the
  2394  // pending status of individual transactions.
  2395  func TestTransactionStatusCheck(t *testing.T) {
  2396  	t.Parallel()
  2397  
  2398  	// Create the pool to test the status retrievals with
  2399  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
  2400  	blockchain := newTestBlockchain(statedb, 1000000, new(event.Feed))
  2401  
  2402  	pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
  2403  	defer pool.Stop()
  2404  
  2405  	// Create the test accounts to check various transaction statuses with
  2406  	keys := make([]*ecdsa.PrivateKey, 3)
  2407  	for i := 0; i < len(keys); i++ {
  2408  		keys[i], _ = crypto.GenerateKey()
  2409  		testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
  2410  	}
  2411  	// Generate and queue a batch of transactions, both pending and queued
  2412  	txs := types.Transactions{}
  2413  
  2414  	txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[0])) // Pending only
  2415  	txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[1])) // Pending and queued
  2416  	txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[1]))
  2417  	txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[2])) // Queued only
  2418  
  2419  	// Import the transaction and ensure they are correctly added
  2420  	pool.AddRemotesSync(txs)
  2421  
  2422  	pending, queued := pool.Stats()
  2423  	if pending != 2 {
  2424  		t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
  2425  	}
  2426  	if queued != 2 {
  2427  		t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
  2428  	}
  2429  	if err := validateTxPoolInternals(pool); err != nil {
  2430  		t.Fatalf("pool internal state corrupted: %v", err)
  2431  	}
  2432  	// Retrieve the status of each transaction and validate them
  2433  	hashes := make([]common.Hash, len(txs))
  2434  	for i, tx := range txs {
  2435  		hashes[i] = tx.Hash()
  2436  	}
  2437  	hashes = append(hashes, common.Hash{})
  2438  
  2439  	statuses := pool.Status(hashes)
  2440  	expect := []TxStatus{TxStatusPending, TxStatusPending, TxStatusQueued, TxStatusQueued, TxStatusUnknown}
  2441  
  2442  	for i := 0; i < len(statuses); i++ {
  2443  		if statuses[i] != expect[i] {
  2444  			t.Errorf("transaction %d: status mismatch: have %v, want %v", i, statuses[i], expect[i])
  2445  		}
  2446  	}
  2447  }
  2448  
  2449  // Test the transaction slots consumption is computed correctly
  2450  func TestTransactionSlotCount(t *testing.T) {
  2451  	t.Parallel()
  2452  
  2453  	key, _ := crypto.GenerateKey()
  2454  
  2455  	// Check that an empty transaction consumes a single slot
  2456  	smallTx := pricedDataTransaction(0, 0, big.NewInt(0), key, 0)
  2457  	if slots := numSlots(smallTx); slots != 1 {
  2458  		t.Fatalf("small transactions slot count mismatch: have %d want %d", slots, 1)
  2459  	}
  2460  	// Check that a large transaction consumes the correct number of slots
  2461  	bigTx := pricedDataTransaction(0, 0, big.NewInt(0), key, uint64(10*txSlotSize))
  2462  	if slots := numSlots(bigTx); slots != 11 {
  2463  		t.Fatalf("big transactions slot count mismatch: have %d want %d", slots, 11)
  2464  	}
  2465  }
  2466  
  2467  // Benchmarks the speed of validating the contents of the pending queue of the
  2468  // transaction pool.
  2469  func BenchmarkPendingDemotion100(b *testing.B)   { benchmarkPendingDemotion(b, 100) }
  2470  func BenchmarkPendingDemotion1000(b *testing.B)  { benchmarkPendingDemotion(b, 1000) }
  2471  func BenchmarkPendingDemotion10000(b *testing.B) { benchmarkPendingDemotion(b, 10000) }
  2472  
  2473  func benchmarkPendingDemotion(b *testing.B, size int) {
  2474  	// Add a batch of transactions to a pool one by one
  2475  	pool, key := setupTxPool()
  2476  	defer pool.Stop()
  2477  
  2478  	account := crypto.PubkeyToAddress(key.PublicKey)
  2479  	testAddBalance(pool, account, big.NewInt(1000000))
  2480  
  2481  	for i := 0; i < size; i++ {
  2482  		tx := transaction(uint64(i), 100000, key)
  2483  		pool.promoteTx(account, tx.Hash(), tx)
  2484  	}
  2485  	// Benchmark the speed of pool validation
  2486  	b.ResetTimer()
  2487  	for i := 0; i < b.N; i++ {
  2488  		pool.demoteUnexecutables()
  2489  	}
  2490  }
  2491  
  2492  // Benchmarks the speed of scheduling the contents of the future queue of the
  2493  // transaction pool.
  2494  func BenchmarkFuturePromotion100(b *testing.B)   { benchmarkFuturePromotion(b, 100) }
  2495  func BenchmarkFuturePromotion1000(b *testing.B)  { benchmarkFuturePromotion(b, 1000) }
  2496  func BenchmarkFuturePromotion10000(b *testing.B) { benchmarkFuturePromotion(b, 10000) }
  2497  
  2498  func benchmarkFuturePromotion(b *testing.B, size int) {
  2499  	// Add a batch of transactions to a pool one by one
  2500  	pool, key := setupTxPool()
  2501  	defer pool.Stop()
  2502  
  2503  	account := crypto.PubkeyToAddress(key.PublicKey)
  2504  	testAddBalance(pool, account, big.NewInt(1000000))
  2505  
  2506  	for i := 0; i < size; i++ {
  2507  		tx := transaction(uint64(1+i), 100000, key)
  2508  		pool.enqueueTx(tx.Hash(), tx, false, true)
  2509  	}
  2510  	// Benchmark the speed of pool validation
  2511  	b.ResetTimer()
  2512  	for i := 0; i < b.N; i++ {
  2513  		pool.promoteExecutables(nil)
  2514  	}
  2515  }
  2516  
  2517  // Benchmarks the speed of batched transaction insertion.
  2518  func BenchmarkPoolBatchInsert100(b *testing.B)   { benchmarkPoolBatchInsert(b, 100, false) }
  2519  func BenchmarkPoolBatchInsert1000(b *testing.B)  { benchmarkPoolBatchInsert(b, 1000, false) }
  2520  func BenchmarkPoolBatchInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 10000, false) }
  2521  
  2522  func BenchmarkPoolBatchLocalInsert100(b *testing.B)   { benchmarkPoolBatchInsert(b, 100, true) }
  2523  func BenchmarkPoolBatchLocalInsert1000(b *testing.B)  { benchmarkPoolBatchInsert(b, 1000, true) }
  2524  func BenchmarkPoolBatchLocalInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 10000, true) }
  2525  
  2526  func benchmarkPoolBatchInsert(b *testing.B, size int, local bool) {
  2527  	// Generate a batch of transactions to enqueue into the pool
  2528  	pool, key := setupTxPool()
  2529  	defer pool.Stop()
  2530  
  2531  	account := crypto.PubkeyToAddress(key.PublicKey)
  2532  	testAddBalance(pool, account, big.NewInt(1000000))
  2533  
  2534  	batches := make([]types.Transactions, b.N)
  2535  	for i := 0; i < b.N; i++ {
  2536  		batches[i] = make(types.Transactions, size)
  2537  		for j := 0; j < size; j++ {
  2538  			batches[i][j] = transaction(uint64(size*i+j), 100000, key)
  2539  		}
  2540  	}
  2541  	// Benchmark importing the transactions into the queue
  2542  	b.ResetTimer()
  2543  	for _, batch := range batches {
  2544  		if local {
  2545  			pool.AddLocals(batch)
  2546  		} else {
  2547  			pool.AddRemotes(batch)
  2548  		}
  2549  	}
  2550  }
  2551  
  2552  func BenchmarkInsertRemoteWithAllLocals(b *testing.B) {
  2553  	// Allocate keys for testing
  2554  	key, _ := crypto.GenerateKey()
  2555  	account := crypto.PubkeyToAddress(key.PublicKey)
  2556  
  2557  	remoteKey, _ := crypto.GenerateKey()
  2558  	remoteAddr := crypto.PubkeyToAddress(remoteKey.PublicKey)
  2559  
  2560  	locals := make([]*types.Transaction, 4096+1024) // Occupy all slots
  2561  	for i := 0; i < len(locals); i++ {
  2562  		locals[i] = transaction(uint64(i), 100000, key)
  2563  	}
  2564  	remotes := make([]*types.Transaction, 1000)
  2565  	for i := 0; i < len(remotes); i++ {
  2566  		remotes[i] = pricedTransaction(uint64(i), 100000, big.NewInt(2), remoteKey) // Higher gasprice
  2567  	}
  2568  	// Benchmark importing the transactions into the queue
  2569  	b.ResetTimer()
  2570  	for i := 0; i < b.N; i++ {
  2571  		b.StopTimer()
  2572  		pool, _ := setupTxPool()
  2573  		testAddBalance(pool, account, big.NewInt(100000000))
  2574  		for _, local := range locals {
  2575  			pool.AddLocal(local)
  2576  		}
  2577  		b.StartTimer()
  2578  		// Assign a high enough balance for testing
  2579  		testAddBalance(pool, remoteAddr, big.NewInt(100000000))
  2580  		for i := 0; i < len(remotes); i++ {
  2581  			pool.AddRemotes([]*types.Transaction{remotes[i]})
  2582  		}
  2583  		pool.Stop()
  2584  	}
  2585  }
  2586  
  2587  // Benchmarks the speed of batch transaction insertion in case of multiple accounts.
  2588  func BenchmarkPoolMultiAccountBatchInsert(b *testing.B) {
  2589  	// Generate a batch of transactions to enqueue into the pool
  2590  	pool, _ := setupTxPool()
  2591  	defer pool.Stop()
  2592  	b.ReportAllocs()
  2593  	batches := make(types.Transactions, b.N)
  2594  	for i := 0; i < b.N; i++ {
  2595  		key, _ := crypto.GenerateKey()
  2596  		account := crypto.PubkeyToAddress(key.PublicKey)
  2597  		pool.currentState.AddBalance(account, big.NewInt(1000000))
  2598  		tx := transaction(uint64(0), 100000, key)
  2599  		batches[i] = tx
  2600  	}
  2601  	// Benchmark importing the transactions into the queue
  2602  	b.ResetTimer()
  2603  	for _, tx := range batches {
  2604  		pool.AddRemotesSync([]*types.Transaction{tx})
  2605  	}
  2606  }