github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/core/tx_pool.go (about)

     1  package core
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"math"
     7  	"math/big"
     8  	"sort"
     9  	"sync"
    10  	"time"
    11  
    12  	"github.com/neatlab/neatio/chain/core/state"
    13  	"github.com/neatlab/neatio/chain/core/types"
    14  	"github.com/neatlab/neatio/chain/log"
    15  	neatAbi "github.com/neatlab/neatio/neatabi/abi"
    16  	"github.com/neatlab/neatio/params"
    17  	"github.com/neatlab/neatio/utilities/common"
    18  	"github.com/neatlab/neatio/utilities/common/prque"
    19  	"github.com/neatlab/neatio/utilities/event"
    20  	"github.com/neatlab/neatio/utilities/metrics"
    21  )
    22  
    23  const (
    24  	chainHeadChanSize = 10
    25  )
    26  
    27  var (
    28  	ErrInvalidSender = errors.New("invalid sender")
    29  
    30  	ErrInvalidAddress = errors.New("invalid address")
    31  
    32  	ErrNonceTooLow = errors.New("nonce too low")
    33  
    34  	ErrUnderpriced = errors.New("transaction underpriced")
    35  
    36  	ErrReplaceUnderpriced = errors.New("replacement transaction underpriced")
    37  
    38  	ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value")
    39  
    40  	ErrIntrinsicGas = errors.New("intrinsic gas too low")
    41  
    42  	ErrGasLimit = errors.New("exceeds block gas limit")
    43  
    44  	ErrNegativeValue = errors.New("negative value")
    45  
    46  	ErrOversizedData = errors.New("oversized data")
    47  )
    48  
    49  var (
    50  	evictionInterval    = time.Minute
    51  	statsReportInterval = 8 * time.Second
    52  )
    53  
    54  var (
    55  	pendingDiscardCounter   = metrics.NewRegisteredCounter("txpool/pending/discard", nil)
    56  	pendingReplaceCounter   = metrics.NewRegisteredCounter("txpool/pending/replace", nil)
    57  	pendingRateLimitCounter = metrics.NewRegisteredCounter("txpool/pending/ratelimit", nil)
    58  	pendingNofundsCounter   = metrics.NewRegisteredCounter("txpool/pending/nofunds", nil)
    59  
    60  	queuedDiscardCounter   = metrics.NewRegisteredCounter("txpool/queued/discard", nil)
    61  	queuedReplaceCounter   = metrics.NewRegisteredCounter("txpool/queued/replace", nil)
    62  	queuedRateLimitCounter = metrics.NewRegisteredCounter("txpool/queued/ratelimit", nil)
    63  	queuedNofundsCounter   = metrics.NewRegisteredCounter("txpool/queued/nofunds", nil)
    64  
    65  	invalidTxCounter     = metrics.NewRegisteredCounter("txpool/invalid", nil)
    66  	underpricedTxCounter = metrics.NewRegisteredCounter("txpool/underpriced", nil)
    67  )
    68  
    69  type TxStatus uint
    70  
    71  const (
    72  	TxStatusUnknown TxStatus = iota
    73  	TxStatusQueued
    74  	TxStatusPending
    75  	TxStatusIncluded
    76  )
    77  
    78  type blockChain interface {
    79  	CurrentBlock() *types.Block
    80  	GetBlock(hash common.Hash, number uint64) *types.Block
    81  	StateAt(root common.Hash) (*state.StateDB, error)
    82  
    83  	SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription
    84  }
    85  
    86  type TxPoolConfig struct {
    87  	NoLocals  bool
    88  	Journal   string
    89  	Rejournal time.Duration
    90  
    91  	PriceLimit uint64
    92  	PriceBump  uint64
    93  
    94  	AccountSlots uint64
    95  	GlobalSlots  uint64
    96  	AccountQueue uint64
    97  	GlobalQueue  uint64
    98  
    99  	Lifetime time.Duration
   100  }
   101  
   102  var DefaultTxPoolConfig = TxPoolConfig{
   103  	Journal:   "transactions.rlp",
   104  	Rejournal: time.Hour,
   105  
   106  	PriceLimit: 1,
   107  	PriceBump:  10,
   108  
   109  	AccountSlots: 16,
   110  	GlobalSlots:  4096,
   111  	AccountQueue: 64,
   112  	GlobalQueue:  1024,
   113  
   114  	Lifetime: 3 * time.Hour,
   115  }
   116  
   117  func (config *TxPoolConfig) sanitize() TxPoolConfig {
   118  	conf := *config
   119  	if conf.Rejournal < time.Second {
   120  		log.Warn("Sanitizing invalid txpool journal time", "provided", conf.Rejournal, "updated", time.Second)
   121  		conf.Rejournal = time.Second
   122  	}
   123  	if conf.PriceLimit < 1 {
   124  		log.Warn("Sanitizing invalid txpool price limit", "provided", conf.PriceLimit, "updated", DefaultTxPoolConfig.PriceLimit)
   125  		conf.PriceLimit = DefaultTxPoolConfig.PriceLimit
   126  	}
   127  	if conf.PriceBump < 1 {
   128  		log.Warn("Sanitizing invalid txpool price bump", "provided", conf.PriceBump, "updated", DefaultTxPoolConfig.PriceBump)
   129  		conf.PriceBump = DefaultTxPoolConfig.PriceBump
   130  	}
   131  	return conf
   132  }
   133  
   134  type TxPool struct {
   135  	config       TxPoolConfig
   136  	chainconfig  *params.ChainConfig
   137  	chain        blockChain
   138  	gasPrice     *big.Int
   139  	txFeed       event.Feed
   140  	scope        event.SubscriptionScope
   141  	chainHeadCh  chan ChainHeadEvent
   142  	chainHeadSub event.Subscription
   143  	signer       types.Signer
   144  	mu           sync.RWMutex
   145  
   146  	currentState  *state.StateDB
   147  	pendingState  *state.ManagedState
   148  	currentMaxGas uint64
   149  
   150  	locals  *accountSet
   151  	journal *txJournal
   152  
   153  	pending map[common.Address]*txList
   154  	queue   map[common.Address]*txList
   155  	beats   map[common.Address]time.Time
   156  	all     map[common.Hash]*types.Transaction
   157  	priced  *txPricedList
   158  
   159  	wg sync.WaitGroup
   160  
   161  	cch CrossChainHelper
   162  }
   163  
   164  var TxPoolSigner types.Signer = nil
   165  
   166  func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain, cch CrossChainHelper) *TxPool {
   167  
   168  	config = (&config).sanitize()
   169  
   170  	pool := &TxPool{
   171  		config:      config,
   172  		chainconfig: chainconfig,
   173  		chain:       chain,
   174  		signer:      types.NewEIP155Signer(chainconfig.ChainId),
   175  		pending:     make(map[common.Address]*txList),
   176  		queue:       make(map[common.Address]*txList),
   177  		beats:       make(map[common.Address]time.Time),
   178  		all:         make(map[common.Hash]*types.Transaction),
   179  		chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize),
   180  		gasPrice:    new(big.Int).SetUint64(config.PriceLimit),
   181  		cch:         cch,
   182  	}
   183  	pool.locals = newAccountSet(pool.signer)
   184  	pool.priced = newTxPricedList(&pool.all)
   185  	pool.reset(nil, chain.CurrentBlock().Header())
   186  
   187  	if !config.NoLocals && config.Journal != "" {
   188  		pool.journal = newTxJournal(config.Journal)
   189  
   190  		log.Debug("Load transaction journal", "journal", pool.journal)
   191  		if err := pool.journal.load(pool.AddLocal); err != nil {
   192  			log.Warn("Failed to load transaction journal", "err", err)
   193  		}
   194  		if err := pool.journal.rotate(pool.local()); err != nil {
   195  			log.Warn("Failed to rotate transaction journal", "err", err)
   196  		}
   197  	}
   198  
   199  	TxPoolSigner = pool.signer
   200  
   201  	pool.chainHeadSub = pool.chain.SubscribeChainHeadEvent(pool.chainHeadCh)
   202  
   203  	pool.wg.Add(1)
   204  	go pool.loop()
   205  
   206  	return pool
   207  }
   208  
   209  func (pool *TxPool) loop() {
   210  	defer pool.wg.Done()
   211  
   212  	var prevPending, prevQueued, prevStales int
   213  
   214  	report := time.NewTicker(statsReportInterval)
   215  	defer report.Stop()
   216  
   217  	evict := time.NewTicker(evictionInterval)
   218  	defer evict.Stop()
   219  
   220  	journal := time.NewTicker(pool.config.Rejournal)
   221  	defer journal.Stop()
   222  
   223  	head := pool.chain.CurrentBlock()
   224  
   225  	for {
   226  		select {
   227  
   228  		case ev := <-pool.chainHeadCh:
   229  			if ev.Block != nil {
   230  				pool.mu.Lock()
   231  				pool.reset(head.Header(), ev.Block.Header())
   232  				head = ev.Block
   233  				pool.mu.Unlock()
   234  			}
   235  
   236  		case <-pool.chainHeadSub.Err():
   237  			return
   238  
   239  		case <-report.C:
   240  			pool.mu.RLock()
   241  			pending, queued := pool.stats()
   242  			stales := pool.priced.stales
   243  			pool.mu.RUnlock()
   244  
   245  			if pending != prevPending || queued != prevQueued || stales != prevStales {
   246  				log.Debug("Transaction pool status report", "executable", pending, "queued", queued, "stales", stales)
   247  				prevPending, prevQueued, prevStales = pending, queued, stales
   248  			}
   249  
   250  		case <-evict.C:
   251  			pool.mu.Lock()
   252  			for addr := range pool.queue {
   253  
   254  				if pool.locals.contains(addr) {
   255  					continue
   256  				}
   257  
   258  				if time.Since(pool.beats[addr]) > pool.config.Lifetime {
   259  					for _, tx := range pool.queue[addr].Flatten() {
   260  						pool.removeTx(tx.Hash())
   261  					}
   262  				}
   263  			}
   264  			pool.mu.Unlock()
   265  
   266  		case <-journal.C:
   267  			if pool.journal != nil {
   268  				pool.mu.Lock()
   269  				if err := pool.journal.rotate(pool.local()); err != nil {
   270  					log.Warn("Failed to rotate local tx journal", "err", err)
   271  				}
   272  				pool.mu.Unlock()
   273  			}
   274  		}
   275  	}
   276  }
   277  
   278  func (pool *TxPool) lockedReset(oldHead, newHead *types.Header) {
   279  	pool.mu.Lock()
   280  	defer pool.mu.Unlock()
   281  
   282  	pool.reset(oldHead, newHead)
   283  }
   284  
   285  func (pool *TxPool) reset(oldHead, newHead *types.Header) {
   286  
   287  	var reinject types.Transactions
   288  
   289  	if oldHead != nil && oldHead.Hash() != newHead.ParentHash {
   290  
   291  		oldNum := oldHead.Number.Uint64()
   292  		newNum := newHead.Number.Uint64()
   293  
   294  		if depth := uint64(math.Abs(float64(oldNum) - float64(newNum))); depth > 64 {
   295  			log.Debug("Skipping deep transaction reorg", "depth", depth)
   296  		} else {
   297  
   298  			var discarded, included types.Transactions
   299  
   300  			var (
   301  				rem = pool.chain.GetBlock(oldHead.Hash(), oldHead.Number.Uint64())
   302  				add = pool.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64())
   303  			)
   304  			for rem.NumberU64() > add.NumberU64() {
   305  				discarded = append(discarded, rem.Transactions()...)
   306  				if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil {
   307  					log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash())
   308  					return
   309  				}
   310  			}
   311  			for add.NumberU64() > rem.NumberU64() {
   312  				included = append(included, add.Transactions()...)
   313  				if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil {
   314  					log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash())
   315  					return
   316  				}
   317  			}
   318  			for rem.Hash() != add.Hash() {
   319  				discarded = append(discarded, rem.Transactions()...)
   320  				if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil {
   321  					log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash())
   322  					return
   323  				}
   324  				included = append(included, add.Transactions()...)
   325  				if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil {
   326  					log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash())
   327  					return
   328  				}
   329  			}
   330  			reinject = types.TxDifference(discarded, included)
   331  		}
   332  	}
   333  
   334  	if newHead == nil {
   335  		newHead = pool.chain.CurrentBlock().Header()
   336  	}
   337  	statedb, err := pool.chain.StateAt(newHead.Root)
   338  	if err != nil {
   339  		log.Error("Failed to reset txpool state", "err", err)
   340  		return
   341  	}
   342  	pool.currentState = statedb
   343  	pool.pendingState = state.ManageState(statedb)
   344  	pool.currentMaxGas = newHead.GasLimit
   345  
   346  	log.Debug("Reinjecting stale transactions", "count", len(reinject))
   347  	pool.addTxsLocked(reinject, false)
   348  
   349  	pool.demoteUnexecutables()
   350  
   351  	for addr, list := range pool.pending {
   352  		txs := list.Flatten()
   353  		pool.pendingState.SetNonce(addr, txs[len(txs)-1].Nonce()+1)
   354  	}
   355  
   356  	pool.promoteExecutables(nil)
   357  }
   358  
   359  func (pool *TxPool) Stop() {
   360  
   361  	pool.scope.Close()
   362  
   363  	pool.chainHeadSub.Unsubscribe()
   364  	pool.wg.Wait()
   365  
   366  	if pool.journal != nil {
   367  		pool.journal.close()
   368  	}
   369  	log.Info("Transaction pool stopped")
   370  }
   371  
   372  func (pool *TxPool) SubscribeTxPreEvent(ch chan<- TxPreEvent) event.Subscription {
   373  	return pool.scope.Track(pool.txFeed.Subscribe(ch))
   374  }
   375  
   376  func (pool *TxPool) GasPrice() *big.Int {
   377  	pool.mu.RLock()
   378  	defer pool.mu.RUnlock()
   379  
   380  	return new(big.Int).Set(pool.gasPrice)
   381  }
   382  
   383  func (pool *TxPool) SetGasPrice(price *big.Int) {
   384  	pool.mu.Lock()
   385  	defer pool.mu.Unlock()
   386  
   387  	pool.gasPrice = price
   388  	for _, tx := range pool.priced.Cap(price, pool.locals) {
   389  		pool.removeTx(tx.Hash())
   390  	}
   391  	log.Info("Transaction pool price threshold updated", "price", price)
   392  }
   393  
   394  func (pool *TxPool) State() *state.ManagedState {
   395  	pool.mu.RLock()
   396  	defer pool.mu.RUnlock()
   397  
   398  	return pool.pendingState
   399  }
   400  
   401  func (pool *TxPool) Stats() (int, int) {
   402  	pool.mu.RLock()
   403  	defer pool.mu.RUnlock()
   404  
   405  	return pool.stats()
   406  }
   407  
   408  func (pool *TxPool) stats() (int, int) {
   409  	pending := 0
   410  	for _, list := range pool.pending {
   411  		pending += list.Len()
   412  	}
   413  	queued := 0
   414  	for _, list := range pool.queue {
   415  		queued += list.Len()
   416  	}
   417  	return pending, queued
   418  }
   419  
   420  func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) {
   421  	pool.mu.Lock()
   422  	defer pool.mu.Unlock()
   423  
   424  	pending := make(map[common.Address]types.Transactions)
   425  	for addr, list := range pool.pending {
   426  		pending[addr] = list.Flatten()
   427  	}
   428  	queued := make(map[common.Address]types.Transactions)
   429  	for addr, list := range pool.queue {
   430  		queued[addr] = list.Flatten()
   431  	}
   432  	return pending, queued
   433  }
   434  
   435  func (pool *TxPool) Pending() (map[common.Address]types.Transactions, error) {
   436  	pool.mu.Lock()
   437  	defer pool.mu.Unlock()
   438  
   439  	pending := make(map[common.Address]types.Transactions)
   440  	for addr, list := range pool.pending {
   441  		pending[addr] = list.Flatten()
   442  	}
   443  	return pending, nil
   444  }
   445  
   446  func (pool *TxPool) local() map[common.Address]types.Transactions {
   447  	txs := make(map[common.Address]types.Transactions)
   448  	for addr := range pool.locals.accounts {
   449  		if pending := pool.pending[addr]; pending != nil {
   450  			txs[addr] = append(txs[addr], pending.Flatten()...)
   451  		}
   452  		if queued := pool.queue[addr]; queued != nil {
   453  			txs[addr] = append(txs[addr], queued.Flatten()...)
   454  		}
   455  	}
   456  	return txs
   457  }
   458  
   459  func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
   460  
   461  	if tx.Size() > 32*1024 {
   462  		return ErrOversizedData
   463  	}
   464  
   465  	if tx.Value().Sign() < 0 {
   466  		return ErrNegativeValue
   467  	}
   468  
   469  	if pool.currentMaxGas < tx.Gas() {
   470  		return ErrGasLimit
   471  	}
   472  
   473  	from, err := types.Sender(pool.signer, tx)
   474  	if err != nil {
   475  		return ErrInvalidSender
   476  	}
   477  
   478  	local = local || pool.locals.contains(from)
   479  	if !local && pool.gasPrice.Cmp(tx.GasPrice()) > 0 {
   480  		return ErrUnderpriced
   481  	}
   482  
   483  	if pool.currentState.GetNonce(from) > tx.Nonce() {
   484  		return ErrNonceTooLow
   485  	}
   486  
   487  	if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 {
   488  		return ErrInsufficientFunds
   489  	}
   490  
   491  	if !neatAbi.IsNeatChainContractAddr(tx.To()) {
   492  		intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, true)
   493  		if err != nil {
   494  			return err
   495  		}
   496  		if tx.Gas() < intrGas {
   497  			return ErrIntrinsicGas
   498  		}
   499  	} else {
   500  
   501  		data := tx.Data()
   502  		function, err := neatAbi.FunctionTypeFromId(data[:4])
   503  		if err != nil {
   504  			return err
   505  		}
   506  
   507  		if pool.chainconfig.IsMainChain() && !function.AllowInMainChain() {
   508  			return ErrNotAllowedInMainChain
   509  		} else if !pool.chainconfig.IsMainChain() && !function.AllowInSideChain() {
   510  			return ErrNotAllowedInSideChain
   511  		}
   512  
   513  		log.Infof("validateTx Chain Function %v", function.String())
   514  		if validateCb := GetValidateCb(function); validateCb != nil {
   515  			if function.IsCrossChainType() {
   516  				if fn, ok := validateCb.(CrossChainValidateCb); ok {
   517  					pool.cch.GetMutex().Lock()
   518  					err := fn(tx, pool.currentState, pool.cch)
   519  					pool.cch.GetMutex().Unlock()
   520  					if err != nil {
   521  						return err
   522  					}
   523  				} else {
   524  					panic("callback func is wrong, this should not happened, please check the code")
   525  				}
   526  			} else {
   527  				if fn, ok := validateCb.(NonCrossChainValidateCb); ok {
   528  					if err := fn(tx, pool.currentState, pool.chain.(*BlockChain)); err != nil {
   529  						return err
   530  					}
   531  				} else {
   532  					panic("callback func is wrong, this should not happened, please check the code")
   533  				}
   534  			}
   535  		}
   536  	}
   537  
   538  	return nil
   539  }
   540  
   541  func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) {
   542  
   543  	hash := tx.Hash()
   544  	if pool.all[hash] != nil {
   545  		log.Trace("Discarding already known transaction", "hash", hash)
   546  		return false, fmt.Errorf("known transaction: %x", hash)
   547  	}
   548  
   549  	if err := pool.validateTx(tx, local); err != nil {
   550  		log.Trace("Discarding invalid transaction", "hash", hash, "err", err)
   551  		invalidTxCounter.Inc(1)
   552  		return false, err
   553  	}
   554  
   555  	if !params.GenCfg.PerfTest &&
   556  		uint64(len(pool.all)) >= pool.config.GlobalSlots+pool.config.GlobalQueue {
   557  
   558  		if pool.priced.Underpriced(tx, pool.locals) {
   559  			log.Trace("Discarding underpriced transaction", "hash", hash, "price", tx.GasPrice())
   560  			underpricedTxCounter.Inc(1)
   561  			return false, ErrUnderpriced
   562  		}
   563  
   564  		drop := pool.priced.Discard(len(pool.all)-int(pool.config.GlobalSlots+pool.config.GlobalQueue-1), pool.locals)
   565  		for _, tx := range drop {
   566  			log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "price", tx.GasPrice())
   567  			underpricedTxCounter.Inc(1)
   568  			pool.removeTx(tx.Hash())
   569  		}
   570  	}
   571  
   572  	from, _ := types.Sender(pool.signer, tx)
   573  	if list := pool.pending[from]; list != nil && list.Overlaps(tx) {
   574  
   575  		inserted, old := list.Add(tx, pool.config.PriceBump)
   576  		if !inserted {
   577  			pendingDiscardCounter.Inc(1)
   578  			return false, ErrReplaceUnderpriced
   579  		}
   580  
   581  		if old != nil {
   582  			delete(pool.all, old.Hash())
   583  			pool.priced.Removed()
   584  			pendingReplaceCounter.Inc(1)
   585  		}
   586  		pool.all[tx.Hash()] = tx
   587  		pool.priced.Put(tx)
   588  		pool.journalTx(from, tx)
   589  
   590  		log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To())
   591  
   592  		go pool.txFeed.Send(TxPreEvent{tx})
   593  
   594  		return old != nil, nil
   595  	}
   596  
   597  	replace, err := pool.enqueueTx(hash, tx)
   598  	if err != nil {
   599  		return false, err
   600  	}
   601  
   602  	if local {
   603  		pool.locals.add(from)
   604  	}
   605  	pool.journalTx(from, tx)
   606  
   607  	log.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To())
   608  	return replace, nil
   609  }
   610  
   611  func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction) (bool, error) {
   612  
   613  	from, _ := types.Sender(pool.signer, tx)
   614  	if pool.queue[from] == nil {
   615  		pool.queue[from] = newTxList(false)
   616  	}
   617  	inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump)
   618  	if !inserted {
   619  
   620  		queuedDiscardCounter.Inc(1)
   621  		return false, ErrReplaceUnderpriced
   622  	}
   623  
   624  	if old != nil {
   625  		delete(pool.all, old.Hash())
   626  		pool.priced.Removed()
   627  		queuedReplaceCounter.Inc(1)
   628  	}
   629  	pool.all[hash] = tx
   630  	pool.priced.Put(tx)
   631  	return old != nil, nil
   632  }
   633  
   634  func (pool *TxPool) journalTx(from common.Address, tx *types.Transaction) {
   635  
   636  	if pool.journal == nil || !pool.locals.contains(from) {
   637  		return
   638  	}
   639  	if err := pool.journal.insert(tx); err != nil {
   640  		log.Warn("Failed to journal local transaction", "err", err)
   641  	}
   642  }
   643  
   644  func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.Transaction) {
   645  
   646  	if pool.pending[addr] == nil {
   647  		pool.pending[addr] = newTxList(true)
   648  	}
   649  	list := pool.pending[addr]
   650  
   651  	inserted, old := list.Add(tx, pool.config.PriceBump)
   652  	if !inserted {
   653  
   654  		delete(pool.all, hash)
   655  		pool.priced.Removed()
   656  
   657  		pendingDiscardCounter.Inc(1)
   658  		return
   659  	}
   660  
   661  	if old != nil {
   662  		delete(pool.all, old.Hash())
   663  		pool.priced.Removed()
   664  
   665  		pendingReplaceCounter.Inc(1)
   666  	}
   667  
   668  	if pool.all[hash] == nil {
   669  		pool.all[hash] = tx
   670  		pool.priced.Put(tx)
   671  	}
   672  
   673  	pool.beats[addr] = time.Now()
   674  	pool.pendingState.SetNonce(addr, tx.Nonce()+1)
   675  
   676  	go pool.txFeed.Send(TxPreEvent{tx})
   677  }
   678  
   679  func (pool *TxPool) AddLocal(tx *types.Transaction) error {
   680  	return pool.addTx(tx, !pool.config.NoLocals)
   681  }
   682  
   683  func (pool *TxPool) AddRemote(tx *types.Transaction) error {
   684  	return pool.addTx(tx, false)
   685  }
   686  
   687  func (pool *TxPool) AddLocals(txs []*types.Transaction) []error {
   688  	return pool.addTxs(txs, !pool.config.NoLocals)
   689  }
   690  
   691  func (pool *TxPool) AddRemotes(txs []*types.Transaction) []error {
   692  	return pool.addTxs(txs, false)
   693  }
   694  
   695  func (pool *TxPool) addTx(tx *types.Transaction, local bool) error {
   696  	pool.mu.Lock()
   697  	defer pool.mu.Unlock()
   698  
   699  	replace, err := pool.add(tx, local)
   700  	if err != nil {
   701  		return err
   702  	}
   703  
   704  	if !replace {
   705  		from, _ := types.Sender(pool.signer, tx)
   706  		pool.promoteExecutables([]common.Address{from})
   707  	}
   708  	return nil
   709  }
   710  
   711  func (pool *TxPool) addTxs(txs []*types.Transaction, local bool) []error {
   712  	pool.mu.Lock()
   713  	defer pool.mu.Unlock()
   714  	return pool.addTxsLocked(txs, local)
   715  }
   716  
   717  func (pool *TxPool) addTxsLocked(txs []*types.Transaction, local bool) []error {
   718  
   719  	dirty := make(map[common.Address]struct{})
   720  	errs := make([]error, len(txs))
   721  	for i, tx := range txs {
   722  		var replace bool
   723  		if replace, errs[i] = pool.add(tx, local); errs[i] == nil {
   724  			if !replace {
   725  				from, _ := types.Sender(pool.signer, tx)
   726  				dirty[from] = struct{}{}
   727  			}
   728  		}
   729  	}
   730  
   731  	if len(dirty) > 0 {
   732  		addrs := make([]common.Address, 0, len(dirty))
   733  		for addr := range dirty {
   734  			addrs = append(addrs, addr)
   735  		}
   736  		pool.promoteExecutables(addrs)
   737  	}
   738  
   739  	return errs
   740  }
   741  
   742  func (pool *TxPool) Status(hashes []common.Hash) []TxStatus {
   743  	pool.mu.RLock()
   744  	defer pool.mu.RUnlock()
   745  
   746  	status := make([]TxStatus, len(hashes))
   747  	for i, hash := range hashes {
   748  		if tx := pool.all[hash]; tx != nil {
   749  			from, _ := types.Sender(pool.signer, tx)
   750  			if pool.pending[from] != nil && pool.pending[from].txs.items[tx.Nonce()] != nil {
   751  				status[i] = TxStatusPending
   752  			} else {
   753  				status[i] = TxStatusQueued
   754  			}
   755  		}
   756  	}
   757  	return status
   758  }
   759  
   760  func (pool *TxPool) Get(hash common.Hash) *types.Transaction {
   761  	pool.mu.RLock()
   762  	defer pool.mu.RUnlock()
   763  
   764  	return pool.all[hash]
   765  }
   766  
   767  func (pool *TxPool) RemoveTxs(txs types.Transactions) {
   768  	pool.mu.Lock()
   769  	defer pool.mu.Unlock()
   770  
   771  	for _, tx := range txs {
   772  		pool.removeTx(tx.Hash())
   773  	}
   774  }
   775  
   776  func (pool *TxPool) removeTx(hash common.Hash) {
   777  
   778  	tx, ok := pool.all[hash]
   779  	if !ok {
   780  		return
   781  	}
   782  	addr, _ := types.Sender(pool.signer, tx)
   783  
   784  	delete(pool.all, hash)
   785  	pool.priced.Removed()
   786  
   787  	if pending := pool.pending[addr]; pending != nil {
   788  		if removed, invalids := pending.Remove(tx); removed {
   789  
   790  			if pending.Empty() {
   791  				delete(pool.pending, addr)
   792  				delete(pool.beats, addr)
   793  			}
   794  
   795  			for _, tx := range invalids {
   796  				pool.enqueueTx(tx.Hash(), tx)
   797  			}
   798  
   799  			if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr) > nonce {
   800  				pool.pendingState.SetNonce(addr, nonce)
   801  			}
   802  			return
   803  		}
   804  	}
   805  
   806  	if future := pool.queue[addr]; future != nil {
   807  		future.Remove(tx)
   808  		if future.Empty() {
   809  			delete(pool.queue, addr)
   810  		}
   811  	}
   812  }
   813  
   814  func (pool *TxPool) promoteExecutables(accounts []common.Address) {
   815  
   816  	if accounts == nil {
   817  		accounts = make([]common.Address, 0, len(pool.queue))
   818  		for addr := range pool.queue {
   819  			accounts = append(accounts, addr)
   820  		}
   821  	}
   822  
   823  	for _, addr := range accounts {
   824  		list := pool.queue[addr]
   825  		if list == nil {
   826  			continue
   827  		}
   828  
   829  		for _, tx := range list.Forward(pool.currentState.GetNonce(addr)) {
   830  			hash := tx.Hash()
   831  			log.Trace("Removed old queued transaction", "hash", hash)
   832  			delete(pool.all, hash)
   833  			pool.priced.Removed()
   834  		}
   835  
   836  		drops, _ := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas)
   837  		for _, tx := range drops {
   838  			hash := tx.Hash()
   839  			log.Trace("Removed unpayable queued transaction", "hash", hash)
   840  			delete(pool.all, hash)
   841  			pool.priced.Removed()
   842  			queuedNofundsCounter.Inc(1)
   843  		}
   844  
   845  		for _, tx := range list.Ready(pool.pendingState.GetNonce(addr)) {
   846  			hash := tx.Hash()
   847  			log.Trace("Promoting queued transaction", "hash", hash)
   848  			pool.promoteTx(addr, hash, tx)
   849  		}
   850  
   851  		if !pool.locals.contains(addr) {
   852  			for _, tx := range list.Cap(int(pool.config.AccountQueue)) {
   853  				hash := tx.Hash()
   854  				delete(pool.all, hash)
   855  				pool.priced.Removed()
   856  				queuedRateLimitCounter.Inc(1)
   857  				log.Trace("Removed cap-exceeding queued transaction", "hash", hash)
   858  			}
   859  		}
   860  
   861  		if list.Empty() {
   862  			delete(pool.queue, addr)
   863  		}
   864  	}
   865  
   866  	pending := uint64(0)
   867  	for _, list := range pool.pending {
   868  		pending += uint64(list.Len())
   869  	}
   870  	if pending > pool.config.GlobalSlots {
   871  		pendingBeforeCap := pending
   872  
   873  		spammers := prque.New(nil)
   874  		for addr, list := range pool.pending {
   875  
   876  			if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.AccountSlots {
   877  				spammers.Push(addr, int64(list.Len()))
   878  			}
   879  		}
   880  
   881  		offenders := []common.Address{}
   882  		for pending > pool.config.GlobalSlots && !spammers.Empty() {
   883  
   884  			offender, _ := spammers.Pop()
   885  			offenders = append(offenders, offender.(common.Address))
   886  
   887  			if len(offenders) > 1 {
   888  
   889  				threshold := pool.pending[offender.(common.Address)].Len()
   890  
   891  				for pending > pool.config.GlobalSlots && pool.pending[offenders[len(offenders)-2]].Len() > threshold {
   892  					for i := 0; i < len(offenders)-1; i++ {
   893  						list := pool.pending[offenders[i]]
   894  						for _, tx := range list.Cap(list.Len() - 1) {
   895  
   896  							hash := tx.Hash()
   897  							delete(pool.all, hash)
   898  							pool.priced.Removed()
   899  
   900  							if nonce := tx.Nonce(); pool.pendingState.GetNonce(offenders[i]) > nonce {
   901  								pool.pendingState.SetNonce(offenders[i], nonce)
   902  							}
   903  							log.Trace("Removed fairness-exceeding pending transaction", "hash", hash)
   904  						}
   905  						pending--
   906  					}
   907  				}
   908  			}
   909  		}
   910  
   911  		if pending > pool.config.GlobalSlots && len(offenders) > 0 {
   912  			for pending > pool.config.GlobalSlots && uint64(pool.pending[offenders[len(offenders)-1]].Len()) > pool.config.AccountSlots {
   913  				for _, addr := range offenders {
   914  					list := pool.pending[addr]
   915  					for _, tx := range list.Cap(list.Len() - 1) {
   916  
   917  						hash := tx.Hash()
   918  						delete(pool.all, hash)
   919  						pool.priced.Removed()
   920  
   921  						if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr) > nonce {
   922  							pool.pendingState.SetNonce(addr, nonce)
   923  						}
   924  						log.Trace("Removed fairness-exceeding pending transaction", "hash", hash)
   925  					}
   926  					pending--
   927  				}
   928  			}
   929  		}
   930  		pendingRateLimitCounter.Inc(int64(pendingBeforeCap - pending))
   931  	}
   932  
   933  	queued := uint64(0)
   934  	for _, list := range pool.queue {
   935  		queued += uint64(list.Len())
   936  	}
   937  	if queued > pool.config.GlobalQueue {
   938  
   939  		addresses := make(addresssByHeartbeat, 0, len(pool.queue))
   940  		for addr := range pool.queue {
   941  			if !pool.locals.contains(addr) {
   942  				addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]})
   943  			}
   944  		}
   945  		sort.Sort(addresses)
   946  
   947  		for drop := queued - pool.config.GlobalQueue; drop > 0 && len(addresses) > 0; {
   948  			addr := addresses[len(addresses)-1]
   949  			list := pool.queue[addr.address]
   950  
   951  			addresses = addresses[:len(addresses)-1]
   952  
   953  			if size := uint64(list.Len()); size <= drop {
   954  				for _, tx := range list.Flatten() {
   955  					pool.removeTx(tx.Hash())
   956  				}
   957  				drop -= size
   958  				queuedRateLimitCounter.Inc(int64(size))
   959  				continue
   960  			}
   961  
   962  			txs := list.Flatten()
   963  			for i := len(txs) - 1; i >= 0 && drop > 0; i-- {
   964  				pool.removeTx(txs[i].Hash())
   965  				drop--
   966  				queuedRateLimitCounter.Inc(1)
   967  			}
   968  		}
   969  	}
   970  }
   971  
   972  func (pool *TxPool) demoteUnexecutables() {
   973  
   974  	for addr, list := range pool.pending {
   975  		nonce := pool.currentState.GetNonce(addr)
   976  
   977  		for _, tx := range list.Forward(nonce) {
   978  			hash := tx.Hash()
   979  			log.Trace("Removed old pending transaction", "hash", hash)
   980  			delete(pool.all, hash)
   981  			pool.priced.Removed()
   982  		}
   983  
   984  		drops, invalids := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas)
   985  		for _, tx := range drops {
   986  			hash := tx.Hash()
   987  			log.Trace("Removed unpayable pending transaction", "hash", hash)
   988  			delete(pool.all, hash)
   989  			pool.priced.Removed()
   990  			pendingNofundsCounter.Inc(1)
   991  		}
   992  		for _, tx := range invalids {
   993  			hash := tx.Hash()
   994  			log.Trace("Demoting pending transaction", "hash", hash)
   995  			pool.enqueueTx(hash, tx)
   996  		}
   997  
   998  		if list.Len() > 0 && list.txs.Get(nonce) == nil {
   999  			for _, tx := range list.Cap(0) {
  1000  				hash := tx.Hash()
  1001  				log.Error("Demoting invalidated transaction", "hash", hash)
  1002  				pool.enqueueTx(hash, tx)
  1003  			}
  1004  		}
  1005  
  1006  		if list.Empty() {
  1007  			delete(pool.pending, addr)
  1008  			delete(pool.beats, addr)
  1009  		}
  1010  	}
  1011  }
  1012  
  1013  type addressByHeartbeat struct {
  1014  	address   common.Address
  1015  	heartbeat time.Time
  1016  }
  1017  
  1018  type addresssByHeartbeat []addressByHeartbeat
  1019  
  1020  func (a addresssByHeartbeat) Len() int           { return len(a) }
  1021  func (a addresssByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) }
  1022  func (a addresssByHeartbeat) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
  1023  
  1024  type accountSet struct {
  1025  	accounts map[common.Address]struct{}
  1026  	signer   types.Signer
  1027  }
  1028  
  1029  func newAccountSet(signer types.Signer) *accountSet {
  1030  	return &accountSet{
  1031  		accounts: make(map[common.Address]struct{}),
  1032  		signer:   signer,
  1033  	}
  1034  }
  1035  
  1036  func (as *accountSet) contains(addr common.Address) bool {
  1037  	_, exist := as.accounts[addr]
  1038  	return exist
  1039  }
  1040  
  1041  func (as *accountSet) containsTx(tx *types.Transaction) bool {
  1042  	if addr, err := types.Sender(as.signer, tx); err == nil {
  1043  		return as.contains(addr)
  1044  	}
  1045  	return false
  1046  }
  1047  
  1048  func (as *accountSet) add(addr common.Address) {
  1049  	as.accounts[addr] = struct{}{}
  1050  }