github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/tx_pool.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:35</date>
    10  //</624450080895668224>
    11  
    12  
    13  package core
    14  
    15  import (
    16  	"errors"
    17  	"fmt"
    18  	"math"
    19  	"math/big"
    20  	"sort"
    21  	"sync"
    22  	"time"
    23  
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/common/prque"
    26  	"github.com/ethereum/go-ethereum/core/state"
    27  	"github.com/ethereum/go-ethereum/core/types"
    28  	"github.com/ethereum/go-ethereum/event"
    29  	"github.com/ethereum/go-ethereum/log"
    30  	"github.com/ethereum/go-ethereum/metrics"
    31  	"github.com/ethereum/go-ethereum/params"
    32  )
    33  
    34  const (
    35  //ChainHeadChansize是侦听ChainHeadEvent的通道的大小。
    36  	chainHeadChanSize = 10
    37  )
    38  
    39  var (
    40  //如果事务包含无效签名,则返回errInvalidSender。
    41  	ErrInvalidSender = errors.New("invalid sender")
    42  
    43  //如果事务的nonce低于
    44  //一个存在于本地链中。
    45  	ErrNonceTooLow = errors.New("nonce too low")
    46  
    47  //如果交易的天然气价格低于最低价格,则返回定价错误。
    48  //为事务池配置。
    49  	ErrUnderpriced = errors.New("transaction underpriced")
    50  
    51  //如果试图替换事务,则返回erreplaceCunderpriced
    52  //另一个没有要求的价格上涨。
    53  	ErrReplaceUnderpriced = errors.New("replacement transaction underpriced")
    54  
    55  //如果执行事务的总成本为
    56  //高于用户帐户的余额。
    57  	ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value")
    58  
    59  //如果交易指定使用更少的气体,则返回errintrinsicgas
    60  //启动调用所需的。
    61  	ErrIntrinsicGas = errors.New("intrinsic gas too low")
    62  
    63  //如果交易请求的气体限制超过
    64  //当前块的最大允许量。
    65  	ErrGasLimit = errors.New("exceeds block gas limit")
    66  
    67  //errNegativeValue是一个健全的错误,用于确保没有人能够指定
    68  //负值的交易记录。
    69  	ErrNegativeValue = errors.New("negative value")
    70  
    71  //如果事务的输入数据大于
    72  //而不是用户可能使用的一些有意义的限制。这不是共识错误
    73  //使事务无效,而不是DoS保护。
    74  	ErrOversizedData = errors.New("oversized data")
    75  )
    76  
    77  var (
    78  evictionInterval    = time.Minute     //检查可收回事务的时间间隔
    79  statsReportInterval = 8 * time.Second //报告事务池统计的时间间隔
    80  )
    81  
    82  var (
    83  //挂起池的指标
    84  	pendingDiscardCounter   = metrics.NewRegisteredCounter("txpool/pending/discard", nil)
    85  	pendingReplaceCounter   = metrics.NewRegisteredCounter("txpool/pending/replace", nil)
    86  pendingRateLimitCounter = metrics.NewRegisteredCounter("txpool/pending/ratelimit", nil) //由于速率限制而下降
    87  pendingNofundsCounter   = metrics.NewRegisteredCounter("txpool/pending/nofunds", nil)   //因资金不足而放弃
    88  
    89  //排队池的指标
    90  	queuedDiscardCounter   = metrics.NewRegisteredCounter("txpool/queued/discard", nil)
    91  	queuedReplaceCounter   = metrics.NewRegisteredCounter("txpool/queued/replace", nil)
    92  queuedRateLimitCounter = metrics.NewRegisteredCounter("txpool/queued/ratelimit", nil) //由于速率限制而下降
    93  queuedNofundsCounter   = metrics.NewRegisteredCounter("txpool/queued/nofunds", nil)   //因资金不足而放弃
    94  
    95  //一般Tx指标
    96  	invalidTxCounter     = metrics.NewRegisteredCounter("txpool/invalid", nil)
    97  	underpricedTxCounter = metrics.NewRegisteredCounter("txpool/underpriced", nil)
    98  )
    99  
   100  //txstatus是由池看到的事务的当前状态。
   101  type TxStatus uint
   102  
   103  const (
   104  	TxStatusUnknown TxStatus = iota
   105  	TxStatusQueued
   106  	TxStatusPending
   107  	TxStatusIncluded
   108  )
   109  
   110  //区块链提供区块链的状态和当前的天然气限制。
   111  //Tx池和事件订阅服务器中的一些预检查。
   112  type blockChain interface {
   113  	CurrentBlock() *types.Block
   114  	GetBlock(hash common.Hash, number uint64) *types.Block
   115  	StateAt(root common.Hash) (*state.StateDB, error)
   116  
   117  	SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription
   118  }
   119  
   120  //TxPoolConfig是事务池的配置参数。
   121  type TxPoolConfig struct {
   122  Locals    []common.Address //默认情况下应视为本地地址的地址
   123  NoLocals  bool             //是否应禁用本地事务处理
   124  Journal   string           //在节点重新启动后幸存的本地事务日志
   125  Rejournal time.Duration    //重新生成本地事务日记帐的时间间隔
   126  
   127  PriceLimit uint64 //用于验收的最低天然气价格
   128  PriceBump  uint64 //替换已存在交易的最低价格波动百分比(nonce)
   129  
   130  AccountSlots uint64 //每个帐户保证的可执行事务槽数
   131  GlobalSlots  uint64 //所有帐户的最大可执行事务槽数
   132  AccountQueue uint64 //每个帐户允许的最大不可执行事务槽数
   133  GlobalQueue  uint64 //所有帐户的最大不可执行事务槽数
   134  
   135  Lifetime time.Duration //非可执行事务排队的最长时间
   136  }
   137  
   138  //DefaultTxPoolConfig包含事务的默认配置
   139  //池。
   140  var DefaultTxPoolConfig = TxPoolConfig{
   141  	Journal:   "transactions.rlp",
   142  	Rejournal: time.Hour,
   143  
   144  	PriceLimit: 1,
   145  	PriceBump:  10,
   146  
   147  	AccountSlots: 16,
   148  	GlobalSlots:  4096,
   149  	AccountQueue: 64,
   150  	GlobalQueue:  1024,
   151  
   152  	Lifetime: 3 * time.Hour,
   153  }
   154  
   155  //清理检查提供的用户配置并更改
   156  //不合理或不可行。
   157  func (config *TxPoolConfig) sanitize() TxPoolConfig {
   158  	conf := *config
   159  	if conf.Rejournal < time.Second {
   160  		log.Warn("Sanitizing invalid txpool journal time", "provided", conf.Rejournal, "updated", time.Second)
   161  		conf.Rejournal = time.Second
   162  	}
   163  	if conf.PriceLimit < 1 {
   164  		log.Warn("Sanitizing invalid txpool price limit", "provided", conf.PriceLimit, "updated", DefaultTxPoolConfig.PriceLimit)
   165  		conf.PriceLimit = DefaultTxPoolConfig.PriceLimit
   166  	}
   167  	if conf.PriceBump < 1 {
   168  		log.Warn("Sanitizing invalid txpool price bump", "provided", conf.PriceBump, "updated", DefaultTxPoolConfig.PriceBump)
   169  		conf.PriceBump = DefaultTxPoolConfig.PriceBump
   170  	}
   171  	if conf.AccountSlots < 1 {
   172  		log.Warn("Sanitizing invalid txpool account slots", "provided", conf.AccountSlots, "updated", DefaultTxPoolConfig.AccountSlots)
   173  		conf.AccountSlots = DefaultTxPoolConfig.AccountSlots
   174  	}
   175  	if conf.GlobalSlots < 1 {
   176  		log.Warn("Sanitizing invalid txpool global slots", "provided", conf.GlobalSlots, "updated", DefaultTxPoolConfig.GlobalSlots)
   177  		conf.GlobalSlots = DefaultTxPoolConfig.GlobalSlots
   178  	}
   179  	if conf.AccountQueue < 1 {
   180  		log.Warn("Sanitizing invalid txpool account queue", "provided", conf.AccountQueue, "updated", DefaultTxPoolConfig.AccountQueue)
   181  		conf.AccountQueue = DefaultTxPoolConfig.AccountQueue
   182  	}
   183  	if conf.GlobalQueue < 1 {
   184  		log.Warn("Sanitizing invalid txpool global queue", "provided", conf.GlobalQueue, "updated", DefaultTxPoolConfig.GlobalQueue)
   185  		conf.GlobalQueue = DefaultTxPoolConfig.GlobalQueue
   186  	}
   187  	if conf.Lifetime < 1 {
   188  		log.Warn("Sanitizing invalid txpool lifetime", "provided", conf.Lifetime, "updated", DefaultTxPoolConfig.Lifetime)
   189  		conf.Lifetime = DefaultTxPoolConfig.Lifetime
   190  	}
   191  	return conf
   192  }
   193  
   194  //TxPool包含所有当前已知的事务。交易
   195  //从网络接收或提交时输入池
   196  //局部地。当它们包含在区块链中时,它们退出池。
   197  //
   198  //池将可处理的事务(可应用于
   199  //当前状态)和未来交易。事务在这些事务之间移动
   200  //两种状态随着时间的推移而被接收和处理。
   201  type TxPool struct {
   202  	config       TxPoolConfig
   203  	chainconfig  *params.ChainConfig
   204  	chain        blockChain
   205  	gasPrice     *big.Int
   206  	txFeed       event.Feed
   207  	scope        event.SubscriptionScope
   208  	chainHeadCh  chan ChainHeadEvent
   209  	chainHeadSub event.Subscription
   210  	signer       types.Signer
   211  	mu           sync.RWMutex
   212  
   213  currentState  *state.StateDB      //区块链头中的当前状态
   214  pendingState  *state.ManagedState //挂起状态跟踪虚拟当前
   215  currentMaxGas uint64              //交易上限的当前天然气限额
   216  
   217  locals  *accountSet //要免除逐出规则的本地事务集
   218  journal *txJournal  //备份到磁盘的本地事务日志
   219  
   220  pending map[common.Address]*txList   //所有当前可处理的事务
   221  queue   map[common.Address]*txList   //排队但不可处理的事务
   222  beats   map[common.Address]time.Time //每个已知帐户的最后一个心跳
   223  all     *txLookup                    //允许查找的所有事务
   224  priced  *txPricedList                //按价格排序的所有交易记录
   225  
   226  wg sync.WaitGroup //用于关机同步
   227  
   228  	homestead bool
   229  }
   230  
   231  //newtxpool创建一个新的事务池来收集、排序和筛选入站事务
   232  //来自网络的事务。
   233  func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain) *TxPool {
   234  //对输入进行消毒,以确保不设定脆弱的天然气价格。
   235  	config = (&config).sanitize()
   236  
   237  //使用事务池的初始设置创建事务池
   238  	pool := &TxPool{
   239  		config:      config,
   240  		chainconfig: chainconfig,
   241  		chain:       chain,
   242  		signer:      types.NewEIP155Signer(chainconfig.ChainID),
   243  		pending:     make(map[common.Address]*txList),
   244  		queue:       make(map[common.Address]*txList),
   245  		beats:       make(map[common.Address]time.Time),
   246  		all:         newTxLookup(),
   247  		chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize),
   248  		gasPrice:    new(big.Int).SetUint64(config.PriceLimit),
   249  	}
   250  	pool.locals = newAccountSet(pool.signer)
   251  	for _, addr := range config.Locals {
   252  		log.Info("Setting new local account", "address", addr)
   253  		pool.locals.add(addr)
   254  	}
   255  	pool.priced = newTxPricedList(pool.all)
   256  	pool.reset(nil, chain.CurrentBlock().Header())
   257  
   258  //如果启用了本地事务和日记,则从磁盘加载
   259  	if !config.NoLocals && config.Journal != "" {
   260  		pool.journal = newTxJournal(config.Journal)
   261  
   262  		if err := pool.journal.load(pool.AddLocals); err != nil {
   263  			log.Warn("Failed to load transaction journal", "err", err)
   264  		}
   265  		if err := pool.journal.rotate(pool.local()); err != nil {
   266  			log.Warn("Failed to rotate transaction journal", "err", err)
   267  		}
   268  	}
   269  //从区块链订阅事件
   270  	pool.chainHeadSub = pool.chain.SubscribeChainHeadEvent(pool.chainHeadCh)
   271  
   272  //启动事件循环并返回
   273  	pool.wg.Add(1)
   274  	go pool.loop()
   275  
   276  	return pool
   277  }
   278  
   279  //循环是事务池的主事件循环,等待并响应
   280  //外部区块链事件以及各种报告和交易
   281  //驱逐事件。
   282  func (pool *TxPool) loop() {
   283  	defer pool.wg.Done()
   284  
   285  //启动统计报告和事务逐出标记
   286  	var prevPending, prevQueued, prevStales int
   287  
   288  	report := time.NewTicker(statsReportInterval)
   289  	defer report.Stop()
   290  
   291  	evict := time.NewTicker(evictionInterval)
   292  	defer evict.Stop()
   293  
   294  	journal := time.NewTicker(pool.config.Rejournal)
   295  	defer journal.Stop()
   296  
   297  //跟踪事务重新排序的前一个标题
   298  	head := pool.chain.CurrentBlock()
   299  
   300  //持续等待并对各种事件作出反应
   301  	for {
   302  		select {
   303  //处理ChainHeadEvent
   304  		case ev := <-pool.chainHeadCh:
   305  			if ev.Block != nil {
   306  				pool.mu.Lock()
   307  				if pool.chainconfig.IsHomestead(ev.Block.Number()) {
   308  					pool.homestead = true
   309  				}
   310  				pool.reset(head.Header(), ev.Block.Header())
   311  				head = ev.Block
   312  
   313  				pool.mu.Unlock()
   314  			}
   315  //由于系统停止而取消订阅
   316  		case <-pool.chainHeadSub.Err():
   317  			return
   318  
   319  //处理统计报告标记
   320  		case <-report.C:
   321  			pool.mu.RLock()
   322  			pending, queued := pool.stats()
   323  			stales := pool.priced.stales
   324  			pool.mu.RUnlock()
   325  
   326  			if pending != prevPending || queued != prevQueued || stales != prevStales {
   327  				log.Debug("Transaction pool status report", "executable", pending, "queued", queued, "stales", stales)
   328  				prevPending, prevQueued, prevStales = pending, queued, stales
   329  			}
   330  
   331  //处理非活动帐户事务收回
   332  		case <-evict.C:
   333  			pool.mu.Lock()
   334  			for addr := range pool.queue {
   335  //从逐出机制跳过本地事务
   336  				if pool.locals.contains(addr) {
   337  					continue
   338  				}
   339  //任何年龄足够大的非本地人都应该被除名。
   340  				if time.Since(pool.beats[addr]) > pool.config.Lifetime {
   341  					for _, tx := range pool.queue[addr].Flatten() {
   342  						pool.removeTx(tx.Hash(), true)
   343  					}
   344  				}
   345  			}
   346  			pool.mu.Unlock()
   347  
   348  //处理本地事务日记帐轮换
   349  		case <-journal.C:
   350  			if pool.journal != nil {
   351  				pool.mu.Lock()
   352  				if err := pool.journal.rotate(pool.local()); err != nil {
   353  					log.Warn("Failed to rotate local tx journal", "err", err)
   354  				}
   355  				pool.mu.Unlock()
   356  			}
   357  		}
   358  	}
   359  }
   360  
   361  //LockedReset是一个包装重置,允许在线程安全中调用它。
   362  //态度。此方法仅在检测仪中使用!
   363  func (pool *TxPool) lockedReset(oldHead, newHead *types.Header) {
   364  	pool.mu.Lock()
   365  	defer pool.mu.Unlock()
   366  
   367  	pool.reset(oldHead, newHead)
   368  }
   369  
   370  //重置检索区块链的当前状态并确保内容
   371  //的事务池对于链状态有效。
   372  func (pool *TxPool) reset(oldHead, newHead *types.Header) {
   373  //如果要重新定位旧状态,请重新拒绝所有已删除的事务
   374  	var reinject types.Transactions
   375  
   376  	if oldHead != nil && oldHead.Hash() != newHead.ParentHash {
   377  //如果REORG太深,请避免这样做(将在快速同步期间发生)
   378  		oldNum := oldHead.Number.Uint64()
   379  		newNum := newHead.Number.Uint64()
   380  
   381  		if depth := uint64(math.Abs(float64(oldNum) - float64(newNum))); depth > 64 {
   382  			log.Debug("Skipping deep transaction reorg", "depth", depth)
   383  		} else {
   384  //REORG看起来很浅,足以将所有事务拉入内存
   385  			var discarded, included types.Transactions
   386  
   387  			var (
   388  				rem = pool.chain.GetBlock(oldHead.Hash(), oldHead.Number.Uint64())
   389  				add = pool.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64())
   390  			)
   391  			for rem.NumberU64() > add.NumberU64() {
   392  				discarded = append(discarded, rem.Transactions()...)
   393  				if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil {
   394  					log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash())
   395  					return
   396  				}
   397  			}
   398  			for add.NumberU64() > rem.NumberU64() {
   399  				included = append(included, add.Transactions()...)
   400  				if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil {
   401  					log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash())
   402  					return
   403  				}
   404  			}
   405  			for rem.Hash() != add.Hash() {
   406  				discarded = append(discarded, rem.Transactions()...)
   407  				if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil {
   408  					log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash())
   409  					return
   410  				}
   411  				included = append(included, add.Transactions()...)
   412  				if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil {
   413  					log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash())
   414  					return
   415  				}
   416  			}
   417  			reinject = types.TxDifference(discarded, included)
   418  		}
   419  	}
   420  //将内部状态初始化为当前头部
   421  	if newHead == nil {
   422  newHead = pool.chain.CurrentBlock().Header() //测试过程中的特殊情况
   423  	}
   424  	statedb, err := pool.chain.StateAt(newHead.Root)
   425  	if err != nil {
   426  		log.Error("Failed to reset txpool state", "err", err)
   427  		return
   428  	}
   429  	pool.currentState = statedb
   430  	pool.pendingState = state.ManageState(statedb)
   431  	pool.currentMaxGas = newHead.GasLimit
   432  
   433  //插入由于重新排序而丢弃的任何事务
   434  	log.Debug("Reinjecting stale transactions", "count", len(reinject))
   435  	senderCacher.recover(pool.signer, reinject)
   436  	pool.addTxsLocked(reinject, false)
   437  
   438  //验证挂起事务池,这将删除
   439  //包含在块中的任何交易或
   440  //已因另一个交易(例如
   441  //更高的天然气价格)
   442  	pool.demoteUnexecutables()
   443  
   444  //将所有帐户更新为最新的已知挂起的当前帐户
   445  	for addr, list := range pool.pending {
   446  txs := list.Flatten() //很重,但会被缓存,矿工无论如何都需要它。
   447  		pool.pendingState.SetNonce(addr, txs[len(txs)-1].Nonce()+1)
   448  	}
   449  //检查队列并尽可能将事务转移到挂起的
   450  //或者去掉那些已经失效的
   451  	pool.promoteExecutables(nil)
   452  }
   453  
   454  //stop终止事务池。
   455  func (pool *TxPool) Stop() {
   456  //取消订阅从txpool注册的所有订阅
   457  	pool.scope.Close()
   458  
   459  //取消订阅从区块链注册的订阅
   460  	pool.chainHeadSub.Unsubscribe()
   461  	pool.wg.Wait()
   462  
   463  	if pool.journal != nil {
   464  		pool.journal.close()
   465  	}
   466  	log.Info("Transaction pool stopped")
   467  }
   468  
   469  //subscripeWtxsEvent注册newtxSevent和的订阅
   470  //开始向给定通道发送事件。
   471  func (pool *TxPool) SubscribeNewTxsEvent(ch chan<- NewTxsEvent) event.Subscription {
   472  	return pool.scope.Track(pool.txFeed.Subscribe(ch))
   473  }
   474  
   475  //Gasprice返回交易池强制执行的当前天然气价格。
   476  func (pool *TxPool) GasPrice() *big.Int {
   477  	pool.mu.RLock()
   478  	defer pool.mu.RUnlock()
   479  
   480  	return new(big.Int).Set(pool.gasPrice)
   481  }
   482  
   483  //setgasprice更新交易池要求的
   484  //新事务,并将所有事务降低到此阈值以下。
   485  func (pool *TxPool) SetGasPrice(price *big.Int) {
   486  	pool.mu.Lock()
   487  	defer pool.mu.Unlock()
   488  
   489  	pool.gasPrice = price
   490  	for _, tx := range pool.priced.Cap(price, pool.locals) {
   491  		pool.removeTx(tx.Hash(), false)
   492  	}
   493  	log.Info("Transaction pool price threshold updated", "price", price)
   494  }
   495  
   496  //状态返回事务池的虚拟托管状态。
   497  func (pool *TxPool) State() *state.ManagedState {
   498  	pool.mu.RLock()
   499  	defer pool.mu.RUnlock()
   500  
   501  	return pool.pendingState
   502  }
   503  
   504  //stats检索当前池的统计信息,即挂起的数目和
   505  //排队(不可执行)的事务数。
   506  func (pool *TxPool) Stats() (int, int) {
   507  	pool.mu.RLock()
   508  	defer pool.mu.RUnlock()
   509  
   510  	return pool.stats()
   511  }
   512  
   513  //stats检索当前池的统计信息,即挂起的数目和
   514  //排队(不可执行)的事务数。
   515  func (pool *TxPool) stats() (int, int) {
   516  	pending := 0
   517  	for _, list := range pool.pending {
   518  		pending += list.Len()
   519  	}
   520  	queued := 0
   521  	for _, list := range pool.queue {
   522  		queued += list.Len()
   523  	}
   524  	return pending, queued
   525  }
   526  
   527  //Content检索事务池的数据内容,并返回
   528  //挂起的和排队的事务,按帐户分组并按nonce排序。
   529  func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) {
   530  	pool.mu.Lock()
   531  	defer pool.mu.Unlock()
   532  
   533  	pending := make(map[common.Address]types.Transactions)
   534  	for addr, list := range pool.pending {
   535  		pending[addr] = list.Flatten()
   536  	}
   537  	queued := make(map[common.Address]types.Transactions)
   538  	for addr, list := range pool.queue {
   539  		queued[addr] = list.Flatten()
   540  	}
   541  	return pending, queued
   542  }
   543  
   544  //挂起检索所有当前可处理的事务,按来源分组
   545  //帐户并按nonce排序。返回的事务集是一个副本,可以
   546  //通过调用代码自由修改。
   547  func (pool *TxPool) Pending() (map[common.Address]types.Transactions, error) {
   548  	pool.mu.Lock()
   549  	defer pool.mu.Unlock()
   550  
   551  	pending := make(map[common.Address]types.Transactions)
   552  	for addr, list := range pool.pending {
   553  		pending[addr] = list.Flatten()
   554  	}
   555  	return pending, nil
   556  }
   557  
   558  //局部变量检索池当前认为是本地的帐户。
   559  func (pool *TxPool) Locals() []common.Address {
   560  	pool.mu.Lock()
   561  	defer pool.mu.Unlock()
   562  
   563  	return pool.locals.flatten()
   564  }
   565  
   566  //本地检索所有当前已知的本地事务,按来源分组
   567  //帐户并按nonce排序。返回的事务集是一个副本,可以
   568  //通过调用代码自由修改。
   569  func (pool *TxPool) local() map[common.Address]types.Transactions {
   570  	txs := make(map[common.Address]types.Transactions)
   571  	for addr := range pool.locals.accounts {
   572  		if pending := pool.pending[addr]; pending != nil {
   573  			txs[addr] = append(txs[addr], pending.Flatten()...)
   574  		}
   575  		if queued := pool.queue[addr]; queued != nil {
   576  			txs[addr] = append(txs[addr], queued.Flatten()...)
   577  		}
   578  	}
   579  	return txs
   580  }
   581  
   582  //validatetx根据共识检查交易是否有效
   583  //规则并遵守本地节点的一些启发式限制(价格和大小)。
   584  func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
   585  //启发式限制,拒绝超过32KB的事务以防止DoS攻击
   586  	if tx.Size() > 32*1024 {
   587  		return ErrOversizedData
   588  	}
   589  //交易记录不能为负数。使用RLP解码可能永远不会发生这种情况。
   590  //但如果使用RPC创建事务,则可能发生事务。
   591  	if tx.Value().Sign() < 0 {
   592  		return ErrNegativeValue
   593  	}
   594  //确保交易不超过当前区块限制天然气。
   595  	if pool.currentMaxGas < tx.Gas() {
   596  		return ErrGasLimit
   597  	}
   598  //确保事务签名正确
   599  	from, err := types.Sender(pool.signer, tx)
   600  	if err != nil {
   601  		return ErrInvalidSender
   602  	}
   603  //以我们自己接受的最低天然气价格取消非本地交易
   604  local = local || pool.locals.contains(from) //即使事务从网络到达,帐户也可以是本地的
   605  	if !local && pool.gasPrice.Cmp(tx.GasPrice()) > 0 {
   606  		return ErrUnderpriced
   607  	}
   608  //确保事务遵循非紧急排序
   609  	if pool.currentState.GetNonce(from) > tx.Nonce() {
   610  		return ErrNonceTooLow
   611  	}
   612  //交易人应该有足够的资金来支付费用。
   613  //成本==V+gp*gl
   614  	if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 {
   615  		return ErrInsufficientFunds
   616  	}
   617  	intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead)
   618  	if err != nil {
   619  		return err
   620  	}
   621  	if tx.Gas() < intrGas {
   622  		return ErrIntrinsicGas
   623  	}
   624  	return nil
   625  }
   626  
   627  //添加验证事务并将其插入到的不可执行队列中
   628  //稍后等待提升和执行。如果交易是
   629  //一个已挂起或排队的,它将覆盖上一个并返回此
   630  //所以外部代码不会毫无用处地调用promote。
   631  //
   632  //如果新添加的事务标记为本地,则其发送帐户将
   633  //白名单,防止任何关联交易退出
   634  //由于定价限制而形成的池。
   635  func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) {
   636  //如果事务已经知道,则丢弃它
   637  	hash := tx.Hash()
   638  	if pool.all.Get(hash) != nil {
   639  		log.Trace("Discarding already known transaction", "hash", hash)
   640  		return false, fmt.Errorf("known transaction: %x", hash)
   641  	}
   642  //如果事务未能通过基本验证,则放弃它
   643  	if err := pool.validateTx(tx, local); err != nil {
   644  		log.Trace("Discarding invalid transaction", "hash", hash, "err", err)
   645  		invalidTxCounter.Inc(1)
   646  		return false, err
   647  	}
   648  //如果事务池已满,则放弃定价过低的事务
   649  	if uint64(pool.all.Count()) >= pool.config.GlobalSlots+pool.config.GlobalQueue {
   650  //如果新交易定价过低,不要接受
   651  		if !local && pool.priced.Underpriced(tx, pool.locals) {
   652  			log.Trace("Discarding underpriced transaction", "hash", hash, "price", tx.GasPrice())
   653  			underpricedTxCounter.Inc(1)
   654  			return false, ErrUnderpriced
   655  		}
   656  //新的交易比我们糟糕的交易好,给它腾出空间。
   657  		drop := pool.priced.Discard(pool.all.Count()-int(pool.config.GlobalSlots+pool.config.GlobalQueue-1), pool.locals)
   658  		for _, tx := range drop {
   659  			log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "price", tx.GasPrice())
   660  			underpricedTxCounter.Inc(1)
   661  			pool.removeTx(tx.Hash(), false)
   662  		}
   663  	}
   664  //如果事务正在替换已挂起的事务,请直接执行
   665  from, _ := types.Sender(pool.signer, tx) //已验证
   666  	if list := pool.pending[from]; list != nil && list.Overlaps(tx) {
   667  //一旦已经挂起,检查是否满足所需的价格上涨
   668  		inserted, old := list.Add(tx, pool.config.PriceBump)
   669  		if !inserted {
   670  			pendingDiscardCounter.Inc(1)
   671  			return false, ErrReplaceUnderpriced
   672  		}
   673  //新交易更好,替换旧交易
   674  		if old != nil {
   675  			pool.all.Remove(old.Hash())
   676  			pool.priced.Removed()
   677  			pendingReplaceCounter.Inc(1)
   678  		}
   679  		pool.all.Add(tx)
   680  		pool.priced.Put(tx)
   681  		pool.journalTx(from, tx)
   682  
   683  		log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To())
   684  
   685  //我们直接注入了一个替换事务,通知子系统
   686  		go pool.txFeed.Send(NewTxsEvent{types.Transactions{tx}})
   687  
   688  		return old != nil, nil
   689  	}
   690  //新事务没有替换挂起的事务,请推入队列
   691  	replace, err := pool.enqueueTx(hash, tx)
   692  	if err != nil {
   693  		return false, err
   694  	}
   695  //标记本地地址和日记帐本地交易记录
   696  	if local {
   697  		if !pool.locals.contains(from) {
   698  			log.Info("Setting new local account", "address", from)
   699  			pool.locals.add(from)
   700  		}
   701  	}
   702  	pool.journalTx(from, tx)
   703  
   704  	log.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To())
   705  	return replace, nil
   706  }
   707  
   708  //enqueuetx将新事务插入到不可执行的事务队列中。
   709  //
   710  //注意,此方法假定池锁被保持!
   711  func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction) (bool, error) {
   712  //尝试将事务插入将来的队列
   713  from, _ := types.Sender(pool.signer, tx) //已验证
   714  	if pool.queue[from] == nil {
   715  		pool.queue[from] = newTxList(false)
   716  	}
   717  	inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump)
   718  	if !inserted {
   719  //旧的交易更好,放弃这个
   720  		queuedDiscardCounter.Inc(1)
   721  		return false, ErrReplaceUnderpriced
   722  	}
   723  //放弃任何以前的交易并标记此交易
   724  	if old != nil {
   725  		pool.all.Remove(old.Hash())
   726  		pool.priced.Removed()
   727  		queuedReplaceCounter.Inc(1)
   728  	}
   729  	if pool.all.Get(hash) == nil {
   730  		pool.all.Add(tx)
   731  		pool.priced.Put(tx)
   732  	}
   733  	return old != nil, nil
   734  }
   735  
   736  //JournalTx将指定的事务添加到本地磁盘日志(如果是)
   737  //视为从本地帐户发送。
   738  func (pool *TxPool) journalTx(from common.Address, tx *types.Transaction) {
   739  //只有启用了日记帐且事务是本地的
   740  	if pool.journal == nil || !pool.locals.contains(from) {
   741  		return
   742  	}
   743  	if err := pool.journal.insert(tx); err != nil {
   744  		log.Warn("Failed to journal local transaction", "err", err)
   745  	}
   746  }
   747  
   748  //promotetx将事务添加到挂起(可处理)的事务列表中
   749  //并返回它是插入的还是旧的更好。
   750  //
   751  //注意,此方法假定池锁被保持!
   752  func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.Transaction) bool {
   753  //尝试将事务插入挂起队列
   754  	if pool.pending[addr] == nil {
   755  		pool.pending[addr] = newTxList(true)
   756  	}
   757  	list := pool.pending[addr]
   758  
   759  	inserted, old := list.Add(tx, pool.config.PriceBump)
   760  	if !inserted {
   761  //旧的交易更好,放弃这个
   762  		pool.all.Remove(hash)
   763  		pool.priced.Removed()
   764  
   765  		pendingDiscardCounter.Inc(1)
   766  		return false
   767  	}
   768  //否则放弃任何以前的交易并标记此
   769  	if old != nil {
   770  		pool.all.Remove(old.Hash())
   771  		pool.priced.Removed()
   772  
   773  		pendingReplaceCounter.Inc(1)
   774  	}
   775  //故障保护以绕过直接挂起的插入(测试)
   776  	if pool.all.Get(hash) == nil {
   777  		pool.all.Add(tx)
   778  		pool.priced.Put(tx)
   779  	}
   780  //设置潜在的新挂起nonce并通知新tx的任何子系统
   781  	pool.beats[addr] = time.Now()
   782  	pool.pendingState.SetNonce(addr, tx.Nonce()+1)
   783  
   784  	return true
   785  }
   786  
   787  //addlocal将单个事务排入池中(如果该事务有效),标记
   788  //同时将发送方作为本地发送方,确保它绕过本地发送方
   789  //定价限制。
   790  func (pool *TxPool) AddLocal(tx *types.Transaction) error {
   791  	return pool.addTx(tx, !pool.config.NoLocals)
   792  }
   793  
   794  //如果单个事务有效,则addremote将其排入池中。如果
   795  //发送方不属于本地跟踪的发送方,完全定价约束将
   796  //申请。
   797  func (pool *TxPool) AddRemote(tx *types.Transaction) error {
   798  	return pool.addTx(tx, false)
   799  }
   800  
   801  //addlocals将一批事务排队放入池中,如果它们有效,
   802  //同时将发送者标记为本地发送者,确保他们四处走动
   803  //本地定价限制。
   804  func (pool *TxPool) AddLocals(txs []*types.Transaction) []error {
   805  	return pool.addTxs(txs, !pool.config.NoLocals)
   806  }
   807  
   808  //如果一批事务有效,addremotes会将其排队放入池中。
   809  //如果发送方不在本地跟踪的发送方中,则完全定价约束
   810  //将适用。
   811  func (pool *TxPool) AddRemotes(txs []*types.Transaction) []error {
   812  	return pool.addTxs(txs, false)
   813  }
   814  
   815  //addtx将单个事务排队放入池中(如果该事务有效)。
   816  func (pool *TxPool) addTx(tx *types.Transaction, local bool) error {
   817  	pool.mu.Lock()
   818  	defer pool.mu.Unlock()
   819  
   820  //尝试插入事务并更新任何状态
   821  	replace, err := pool.add(tx, local)
   822  	if err != nil {
   823  		return err
   824  	}
   825  //如果我们添加了一个新事务,运行提升检查并返回
   826  	if !replace {
   827  from, _ := types.Sender(pool.signer, tx) //已验证
   828  		pool.promoteExecutables([]common.Address{from})
   829  	}
   830  	return nil
   831  }
   832  
   833  //如果一批事务有效,addtx将尝试对其进行排队。
   834  func (pool *TxPool) addTxs(txs []*types.Transaction, local bool) []error {
   835  	pool.mu.Lock()
   836  	defer pool.mu.Unlock()
   837  
   838  	return pool.addTxsLocked(txs, local)
   839  }
   840  
   841  //addtxtslocked尝试对一批事务进行排队,如果它们有效,
   842  //同时假定事务池锁已被持有。
   843  func (pool *TxPool) addTxsLocked(txs []*types.Transaction, local bool) []error {
   844  //添加交易批次,跟踪接受的交易
   845  	dirty := make(map[common.Address]struct{})
   846  	errs := make([]error, len(txs))
   847  
   848  	for i, tx := range txs {
   849  		var replace bool
   850  		if replace, errs[i] = pool.add(tx, local); errs[i] == nil && !replace {
   851  from, _ := types.Sender(pool.signer, tx) //已验证
   852  			dirty[from] = struct{}{}
   853  		}
   854  	}
   855  //仅当实际添加了某些内容时才重新处理内部状态
   856  	if len(dirty) > 0 {
   857  		addrs := make([]common.Address, 0, len(dirty))
   858  		for addr := range dirty {
   859  			addrs = append(addrs, addr)
   860  		}
   861  		pool.promoteExecutables(addrs)
   862  	}
   863  	return errs
   864  }
   865  
   866  //status返回一批事务的状态(未知/挂起/排队)
   867  //通过散列标识。
   868  func (pool *TxPool) Status(hashes []common.Hash) []TxStatus {
   869  	pool.mu.RLock()
   870  	defer pool.mu.RUnlock()
   871  
   872  	status := make([]TxStatus, len(hashes))
   873  	for i, hash := range hashes {
   874  		if tx := pool.all.Get(hash); tx != nil {
   875  from, _ := types.Sender(pool.signer, tx) //已验证
   876  			if pool.pending[from] != nil && pool.pending[from].txs.items[tx.Nonce()] != nil {
   877  				status[i] = TxStatusPending
   878  			} else {
   879  				status[i] = TxStatusQueued
   880  			}
   881  		}
   882  	}
   883  	return status
   884  }
   885  
   886  //get返回包含在池中的事务
   887  //否则为零。
   888  func (pool *TxPool) Get(hash common.Hash) *types.Transaction {
   889  	return pool.all.Get(hash)
   890  }
   891  
   892  //removetx从队列中删除单个事务,移动所有后续事务
   893  //事务返回到未来队列。
   894  func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) {
   895  //获取我们要删除的事务
   896  	tx := pool.all.Get(hash)
   897  	if tx == nil {
   898  		return
   899  	}
   900  addr, _ := types.Sender(pool.signer, tx) //已在插入过程中验证
   901  
   902  //将其从已知事务列表中删除
   903  	pool.all.Remove(hash)
   904  	if outofbound {
   905  		pool.priced.Removed()
   906  	}
   907  //从挂起列表中删除该事务并立即重置帐户
   908  	if pending := pool.pending[addr]; pending != nil {
   909  		if removed, invalids := pending.Remove(tx); removed {
   910  //如果没有剩余的挂起事务,请删除该列表
   911  			if pending.Empty() {
   912  				delete(pool.pending, addr)
   913  				delete(pool.beats, addr)
   914  			}
   915  //推迟任何失效的交易
   916  			for _, tx := range invalids {
   917  				pool.enqueueTx(tx.Hash(), tx)
   918  			}
   919  //如果需要,立即更新帐户
   920  			if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr) > nonce {
   921  				pool.pendingState.SetNonce(addr, nonce)
   922  			}
   923  			return
   924  		}
   925  	}
   926  //事务在将来的队列中
   927  	if future := pool.queue[addr]; future != nil {
   928  		future.Remove(tx)
   929  		if future.Empty() {
   930  			delete(pool.queue, addr)
   931  		}
   932  	}
   933  }
   934  
   935  //PromoteeExecutables将可从
   936  //对一组挂起事务的未来队列。在此过程中,所有
   937  //已删除失效的事务(低nonce、低余额)。
   938  func (pool *TxPool) promoteExecutables(accounts []common.Address) {
   939  //跟踪已提升的事务以立即广播它们
   940  	var promoted []*types.Transaction
   941  
   942  //收集所有可能需要更新的帐户
   943  	if accounts == nil {
   944  		accounts = make([]common.Address, 0, len(pool.queue))
   945  		for addr := range pool.queue {
   946  			accounts = append(accounts, addr)
   947  		}
   948  	}
   949  //遍历所有帐户并升级任何可执行事务
   950  	for _, addr := range accounts {
   951  		list := pool.queue[addr]
   952  		if list == nil {
   953  continue //以防有人用不存在的帐户打电话
   954  		}
   955  //删除所有被认为太旧的事务(低nonce)
   956  		for _, tx := range list.Forward(pool.currentState.GetNonce(addr)) {
   957  			hash := tx.Hash()
   958  			log.Trace("Removed old queued transaction", "hash", hash)
   959  			pool.all.Remove(hash)
   960  			pool.priced.Removed()
   961  		}
   962  //放弃所有成本过高的交易(低余额或无天然气)
   963  		drops, _ := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas)
   964  		for _, tx := range drops {
   965  			hash := tx.Hash()
   966  			log.Trace("Removed unpayable queued transaction", "hash", hash)
   967  			pool.all.Remove(hash)
   968  			pool.priced.Removed()
   969  			queuedNofundsCounter.Inc(1)
   970  		}
   971  //收集所有可执行事务并升级它们
   972  		for _, tx := range list.Ready(pool.pendingState.GetNonce(addr)) {
   973  			hash := tx.Hash()
   974  			if pool.promoteTx(addr, hash, tx) {
   975  				log.Trace("Promoting queued transaction", "hash", hash)
   976  				promoted = append(promoted, tx)
   977  			}
   978  		}
   979  //删除超过允许限制的所有交易记录
   980  		if !pool.locals.contains(addr) {
   981  			for _, tx := range list.Cap(int(pool.config.AccountQueue)) {
   982  				hash := tx.Hash()
   983  				pool.all.Remove(hash)
   984  				pool.priced.Removed()
   985  				queuedRateLimitCounter.Inc(1)
   986  				log.Trace("Removed cap-exceeding queued transaction", "hash", hash)
   987  			}
   988  		}
   989  //如果整个队列条目变为空,则将其删除。
   990  		if list.Empty() {
   991  			delete(pool.queue, addr)
   992  		}
   993  	}
   994  //为新升级的事务通知子系统。
   995  	if len(promoted) > 0 {
   996  		go pool.txFeed.Send(NewTxsEvent{promoted})
   997  	}
   998  //如果待定限额溢出,开始均衡限额
   999  	pending := uint64(0)
  1000  	for _, list := range pool.pending {
  1001  		pending += uint64(list.Len())
  1002  	}
  1003  	if pending > pool.config.GlobalSlots {
  1004  		pendingBeforeCap := pending
  1005  //首先收集一个垃圾邮件命令来惩罚大型交易对手
  1006  		spammers := prque.New(nil)
  1007  		for addr, list := range pool.pending {
  1008  //仅从高收入者逐出交易
  1009  			if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.AccountSlots {
  1010  				spammers.Push(addr, int64(list.Len()))
  1011  			}
  1012  		}
  1013  //逐步取消罪犯的交易
  1014  		offenders := []common.Address{}
  1015  		for pending > pool.config.GlobalSlots && !spammers.Empty() {
  1016  //如果不是本地地址,则检索下一个罪犯
  1017  			offender, _ := spammers.Pop()
  1018  			offenders = append(offenders, offender.(common.Address))
  1019  
  1020  //平衡平衡直到所有相同或低于阈值
  1021  			if len(offenders) > 1 {
  1022  //计算当前所有罪犯的均衡阈值
  1023  				threshold := pool.pending[offender.(common.Address)].Len()
  1024  
  1025  //反复减少所有违规者,直至达到限额或阈值以下。
  1026  				for pending > pool.config.GlobalSlots && pool.pending[offenders[len(offenders)-2]].Len() > threshold {
  1027  					for i := 0; i < len(offenders)-1; i++ {
  1028  						list := pool.pending[offenders[i]]
  1029  						for _, tx := range list.Cap(list.Len() - 1) {
  1030  //也从全局池中删除事务
  1031  							hash := tx.Hash()
  1032  							pool.all.Remove(hash)
  1033  							pool.priced.Removed()
  1034  
  1035  //将当前帐户更新为删除的交易记录
  1036  							if nonce := tx.Nonce(); pool.pendingState.GetNonce(offenders[i]) > nonce {
  1037  								pool.pendingState.SetNonce(offenders[i], nonce)
  1038  							}
  1039  							log.Trace("Removed fairness-exceeding pending transaction", "hash", hash)
  1040  						}
  1041  						pending--
  1042  					}
  1043  				}
  1044  			}
  1045  		}
  1046  //如果仍高于临界值,则降低至极限或最小允许值
  1047  		if pending > pool.config.GlobalSlots && len(offenders) > 0 {
  1048  			for pending > pool.config.GlobalSlots && uint64(pool.pending[offenders[len(offenders)-1]].Len()) > pool.config.AccountSlots {
  1049  				for _, addr := range offenders {
  1050  					list := pool.pending[addr]
  1051  					for _, tx := range list.Cap(list.Len() - 1) {
  1052  //也从全局池中删除事务
  1053  						hash := tx.Hash()
  1054  						pool.all.Remove(hash)
  1055  						pool.priced.Removed()
  1056  
  1057  //将当前帐户更新为删除的交易记录
  1058  						if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr) > nonce {
  1059  							pool.pendingState.SetNonce(addr, nonce)
  1060  						}
  1061  						log.Trace("Removed fairness-exceeding pending transaction", "hash", hash)
  1062  					}
  1063  					pending--
  1064  				}
  1065  			}
  1066  		}
  1067  		pendingRateLimitCounter.Inc(int64(pendingBeforeCap - pending))
  1068  	}
  1069  //如果排队的事务超过了硬限制,请删除最旧的事务。
  1070  	queued := uint64(0)
  1071  	for _, list := range pool.queue {
  1072  		queued += uint64(list.Len())
  1073  	}
  1074  	if queued > pool.config.GlobalQueue {
  1075  //按心跳对所有具有排队事务的帐户排序
  1076  		addresses := make(addressesByHeartbeat, 0, len(pool.queue))
  1077  		for addr := range pool.queue {
  1078  if !pool.locals.contains(addr) { //不要删除本地变量
  1079  				addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]})
  1080  			}
  1081  		}
  1082  		sort.Sort(addresses)
  1083  
  1084  //删除事务,直到总数低于限制或只保留局部变量
  1085  		for drop := queued - pool.config.GlobalQueue; drop > 0 && len(addresses) > 0; {
  1086  			addr := addresses[len(addresses)-1]
  1087  			list := pool.queue[addr.address]
  1088  
  1089  			addresses = addresses[:len(addresses)-1]
  1090  
  1091  //如果小于溢出,则删除所有事务
  1092  			if size := uint64(list.Len()); size <= drop {
  1093  				for _, tx := range list.Flatten() {
  1094  					pool.removeTx(tx.Hash(), true)
  1095  				}
  1096  				drop -= size
  1097  				queuedRateLimitCounter.Inc(int64(size))
  1098  				continue
  1099  			}
  1100  //否则只删除最后几个事务
  1101  			txs := list.Flatten()
  1102  			for i := len(txs) - 1; i >= 0 && drop > 0; i-- {
  1103  				pool.removeTx(txs[i].Hash(), true)
  1104  				drop--
  1105  				queuedRateLimitCounter.Inc(1)
  1106  			}
  1107  		}
  1108  	}
  1109  }
  1110  
  1111  //DemoteNextExecutables从池中删除无效和已处理的事务
  1112  //可执行/挂起队列以及任何无法执行的后续事务
  1113  //将移回将来的队列。
  1114  func (pool *TxPool) demoteUnexecutables() {
  1115  //迭代所有帐户并降级任何不可执行的事务
  1116  	for addr, list := range pool.pending {
  1117  		nonce := pool.currentState.GetNonce(addr)
  1118  
  1119  //删除所有被认为太旧的事务(低nonce)
  1120  		for _, tx := range list.Forward(nonce) {
  1121  			hash := tx.Hash()
  1122  			log.Trace("Removed old pending transaction", "hash", hash)
  1123  			pool.all.Remove(hash)
  1124  			pool.priced.Removed()
  1125  		}
  1126  //删除所有成本过高的事务(余额不足或没有汽油),并将任何无效的事务排队等待稍后处理。
  1127  		drops, invalids := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas)
  1128  		for _, tx := range drops {
  1129  			hash := tx.Hash()
  1130  			log.Trace("Removed unpayable pending transaction", "hash", hash)
  1131  			pool.all.Remove(hash)
  1132  			pool.priced.Removed()
  1133  			pendingNofundsCounter.Inc(1)
  1134  		}
  1135  		for _, tx := range invalids {
  1136  			hash := tx.Hash()
  1137  			log.Trace("Demoting pending transaction", "hash", hash)
  1138  			pool.enqueueTx(hash, tx)
  1139  		}
  1140  //如果前面有空白,警告(不应该发生)并推迟所有交易
  1141  		if list.Len() > 0 && list.txs.Get(nonce) == nil {
  1142  			for _, tx := range list.Cap(0) {
  1143  				hash := tx.Hash()
  1144  				log.Error("Demoting invalidated transaction", "hash", hash)
  1145  				pool.enqueueTx(hash, tx)
  1146  			}
  1147  		}
  1148  //如果整个队列条目变为空,则将其删除。
  1149  		if list.Empty() {
  1150  			delete(pool.pending, addr)
  1151  			delete(pool.beats, addr)
  1152  		}
  1153  	}
  1154  }
  1155  
  1156  //AddressByHeartbeat是用其最后一个活动时间戳标记的帐户地址。
  1157  type addressByHeartbeat struct {
  1158  	address   common.Address
  1159  	heartbeat time.Time
  1160  }
  1161  
  1162  type addressesByHeartbeat []addressByHeartbeat
  1163  
  1164  func (a addressesByHeartbeat) Len() int           { return len(a) }
  1165  func (a addressesByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) }
  1166  func (a addressesByHeartbeat) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
  1167  
  1168  //accountset只是检查是否存在的一组地址,以及一个签名者
  1169  //能够从交易中获得地址。
  1170  type accountSet struct {
  1171  	accounts map[common.Address]struct{}
  1172  	signer   types.Signer
  1173  	cache    *[]common.Address
  1174  }
  1175  
  1176  //newaccountset创建一个新地址集,其中包含发送者的关联签名者
  1177  //导子。
  1178  func newAccountSet(signer types.Signer) *accountSet {
  1179  	return &accountSet{
  1180  		accounts: make(map[common.Address]struct{}),
  1181  		signer:   signer,
  1182  	}
  1183  }
  1184  
  1185  //包含检查给定地址是否包含在集合中。
  1186  func (as *accountSet) contains(addr common.Address) bool {
  1187  	_, exist := as.accounts[addr]
  1188  	return exist
  1189  }
  1190  
  1191  //containstx检查给定Tx的发送方是否在集合内。如果发送者
  1192  //无法派生,此方法返回false。
  1193  func (as *accountSet) containsTx(tx *types.Transaction) bool {
  1194  	if addr, err := types.Sender(as.signer, tx); err == nil {
  1195  		return as.contains(addr)
  1196  	}
  1197  	return false
  1198  }
  1199  
  1200  //添加在要跟踪的集合中插入新地址。
  1201  func (as *accountSet) add(addr common.Address) {
  1202  	as.accounts[addr] = struct{}{}
  1203  	as.cache = nil
  1204  }
  1205  
  1206  //flatten返回此集合中的地址列表,并将其缓存以备以后使用
  1207  //重新使用。The returned slice should not be changed!
  1208  func (as *accountSet) flatten() []common.Address {
  1209  	if as.cache == nil {
  1210  		accounts := make([]common.Address, 0, len(as.accounts))
  1211  		for account := range as.accounts {
  1212  			accounts = append(accounts, account)
  1213  		}
  1214  		as.cache = &accounts
  1215  	}
  1216  	return *as.cache
  1217  }
  1218  
  1219  //TXLoopUp在TXPLE内部用于跟踪事务,同时允许查找
  1220  //互斥争用。
  1221  //
  1222  //注意,尽管此类型受到适当的保护,以防并发访问,但它
  1223  //是**不是**类型,应该在
  1224  //事务池,因为它的内部状态与池紧密耦合
  1225  //内部机制。该类型的唯一目的是允许出界
  1226  //偷看txpool中的池。无需获取范围广泛的
  1227  //txpool.mutex。
  1228  type txLookup struct {
  1229  	all  map[common.Hash]*types.Transaction
  1230  	lock sync.RWMutex
  1231  }
  1232  
  1233  //new txlookup返回新的txlookup结构。
  1234  func newTxLookup() *txLookup {
  1235  	return &txLookup{
  1236  		all: make(map[common.Hash]*types.Transaction),
  1237  	}
  1238  }
  1239  
  1240  //范围对地图中的每个键和值调用f。
  1241  func (t *txLookup) Range(f func(hash common.Hash, tx *types.Transaction) bool) {
  1242  	t.lock.RLock()
  1243  	defer t.lock.RUnlock()
  1244  
  1245  	for key, value := range t.all {
  1246  		if !f(key, value) {
  1247  			break
  1248  		}
  1249  	}
  1250  }
  1251  
  1252  //get返回查找中存在的事务,如果未找到则返回nil。
  1253  func (t *txLookup) Get(hash common.Hash) *types.Transaction {
  1254  	t.lock.RLock()
  1255  	defer t.lock.RUnlock()
  1256  
  1257  	return t.all[hash]
  1258  }
  1259  
  1260  //count返回查找中的当前项目数。
  1261  func (t *txLookup) Count() int {
  1262  	t.lock.RLock()
  1263  	defer t.lock.RUnlock()
  1264  
  1265  	return len(t.all)
  1266  }
  1267  
  1268  //添加将事务添加到查找中。
  1269  func (t *txLookup) Add(tx *types.Transaction) {
  1270  	t.lock.Lock()
  1271  	defer t.lock.Unlock()
  1272  
  1273  	t.all[tx.Hash()] = tx
  1274  }
  1275  
  1276  //删除从查找中删除事务。
  1277  func (t *txLookup) Remove(hash common.Hash) {
  1278  	t.lock.Lock()
  1279  	defer t.lock.Unlock()
  1280  
  1281  	delete(t.all, hash)
  1282  }
  1283