github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/tx_pool.go (about)

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