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 }