github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/tx_list.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  //版权所有2016 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  	"container/heap"
    29  	"math"
    30  	"math/big"
    31  	"sort"
    32  
    33  	"github.com/ethereum/go-ethereum/common"
    34  	"github.com/ethereum/go-ethereum/core/types"
    35  	"github.com/ethereum/go-ethereum/log"
    36  )
    37  
    38  //nonceheap是堆。接口实现超过64位无符号整数
    39  //从可能有间隙的未来队列中检索已排序的事务。
    40  type nonceHeap []uint64
    41  
    42  func (h nonceHeap) Len() int           { return len(h) }
    43  func (h nonceHeap) Less(i, j int) bool { return h[i] < h[j] }
    44  func (h nonceHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
    45  
    46  func (h *nonceHeap) Push(x interface{}) {
    47  	*h = append(*h, x.(uint64))
    48  }
    49  
    50  func (h *nonceHeap) Pop() interface{} {
    51  	old := *h
    52  	n := len(old)
    53  	x := old[n-1]
    54  	*h = old[0 : n-1]
    55  	return x
    56  }
    57  
    58  //txsortedmap是一个nonce->transaction哈希映射,具有基于堆的索引,允许
    59  //以非递增方式迭代内容。
    60  type txSortedMap struct {
    61  items map[uint64]*types.Transaction //存储事务数据的哈希图
    62  index *nonceHeap                    //所有存储事务的当前堆(非严格模式)
    63  cache types.Transactions            //缓存已排序的事务
    64  }
    65  
    66  //newtxsortedmap创建新的非ce排序事务映射。
    67  func newTxSortedMap() *txSortedMap {
    68  	return &txSortedMap{
    69  		items: make(map[uint64]*types.Transaction),
    70  		index: new(nonceHeap),
    71  	}
    72  }
    73  
    74  //get检索与给定nonce关联的当前事务。
    75  func (m *txSortedMap) Get(nonce uint64) *types.Transaction {
    76  	return m.items[nonce]
    77  }
    78  
    79  //在映射中插入新事务,同时更新映射的nonce
    80  //索引。如果已存在具有相同nonce的事务,则将覆盖该事务。
    81  func (m *txSortedMap) Put(tx *types.Transaction) {
    82  	nonce := tx.Nonce()
    83  	if m.items[nonce] == nil {
    84  		heap.Push(m.index, nonce)
    85  	}
    86  	m.items[nonce], m.cache = tx, nil
    87  }
    88  
    89  //forward从映射中删除所有事务,其中nonce小于
    90  //提供阈值。对于任何删除后的事务,都会返回每个已删除的事务。
    91  //维护。
    92  func (m *txSortedMap) Forward(threshold uint64) types.Transactions {
    93  	var removed types.Transactions
    94  
    95  //弹出堆项,直到达到阈值
    96  	for m.index.Len() > 0 && (*m.index)[0] < threshold {
    97  		nonce := heap.Pop(m.index).(uint64)
    98  		removed = append(removed, m.items[nonce])
    99  		delete(m.items, nonce)
   100  	}
   101  //如果我们有一个缓存的订单,转移前面
   102  	if m.cache != nil {
   103  		m.cache = m.cache[len(removed):]
   104  	}
   105  	return removed
   106  }
   107  
   108  //筛选器迭代事务列表并删除其中所有
   109  //指定函数的计算结果为true。
   110  func (m *txSortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions {
   111  	var removed types.Transactions
   112  
   113  //收集所有事务以筛选出
   114  	for nonce, tx := range m.items {
   115  		if filter(tx) {
   116  			removed = append(removed, tx)
   117  			delete(m.items, nonce)
   118  		}
   119  	}
   120  //如果删除了事务,则会破坏堆和缓存
   121  	if len(removed) > 0 {
   122  		*m.index = make([]uint64, 0, len(m.items))
   123  		for nonce := range m.items {
   124  			*m.index = append(*m.index, nonce)
   125  		}
   126  		heap.Init(m.index)
   127  
   128  		m.cache = nil
   129  	}
   130  	return removed
   131  }
   132  
   133  //cap对项目数进行硬限制,返回所有事务
   134  //超过那个限度。
   135  func (m *txSortedMap) Cap(threshold int) types.Transactions {
   136  //项目数量低于限制时短路
   137  	if len(m.items) <= threshold {
   138  		return nil
   139  	}
   140  //否则,收集并删除最高的非ce'd事务
   141  	var drops types.Transactions
   142  
   143  	sort.Sort(*m.index)
   144  	for size := len(m.items); size > threshold; size-- {
   145  		drops = append(drops, m.items[(*m.index)[size-1]])
   146  		delete(m.items, (*m.index)[size-1])
   147  	}
   148  	*m.index = (*m.index)[:threshold]
   149  	heap.Init(m.index)
   150  
   151  //如果我们有一个缓存,把它移到后面
   152  	if m.cache != nil {
   153  		m.cache = m.cache[:len(m.cache)-len(drops)]
   154  	}
   155  	return drops
   156  }
   157  
   158  //移除从维护的映射中删除事务,返回
   159  //找到事务。
   160  func (m *txSortedMap) Remove(nonce uint64) bool {
   161  //无交易时短路
   162  	_, ok := m.items[nonce]
   163  	if !ok {
   164  		return false
   165  	}
   166  //否则,删除事务并修复堆索引
   167  	for i := 0; i < m.index.Len(); i++ {
   168  		if (*m.index)[i] == nonce {
   169  			heap.Remove(m.index, i)
   170  			break
   171  		}
   172  	}
   173  	delete(m.items, nonce)
   174  	m.cache = nil
   175  
   176  	return true
   177  }
   178  
   179  //就绪检索从
   180  //提供了一个准备好进行处理的nonce。返回的事务将
   181  //已从列表中删除。
   182  //
   183  //注意,所有非起始值低于起始值的事务也将返回到
   184  //防止进入无效状态。这不是应该有的事
   185  //发生但最好是自我纠正而不是失败!
   186  func (m *txSortedMap) Ready(start uint64) types.Transactions {
   187  //如果没有可用的交易,则短路
   188  	if m.index.Len() == 0 || (*m.index)[0] > start {
   189  		return nil
   190  	}
   191  //否则开始累积增量事务
   192  	var ready types.Transactions
   193  	for next := (*m.index)[0]; m.index.Len() > 0 && (*m.index)[0] == next; next++ {
   194  		ready = append(ready, m.items[next])
   195  		delete(m.items, next)
   196  		heap.Pop(m.index)
   197  	}
   198  	m.cache = nil
   199  
   200  	return ready
   201  }
   202  
   203  //len返回事务映射的长度。
   204  func (m *txSortedMap) Len() int {
   205  	return len(m.items)
   206  }
   207  
   208  //Flatten基于松散的
   209  //已排序的内部表示。排序结果缓存在
   210  //在对内容进行任何修改之前,需要再次修改。
   211  func (m *txSortedMap) Flatten() types.Transactions {
   212  //如果排序尚未缓存,请创建并缓存排序
   213  	if m.cache == nil {
   214  		m.cache = make(types.Transactions, 0, len(m.items))
   215  		for _, tx := range m.items {
   216  			m.cache = append(m.cache, tx)
   217  		}
   218  		sort.Sort(types.TxByNonce(m.cache))
   219  	}
   220  //复制缓存以防止意外修改
   221  	txs := make(types.Transactions, len(m.cache))
   222  	copy(txs, m.cache)
   223  	return txs
   224  }
   225  
   226  //txlist是属于一个账户的交易的“列表”,按账户排序。
   227  //临时的同一类型可用于存储
   228  //可执行/挂起队列;用于存储非-
   229  //可执行/将来的队列,有轻微的行为更改。
   230  type txList struct {
   231  strict bool         //是否严格连续
   232  txs    *txSortedMap //事务的堆索引排序哈希图
   233  
   234  costcap *big.Int //最高成本核算交易记录的价格(仅当超过余额时重置)
   235  gascap  uint64   //最高支出交易的气体限额(仅在超过区块限额时重置)
   236  }
   237  
   238  //newtxlist创建一个新的事务列表,用于快速维护非索引,
   239  //有间隙、可排序的事务列表。
   240  func newTxList(strict bool) *txList {
   241  	return &txList{
   242  		strict:  strict,
   243  		txs:     newTxSortedMap(),
   244  		costcap: new(big.Int),
   245  	}
   246  }
   247  
   248  //overlaps返回指定的事务是否与一个事务具有相同的nonce
   249  //已经包含在列表中。
   250  func (l *txList) Overlaps(tx *types.Transaction) bool {
   251  	return l.txs.Get(tx.Nonce()) != nil
   252  }
   253  
   254  //add尝试将新事务插入列表,返回
   255  //交易已被接受,如果是,则替换以前的任何交易。
   256  //
   257  //如果新交易被接受到清单中,清单的成本和天然气
   258  //阈值也可能更新。
   259  func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transaction) {
   260  //如果有旧的更好的事务,请中止
   261  	old := l.txs.Get(tx.Nonce())
   262  	if old != nil {
   263  		threshold := new(big.Int).Div(new(big.Int).Mul(old.GasPrice(), big.NewInt(100+int64(priceBump))), big.NewInt(100))
   264  //必须确保新的天然气价格高于旧的天然气价格
   265  //价格以及检查百分比阈值以确保
   266  //这对于低(wei级)天然气价格的替代品是准确的。
   267  		if old.GasPrice().Cmp(tx.GasPrice()) >= 0 || threshold.Cmp(tx.GasPrice()) > 0 {
   268  			return false, nil
   269  		}
   270  	}
   271  //否则,用当前事务覆盖旧事务
   272  	l.txs.Put(tx)
   273  	if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 {
   274  		l.costcap = cost
   275  	}
   276  	if gas := tx.Gas(); l.gascap < gas {
   277  		l.gascap = gas
   278  	}
   279  	return true, old
   280  }
   281  
   282  //Forward从列表中删除所有事务,其中一个nonce低于
   283  //提供阈值。对于任何删除后的事务,都会返回每个已删除的事务。
   284  //维护。
   285  func (l *txList) Forward(threshold uint64) types.Transactions {
   286  	return l.txs.Forward(threshold)
   287  }
   288  
   289  //过滤器从列表中删除成本或气体限制更高的所有事务
   290  //超过提供的阈值。对于任何
   291  //拆卸后维护。严格模式失效的事务也
   292  //返回。
   293  //
   294  //此方法使用缓存的CostCap和GasCap快速确定
   295  //计算所有成本的一个点,或者如果余额覆盖了所有成本。如果门槛
   296  //低于costgas上限,移除后上限将重置为新的上限
   297  //新失效的交易。
   298  func (l *txList) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions, types.Transactions) {
   299  //如果所有事务低于阈值,则短路
   300  	if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit {
   301  		return nil, nil
   302  	}
   303  l.costcap = new(big.Int).Set(costLimit) //将上限降低到阈值
   304  	l.gascap = gasLimit
   305  
   306  //过滤掉账户资金上方的所有交易
   307  	removed := l.txs.Filter(func(tx *types.Transaction) bool { return tx.Cost().Cmp(costLimit) > 0 || tx.Gas() > gasLimit })
   308  
   309  //如果列表是严格的,则筛选高于最低当前值的任何内容
   310  	var invalids types.Transactions
   311  
   312  	if l.strict && len(removed) > 0 {
   313  		lowest := uint64(math.MaxUint64)
   314  		for _, tx := range removed {
   315  			if nonce := tx.Nonce(); lowest > nonce {
   316  				lowest = nonce
   317  			}
   318  		}
   319  		invalids = l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > lowest })
   320  	}
   321  	return removed, invalids
   322  }
   323  
   324  //cap对项目数进行硬限制,返回所有事务
   325  //超过那个限度。
   326  func (l *txList) Cap(threshold int) types.Transactions {
   327  	return l.txs.Cap(threshold)
   328  }
   329  
   330  //移除从维护列表中删除事务,返回
   331  //找到交易,并返回因以下原因而失效的任何交易
   332  //删除(仅限严格模式)。
   333  func (l *txList) Remove(tx *types.Transaction) (bool, types.Transactions) {
   334  //从集合中移除事务
   335  	nonce := tx.Nonce()
   336  	if removed := l.txs.Remove(nonce); !removed {
   337  		return false, nil
   338  	}
   339  //在严格模式下,筛选出不可执行的事务
   340  	if l.strict {
   341  		return true, l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > nonce })
   342  	}
   343  	return true, nil
   344  }
   345  
   346  //就绪检索从
   347  //提供了一个准备好进行处理的nonce。返回的事务将
   348  //已从列表中删除。
   349  //
   350  //注意,所有非起始值低于起始值的事务也将返回到
   351  //防止进入无效状态。这不是应该有的事
   352  //发生但最好是自我纠正而不是失败!
   353  func (l *txList) Ready(start uint64) types.Transactions {
   354  	return l.txs.Ready(start)
   355  }
   356  
   357  //len返回事务列表的长度。
   358  func (l *txList) Len() int {
   359  	return l.txs.Len()
   360  }
   361  
   362  //empty返回事务列表是否为空。
   363  func (l *txList) Empty() bool {
   364  	return l.Len() == 0
   365  }
   366  
   367  //Flatten基于松散的
   368  //已排序的内部表示。排序结果缓存在
   369  //在对内容进行任何修改之前,需要再次修改。
   370  func (l *txList) Flatten() types.Transactions {
   371  	return l.txs.Flatten()
   372  }
   373  
   374  //PriceHeap是一个堆。用于检索的事务的接口实现
   375  //池满时要丢弃的按价格排序的交易记录。
   376  type priceHeap []*types.Transaction
   377  
   378  func (h priceHeap) Len() int      { return len(h) }
   379  func (h priceHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
   380  
   381  func (h priceHeap) Less(i, j int) bool {
   382  //主要按价格排序,返回较便宜的
   383  	switch h[i].GasPrice().Cmp(h[j].GasPrice()) {
   384  	case -1:
   385  		return true
   386  	case 1:
   387  		return false
   388  	}
   389  //如果价格匹配,通过nonce稳定(高nonce更糟)
   390  	return h[i].Nonce() > h[j].Nonce()
   391  }
   392  
   393  func (h *priceHeap) Push(x interface{}) {
   394  	*h = append(*h, x.(*types.Transaction))
   395  }
   396  
   397  func (h *priceHeap) Pop() interface{} {
   398  	old := *h
   399  	n := len(old)
   400  	x := old[n-1]
   401  	*h = old[0 : n-1]
   402  	return x
   403  }
   404  
   405  //txPricedList是一个价格排序堆,允许对事务池进行操作
   406  //价格递增的内容。
   407  type txPricedList struct {
   408  all    *txLookup  //指向所有事务映射的指针
   409  items  *priceHeap //所有存储事务的价格堆
   410  stales int        //失效价格点的数目(重新堆触发器)
   411  }
   412  
   413  //newtxPricedList创建一个新的按价格排序的事务堆。
   414  func newTxPricedList(all *txLookup) *txPricedList {
   415  	return &txPricedList{
   416  		all:   all,
   417  		items: new(priceHeap),
   418  	}
   419  }
   420  
   421  //PUT向堆中插入新事务。
   422  func (l *txPricedList) Put(tx *types.Transaction) {
   423  	heap.Push(l.items, tx)
   424  }
   425  
   426  //已删除通知价格事务列表旧事务已删除
   427  //从游泳池。列表只保留过时对象的计数器并更新
   428  //如果足够大的事务比率过时,则为堆。
   429  func (l *txPricedList) Removed() {
   430  //撞击陈旧的计数器,但如果仍然过低(<25%),则退出。
   431  	l.stales++
   432  	if l.stales <= len(*l.items)/4 {
   433  		return
   434  	}
   435  //似乎我们已经达到了一个关键的陈旧的交易数量,reheap
   436  	reheap := make(priceHeap, 0, l.all.Count())
   437  
   438  	l.stales, l.items = 0, &reheap
   439  	l.all.Range(func(hash common.Hash, tx *types.Transaction) bool {
   440  		*l.items = append(*l.items, tx)
   441  		return true
   442  	})
   443  	heap.Init(l.items)
   444  }
   445  
   446  //cap查找低于给定价格阈值的所有交易,并将其删除
   447  //从定价列表中返回它们以便从整个池中进一步删除。
   448  func (l *txPricedList) Cap(threshold *big.Int, local *accountSet) types.Transactions {
   449  drop := make(types.Transactions, 0, 128) //要删除的远程低价交易
   450  save := make(types.Transactions, 0, 64)  //要保留的本地定价过低交易
   451  
   452  	for len(*l.items) > 0 {
   453  //如果在清理过程中发现过时的事务,则放弃这些事务
   454  		tx := heap.Pop(l.items).(*types.Transaction)
   455  		if l.all.Get(tx.Hash()) == nil {
   456  			l.stales--
   457  			continue
   458  		}
   459  //如果我们达到了临界值,就停止丢弃
   460  		if tx.GasPrice().Cmp(threshold) >= 0 {
   461  			save = append(save, tx)
   462  			break
   463  		}
   464  //找到未过期的事务,除非本地
   465  		if local.containsTx(tx) {
   466  			save = append(save, tx)
   467  		} else {
   468  			drop = append(drop, tx)
   469  		}
   470  	}
   471  	for _, tx := range save {
   472  		heap.Push(l.items, tx)
   473  	}
   474  	return drop
   475  }
   476  
   477  //低价检查交易是否比
   478  //当前正在跟踪的最低价格交易记录。
   479  func (l *txPricedList) Underpriced(tx *types.Transaction, local *accountSet) bool {
   480  //本地交易不能定价过低
   481  	if local.containsTx(tx) {
   482  		return false
   483  	}
   484  //如果在堆开始处找到过时的价格点,则丢弃它们
   485  	for len(*l.items) > 0 {
   486  		head := []*types.Transaction(*l.items)[0]
   487  		if l.all.Get(head.Hash()) == nil {
   488  			l.stales--
   489  			heap.Pop(l.items)
   490  			continue
   491  		}
   492  		break
   493  	}
   494  //检查交易是否定价过低
   495  	if len(*l.items) == 0 {
   496  log.Error("Pricing query for empty pool") //这不可能发生,打印以捕获编程错误
   497  		return false
   498  	}
   499  	cheapest := []*types.Transaction(*l.items)[0]
   500  	return cheapest.GasPrice().Cmp(tx.GasPrice()) >= 0
   501  }
   502  
   503  //Discard查找许多定价最低的事务,将它们从
   504  //并返回它们以便从整个池中进一步删除。
   505  func (l *txPricedList) Discard(count int, local *accountSet) types.Transactions {
   506  drop := make(types.Transactions, 0, count) //要删除的远程低价交易
   507  save := make(types.Transactions, 0, 64)    //要保留的本地定价过低交易
   508  
   509  	for len(*l.items) > 0 && count > 0 {
   510  //如果在清理过程中发现过时的事务,则放弃这些事务
   511  		tx := heap.Pop(l.items).(*types.Transaction)
   512  		if l.all.Get(tx.Hash()) == nil {
   513  			l.stales--
   514  			continue
   515  		}
   516  //找到未过期的事务,除非本地
   517  		if local.containsTx(tx) {
   518  			save = append(save, tx)
   519  		} else {
   520  			drop = append(drop, tx)
   521  			count--
   522  		}
   523  	}
   524  	for _, tx := range save {
   525  		heap.Push(l.items, tx)
   526  	}
   527  	return drop
   528  }