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