github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/miner/unconfirmed.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:40</date> 10 //</624450100587925504> 11 12 13 package miner 14 15 import ( 16 "container/ring" 17 "sync" 18 19 "github.com/ethereum/go-ethereum/common" 20 "github.com/ethereum/go-ethereum/core/types" 21 "github.com/ethereum/go-ethereum/log" 22 ) 23 24 //未确认的块集使用chainretriever来验证 25 //挖掘块是否为规范链的一部分。 26 type chainRetriever interface { 27 //GetHeaderByNumber检索与块号关联的规范头。 28 GetHeaderByNumber(number uint64) *types.Header 29 30 //GetBlockByNumber检索与块号关联的规范块。 31 GetBlockByNumber(number uint64) *types.Block 32 } 33 34 //unconfirmedBlock是关于本地挖掘块的一小部分元数据集合。 35 //它被放入一个未确认的集合中,用于规范链包含跟踪。 36 type unconfirmedBlock struct { 37 index uint64 38 hash common.Hash 39 } 40 41 //unconfirmedBlocks实现数据结构以维护本地挖掘的块 42 //尚未达到足够的成熟度,无法保证连锁经营。它是 43 //当先前挖掘的块被挖掘时,矿工用来向用户提供日志。 44 //有一个足够高的保证不会被重新排列出规范链。 45 type unconfirmedBlocks struct { 46 chain chainRetriever //通过区块链验证规范状态 47 depth uint //丢弃以前块的深度 48 blocks *ring.Ring //阻止信息以允许规范链交叉检查 49 lock sync.RWMutex //防止字段并发访问 50 } 51 52 //NewUnconfirmedBlocks返回新的数据结构以跟踪当前未确认的块。 53 func newUnconfirmedBlocks(chain chainRetriever, depth uint) *unconfirmedBlocks { 54 return &unconfirmedBlocks{ 55 chain: chain, 56 depth: depth, 57 } 58 } 59 60 //insert向未确认的块集添加新的块。 61 func (set *unconfirmedBlocks) Insert(index uint64, hash common.Hash) { 62 //如果在当地开采了一个新的矿块,就要把足够旧的矿块移开。 63 set.Shift(index) 64 65 //将新项创建为其自己的环 66 item := ring.New(1) 67 item.Value = &unconfirmedBlock{ 68 index: index, 69 hash: hash, 70 } 71 //设置为初始环或附加到结尾 72 set.lock.Lock() 73 defer set.lock.Unlock() 74 75 if set.blocks == nil { 76 set.blocks = item 77 } else { 78 set.blocks.Move(-1).Link(item) 79 } 80 //显示一个日志,供用户通知未确认的新挖掘块 81 log.Info("🔨 mined potential block", "number", index, "hash", hash) 82 } 83 84 //SHIFT从集合中删除所有未确认的块,这些块超过未确认的集合深度 85 //允许,对照标准链检查它们是否包含或过时。 86 //报告。 87 func (set *unconfirmedBlocks) Shift(height uint64) { 88 set.lock.Lock() 89 defer set.lock.Unlock() 90 91 for set.blocks != nil { 92 //检索下一个未确认的块,如果太新则中止 93 next := set.blocks.Value.(*unconfirmedBlock) 94 if next.index+uint64(set.depth) > height { 95 break 96 } 97 //块似乎超出深度允许,检查规范状态 98 header := set.chain.GetHeaderByNumber(next.index) 99 switch { 100 case header == nil: 101 log.Warn("Failed to retrieve header of mined block", "number", next.index, "hash", next.hash) 102 case header.Hash() == next.hash: 103 log.Info("🔗 block reached canonical chain", "number", next.index, "hash", next.hash) 104 default: 105 //块不规范,请检查是否有叔叔或丢失的块 106 included := false 107 for number := next.index; !included && number < next.index+uint64(set.depth) && number <= height; number++ { 108 if block := set.chain.GetBlockByNumber(number); block != nil { 109 for _, uncle := range block.Uncles() { 110 if uncle.Hash() == next.hash { 111 included = true 112 break 113 } 114 } 115 } 116 } 117 if included { 118 log.Info("⑂ block became an uncle", "number", next.index, "hash", next.hash) 119 } else { 120 log.Info("😱 block lost", "number", next.index, "hash", next.hash) 121 } 122 } 123 //把木块从环里拿出来 124 if set.blocks.Value == set.blocks.Next().Value { 125 set.blocks = nil 126 } else { 127 set.blocks = set.blocks.Move(-1) 128 set.blocks.Unlink(1) 129 set.blocks = set.blocks.Move(1) 130 } 131 } 132 } 133