github.com/tacshi/go-ethereum@v0.0.0-20230616113857-84a434e20921/core/txpool/txpool_test.go (about)

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