github.com/klaytn/klaytn@v1.12.1/blockchain/tx_pool.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2014 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from core/tx_pool.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package blockchain
    22  
    23  import (
    24  	"errors"
    25  	"fmt"
    26  	"math"
    27  	"math/big"
    28  	"sort"
    29  	"sync"
    30  	"time"
    31  
    32  	"github.com/klaytn/klaytn/blockchain/state"
    33  	"github.com/klaytn/klaytn/blockchain/types"
    34  	"github.com/klaytn/klaytn/common"
    35  	"github.com/klaytn/klaytn/common/prque"
    36  	"github.com/klaytn/klaytn/consensus/misc"
    37  	"github.com/klaytn/klaytn/event"
    38  	"github.com/klaytn/klaytn/kerrors"
    39  	"github.com/klaytn/klaytn/params"
    40  	"github.com/rcrowley/go-metrics"
    41  )
    42  
    43  const (
    44  	// chainHeadChanSize is the size of channel listening to ChainHeadEvent.
    45  	chainHeadChanSize = 10
    46  
    47  	// txSlotSize is used to calculate how many data slots a single transaction
    48  	// takes up based on its size. The slots are used as DoS protection, ensuring
    49  	// that validating a new transaction remains a constant operation (in reality
    50  	// O(maxslots), where max slots are 4 currently).
    51  	txSlotSize = 32 * 1024
    52  
    53  	// MaxTxDataSize is the maximum size a single transaction can have. This field has
    54  	// non-trivial consequences: larger transactions are significantly harder and
    55  	// more expensive to propagate; larger transactions also take more resources
    56  	// to validate whether they fit into the pool or not.
    57  	// TODO-klaytn: Change the name to clarify what it means. It means the max length of the transaction.
    58  	MaxTxDataSize = 4 * txSlotSize // 128KB
    59  
    60  	// demoteUnexecutablesFullValidationTxLimit is the number of txs will be fully validated in demoteUnexecutables.
    61  	demoteUnexecutablesFullValidationTxLimit = 1000
    62  	// txMsgCh is the number of list of transactions can be queued.
    63  	txMsgChSize = 100
    64  )
    65  
    66  var (
    67  	evictionInterval    = time.Minute     // Time interval to check for evictable transactions
    68  	statsReportInterval = 8 * time.Second // Time interval to report transaction pool stats
    69  
    70  	txPoolIsFullErr = fmt.Errorf("txpool is full")
    71  
    72  	errNotAllowedAnchoringTx = errors.New("locally anchoring chaindata tx is not allowed in this node")
    73  )
    74  
    75  var (
    76  	// Metrics for the pending pool
    77  	pendingDiscardCounter   = metrics.NewRegisteredCounter("txpool/pending/discard", nil)
    78  	pendingReplaceCounter   = metrics.NewRegisteredCounter("txpool/pending/replace", nil)
    79  	pendingRateLimitCounter = metrics.NewRegisteredCounter("txpool/pending/ratelimit", nil) // Dropped due to rate limiting
    80  	pendingNofundsCounter   = metrics.NewRegisteredCounter("txpool/pending/nofunds", nil)   // Dropped due to out-of-funds
    81  
    82  	// Metrics for the queued pool
    83  	queuedDiscardCounter   = metrics.NewRegisteredCounter("txpool/queued/discard", nil)
    84  	queuedReplaceCounter   = metrics.NewRegisteredCounter("txpool/queued/replace", nil)
    85  	queuedRateLimitCounter = metrics.NewRegisteredCounter("txpool/queued/ratelimit", nil) // Dropped due to rate limiting
    86  	queuedNofundsCounter   = metrics.NewRegisteredCounter("txpool/queued/nofunds", nil)   // Dropped due to out-of-funds
    87  
    88  	// General tx metrics
    89  	invalidTxCounter     = metrics.NewRegisteredCounter("txpool/invalid", nil)
    90  	underpricedTxCounter = metrics.NewRegisteredCounter("txpool/underpriced", nil)
    91  	refusedTxCounter     = metrics.NewRegisteredCounter("txpool/refuse", nil)
    92  	slotsGauge           = metrics.NewRegisteredGauge("txpool/slots", nil)
    93  )
    94  
    95  // TxStatus is the current status of a transaction as seen by the pool.
    96  type TxStatus uint
    97  
    98  const (
    99  	TxStatusUnknown TxStatus = iota
   100  	TxStatusQueued
   101  	TxStatusPending
   102  	// for Les
   103  	TxStatusIncluded
   104  )
   105  
   106  // blockChain provides the state of blockchain and current gas limit to do
   107  // some pre checks in tx pool and event subscribers.
   108  type blockChain interface {
   109  	CurrentBlock() *types.Block
   110  	GetBlock(hash common.Hash, number uint64) *types.Block
   111  	StateAt(root common.Hash) (*state.StateDB, error)
   112  
   113  	SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription
   114  }
   115  
   116  // TxPoolConfig are the configuration parameters of the transaction pool.
   117  type TxPoolConfig struct {
   118  	NoLocals           bool          // Whether local transaction handling should be disabled
   119  	AllowLocalAnchorTx bool          // if this is true, the txpool allow locally submitted anchor transactions
   120  	DenyRemoteTx       bool          // Denies remote transactions receiving from other peers
   121  	Journal            string        // Journal of local transactions to survive node restarts
   122  	JournalInterval    time.Duration // Time interval to regenerate the local transaction journal
   123  
   124  	PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool
   125  	PriceBump  uint64 // Minimum price bump percentage to replace an already existing transaction (nonce)
   126  
   127  	ExecSlotsAccount    uint64 // Number of executable transaction slots guaranteed per account
   128  	ExecSlotsAll        uint64 // Maximum number of executable transaction slots for all accounts
   129  	NonExecSlotsAccount uint64 // Maximum number of non-executable transaction slots permitted per account
   130  	NonExecSlotsAll     uint64 // Maximum number of non-executable transaction slots for all accounts
   131  
   132  	KeepLocals bool          // Disables removing timed-out local transactions
   133  	Lifetime   time.Duration // Maximum amount of time non-executable transaction are queued
   134  
   135  	NoAccountCreation            bool // Whether account creation transactions should be disabled
   136  	EnableSpamThrottlerAtRuntime bool // Enable txpool spam throttler at runtime
   137  }
   138  
   139  // DefaultTxPoolConfig contains the default configurations for the transaction
   140  // pool.
   141  var DefaultTxPoolConfig = TxPoolConfig{
   142  	Journal:         "transactions.rlp",
   143  	JournalInterval: time.Hour,
   144  
   145  	PriceLimit: 1,
   146  	PriceBump:  10,
   147  
   148  	ExecSlotsAccount:    16,
   149  	ExecSlotsAll:        4096,
   150  	NonExecSlotsAccount: 64,
   151  	NonExecSlotsAll:     1024,
   152  
   153  	KeepLocals: false,
   154  	Lifetime:   5 * time.Minute,
   155  }
   156  
   157  // sanitize checks the provided user configurations and changes anything that's
   158  // unreasonable or unworkable.
   159  func (config *TxPoolConfig) sanitize() TxPoolConfig {
   160  	conf := *config
   161  	if conf.JournalInterval < time.Second {
   162  		logger.Error("Sanitizing invalid txpool journal time", "provided", conf.JournalInterval, "updated", time.Second)
   163  		conf.JournalInterval = time.Second
   164  	}
   165  	if conf.PriceLimit < 1 {
   166  		logger.Error("Sanitizing invalid txpool price limit", "provided", conf.PriceLimit, "updated", DefaultTxPoolConfig.PriceLimit)
   167  		conf.PriceLimit = DefaultTxPoolConfig.PriceLimit
   168  	}
   169  	if conf.PriceBump < 1 {
   170  		logger.Error("Sanitizing invalid txpool price bump", "provided", conf.PriceBump, "updated", DefaultTxPoolConfig.PriceBump)
   171  		conf.PriceBump = DefaultTxPoolConfig.PriceBump
   172  	}
   173  	return conf
   174  }
   175  
   176  // TxPool contains all currently known transactions. Transactions
   177  // enter the pool when they are received from the network or submitted
   178  // locally. They exit the pool when they are included in the blockchain.
   179  //
   180  // The pool separates processable transactions (which can be applied to the
   181  // current state) and future transactions. Transactions move between those
   182  // two states over time as they are received and processed.
   183  type TxPool struct {
   184  	config       TxPoolConfig
   185  	chainconfig  *params.ChainConfig
   186  	chain        blockChain
   187  	gasPrice     *big.Int
   188  	txFeed       event.Feed
   189  	scope        event.SubscriptionScope
   190  	chainHeadCh  chan ChainHeadEvent
   191  	chainHeadSub event.Subscription
   192  	signer       types.Signer
   193  	mu           sync.RWMutex
   194  
   195  	currentBlockNumber uint64                    // Current block number
   196  	currentState       *state.StateDB            // Current state in the blockchain head
   197  	pendingNonce       map[common.Address]uint64 // Pending nonce tracking virtual nonces
   198  
   199  	locals  *accountSet // Set of local transaction to exempt from eviction rules
   200  	journal *txJournal  // Journal of local transaction to back up to disk
   201  
   202  	// TODO-Klaytn
   203  	txMu sync.RWMutex
   204  
   205  	pending map[common.Address]*txList   // All currently processable transactions
   206  	queue   map[common.Address]*txList   // Queued but non-processable transactions
   207  	beats   map[common.Address]time.Time // Last heartbeat from each known account
   208  	all     *txLookup                    // All transactions to allow lookups
   209  	priced  *txPricedList                // All transactions sorted by price
   210  
   211  	wg sync.WaitGroup // for shutdown sync
   212  
   213  	txMsgCh chan types.Transactions
   214  
   215  	rules params.Rules // Fork indicator
   216  }
   217  
   218  // NewTxPool creates a new transaction pool to gather, sort and filter inbound
   219  // transactions from the network.
   220  func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain) *TxPool {
   221  	// Sanitize the input to ensure no vulnerable gas prices are set
   222  	config = (&config).sanitize()
   223  
   224  	// Create the transaction pool with its initial settings
   225  	pool := &TxPool{
   226  		config:       config,
   227  		chainconfig:  chainconfig,
   228  		chain:        chain,
   229  		signer:       types.LatestSignerForChainID(chainconfig.ChainID),
   230  		pending:      make(map[common.Address]*txList),
   231  		queue:        make(map[common.Address]*txList),
   232  		beats:        make(map[common.Address]time.Time),
   233  		all:          newTxLookup(),
   234  		pendingNonce: make(map[common.Address]uint64),
   235  		chainHeadCh:  make(chan ChainHeadEvent, chainHeadChanSize),
   236  		gasPrice:     new(big.Int).SetUint64(chainconfig.UnitPrice),
   237  		txMsgCh:      make(chan types.Transactions, txMsgChSize),
   238  	}
   239  	pool.locals = newAccountSet(pool.signer)
   240  	pool.priced = newTxPricedList(pool.all)
   241  	pool.reset(nil, chain.CurrentBlock().Header())
   242  
   243  	// If local transactions and journaling is enabled, load from disk
   244  	if !config.NoLocals && config.Journal != "" {
   245  		pool.journal = newTxJournal(config.Journal)
   246  
   247  		if err := pool.journal.load(pool.AddLocals); err != nil {
   248  			logger.Error("Failed to load transaction journal", "err", err)
   249  		}
   250  		if err := pool.journal.rotate(pool.local(), pool.signer); err != nil {
   251  			logger.Error("Failed to rotate transaction journal", "err", err)
   252  		}
   253  	}
   254  	// Subscribe events from blockchain
   255  	pool.chainHeadSub = pool.chain.SubscribeChainHeadEvent(pool.chainHeadCh)
   256  
   257  	// Start the event loop and return
   258  	pool.wg.Add(2)
   259  	go pool.loop()
   260  	go pool.handleTxMsg()
   261  
   262  	if config.EnableSpamThrottlerAtRuntime {
   263  		if err := pool.StartSpamThrottler(DefaultSpamThrottlerConfig); err != nil {
   264  			logger.Error("Failed to start spam throttler", "err", err)
   265  		}
   266  	}
   267  
   268  	return pool
   269  }
   270  
   271  // loop is the transaction pool's main event loop, waiting for and reacting to
   272  // outside blockchain events as well as for various reporting and transaction
   273  // eviction events.
   274  func (pool *TxPool) loop() {
   275  	defer pool.wg.Done()
   276  
   277  	// Start the stats reporting and transaction eviction tickers
   278  	var prevPending, prevQueued, prevStales int
   279  
   280  	report := time.NewTicker(statsReportInterval)
   281  	defer report.Stop()
   282  
   283  	evict := time.NewTicker(evictionInterval)
   284  	defer evict.Stop()
   285  
   286  	journal := time.NewTicker(pool.config.JournalInterval)
   287  	defer journal.Stop()
   288  
   289  	// Track the previous head headers for transaction reorgs
   290  	head := pool.chain.CurrentBlock()
   291  
   292  	// Keep waiting for and reacting to the various events
   293  	for {
   294  		select {
   295  		// Handle ChainHeadEvent
   296  		case ev := <-pool.chainHeadCh:
   297  			if ev.Block != nil {
   298  				pool.mu.Lock()
   299  				currBlock := pool.chain.CurrentBlock()
   300  				if ev.Block.Root() != currBlock.Root() {
   301  					pool.mu.Unlock()
   302  					logger.Debug("block from ChainHeadEvent is different from the CurrentBlock",
   303  						"receivedNum", ev.Block.NumberU64(), "receivedHash", ev.Block.Hash().String(),
   304  						"currNum", currBlock.NumberU64(), "currHash", currBlock.Hash().String())
   305  					continue
   306  				}
   307  				pool.reset(head.Header(), ev.Block.Header())
   308  				head = ev.Block
   309  				pool.mu.Unlock()
   310  			}
   311  		// Be unsubscribed due to system stopped
   312  		case <-pool.chainHeadSub.Err():
   313  			return
   314  
   315  		// Handle stats reporting ticks
   316  		case <-report.C:
   317  			pool.mu.RLock()
   318  			pending, queued := pool.stats()
   319  			stales := pool.priced.stales
   320  			pool.mu.RUnlock()
   321  
   322  			if pending != prevPending || queued != prevQueued || stales != prevStales {
   323  				logger.Debug("Transaction pool status report", "executable", pending, "queued", queued, "stales", stales)
   324  				prevPending, prevQueued, prevStales = pending, queued, stales
   325  				txPoolPendingGauge.Update(int64(pending))
   326  				txPoolQueueGauge.Update(int64(queued))
   327  			}
   328  
   329  		// Handle inactive account transaction eviction
   330  		case <-evict.C:
   331  			pool.mu.Lock()
   332  			for addr, beat := range pool.beats {
   333  				// Skip local transactions from the eviction mechanism
   334  				if pool.config.KeepLocals && pool.locals.contains(addr) {
   335  					delete(pool.beats, addr)
   336  					continue
   337  				}
   338  
   339  				// Any non-locals old enough should be removed
   340  				if time.Since(beat) > pool.config.Lifetime {
   341  					if pool.queue[addr] != nil {
   342  						for _, tx := range pool.queue[addr].Flatten() {
   343  							pool.removeTx(tx.Hash(), true)
   344  						}
   345  					}
   346  					delete(pool.beats, addr)
   347  				}
   348  			}
   349  			pool.mu.Unlock()
   350  
   351  		// Handle local transaction journal rotation
   352  		case <-journal.C:
   353  			if pool.journal != nil {
   354  				pool.mu.Lock()
   355  				if err := pool.journal.rotate(pool.local(), pool.signer); err != nil {
   356  					logger.Error("Failed to rotate local tx journal", "err", err)
   357  				}
   358  				pool.mu.Unlock()
   359  			}
   360  		}
   361  	}
   362  }
   363  
   364  // lockedReset is a wrapper around reset to allow calling it in a thread safe
   365  // manner. This method is only ever used in the tester!
   366  func (pool *TxPool) lockedReset(oldHead, newHead *types.Header) {
   367  	pool.mu.Lock()
   368  	defer pool.mu.Unlock()
   369  
   370  	pool.reset(oldHead, newHead)
   371  }
   372  
   373  // reset retrieves the current state of the blockchain and ensures the content
   374  // of the transaction pool is valid with regard to the chain state.
   375  func (pool *TxPool) reset(oldHead, newHead *types.Header) {
   376  	// If we're reorging an old state, reinject all dropped transactions
   377  	var reinject types.Transactions
   378  
   379  	if oldHead != nil && oldHead.Hash() != newHead.ParentHash {
   380  		// If the reorg is too deep, avoid doing it (will happen during fast sync)
   381  		oldNum := oldHead.Number.Uint64()
   382  		newNum := newHead.Number.Uint64()
   383  
   384  		if depth := uint64(math.Abs(float64(oldNum) - float64(newNum))); depth > 64 {
   385  			logger.Debug("Skipping deep transaction reorg", "depth", depth)
   386  		} else {
   387  			// Reorg seems shallow enough to pull in all transactions into memory
   388  			var discarded, included types.Transactions
   389  
   390  			var (
   391  				rem = pool.chain.GetBlock(oldHead.Hash(), oldHead.Number.Uint64())
   392  				add = pool.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64())
   393  			)
   394  			if rem == nil {
   395  				// This can happen if a setHead function is performed.
   396  				// In this case we can simply discard the old head from the chain, and replace with newhead.
   397  
   398  				// If newNum >= oldNum, then it's not a case of setHead.
   399  				if newNum >= oldNum {
   400  					logger.Error("Transaction pool reset with missing oldhead",
   401  						"old", oldHead.Hash(), "oldnum", oldNum, "new", newHead.Hash(), "newnum", newNum)
   402  					return
   403  				} else {
   404  					// When setHead is performed, then oldHead becomes bigger than newHead, since newHead becomes rewinded blockNumber.
   405  					// If that is the case, we don't have the lost transactions anymore, and
   406  					// there's nothing to add
   407  					logger.Warn("Skipping transaction reset caused by setHead",
   408  						"old", oldHead.Hash(), "oldnum", oldNum, "new", newHead.Hash(), "newnum", newNum)
   409  				}
   410  			} else {
   411  				for rem.NumberU64() > add.NumberU64() {
   412  					discarded = append(discarded, rem.Transactions()...)
   413  					if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil {
   414  						logger.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash())
   415  						return
   416  					}
   417  				}
   418  				for add.NumberU64() > rem.NumberU64() {
   419  					included = append(included, add.Transactions()...)
   420  					if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil {
   421  						logger.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash())
   422  						return
   423  					}
   424  				}
   425  				for rem.Hash() != add.Hash() {
   426  					discarded = append(discarded, rem.Transactions()...)
   427  					if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil {
   428  						logger.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash())
   429  						return
   430  					}
   431  					included = append(included, add.Transactions()...)
   432  					if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil {
   433  						logger.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash())
   434  						return
   435  					}
   436  				}
   437  				reinject = types.TxDifference(discarded, included)
   438  			}
   439  		}
   440  	}
   441  	// Initialize the internal state to the current head
   442  	if newHead == nil {
   443  		newHead = pool.chain.CurrentBlock().Header() // Special case during testing
   444  	}
   445  	stateDB, err := pool.chain.StateAt(newHead.Root)
   446  	if err != nil {
   447  		logger.Error("Failed to reset txpool state", "err", err)
   448  		return
   449  	}
   450  	pool.currentState = stateDB
   451  	pool.pendingNonce = make(map[common.Address]uint64)
   452  	pool.currentBlockNumber = newHead.Number.Uint64()
   453  
   454  	// Inject any transactions discarded due to reorgs
   455  	logger.Debug("Reinjecting stale transactions", "count", len(reinject))
   456  	senderCacher.recover(pool.signer, reinject)
   457  
   458  	// pool.mu.Lock()
   459  	// defer pool.mu.Unlock()
   460  
   461  	pool.addTxsLocked(reinject, false)
   462  
   463  	// validate the pool of pending transactions, this will remove
   464  	// any transactions that have been included in the block or
   465  	// have been invalidated because of another transaction (e.g.
   466  	// higher gas price)
   467  	pool.demoteUnexecutables()
   468  
   469  	pool.txMu.Lock()
   470  	// Update all accounts to the latest known pending nonce
   471  	for addr, list := range pool.pending {
   472  		txs := list.Flatten()
   473  		if len(txs) > 0 {
   474  			// Heavy but will be cached and is needed by the miner anyway
   475  			pool.setPendingNonce(addr, txs[len(txs)-1].Nonce()+1)
   476  		}
   477  	}
   478  	pool.txMu.Unlock()
   479  	// Check the queue and move transactions over to the pending if possible
   480  	// or remove those that have become invalid
   481  	pool.promoteExecutables(nil)
   482  
   483  	// Update all fork indicator by next pending block number.
   484  	pool.rules = pool.chainconfig.Rules(new(big.Int).Add(newHead.Number, big.NewInt(1)))
   485  
   486  	// It needs to update gas price of tx pool since magma hardfork
   487  	if pool.rules.IsMagma {
   488  		pool.gasPrice = misc.NextMagmaBlockBaseFee(newHead, pool.chainconfig.Governance.KIP71)
   489  	}
   490  }
   491  
   492  // Stop terminates the transaction pool.
   493  func (pool *TxPool) Stop() {
   494  	// Unsubscribe all subscriptions registered from txpool
   495  	pool.scope.Close()
   496  
   497  	// Unsubscribe subscriptions registered from blockchain
   498  	pool.chainHeadSub.Unsubscribe()
   499  	pool.wg.Wait()
   500  
   501  	if pool.journal != nil {
   502  		pool.journal.close()
   503  	}
   504  
   505  	pool.StopSpamThrottler()
   506  	logger.Info("Transaction pool stopped")
   507  }
   508  
   509  // SubscribeNewTxsEvent registers a subscription of NewTxsEvent and
   510  // starts sending event to the given channel.
   511  func (pool *TxPool) SubscribeNewTxsEvent(ch chan<- NewTxsEvent) event.Subscription {
   512  	return pool.scope.Track(pool.txFeed.Subscribe(ch))
   513  }
   514  
   515  // GasPrice returns the current gas price enforced by the transaction pool.
   516  func (pool *TxPool) GasPrice() *big.Int {
   517  	pool.mu.RLock()
   518  	defer pool.mu.RUnlock()
   519  
   520  	return new(big.Int).Set(pool.gasPrice)
   521  }
   522  
   523  // SetGasPrice updates the gas price of the transaction pool for new transactions, and drops all old transactions.
   524  func (pool *TxPool) SetGasPrice(price *big.Int) {
   525  	if pool.rules.IsMagma {
   526  		logger.Info("Ignoring SetGasPrice after Magma fork")
   527  		return
   528  	}
   529  	if pool.gasPrice.Cmp(price) != 0 {
   530  		pool.mu.Lock()
   531  
   532  		logger.Info("TxPool.SetGasPrice", "before", pool.gasPrice, "after", price)
   533  
   534  		pool.gasPrice = price
   535  		pool.pending = make(map[common.Address]*txList)
   536  		pool.queue = make(map[common.Address]*txList)
   537  		pool.beats = make(map[common.Address]time.Time)
   538  		pool.all = newTxLookup()
   539  		pool.pendingNonce = make(map[common.Address]uint64)
   540  		pool.locals = newAccountSet(pool.signer)
   541  		pool.priced = newTxPricedList(pool.all)
   542  
   543  		pool.mu.Unlock()
   544  	}
   545  }
   546  
   547  // Stats retrieves the current pool stats, namely the number of pending and the
   548  // number of queued (non-executable) transactions.
   549  func (pool *TxPool) Stats() (int, int) {
   550  	pool.mu.RLock()
   551  	defer pool.mu.RUnlock()
   552  
   553  	return pool.stats()
   554  }
   555  
   556  // stats retrieves the current pool stats, namely the number of pending and the
   557  // number of queued (non-executable) transactions.
   558  func (pool *TxPool) stats() (int, int) {
   559  	pending := 0
   560  	for _, list := range pool.pending {
   561  		pending += list.Len()
   562  	}
   563  	queued := 0
   564  	for _, list := range pool.queue {
   565  		queued += list.Len()
   566  	}
   567  	return pending, queued
   568  }
   569  
   570  // Content retrieves the data content of the transaction pool, returning all the
   571  // pending as well as queued transactions, grouped by account and sorted by nonce.
   572  func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) {
   573  	pool.mu.Lock()
   574  	defer pool.mu.Unlock()
   575  	pool.txMu.Lock()
   576  	defer pool.txMu.Unlock()
   577  
   578  	pending := make(map[common.Address]types.Transactions)
   579  	for addr, list := range pool.pending {
   580  		pending[addr] = list.Flatten()
   581  	}
   582  	queued := make(map[common.Address]types.Transactions)
   583  	for addr, list := range pool.queue {
   584  		queued[addr] = list.Flatten()
   585  	}
   586  	return pending, queued
   587  }
   588  
   589  // Pending retrieves all currently processable transactions, groupped by origin
   590  // account and sorted by nonce. The returned transaction set is a copy and can be
   591  // freely modified by calling code.
   592  func (pool *TxPool) Pending() (map[common.Address]types.Transactions, error) {
   593  	pool.mu.Lock()
   594  	defer pool.mu.Unlock()
   595  	pool.txMu.Lock()
   596  	defer pool.txMu.Unlock()
   597  
   598  	pending := make(map[common.Address]types.Transactions)
   599  	for addr, list := range pool.pending {
   600  		pending[addr] = list.Flatten()
   601  	}
   602  	return pending, nil
   603  }
   604  
   605  // CachedPendingTxsByCount retrieves about number of currently processable transactions
   606  // by requested count, grouped by origin account and sorted by nonce.
   607  func (pool *TxPool) CachedPendingTxsByCount(count int) types.Transactions {
   608  	if count <= 0 {
   609  		return nil
   610  	}
   611  
   612  	// It retrieves the half of the requested transaction recursively for returned
   613  	// transactions much as possible.
   614  	txPerAddr := count / 2
   615  	if txPerAddr == 0 {
   616  		txPerAddr = 1
   617  	}
   618  
   619  	pending := make(types.Transactions, 0, count)
   620  
   621  	pool.mu.Lock()
   622  	defer pool.mu.Unlock()
   623  	pool.txMu.Lock()
   624  	defer pool.txMu.Unlock()
   625  
   626  	if len(pool.pending) == 0 {
   627  		return nil
   628  	}
   629  
   630  	for _, list := range pool.pending {
   631  		pendingPerAccount := list.CachedTxsFlattenByCount(txPerAddr)
   632  
   633  		pending = append(pending, pendingPerAccount...)
   634  		if len(pending) >= count {
   635  			break
   636  		}
   637  
   638  		if len(pendingPerAccount) >= txPerAddr {
   639  			if txPerAddr > 1 {
   640  				txPerAddr = txPerAddr / 2
   641  			}
   642  		}
   643  	}
   644  	return pending
   645  }
   646  
   647  // local retrieves all currently known local transactions, groupped by origin
   648  // account and sorted by nonce. The returned transaction set is a copy and can be
   649  // freely modified by calling code.
   650  func (pool *TxPool) local() map[common.Address]types.Transactions {
   651  	txs := make(map[common.Address]types.Transactions)
   652  	for addr := range pool.locals.accounts {
   653  		if pending := pool.pending[addr]; pending != nil {
   654  			txs[addr] = append(txs[addr], pending.Flatten()...)
   655  		}
   656  		if queued := pool.queue[addr]; queued != nil {
   657  			txs[addr] = append(txs[addr], queued.Flatten()...)
   658  		}
   659  	}
   660  	return txs
   661  }
   662  
   663  // validateTx checks whether a transaction is valid according to the consensus
   664  // rules and adheres to some heuristic limits of the local node (price and size).
   665  func (pool *TxPool) validateTx(tx *types.Transaction) error {
   666  	// Accept only legacy transactions until EIP-2718/2930 activates.
   667  	if !pool.rules.IsEthTxType && tx.IsEthTypedTransaction() {
   668  		return ErrTxTypeNotSupported
   669  	}
   670  	// Reject dynamic fee transactions until EIP-1559 activates.
   671  	if !pool.rules.IsEthTxType && tx.Type() == types.TxTypeEthereumDynamicFee {
   672  		return ErrTxTypeNotSupported
   673  	}
   674  
   675  	// Check whether the init code size has been exceeded
   676  	if pool.rules.IsShanghai && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize {
   677  		return fmt.Errorf("%w: code size %v, limit %v", ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize)
   678  	}
   679  
   680  	// Check chain Id first.
   681  	if tx.Protected() && tx.ChainId().Cmp(pool.chainconfig.ChainID) != 0 {
   682  		return ErrInvalidChainId
   683  	}
   684  
   685  	// NOTE-Klaytn Drop transactions with unexpected gasPrice
   686  	// If the transaction type is DynamicFee tx, Compare transaction's GasFeeCap(MaxFeePerGas) and GasTipCap with tx pool's gasPrice to check to have same value.
   687  	if tx.Type() == types.TxTypeEthereumDynamicFee {
   688  		// Sanity check for extremely large numbers
   689  		if tx.GasTipCap().BitLen() > 256 {
   690  			return ErrTipVeryHigh
   691  		}
   692  
   693  		if tx.GasFeeCap().BitLen() > 256 {
   694  			return ErrFeeCapVeryHigh
   695  		}
   696  
   697  		// Ensure gasFeeCap is greater than or equal to gasTipCap.
   698  		if tx.GasFeeCap().Cmp(tx.GasTipCap()) < 0 {
   699  			return ErrTipAboveFeeCap
   700  		}
   701  
   702  		if pool.rules.IsMagma {
   703  			// Ensure transaction's gasFeeCap is greater than or equal to transaction pool's gasPrice(baseFee).
   704  			if pool.gasPrice.Cmp(tx.GasFeeCap()) > 0 {
   705  				logger.Trace("fail to validate maxFeePerGas", "pool.gasPrice", pool.gasPrice, "maxFeePerGas", tx.GasFeeCap())
   706  				return ErrFeeCapBelowBaseFee
   707  			}
   708  		} else {
   709  
   710  			if pool.gasPrice.Cmp(tx.GasTipCap()) != 0 {
   711  				logger.Trace("fail to validate maxPriorityFeePerGas", "unitprice", pool.gasPrice, "maxPriorityFeePerGas", tx.GasFeeCap())
   712  				return ErrInvalidGasTipCap
   713  			}
   714  
   715  			if pool.gasPrice.Cmp(tx.GasFeeCap()) != 0 {
   716  				logger.Trace("fail to validate maxFeePerGas", "unitprice", pool.gasPrice, "maxFeePerGas", tx.GasTipCap())
   717  				return ErrInvalidGasFeeCap
   718  			}
   719  		}
   720  
   721  	} else {
   722  		if pool.rules.IsMagma {
   723  			if pool.gasPrice.Cmp(tx.GasPrice()) > 0 {
   724  				// Ensure transaction's gasPrice is greater than or equal to transaction pool's gasPrice(baseFee).
   725  				logger.Trace("fail to validate gasprice", "pool.gasPrice", pool.gasPrice, "tx.gasPrice", tx.GasPrice())
   726  				return ErrGasPriceBelowBaseFee
   727  			}
   728  		} else {
   729  			// Unitprice policy before magma hardfork
   730  			if pool.gasPrice.Cmp(tx.GasPrice()) != 0 {
   731  				logger.Trace("fail to validate unitprice", "unitPrice", pool.gasPrice, "txUnitPrice", tx.GasPrice())
   732  				return ErrInvalidUnitPrice
   733  			}
   734  		}
   735  	}
   736  
   737  	// Reject transactions over MaxTxDataSize to prevent DOS attacks
   738  	if uint64(tx.Size()) > MaxTxDataSize {
   739  		return ErrOversizedData
   740  	}
   741  
   742  	// Transactions can't be negative. This may never happen using RLP decoded
   743  	// transactions but may occur if you create a transaction using the RPC.
   744  	if tx.Value().Sign() < 0 {
   745  		return ErrNegativeValue
   746  	}
   747  
   748  	// Make sure the transaction is signed properly
   749  	gasFrom, err := tx.ValidateSender(pool.signer, pool.currentState, pool.currentBlockNumber)
   750  	if err != nil {
   751  		return types.ErrSender(err)
   752  	}
   753  
   754  	var (
   755  		from          = tx.ValidatedSender()
   756  		senderBalance = pool.getBalance(from)
   757  		gasFeePayer   = uint64(0)
   758  	)
   759  	// Ensure the transaction adheres to nonce ordering
   760  	if pool.getNonce(from) > tx.Nonce() {
   761  		return ErrNonceTooLow
   762  	}
   763  
   764  	// Transactor should have enough funds to cover the costs
   765  	// cost == V + GP * GL
   766  	if tx.IsFeeDelegatedTransaction() {
   767  		// balance check for fee-delegated tx
   768  		gasFeePayer, err = tx.ValidateFeePayer(pool.signer, pool.currentState, pool.currentBlockNumber)
   769  		if err != nil {
   770  			return types.ErrFeePayer(err)
   771  		}
   772  
   773  		var (
   774  			feePayer            = tx.ValidatedFeePayer()
   775  			feePayerBalance     = pool.getBalance(feePayer)
   776  			feeRatio, isRatioTx = tx.FeeRatio()
   777  		)
   778  		if isRatioTx {
   779  			// Check fee ratio range
   780  			if !feeRatio.IsValid() {
   781  				return kerrors.ErrFeeRatioOutOfRange
   782  			}
   783  
   784  			feeByFeePayer, feeBySender := types.CalcFeeWithRatio(feeRatio, tx.Fee())
   785  
   786  			if senderBalance.Cmp(new(big.Int).Add(tx.Value(), feeBySender)) < 0 {
   787  				logger.Trace("[tx_pool] insufficient funds for feeBySender", "from", from, "balance", senderBalance, "feeBySender", feeBySender)
   788  				return ErrInsufficientFundsFrom
   789  			}
   790  
   791  			if feePayerBalance.Cmp(feeByFeePayer) < 0 {
   792  				logger.Trace("[tx_pool] insufficient funds for feeByFeePayer", "feePayer", feePayer, "balance", feePayerBalance, "feeByFeePayer", feeByFeePayer)
   793  				return ErrInsufficientFundsFeePayer
   794  			}
   795  		} else {
   796  			if senderBalance.Cmp(tx.Value()) < 0 {
   797  				logger.Trace("[tx_pool] insufficient funds for cost(value)", "from", from, "balance", senderBalance, "value", tx.Value())
   798  				return ErrInsufficientFundsFrom
   799  			}
   800  
   801  			if feePayerBalance.Cmp(tx.Fee()) < 0 {
   802  				logger.Trace("[tx_pool] insufficient funds for cost(gas * price)", "feePayer", feePayer, "balance", feePayerBalance, "fee", tx.Fee())
   803  				return ErrInsufficientFundsFeePayer
   804  			}
   805  		}
   806  		// additional balance check in case of sender = feepayer
   807  		// since a single account has to bear the both cost(feepayer_cost + sender_cost),
   808  		// it is necessary to check whether the balance is equal to the sum of the cost.
   809  		if from == feePayer && senderBalance.Cmp(tx.Cost()) < 0 {
   810  			logger.Trace("[tx_pool] insufficient funds for cost(gas * price + value)", "from", from, "balance", senderBalance, "cost", tx.Cost())
   811  			return ErrInsufficientFundsFrom
   812  		}
   813  	} else {
   814  		// balance check for non-fee-delegated tx
   815  		if senderBalance.Cmp(tx.Cost()) < 0 {
   816  			logger.Trace("[tx_pool] insufficient funds for cost(gas * price + value)", "from", from, "balance", senderBalance, "cost", tx.Cost())
   817  			return ErrInsufficientFundsFrom
   818  		}
   819  	}
   820  
   821  	intrGas, err := tx.IntrinsicGas(pool.currentBlockNumber)
   822  	intrGas += gasFrom + gasFeePayer
   823  	if err != nil {
   824  		return err
   825  	}
   826  	if tx.Gas() < intrGas {
   827  		return ErrIntrinsicGas
   828  	}
   829  
   830  	// "tx.Validate()" conducts additional validation for each new txType.
   831  	// Validate humanReadable address when this tx has "true" in the humanReadable field.
   832  	// Validate accountKey when the this create or update an account
   833  	// Validate the existence of the address which will be created though this Tx
   834  	// Validate a contract account whether it is executable
   835  	if err := tx.Validate(pool.currentState, pool.currentBlockNumber); err != nil {
   836  		return err
   837  	}
   838  
   839  	return nil
   840  }
   841  
   842  // getMaxTxFromQueueWhenNonceIsMissing finds and returns a trasaction with max nonce in queue when a given Tx has missing nonce.
   843  // Otherwise it returns a given Tx itself.
   844  func (pool *TxPool) getMaxTxFromQueueWhenNonceIsMissing(tx *types.Transaction, from *common.Address) *types.Transaction {
   845  	txs := pool.queue[*from].txs
   846  
   847  	maxTx := tx
   848  	if txs.Get(tx.Nonce()) != nil {
   849  		return maxTx
   850  	}
   851  
   852  	for _, t := range txs.items {
   853  		if maxTx.Nonce() < t.Nonce() {
   854  			maxTx = t
   855  		}
   856  	}
   857  	return maxTx
   858  }
   859  
   860  // add validates a transaction and inserts it into the non-executable queue for
   861  // later pending promotion and execution. If the transaction is a replacement for
   862  // an already pending or queued one, it overwrites the previous and returns this
   863  // so outer code doesn't uselessly call promote.
   864  //
   865  // If a newly added transaction is marked as local, its sending account will be
   866  // whitelisted, preventing any associated transaction from being dropped out of
   867  // the pool due to pricing constraints.
   868  func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) {
   869  	// If the transaction is already known, discard it
   870  	hash := tx.Hash()
   871  	if pool.all.Get(hash) != nil {
   872  		logger.Trace("Discarding already known transaction", "hash", hash)
   873  		return false, fmt.Errorf("known transaction: %x", hash)
   874  	}
   875  	// If the transaction fails basic validation, discard it
   876  	if err := pool.validateTx(tx); err != nil {
   877  		logger.Trace("Discarding invalid transaction", "hash", hash, "err", err)
   878  		invalidTxCounter.Inc(1)
   879  		return false, err
   880  	}
   881  
   882  	// If the transaction pool is full and new Tx is valid,
   883  	// (1) discard a new Tx if there is no room for the account of the Tx
   884  	// (2) remove an old Tx with the largest nonce from queue to make a room for a new Tx with missing nonce
   885  	// (3) discard a new Tx if the new Tx does not have a missing nonce
   886  	// (4) discard underpriced transactions
   887  	if uint64(pool.all.Slots()+numSlots(tx)) > pool.config.ExecSlotsAll+pool.config.NonExecSlotsAll {
   888  		// (1) discard a new Tx if there is no room for the account of the Tx
   889  		from, _ := types.Sender(pool.signer, tx)
   890  		if pool.queue[from] == nil {
   891  			logger.Trace("Rejecting a new Tx, because TxPool is full and there is no room for the account", "hash", tx.Hash(), "account", from)
   892  			refusedTxCounter.Inc(1)
   893  			return false, fmt.Errorf("txpool is full: %d", uint64(pool.all.Count()))
   894  		}
   895  
   896  		maxTx := pool.getMaxTxFromQueueWhenNonceIsMissing(tx, &from)
   897  		if maxTx != tx {
   898  			// (2) remove an old Tx with the largest nonce from queue to make a room for a new Tx with missing nonce
   899  			pool.removeTx(maxTx.Hash(), true)
   900  			logger.Trace("Removing an old Tx with the max nonce to insert a new Tx with missing nonce, because TxPool is full", "account", from, "new nonce(previously missing)", tx.Nonce(), "removed max nonce", maxTx.Nonce())
   901  		} else {
   902  			// (3) discard a new Tx if the new Tx does not have a missing nonce
   903  			logger.Trace("Rejecting a new Tx, because TxPool is full and a new TX does not have missing nonce", "hash", tx.Hash())
   904  			refusedTxCounter.Inc(1)
   905  			return false, fmt.Errorf("txpool is full and the new tx does not have missing nonce: %d", uint64(pool.all.Count()))
   906  		}
   907  
   908  		// (4) discard underpriced transactions
   909  		// If the new transaction is underpriced, don't accept it
   910  		if !local && pool.priced.Underpriced(tx, pool.locals) {
   911  			logger.Trace("Discarding underpriced transaction", "hash", hash, "price", tx.GasPrice())
   912  			underpricedTxCounter.Inc(1)
   913  			return false, ErrUnderpriced
   914  		}
   915  		// New transaction is better than our worse ones, make room for it
   916  		drop := pool.priced.Discard(pool.all.Slots()-int(pool.config.ExecSlotsAll+pool.config.NonExecSlotsAll)+numSlots(tx), pool.locals)
   917  		for _, tx := range drop {
   918  			logger.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "price", tx.GasPrice())
   919  			underpricedTxCounter.Inc(1)
   920  			pool.removeTx(tx.Hash(), false)
   921  		}
   922  	}
   923  	// If the transaction is replacing an already pending one, do directly
   924  	from, _ := types.Sender(pool.signer, tx) // already validated
   925  	if list := pool.pending[from]; list != nil && list.Overlaps(tx) {
   926  		// Nonce already pending, check if required price bump is met
   927  		inserted, old := list.Add(tx, pool.config.PriceBump, pool.rules.IsMagma)
   928  		if !inserted {
   929  			pendingDiscardCounter.Inc(1)
   930  			return false, ErrAlreadyNonceExistInPool
   931  		}
   932  		// New transaction is better, replace old one
   933  		if old != nil {
   934  			pool.all.Remove(old.Hash())
   935  			pool.priced.Removed()
   936  			pendingReplaceCounter.Inc(1)
   937  		}
   938  		pool.all.Add(tx)
   939  		pool.priced.Put(tx)
   940  		pool.journalTx(from, tx)
   941  
   942  		logger.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To())
   943  
   944  		// We've directly injected a replacement transaction, notify subsystems
   945  		go pool.txFeed.Send(NewTxsEvent{types.Transactions{tx}})
   946  
   947  		return old != nil, nil
   948  	}
   949  	// New transaction isn't replacing a pending one, push into queue
   950  	replace, err := pool.enqueueTx(hash, tx)
   951  	if err != nil {
   952  		return false, err
   953  	}
   954  	// Mark local addresses and journal local transactions
   955  	if local {
   956  		pool.locals.add(from)
   957  	}
   958  	pool.journalTx(from, tx)
   959  
   960  	logger.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To())
   961  	return replace, nil
   962  }
   963  
   964  // enqueueTx inserts a new transaction into the non-executable transaction queue.
   965  //
   966  // Note, this method assumes the pool lock is held!
   967  func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction) (bool, error) {
   968  	// Try to insert the transaction into the future queue
   969  	from, _ := types.Sender(pool.signer, tx) // already validated
   970  	if pool.queue[from] == nil {
   971  		pool.queue[from] = newTxList(false)
   972  	}
   973  	inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump, pool.rules.IsMagma)
   974  	if !inserted {
   975  		// An older transaction was better, discard this
   976  		queuedDiscardCounter.Inc(1)
   977  		return false, ErrAlreadyNonceExistInPool
   978  	}
   979  	// Discard any previous transaction and mark this
   980  	if old != nil {
   981  		pool.all.Remove(old.Hash())
   982  		pool.priced.Removed()
   983  		queuedReplaceCounter.Inc(1)
   984  	}
   985  	if pool.all.Get(hash) == nil {
   986  		pool.all.Add(tx)
   987  		pool.priced.Put(tx)
   988  	}
   989  
   990  	pool.checkAndSetBeat(from)
   991  	return old != nil, nil
   992  }
   993  
   994  // journalTx adds the specified transaction to the local disk journal if it is
   995  // deemed to have been sent from a local account.
   996  func (pool *TxPool) journalTx(from common.Address, tx *types.Transaction) {
   997  	// Only journal if it's enabled and the transaction is local
   998  	if pool.journal == nil || !pool.locals.contains(from) {
   999  		return
  1000  	}
  1001  	if err := pool.journal.insert(tx); err != nil {
  1002  		logger.Error("Failed to journal local transaction", "err", err)
  1003  	}
  1004  }
  1005  
  1006  // promoteTx adds a transaction to the pending (processable) list of transactions
  1007  // and returns whether it was inserted or an older was better.
  1008  //
  1009  // Note, this method assumes the pool lock is held!
  1010  func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.Transaction) bool {
  1011  	// Try to insert the transaction into the pending queue
  1012  	if pool.pending[addr] == nil {
  1013  		pool.pending[addr] = newTxList(true)
  1014  	}
  1015  	list := pool.pending[addr]
  1016  
  1017  	inserted, old := list.Add(tx, pool.config.PriceBump, pool.rules.IsMagma)
  1018  	if !inserted {
  1019  		// An older transaction was better, discard this
  1020  		pool.all.Remove(hash)
  1021  		pool.priced.Removed()
  1022  
  1023  		pendingDiscardCounter.Inc(1)
  1024  		return false
  1025  	}
  1026  	// Otherwise discard any previous transaction and mark this
  1027  	if old != nil {
  1028  		pool.all.Remove(old.Hash())
  1029  		pool.priced.Removed()
  1030  
  1031  		pendingReplaceCounter.Inc(1)
  1032  	}
  1033  	// Failsafe to work around direct pending inserts (tests)
  1034  	if pool.all.Get(hash) == nil {
  1035  		pool.all.Add(tx)
  1036  		pool.priced.Put(tx)
  1037  	}
  1038  	// Set the potentially new pending nonce and notify any subsystems of the new tx
  1039  	pool.beats[addr] = time.Now()
  1040  	pool.setPendingNonce(addr, tx.Nonce()+1)
  1041  
  1042  	return true
  1043  }
  1044  
  1045  // HandleTxMsg transfers transactions to a channel where handleTxMsg calls AddRemotes
  1046  // to handle them. This is made not to wait from the results from TxPool.AddRemotes.
  1047  func (pool *TxPool) HandleTxMsg(txs types.Transactions) {
  1048  	if pool.config.DenyRemoteTx {
  1049  		return
  1050  	}
  1051  
  1052  	// Filter spam txs based on to-address of failed txs
  1053  	spamThrottler := GetSpamThrottler()
  1054  	if spamThrottler != nil {
  1055  		pool.mu.RLock()
  1056  		poolSize := uint64(pool.all.Count())
  1057  		pool.mu.RUnlock()
  1058  
  1059  		// Activate spam throttler when pool has enough txs
  1060  		if poolSize > uint64(spamThrottler.config.ActivateTxPoolSize) {
  1061  			allowTxs, throttleTxs := spamThrottler.classifyTxs(txs)
  1062  
  1063  			for _, tx := range throttleTxs {
  1064  				select {
  1065  				case spamThrottler.throttleCh <- tx:
  1066  				default:
  1067  					logger.Trace("drop a tx when throttleTxs channel is full", "txHash", tx.Hash())
  1068  					throttlerDropCount.Inc(1)
  1069  				}
  1070  			}
  1071  
  1072  			txs = allowTxs
  1073  		}
  1074  	}
  1075  
  1076  	// TODO-Klaytn: Consider removing the next line and move the above logic to `addTx` or `AddRemotes`
  1077  	senderCacher.recover(pool.signer, txs)
  1078  	pool.txMsgCh <- txs
  1079  }
  1080  
  1081  func (pool *TxPool) throttleLoop(spamThrottler *throttler) {
  1082  	ticker := time.Tick(time.Second)
  1083  	throttleNum := int(spamThrottler.config.ThrottleTPS)
  1084  
  1085  	for {
  1086  		select {
  1087  		case <-spamThrottler.quitCh:
  1088  			logger.Info("Stop spam throttler loop")
  1089  			return
  1090  
  1091  		case <-ticker:
  1092  			txs := types.Transactions{}
  1093  
  1094  			iterNum := len(spamThrottler.throttleCh)
  1095  			if iterNum > throttleNum {
  1096  				iterNum = throttleNum
  1097  			}
  1098  
  1099  			for i := 0; i < iterNum; i++ {
  1100  				tx := <-spamThrottler.throttleCh
  1101  				txs = append(txs, tx)
  1102  			}
  1103  
  1104  			if len(txs) > 0 {
  1105  				pool.AddRemotes(txs)
  1106  			}
  1107  		}
  1108  	}
  1109  }
  1110  
  1111  func (pool *TxPool) StartSpamThrottler(conf *ThrottlerConfig) error {
  1112  	spamThrottlerMu.Lock()
  1113  	defer spamThrottlerMu.Unlock()
  1114  
  1115  	if spamThrottler != nil {
  1116  		return errors.New("spam throttler was already running")
  1117  	}
  1118  
  1119  	if conf == nil {
  1120  		conf = DefaultSpamThrottlerConfig
  1121  	}
  1122  
  1123  	if err := validateConfig(conf); err != nil {
  1124  		return err
  1125  	}
  1126  
  1127  	t := &throttler{
  1128  		config:     conf,
  1129  		candidates: make(map[common.Address]int),
  1130  		throttled:  make(map[common.Address]int),
  1131  		allowed:    make(map[common.Address]bool),
  1132  		mu:         new(sync.RWMutex),
  1133  		threshold:  conf.InitialThreshold,
  1134  		throttleCh: make(chan *types.Transaction, conf.ThrottleTPS*5),
  1135  		quitCh:     make(chan struct{}),
  1136  	}
  1137  
  1138  	go pool.throttleLoop(t)
  1139  
  1140  	spamThrottler = t
  1141  	logger.Info("Start spam throttler", "config", *conf)
  1142  	return nil
  1143  }
  1144  
  1145  func (pool *TxPool) StopSpamThrottler() {
  1146  	spamThrottlerMu.Lock()
  1147  	defer spamThrottlerMu.Unlock()
  1148  
  1149  	if spamThrottler != nil {
  1150  		close(spamThrottler.quitCh)
  1151  	}
  1152  
  1153  	spamThrottler = nil
  1154  	candidateSizeGauge.Update(0)
  1155  	throttledSizeGauge.Update(0)
  1156  	allowedSizeGauge.Update(0)
  1157  	throttlerUpdateTimeGauge.Update(0)
  1158  	throttlerDropCount.Clear()
  1159  }
  1160  
  1161  // handleTxMsg calls TxPool.AddRemotes by retrieving transactions from TxPool.txMsgCh.
  1162  func (pool *TxPool) handleTxMsg() {
  1163  	defer pool.wg.Done()
  1164  
  1165  	for {
  1166  		select {
  1167  		case txs := <-pool.txMsgCh:
  1168  			pool.AddRemotes(txs)
  1169  		case <-pool.chainHeadSub.Err():
  1170  			return
  1171  		}
  1172  	}
  1173  }
  1174  
  1175  // AddLocal enqueues a single transaction into the pool if it is valid, marking
  1176  // the sender as a local one in the mean time, ensuring it goes around the local
  1177  // pricing constraints.
  1178  func (pool *TxPool) AddLocal(tx *types.Transaction) error {
  1179  	if tx.Type().IsChainDataAnchoring() && !pool.config.AllowLocalAnchorTx {
  1180  		return errNotAllowedAnchoringTx
  1181  	}
  1182  
  1183  	pool.mu.RLock()
  1184  	poolSize := uint64(pool.all.Count())
  1185  	pool.mu.RUnlock()
  1186  	if poolSize >= pool.config.ExecSlotsAll+pool.config.NonExecSlotsAll {
  1187  		return fmt.Errorf("txpool is full: %d", poolSize)
  1188  	}
  1189  	return pool.addTx(tx, !pool.config.NoLocals)
  1190  }
  1191  
  1192  // AddRemote enqueues a single transaction into the pool if it is valid. If the
  1193  // sender is not among the locally tracked ones, full pricing constraints will
  1194  // apply.
  1195  func (pool *TxPool) AddRemote(tx *types.Transaction) error {
  1196  	return pool.addTx(tx, false)
  1197  }
  1198  
  1199  // AddLocals enqueues a batch of transactions into the pool if they are valid,
  1200  // marking the senders as a local ones in the mean time, ensuring they go around
  1201  // the local pricing constraints.
  1202  func (pool *TxPool) AddLocals(txs []*types.Transaction) []error {
  1203  	return pool.checkAndAddTxs(txs, !pool.config.NoLocals)
  1204  }
  1205  
  1206  // AddRemotes enqueues a batch of transactions into the pool if they are valid.
  1207  // If the senders are not among the locally tracked ones, full pricing constraints
  1208  // will apply.
  1209  func (pool *TxPool) AddRemotes(txs []*types.Transaction) []error {
  1210  	return pool.checkAndAddTxs(txs, false)
  1211  }
  1212  
  1213  // checkAndAddTxs compares the size of given transactions and the capacity of TxPool.
  1214  // If given transactions exceed the capacity of TxPool, it slices the given transactions
  1215  // so it can fit into TxPool's capacity.
  1216  func (pool *TxPool) checkAndAddTxs(txs []*types.Transaction, local bool) []error {
  1217  	pool.mu.RLock()
  1218  	poolSize := uint64(pool.all.Count())
  1219  	pool.mu.RUnlock()
  1220  	poolCapacity := int(pool.config.ExecSlotsAll + pool.config.NonExecSlotsAll - poolSize)
  1221  	numTxs := len(txs)
  1222  
  1223  	if poolCapacity < numTxs {
  1224  		txs = txs[:poolCapacity]
  1225  	}
  1226  
  1227  	errs := pool.addTxs(txs, local)
  1228  
  1229  	if poolCapacity < numTxs {
  1230  		for i := 0; i < numTxs-poolCapacity; i++ {
  1231  			errs = append(errs, txPoolIsFullErr)
  1232  		}
  1233  	}
  1234  
  1235  	return errs
  1236  }
  1237  
  1238  // addTx enqueues a single transaction into the pool if it is valid.
  1239  func (pool *TxPool) addTx(tx *types.Transaction, local bool) error {
  1240  	senderCacher.recover(pool.signer, []*types.Transaction{tx})
  1241  
  1242  	pool.mu.Lock()
  1243  	defer pool.mu.Unlock()
  1244  
  1245  	// Try to inject the transaction and update any state
  1246  	replace, err := pool.add(tx, local)
  1247  	if err != nil {
  1248  		return err
  1249  	}
  1250  	// If we added a new transaction, run promotion checks and return
  1251  	if !replace {
  1252  		from, _ := types.Sender(pool.signer, tx) // already validated
  1253  		pool.promoteExecutables([]common.Address{from})
  1254  	}
  1255  	return nil
  1256  }
  1257  
  1258  // addTxs attempts to queue a batch of transactions if they are valid.
  1259  func (pool *TxPool) addTxs(txs []*types.Transaction, local bool) []error {
  1260  	senderCacher.recover(pool.signer, txs)
  1261  
  1262  	pool.mu.Lock()
  1263  	defer pool.mu.Unlock()
  1264  
  1265  	return pool.addTxsLocked(txs, local)
  1266  }
  1267  
  1268  // addTxsLocked attempts to queue a batch of transactions if they are valid,
  1269  // whilst assuming the transaction pool lock is already held.
  1270  func (pool *TxPool) addTxsLocked(txs []*types.Transaction, local bool) []error {
  1271  	// Add the batch of transaction, tracking the accepted ones
  1272  	dirty := make(map[common.Address]struct{})
  1273  	errs := make([]error, len(txs))
  1274  
  1275  	for i, tx := range txs {
  1276  		var replace bool
  1277  		if replace, errs[i] = pool.add(tx, local); errs[i] == nil {
  1278  			if !replace {
  1279  				from, _ := types.Sender(pool.signer, tx) // already validated
  1280  				dirty[from] = struct{}{}
  1281  			}
  1282  		}
  1283  	}
  1284  
  1285  	// Only reprocess the internal state if something was actually added
  1286  	if len(dirty) > 0 {
  1287  		addrs := make([]common.Address, 0, len(dirty))
  1288  		for addr := range dirty {
  1289  			addrs = append(addrs, addr)
  1290  		}
  1291  		pool.promoteExecutables(addrs)
  1292  	}
  1293  	return errs
  1294  }
  1295  
  1296  // Status returns the status (unknown/pending/queued) of a batch of transactions
  1297  // identified by their hashes.
  1298  func (pool *TxPool) Status(hashes []common.Hash) []TxStatus {
  1299  	pool.mu.RLock()
  1300  	defer pool.mu.RUnlock()
  1301  
  1302  	status := make([]TxStatus, len(hashes))
  1303  	for i, hash := range hashes {
  1304  		if tx := pool.all.Get(hash); tx != nil {
  1305  			from, _ := types.Sender(pool.signer, tx) // already validated
  1306  			if pool.pending[from] != nil && pool.pending[from].txs.items[tx.Nonce()] != nil {
  1307  				status[i] = TxStatusPending
  1308  			} else {
  1309  				status[i] = TxStatusQueued
  1310  			}
  1311  		}
  1312  	}
  1313  	return status
  1314  }
  1315  
  1316  // Get returns a transaction if it is contained in the pool
  1317  // and nil otherwise.
  1318  func (pool *TxPool) Get(hash common.Hash) *types.Transaction {
  1319  	return pool.all.Get(hash)
  1320  }
  1321  
  1322  // checkAndSetBeat sets the beat of the account if there is no beat of the account.
  1323  func (pool *TxPool) checkAndSetBeat(addr common.Address) {
  1324  	_, exist := pool.beats[addr]
  1325  
  1326  	if !exist {
  1327  		pool.beats[addr] = time.Now()
  1328  	}
  1329  }
  1330  
  1331  // removeTx removes a single transaction from the queue, moving all subsequent
  1332  // transactions back to the future queue.
  1333  func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) {
  1334  	// Fetch the transaction we wish to delete
  1335  	tx := pool.all.Get(hash)
  1336  	if tx == nil {
  1337  		return
  1338  	}
  1339  	addr, _ := types.Sender(pool.signer, tx) // already validated during insertion
  1340  
  1341  	// Remove it from the list of known transactions
  1342  	pool.all.Remove(hash)
  1343  	if outofbound {
  1344  		pool.priced.Removed()
  1345  	}
  1346  	// Remove the transaction from the pending lists and reset the account nonce
  1347  	if pending := pool.pending[addr]; pending != nil {
  1348  		if removed, invalids := pending.Remove(tx); removed {
  1349  			// If no more pending transactions are left, remove the list
  1350  			if pending.Empty() {
  1351  				delete(pool.pending, addr)
  1352  			}
  1353  			// Postpone any invalidated transactions
  1354  			for _, tx := range invalids {
  1355  				pool.enqueueTx(tx.Hash(), tx)
  1356  			}
  1357  			pool.updatePendingNonce(addr, tx.Nonce())
  1358  			return
  1359  		}
  1360  	}
  1361  	// Transaction is in the future queue
  1362  	if future := pool.queue[addr]; future != nil {
  1363  		future.Remove(tx)
  1364  		if future.Empty() {
  1365  			delete(pool.queue, addr)
  1366  		}
  1367  	}
  1368  }
  1369  
  1370  // promoteExecutables moves transactions that have become processable from the
  1371  // future queue to the set of pending transactions. During this process, all
  1372  // invalidated transactions (low nonce, low balance) are deleted.
  1373  func (pool *TxPool) promoteExecutables(accounts []common.Address) {
  1374  	pool.txMu.Lock()
  1375  	defer pool.txMu.Unlock()
  1376  	// Track the promoted transactions to broadcast them at once
  1377  	var promoted []*types.Transaction
  1378  
  1379  	// Gather all the accounts potentially needing updates
  1380  	if accounts == nil {
  1381  		accounts = make([]common.Address, 0, len(pool.queue))
  1382  		for addr := range pool.queue {
  1383  			accounts = append(accounts, addr)
  1384  		}
  1385  	}
  1386  
  1387  	// Iterate over all accounts and promote any executable transactions
  1388  	for _, addr := range accounts {
  1389  		list := pool.queue[addr]
  1390  		if list == nil {
  1391  			continue // Just in case someone calls with a non existing account
  1392  		}
  1393  		// Drop all transactions that are deemed too old (low nonce)
  1394  		for _, tx := range list.Forward(pool.getNonce(addr)) {
  1395  			hash := tx.Hash()
  1396  			logger.Trace("Removed old queued transaction", "hash", hash)
  1397  			pool.all.Remove(hash)
  1398  			pool.priced.Removed()
  1399  		}
  1400  		// Drop all transactions that are too costly (low balance)
  1401  		drops, _ := list.Filter(addr, pool)
  1402  		for _, tx := range drops {
  1403  			hash := tx.Hash()
  1404  			logger.Trace("Removed unpayable queued transaction", "hash", hash)
  1405  			pool.all.Remove(hash)
  1406  			pool.priced.Removed()
  1407  			queuedNofundsCounter.Inc(1)
  1408  		}
  1409  
  1410  		// Gather all executable transactions and promote them
  1411  		var readyTxs types.Transactions
  1412  		if pool.rules.IsMagma {
  1413  			readyTxs = list.ReadyWithGasPrice(pool.getPendingNonce(addr), pool.gasPrice)
  1414  		} else {
  1415  			readyTxs = list.Ready(pool.getPendingNonce(addr))
  1416  		}
  1417  		for _, tx := range readyTxs {
  1418  			hash := tx.Hash()
  1419  			if pool.promoteTx(addr, hash, tx) {
  1420  				logger.Trace("Promoting queued transaction", "hash", hash)
  1421  				promoted = append(promoted, tx)
  1422  			}
  1423  		}
  1424  
  1425  		// Drop all transactions over the allowed limit
  1426  		if !pool.locals.contains(addr) {
  1427  			for _, tx := range list.Cap(int(pool.config.NonExecSlotsAccount)) {
  1428  				hash := tx.Hash()
  1429  				pool.all.Remove(hash)
  1430  				pool.priced.Removed()
  1431  				queuedRateLimitCounter.Inc(1)
  1432  				logger.Trace("Removed cap-exceeding queued transaction", "hash", hash)
  1433  			}
  1434  		}
  1435  		// Delete the entire queue entry if it became empty.
  1436  		if list.Empty() {
  1437  			delete(pool.queue, addr)
  1438  		}
  1439  	}
  1440  	// Notify subsystem for new promoted transactions.
  1441  	if len(promoted) > 0 {
  1442  		pool.txFeed.Send(NewTxsEvent{promoted})
  1443  	}
  1444  	// If the pending limit is overflown, start equalizing allowances
  1445  	pending := uint64(0)
  1446  	for _, list := range pool.pending {
  1447  		pending += uint64(list.Len())
  1448  	}
  1449  
  1450  	if pending > pool.config.ExecSlotsAll {
  1451  		pendingBeforeCap := pending
  1452  		// Assemble a spam order to penalize large transactors first
  1453  		spammers := prque.New()
  1454  		for addr, list := range pool.pending {
  1455  			// Only evict transactions from high rollers
  1456  			if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.ExecSlotsAccount {
  1457  				spammers.Push(addr, int64(list.Len()))
  1458  			}
  1459  		}
  1460  		// Gradually drop transactions from offenders
  1461  		offenders := []common.Address{}
  1462  		for pending > pool.config.ExecSlotsAll && !spammers.Empty() {
  1463  			// Retrieve the next offender if not local address
  1464  			offender, _ := spammers.Pop()
  1465  			offenders = append(offenders, offender.(common.Address))
  1466  
  1467  			// Equalize balances until all the same or below threshold
  1468  			if len(offenders) > 1 {
  1469  				// Calculate the equalization threshold for all current offenders
  1470  				threshold := pool.pending[offender.(common.Address)].Len()
  1471  
  1472  				// Iteratively reduce all offenders until below limit or threshold reached
  1473  				for pending > pool.config.ExecSlotsAll && pool.pending[offenders[len(offenders)-2]].Len() > threshold {
  1474  					for i := 0; i < len(offenders)-1; i++ {
  1475  						list := pool.pending[offenders[i]]
  1476  						for _, tx := range list.Cap(list.Len() - 1) {
  1477  							// Drop the transaction from the global pools too
  1478  							hash := tx.Hash()
  1479  							pool.all.Remove(hash)
  1480  							pool.priced.Removed()
  1481  
  1482  							// Update the account nonce to the dropped transaction
  1483  							pool.updatePendingNonce(offenders[i], tx.Nonce())
  1484  							logger.Trace("Removed fairness-exceeding pending transaction", "hash", hash)
  1485  						}
  1486  						pending--
  1487  					}
  1488  				}
  1489  			}
  1490  		}
  1491  		// If still above threshold, reduce to limit or min allowance
  1492  		if pending > pool.config.ExecSlotsAll && len(offenders) > 0 {
  1493  			for pending > pool.config.ExecSlotsAll && uint64(pool.pending[offenders[len(offenders)-1]].Len()) > pool.config.ExecSlotsAccount {
  1494  				for _, addr := range offenders {
  1495  					list := pool.pending[addr]
  1496  					for _, tx := range list.Cap(list.Len() - 1) {
  1497  						// Drop the transaction from the global pools too
  1498  						hash := tx.Hash()
  1499  						pool.all.Remove(hash)
  1500  						pool.priced.Removed()
  1501  
  1502  						// Update the account nonce to the dropped transaction
  1503  						pool.updatePendingNonce(addr, tx.Nonce())
  1504  						logger.Trace("Removed fairness-exceeding pending transaction", "hash", hash)
  1505  					}
  1506  					pending--
  1507  				}
  1508  			}
  1509  		}
  1510  		pendingRateLimitCounter.Inc(int64(pendingBeforeCap - pending))
  1511  	}
  1512  	// If we've queued more transactions than the hard limit, drop oldest ones
  1513  	queued := uint64(0)
  1514  	for _, list := range pool.queue {
  1515  		queued += uint64(list.Len())
  1516  	}
  1517  
  1518  	if queued > pool.config.NonExecSlotsAll {
  1519  		// Sort all accounts with queued transactions by heartbeat
  1520  		addresses := make(addresssByHeartbeat, 0, len(pool.queue))
  1521  		for addr := range pool.queue {
  1522  			if !pool.locals.contains(addr) { // don't drop locals
  1523  				addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]})
  1524  			}
  1525  		}
  1526  		sort.Sort(addresses)
  1527  
  1528  		// Drop transactions until the total is below the limit or only locals remain
  1529  		for drop := queued - pool.config.NonExecSlotsAll; drop > 0 && len(addresses) > 0; {
  1530  			addr := addresses[len(addresses)-1]
  1531  			list := pool.queue[addr.address]
  1532  
  1533  			addresses = addresses[:len(addresses)-1]
  1534  
  1535  			// Drop all transactions if they are less than the overflow
  1536  			if size := uint64(list.Len()); size <= drop {
  1537  				for _, tx := range list.Flatten() {
  1538  					pool.removeTx(tx.Hash(), true)
  1539  				}
  1540  				drop -= size
  1541  				queuedRateLimitCounter.Inc(int64(size))
  1542  				continue
  1543  			}
  1544  			// Otherwise drop only last few transactions
  1545  			txs := list.Flatten()
  1546  			for i := len(txs) - 1; i >= 0 && drop > 0; i-- {
  1547  				pool.removeTx(txs[i].Hash(), true)
  1548  				drop--
  1549  				queuedRateLimitCounter.Inc(1)
  1550  			}
  1551  		}
  1552  	}
  1553  }
  1554  
  1555  // demoteUnexecutables removes invalid and processed transactions from the pools
  1556  // executable/pending queue and any subsequent transactions that become unexecutable
  1557  // are moved back into the future queue.
  1558  func (pool *TxPool) demoteUnexecutables() {
  1559  	pool.txMu.Lock()
  1560  	defer pool.txMu.Unlock()
  1561  
  1562  	// full-validation count. demoteUnexecutables does full-validation for a limited number of txs.
  1563  	cnt := 0
  1564  	// Iterate over all accounts and demote any non-executable transactions
  1565  	for addr, list := range pool.pending {
  1566  		nonce := pool.getNonce(addr)
  1567  		var drops, invalids types.Transactions
  1568  
  1569  		// Drop all transactions that are deemed too old (low nonce)
  1570  		for _, tx := range list.Forward(nonce) {
  1571  			hash := tx.Hash()
  1572  			logger.Trace("Removed old pending transaction", "hash", hash)
  1573  			pool.all.Remove(hash)
  1574  			pool.priced.Removed()
  1575  		}
  1576  
  1577  		// demoteUnexecutables does full-validation for a limited number of txs. Otherwise, it only validate nonce.
  1578  		// The logic below loosely checks the tx count for the efficiency and the simplicity.
  1579  		if cnt < demoteUnexecutablesFullValidationTxLimit {
  1580  			cnt += list.Len()
  1581  			drops, invalids = list.Filter(addr, pool)
  1582  		} else {
  1583  			drops, invalids = list.FilterUnexecutable()
  1584  		}
  1585  
  1586  		// Drop all transactions that are unexecutable, and queue any invalids back for later
  1587  		for _, tx := range drops {
  1588  			hash := tx.Hash()
  1589  			logger.Trace("Removed unexecutable pending transaction", "hash", hash)
  1590  			pool.all.Remove(hash)
  1591  			pool.priced.Removed()
  1592  			pendingNofundsCounter.Inc(1)
  1593  		}
  1594  
  1595  		for _, tx := range invalids {
  1596  			hash := tx.Hash()
  1597  			logger.Trace("Demoting pending transaction", "hash", hash)
  1598  			pool.enqueueTx(hash, tx)
  1599  		}
  1600  		// If there's a gap in front, warn (should never happen) and postpone all transactions
  1601  		if list.Len() > 0 && list.txs.Get(nonce) == nil {
  1602  			for _, tx := range list.Cap(0) {
  1603  				hash := tx.Hash()
  1604  				logger.Error("Demoting invalidated transaction", "hash", hash)
  1605  				pool.enqueueTx(hash, tx)
  1606  			}
  1607  		}
  1608  
  1609  		// Enqueue transaction if gasPrice of transaction is lower than gasPrice of txPool.
  1610  		// All transactions with a nonce greater than enqueued transaction also stored queue.
  1611  		if pool.rules.IsMagma && list.Len() > 0 {
  1612  			for _, tx := range list.Flatten() {
  1613  				hash := tx.Hash()
  1614  				if tx.GasPrice().Cmp(pool.gasPrice) < 0 {
  1615  					logger.Trace("Demoting the tx that is lower than the baseFee and those greater than the nonce of the tx.", "txhash", hash)
  1616  					removed, invalids := list.Remove(tx) // delete all transactions satisfying the nonce value > tx.Nonce()
  1617  					if removed {
  1618  						for _, invalidTx := range invalids {
  1619  							pool.enqueueTx(invalidTx.Hash(), invalidTx)
  1620  						}
  1621  						pool.enqueueTx(hash, tx)
  1622  					}
  1623  					break
  1624  				}
  1625  			}
  1626  		}
  1627  
  1628  		// Delete the entire queue entry if it became empty.
  1629  		if list.Empty() {
  1630  			delete(pool.pending, addr)
  1631  		}
  1632  	}
  1633  }
  1634  
  1635  // getNonce returns the nonce of the account from the cache. If it is not in the cache, it gets the nonce from the stateDB.
  1636  func (pool *TxPool) getNonce(addr common.Address) uint64 {
  1637  	return pool.currentState.GetNonce(addr)
  1638  }
  1639  
  1640  // getBalance returns the balance of the account from the cache. If it is not in the cache, it gets the balance from the stateDB.
  1641  func (pool *TxPool) getBalance(addr common.Address) *big.Int {
  1642  	return pool.currentState.GetBalance(addr)
  1643  }
  1644  
  1645  // GetPendingNonce is a method to check the last nonce value of pending in external API.
  1646  // Use getPendingNonce to get the nonce value inside txpool because it catches the lock.
  1647  func (pool *TxPool) GetPendingNonce(addr common.Address) uint64 {
  1648  	pool.mu.Lock()
  1649  	defer pool.mu.Unlock()
  1650  
  1651  	return pool.getPendingNonce(addr)
  1652  }
  1653  
  1654  // getPendingNonce returns the canonical nonce for the managed or unmanaged account.
  1655  func (pool *TxPool) getPendingNonce(addr common.Address) uint64 {
  1656  	cNonce := pool.getNonce(addr)
  1657  	if pNonce, exist := pool.pendingNonce[addr]; !exist || pNonce < cNonce {
  1658  		pool.pendingNonce[addr] = cNonce
  1659  	}
  1660  
  1661  	return pool.pendingNonce[addr]
  1662  }
  1663  
  1664  // setPendingNonce sets the new canonical nonce for the managed state.
  1665  func (pool *TxPool) setPendingNonce(addr common.Address, nonce uint64) {
  1666  	pool.pendingNonce[addr] = nonce
  1667  }
  1668  
  1669  // updatePendingNonce updates the account nonce to the dropped transaction.
  1670  func (pool *TxPool) updatePendingNonce(addr common.Address, nonce uint64) {
  1671  	if pool.getPendingNonce(addr) > nonce {
  1672  		pool.setPendingNonce(addr, nonce)
  1673  	}
  1674  }
  1675  
  1676  // addressByHeartbeat is an account address tagged with its last activity timestamp.
  1677  type addressByHeartbeat struct {
  1678  	address   common.Address
  1679  	heartbeat time.Time
  1680  }
  1681  
  1682  type addresssByHeartbeat []addressByHeartbeat
  1683  
  1684  func (a addresssByHeartbeat) Len() int           { return len(a) }
  1685  func (a addresssByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) }
  1686  func (a addresssByHeartbeat) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
  1687  
  1688  // accountSet is simply a set of addresses to check for existence, and a signer
  1689  // capable of deriving addresses from transactions.
  1690  type accountSet struct {
  1691  	accounts map[common.Address]struct{}
  1692  	signer   types.Signer
  1693  }
  1694  
  1695  // newAccountSet creates a new address set with an associated signer for sender
  1696  // derivations.
  1697  func newAccountSet(signer types.Signer) *accountSet {
  1698  	return &accountSet{
  1699  		accounts: make(map[common.Address]struct{}),
  1700  		signer:   signer,
  1701  	}
  1702  }
  1703  
  1704  // contains checks if a given address is contained within the set.
  1705  func (as *accountSet) contains(addr common.Address) bool {
  1706  	_, exist := as.accounts[addr]
  1707  	return exist
  1708  }
  1709  
  1710  // containsTx checks if the sender of a given tx is within the set. If the sender
  1711  // cannot be derived, this method returns false.
  1712  func (as *accountSet) containsTx(tx *types.Transaction) bool {
  1713  	if addr, err := types.Sender(as.signer, tx); err == nil {
  1714  		return as.contains(addr)
  1715  	}
  1716  	return false
  1717  }
  1718  
  1719  // add inserts a new address into the set to track.
  1720  func (as *accountSet) add(addr common.Address) {
  1721  	as.accounts[addr] = struct{}{}
  1722  }
  1723  
  1724  // txLookup is used internally by TxPool to track transactions while allowing lookup without
  1725  // mutex contention.
  1726  //
  1727  // Note, although this type is properly protected against concurrent access, it
  1728  // is **not** a type that should ever be mutated or even exposed outside of the
  1729  // transaction pool, since its internal state is tightly coupled with the pools
  1730  // internal mechanisms. The sole purpose of the type is to permit out-of-bound
  1731  // peeking into the pool in TxPool.Get without having to acquire the widely scoped
  1732  // TxPool.mu mutex.
  1733  type txLookup struct {
  1734  	all   map[common.Hash]*types.Transaction
  1735  	slots int
  1736  	lock  sync.RWMutex
  1737  }
  1738  
  1739  // newTxLookup returns a new txLookup structure.
  1740  func newTxLookup() *txLookup {
  1741  	slotsGauge.Update(int64(0))
  1742  	return &txLookup{
  1743  		all: make(map[common.Hash]*types.Transaction),
  1744  	}
  1745  }
  1746  
  1747  // Slots returns the current number of slots used in the lookup.
  1748  func (t *txLookup) Slots() int {
  1749  	t.lock.RLock()
  1750  	defer t.lock.RUnlock()
  1751  
  1752  	return t.slots
  1753  }
  1754  
  1755  // Range calls f on each key and value present in the map.
  1756  func (t *txLookup) Range(f func(hash common.Hash, tx *types.Transaction) bool) {
  1757  	t.lock.RLock()
  1758  	defer t.lock.RUnlock()
  1759  
  1760  	for key, value := range t.all {
  1761  		if !f(key, value) {
  1762  			break
  1763  		}
  1764  	}
  1765  }
  1766  
  1767  // Get returns a transaction if it exists in the lookup, or nil if not found.
  1768  func (t *txLookup) Get(hash common.Hash) *types.Transaction {
  1769  	t.lock.RLock()
  1770  	defer t.lock.RUnlock()
  1771  
  1772  	return t.all[hash]
  1773  }
  1774  
  1775  // Count returns the current number of items in the lookup.
  1776  func (t *txLookup) Count() int {
  1777  	t.lock.RLock()
  1778  	defer t.lock.RUnlock()
  1779  
  1780  	return len(t.all)
  1781  }
  1782  
  1783  // Add adds a transaction to the lookup.
  1784  func (t *txLookup) Add(tx *types.Transaction) {
  1785  	t.lock.Lock()
  1786  	defer t.lock.Unlock()
  1787  
  1788  	t.slots += numSlots(tx)
  1789  	slotsGauge.Update(int64(t.slots))
  1790  
  1791  	t.all[tx.Hash()] = tx
  1792  }
  1793  
  1794  // Remove removes a transaction from the lookup.
  1795  func (t *txLookup) Remove(hash common.Hash) {
  1796  	t.lock.Lock()
  1797  	defer t.lock.Unlock()
  1798  
  1799  	t.slots -= numSlots(t.all[hash])
  1800  	slotsGauge.Update(int64(t.slots))
  1801  
  1802  	delete(t.all, hash)
  1803  }
  1804  
  1805  // numSlots calculates the number of slots needed for a single transaction.
  1806  func numSlots(tx *types.Transaction) int {
  1807  	return int((tx.Size() + txSlotSize - 1) / txSlotSize)
  1808  }