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