github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/consensus/clique/clique.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 12:09:32</date>
    10  //</624342610781147136>
    11  
    12  
    13  //包裹集团实施权威证明共识引擎。
    14  package clique
    15  
    16  import (
    17  	"bytes"
    18  	"errors"
    19  	"math/big"
    20  	"math/rand"
    21  	"sync"
    22  	"time"
    23  
    24  	"github.com/ethereum/go-ethereum/accounts"
    25  	"github.com/ethereum/go-ethereum/common"
    26  	"github.com/ethereum/go-ethereum/common/hexutil"
    27  	"github.com/ethereum/go-ethereum/consensus"
    28  	"github.com/ethereum/go-ethereum/consensus/misc"
    29  	"github.com/ethereum/go-ethereum/core/state"
    30  	"github.com/ethereum/go-ethereum/core/types"
    31  	"github.com/ethereum/go-ethereum/crypto"
    32  	"github.com/ethereum/go-ethereum/crypto/sha3"
    33  	"github.com/ethereum/go-ethereum/ethdb"
    34  	"github.com/ethereum/go-ethereum/log"
    35  	"github.com/ethereum/go-ethereum/params"
    36  	"github.com/ethereum/go-ethereum/rlp"
    37  	"github.com/ethereum/go-ethereum/rpc"
    38  	lru "github.com/hashicorp/golang-lru"
    39  )
    40  
    41  const (
    42  checkpointInterval = 1024 //将投票快照保存到数据库之后的块数
    43  inmemorySnapshots  = 128  //要保留在内存中的最近投票快照数
    44  inmemorySignatures = 4096 //要保存在内存中的最近块签名数
    45  
    46  wiggleTime = 500 * time.Millisecond //允许并发签名者的随机延迟(每个签名者)
    47  )
    48  
    49  //集团权威证明协议常数。
    50  var (
    51  epochLength = uint64(30000) //在其之后检查和重置挂起投票的默认块数
    52  
    53  extraVanity = 32 //固定为签名者虚荣保留的额外数据前缀字节数
    54  extraSeal   = 65 //固定为签名者密封保留的额外数据后缀字节数
    55  
    56  nonceAuthVote = hexutil.MustDecode("0xffffffffffffffff") //
    57  nonceDropVote = hexutil.MustDecode("0x0000000000000000") //要在删除签名者时投票的Magic nonce编号。
    58  
    59  uncleHash = types.CalcUncleHash(nil) //作为叔叔,Keccak256(rlp([])在POW之外总是毫无意义的。
    60  
    61  diffInTurn = big.NewInt(2) //阻止依次签名的困难
    62  diffNoTurn = big.NewInt(1) //阻止错误签名的困难
    63  )
    64  
    65  //将块标记为无效的各种错误消息。这些应该是私人的
    66  //防止在
    67  //代码库,如果引擎被换出,则固有的中断。请把普通
    68  //共识包中的错误类型。
    69  var (
    70  //当请求块的签名者列表时,返回errunknownblock。
    71  //这不是本地区块链的一部分。
    72  	errUnknownBlock = errors.New("unknown block")
    73  
    74  //如果检查点/时代转换,则返回errInvalidCheckpoint受益人
    75  //块的受益人设置为非零。
    76  	errInvalidCheckpointBeneficiary = errors.New("beneficiary in checkpoint block non-zero")
    77  
    78  //
    79  //
    80  	errInvalidVote = errors.New("vote nonce not 0x00..0 or 0xff..f")
    81  
    82  //如果检查点/epoch转换块,则返回errInvalidCheckpointVote
    83  //将投票当前设置为非零。
    84  	errInvalidCheckpointVote = errors.New("vote nonce in checkpoint block non-zero")
    85  
    86  //如果块的额外数据节短于
    87  //32字节,这是存储签名者虚荣所必需的。
    88  	errMissingVanity = errors.New("extra-data 32 byte vanity prefix missing")
    89  
    90  //
    91  //包含65字节的secp256k1签名。
    92  	errMissingSignature = errors.New("extra-data 65 byte suffix signature missing")
    93  
    94  //如果非检查点块中包含签名者数据,则返回errExtrasigners。
    95  //它们的额外数据字段。
    96  	errExtraSigners = errors.New("non-checkpoint block contains extra signer list")
    97  
    98  //如果检查点块包含
    99  //签名者列表无效(即不能被20字节整除,或不正确
   100  //那些)
   101  	errInvalidCheckpointSigners = errors.New("invalid signer list on checkpoint block")
   102  
   103  //如果块的mix digest为非零,则返回errInvalidMixDigest。
   104  	errInvalidMixDigest = errors.New("non-zero mix digest")
   105  
   106  //如果块包含非空的叔叔列表,则返回errInvalidUncleHash。
   107  	errInvalidUncleHash = errors.New("non empty uncle hash")
   108  
   109  //如果块的难度不是
   110  //1或2,或者如果值与签名者的圈数不匹配。
   111  	errInvalidDifficulty = errors.New("invalid difficulty")
   112  
   113  //如果块的时间戳低于,则返回errInvalidTimestamp
   114  //上一个块的时间戳+最小块周期。
   115  	ErrInvalidTimestamp = errors.New("invalid timestamp")
   116  
   117  //如果尝试授权列表,则返回errInvalidVotingChain
   118  //通过超出范围或不连续的标题进行修改。
   119  	errInvalidVotingChain = errors.New("invalid voting chain")
   120  
   121  //如果头由非授权实体签名,则返回errUnauthorized。
   122  	errUnauthorized = errors.New("unauthorized")
   123  
   124  //
   125  //在即时链上(0秒周期)。重要的是要拒绝这些
   126  //块奖励为零,所以一个空块会使链膨胀…快。
   127  	errWaitTransactions = errors.New("waiting for transactions")
   128  )
   129  
   130  //signerfn是一个签名者回调函数,用于请求哈希由
   131  //备用账户。
   132  type SignerFn func(accounts.Account, []byte) ([]byte, error)
   133  
   134  //sighash返回用作权限证明输入的哈希
   135  //
   136  //
   137  //
   138  //注意,该方法要求额外数据至少为65字节,否则
   139  //恐慌。这样做是为了避免意外使用这两个表单(存在签名
   140  //或者不是),这可能会被滥用,从而为同一个头产生不同的散列。
   141  func sigHash(header *types.Header) (hash common.Hash) {
   142  	hasher := sha3.NewKeccak256()
   143  
   144  	rlp.Encode(hasher, []interface{}{
   145  		header.ParentHash,
   146  		header.UncleHash,
   147  		header.Coinbase,
   148  		header.Root,
   149  		header.TxHash,
   150  		header.ReceiptHash,
   151  		header.Bloom,
   152  		header.Difficulty,
   153  		header.Number,
   154  		header.GasLimit,
   155  		header.GasUsed,
   156  		header.Time,
   157  header.Extra[:len(header.Extra)-65], //是的,如果多余的太短,这会很恐慌的
   158  		header.MixDigest,
   159  		header.Nonce,
   160  	})
   161  	hasher.Sum(hash[:0])
   162  	return hash
   163  }
   164  
   165  //ecrecover从签名的头中提取以太坊帐户地址。
   166  func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
   167  //如果签名已经缓存,则返回
   168  	hash := header.Hash()
   169  	if address, known := sigcache.Get(hash); known {
   170  		return address.(common.Address), nil
   171  	}
   172  //从头中检索签名额外数据
   173  	if len(header.Extra) < extraSeal {
   174  		return common.Address{}, errMissingSignature
   175  	}
   176  	signature := header.Extra[len(header.Extra)-extraSeal:]
   177  
   178  //恢复公钥和以太坊地址
   179  	pubkey, err := crypto.Ecrecover(sigHash(header).Bytes(), signature)
   180  	if err != nil {
   181  		return common.Address{}, err
   182  	}
   183  	var signer common.Address
   184  	copy(signer[:], crypto.Keccak256(pubkey[1:])[12:])
   185  
   186  	sigcache.Add(hash, signer)
   187  	return signer, nil
   188  }
   189  
   190  //集团是权威的证明,共识引擎建议支持
   191  //
   192  type Clique struct {
   193  config *params.CliqueConfig //共识引擎配置参数
   194  db     ethdb.Database       //存储和检索快照检查点的数据库
   195  
   196  recents    *lru.ARCCache //最近块的快照以加快重新排序
   197  signatures *lru.ARCCache //加快开采速度的近期区块特征
   198  
   199  proposals map[common.Address]bool //
   200  
   201  signer common.Address //签名密钥的以太坊地址
   202  signFn SignerFn       //用于授权哈希的签名程序函数
   203  lock   sync.RWMutex   //保护签名者字段
   204  }
   205  
   206  //新创建的集团权威证明共识引擎
   207  //签名者设置为用户提供的签名者。
   208  func New(config *params.CliqueConfig, db ethdb.Database) *Clique {
   209  //将所有缺少的共识参数设置为默认值
   210  	conf := *config
   211  	if conf.Epoch == 0 {
   212  		conf.Epoch = epochLength
   213  	}
   214  //分配快照缓存并创建引擎
   215  	recents, _ := lru.NewARC(inmemorySnapshots)
   216  	signatures, _ := lru.NewARC(inmemorySignatures)
   217  
   218  	return &Clique{
   219  		config:     &conf,
   220  		db:         db,
   221  		recents:    recents,
   222  		signatures: signatures,
   223  		proposals:  make(map[common.Address]bool),
   224  	}
   225  }
   226  
   227  //作者实现共识引擎,返回以太坊地址恢复
   228  //从标题的额外数据部分的签名。
   229  func (c *Clique) Author(header *types.Header) (common.Address, error) {
   230  	return ecrecover(header, c.signatures)
   231  }
   232  
   233  //verifyheader检查头是否符合共识规则。
   234  func (c *Clique) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
   235  	return c.verifyHeader(chain, header, nil)
   236  }
   237  
   238  //
   239  //方法返回一个退出通道以中止操作,并返回一个结果通道以
   240  //检索异步验证(顺序是输入切片的顺序)。
   241  func (c *Clique) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
   242  	abort := make(chan struct{})
   243  	results := make(chan error, len(headers))
   244  
   245  	go func() {
   246  		for i, header := range headers {
   247  			err := c.verifyHeader(chain, header, headers[:i])
   248  
   249  			select {
   250  			case <-abort:
   251  				return
   252  			case results <- err:
   253  			}
   254  		}
   255  	}()
   256  	return abort, results
   257  }
   258  
   259  //verifyheader检查一个header是否符合共识规则。
   260  //调用者可以选择按一批父级(升序)传递以避免
   261  //从数据库中查找。这对于并发验证很有用
   262  //一批新的头文件。
   263  func (c *Clique) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   264  	if header.Number == nil {
   265  		return errUnknownBlock
   266  	}
   267  	number := header.Number.Uint64()
   268  
   269  //不要浪费时间检查未来的街区
   270  	if header.Time.Cmp(big.NewInt(time.Now().Unix())) > 0 {
   271  		return consensus.ErrFutureBlock
   272  	}
   273  //检查点块需要强制零受益人
   274  	checkpoint := (number % c.config.Epoch) == 0
   275  	if checkpoint && header.Coinbase != (common.Address{}) {
   276  		return errInvalidCheckpointBeneficiary
   277  	}
   278  //nonce必须是0x00..0或0xff..f,在检查点上强制使用零
   279  	if !bytes.Equal(header.Nonce[:], nonceAuthVote) && !bytes.Equal(header.Nonce[:], nonceDropVote) {
   280  		return errInvalidVote
   281  	}
   282  	if checkpoint && !bytes.Equal(header.Nonce[:], nonceDropVote) {
   283  		return errInvalidCheckpointVote
   284  	}
   285  //检查额外数据是否包含虚荣和签名
   286  	if len(header.Extra) < extraVanity {
   287  		return errMissingVanity
   288  	}
   289  	if len(header.Extra) < extraVanity+extraSeal {
   290  		return errMissingSignature
   291  	}
   292  //确保额外数据包含检查点上的签名者列表,但不包含其他数据。
   293  	signersBytes := len(header.Extra) - extraVanity - extraSeal
   294  	if !checkpoint && signersBytes != 0 {
   295  		return errExtraSigners
   296  	}
   297  	if checkpoint && signersBytes%common.AddressLength != 0 {
   298  		return errInvalidCheckpointSigners
   299  	}
   300  //确保混合摘要为零,因为我们当前没有分叉保护
   301  	if header.MixDigest != (common.Hash{}) {
   302  		return errInvalidMixDigest
   303  	}
   304  //确保该区块不包含任何在POA中无意义的叔叔。
   305  	if header.UncleHash != uncleHash {
   306  		return errInvalidUncleHash
   307  	}
   308  //确保块的难度有意义(此时可能不正确)
   309  	if number > 0 {
   310  		if header.Difficulty == nil || (header.Difficulty.Cmp(diffInTurn) != 0 && header.Difficulty.Cmp(diffNoTurn) != 0) {
   311  			return errInvalidDifficulty
   312  		}
   313  	}
   314  //如果所有检查都通过,则验证硬分叉的任何特殊字段
   315  	if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil {
   316  		return err
   317  	}
   318  //通过所有基本检查,验证级联字段
   319  	return c.verifyCascadingFields(chain, header, parents)
   320  }
   321  
   322  //verifycascadingfields验证所有不独立的头字段,
   323  //而是依赖于前一批头文件。呼叫者可以选择通过
   324  //在一批家长中(升序),以避免从
   325  //数据库。这对于同时验证一批新头文件很有用。
   326  func (c *Clique) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   327  //Genesis区块始终是有效的死胡同
   328  	number := header.Number.Uint64()
   329  	if number == 0 {
   330  		return nil
   331  	}
   332  //确保块的时间戳与其父块的时间戳不太接近
   333  	var parent *types.Header
   334  	if len(parents) > 0 {
   335  		parent = parents[len(parents)-1]
   336  	} else {
   337  		parent = chain.GetHeader(header.ParentHash, number-1)
   338  	}
   339  	if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash {
   340  		return consensus.ErrUnknownAncestor
   341  	}
   342  	if parent.Time.Uint64()+c.config.Period > header.Time.Uint64() {
   343  		return ErrInvalidTimestamp
   344  	}
   345  //检索验证此头并缓存它所需的快照
   346  	snap, err := c.snapshot(chain, number-1, header.ParentHash, parents)
   347  	if err != nil {
   348  		return err
   349  	}
   350  //如果该块是检查点块,请验证签名者列表
   351  	if number%c.config.Epoch == 0 {
   352  		signers := make([]byte, len(snap.Signers)*common.AddressLength)
   353  		for i, signer := range snap.signers() {
   354  			copy(signers[i*common.AddressLength:], signer[:])
   355  		}
   356  		extraSuffix := len(header.Extra) - extraSeal
   357  		if !bytes.Equal(header.Extra[extraVanity:extraSuffix], signers) {
   358  			return errInvalidCheckpointSigners
   359  		}
   360  	}
   361  //所有基本检查通过,确认密封并返回
   362  	return c.verifySeal(chain, header, parents)
   363  }
   364  
   365  //快照在给定时间点检索授权快照。
   366  func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) {
   367  //在内存或磁盘上搜索快照以查找检查点
   368  	var (
   369  		headers []*types.Header
   370  		snap    *Snapshot
   371  	)
   372  	for snap == nil {
   373  //如果找到内存中的快照,请使用
   374  		if s, ok := c.recents.Get(hash); ok {
   375  			snap = s.(*Snapshot)
   376  			break
   377  		}
   378  //如果可以找到磁盘上的检查点快照,请使用
   379  		if number%checkpointInterval == 0 {
   380  			if s, err := loadSnapshot(c.config, c.signatures, c.db, hash); err == nil {
   381  				log.Trace("Loaded voting snapshot from disk", "number", number, "hash", hash)
   382  				snap = s
   383  				break
   384  			}
   385  		}
   386  //如果我们在一个检查点块,拍一张快照
   387  		if number%c.config.Epoch == 0 {
   388  			checkpoint := chain.GetHeaderByNumber(number)
   389  			if checkpoint != nil {
   390  				hash := checkpoint.Hash()
   391  
   392  				signers := make([]common.Address, (len(checkpoint.Extra)-extraVanity-extraSeal)/common.AddressLength)
   393  				for i := 0; i < len(signers); i++ {
   394  					copy(signers[i][:], checkpoint.Extra[extraVanity+i*common.AddressLength:])
   395  				}
   396  				snap = newSnapshot(c.config, c.signatures, number, hash, signers)
   397  				if err := snap.store(c.db); err != nil {
   398  					return nil, err
   399  				}
   400  				log.Info("Stored checkpoint snapshot to disk", "number", number, "hash", hash)
   401  				break
   402  			}
   403  		}
   404  //没有此头的快照,收集头并向后移动
   405  		var header *types.Header
   406  		if len(parents) > 0 {
   407  //如果我们有明确的父母,从那里挑选(强制)
   408  			header = parents[len(parents)-1]
   409  			if header.Hash() != hash || header.Number.Uint64() != number {
   410  				return nil, consensus.ErrUnknownAncestor
   411  			}
   412  			parents = parents[:len(parents)-1]
   413  		} else {
   414  //没有明确的父级(或不再存在),请访问数据库
   415  			header = chain.GetHeader(hash, number)
   416  			if header == nil {
   417  				return nil, consensus.ErrUnknownAncestor
   418  			}
   419  		}
   420  		headers = append(headers, header)
   421  		number, hash = number-1, header.ParentHash
   422  	}
   423  //找到上一个快照,在其上应用任何挂起的头
   424  	for i := 0; i < len(headers)/2; i++ {
   425  		headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i]
   426  	}
   427  	snap, err := snap.apply(headers)
   428  	if err != nil {
   429  		return nil, err
   430  	}
   431  	c.recents.Add(snap.Hash, snap)
   432  
   433  //如果生成了新的检查点快照,请保存到磁盘
   434  	if snap.Number%checkpointInterval == 0 && len(headers) > 0 {
   435  		if err = snap.store(c.db); err != nil {
   436  			return nil, err
   437  		}
   438  		log.Trace("Stored voting snapshot to disk", "number", snap.Number, "hash", snap.Hash)
   439  	}
   440  	return snap, err
   441  }
   442  
   443  //verifyuncles实现converse.engine,始终返回任何
   444  //因为这个共识机制不允许叔叔。
   445  func (c *Clique) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
   446  	if len(block.Uncles()) > 0 {
   447  		return errors.New("uncles not allowed")
   448  	}
   449  	return nil
   450  }
   451  
   452  //验证seal是否执行consension.engine,检查签名是否包含
   453  //头部满足共识协议要求。
   454  func (c *Clique) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
   455  	return c.verifySeal(chain, header, nil)
   456  }
   457  
   458  //verifyseal检查标题中包含的签名是否满足
   459  //共识协议要求。该方法接受可选的父级列表
   460  //还不属于本地区块链以生成快照的头段
   461  //从…
   462  func (c *Clique) verifySeal(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   463  //验证不支持Genesis块
   464  	number := header.Number.Uint64()
   465  	if number == 0 {
   466  		return errUnknownBlock
   467  	}
   468  //检索验证此头并缓存它所需的快照
   469  	snap, err := c.snapshot(chain, number-1, header.ParentHash, parents)
   470  	if err != nil {
   471  		return err
   472  	}
   473  
   474  //解析授权密钥并检查签名者
   475  	signer, err := ecrecover(header, c.signatures)
   476  	if err != nil {
   477  		return err
   478  	}
   479  	if _, ok := snap.Signers[signer]; !ok {
   480  		return errUnauthorized
   481  	}
   482  	for seen, recent := range snap.Recents {
   483  		if recent == signer {
   484  //签名者在Recents中,只有当当前块不将其移出时才会失败。
   485  			if limit := uint64(len(snap.Signers)/2 + 1); seen > number-limit {
   486  				return errUnauthorized
   487  			}
   488  		}
   489  	}
   490  //确保难度与签名人的转弯度相对应。
   491  	inturn := snap.inturn(header.Number.Uint64(), signer)
   492  	if inturn && header.Difficulty.Cmp(diffInTurn) != 0 {
   493  		return errInvalidDifficulty
   494  	}
   495  	if !inturn && header.Difficulty.Cmp(diffNoTurn) != 0 {
   496  		return errInvalidDifficulty
   497  	}
   498  	return nil
   499  }
   500  
   501  //准备执行共识。引擎,准备
   502  //用于在顶部运行事务的标题。
   503  func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) error {
   504  //如果街区不是检查站,随机投票(现在足够好了)
   505  	header.Coinbase = common.Address{}
   506  	header.Nonce = types.BlockNonce{}
   507  
   508  	number := header.Number.Uint64()
   509  //组装投票快照以检查哪些投票有意义
   510  	snap, err := c.snapshot(chain, number-1, header.ParentHash, nil)
   511  	if err != nil {
   512  		return err
   513  	}
   514  	if number%c.config.Epoch != 0 {
   515  		c.lock.RLock()
   516  
   517  //收集所有有意义的投票提案
   518  		addresses := make([]common.Address, 0, len(c.proposals))
   519  		for address, authorize := range c.proposals {
   520  			if snap.validVote(address, authorize) {
   521  				addresses = append(addresses, address)
   522  			}
   523  		}
   524  //如果有悬而未决的提案,就投票表决。
   525  		if len(addresses) > 0 {
   526  			header.Coinbase = addresses[rand.Intn(len(addresses))]
   527  			if c.proposals[header.Coinbase] {
   528  				copy(header.Nonce[:], nonceAuthVote)
   529  			} else {
   530  				copy(header.Nonce[:], nonceDropVote)
   531  			}
   532  		}
   533  		c.lock.RUnlock()
   534  	}
   535  //设置正确的难度
   536  	header.Difficulty = CalcDifficulty(snap, c.signer)
   537  
   538  //确保额外的数据包含所有的组件
   539  	if len(header.Extra) < extraVanity {
   540  		header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...)
   541  	}
   542  	header.Extra = header.Extra[:extraVanity]
   543  
   544  	if number%c.config.Epoch == 0 {
   545  		for _, signer := range snap.signers() {
   546  			header.Extra = append(header.Extra, signer[:]...)
   547  		}
   548  	}
   549  	header.Extra = append(header.Extra, make([]byte, extraSeal)...)
   550  
   551  //混合摘要现在保留,设置为空
   552  	header.MixDigest = common.Hash{}
   553  
   554  //确保时间戳具有正确的延迟
   555  	parent := chain.GetHeader(header.ParentHash, number-1)
   556  	if parent == nil {
   557  		return consensus.ErrUnknownAncestor
   558  	}
   559  	header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(c.config.Period))
   560  	if header.Time.Int64() < time.Now().Unix() {
   561  		header.Time = big.NewInt(time.Now().Unix())
   562  	}
   563  	return nil
   564  }
   565  
   566  //完成执行共识。引擎,确保没有设置叔叔,也没有阻止
   567  //奖励,并返回最后一个块。
   568  func (c *Clique) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
   569  //在POA中没有集体奖励,所以国家保持原样,叔叔们被抛弃。
   570  	header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   571  	header.UncleHash = types.CalcUncleHash(nil)
   572  
   573  //组装并返回最后一个密封块
   574  	return types.NewBlock(header, txs, nil, receipts), nil
   575  }
   576  
   577  //authorize向共识引擎注入一个私钥以创建新的块
   578  //用。
   579  func (c *Clique) Authorize(signer common.Address, signFn SignerFn) {
   580  	c.lock.Lock()
   581  	defer c.lock.Unlock()
   582  
   583  	c.signer = signer
   584  	c.signFn = signFn
   585  }
   586  
   587  //seal实现共识。引擎,试图创建一个密封块使用
   588  //本地签名凭据。
   589  func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) {
   590  	header := block.Header()
   591  
   592  //不支持密封Genesis块
   593  	number := header.Number.Uint64()
   594  	if number == 0 {
   595  		return nil, errUnknownBlock
   596  	}
   597  //对于0周期链条,拒绝密封空块(无奖励,但会旋转密封)
   598  	if c.config.Period == 0 && len(block.Transactions()) == 0 {
   599  		return nil, errWaitTransactions
   600  	}
   601  //在整个密封过程中不要保留签名者字段
   602  	c.lock.RLock()
   603  	signer, signFn := c.signer, c.signFn
   604  	c.lock.RUnlock()
   605  
   606  //如果我们未经授权在一个街区内签字,我们就要出狱。
   607  	snap, err := c.snapshot(chain, number-1, header.ParentHash, nil)
   608  	if err != nil {
   609  		return nil, err
   610  	}
   611  	if _, authorized := snap.Signers[signer]; !authorized {
   612  		return nil, errUnauthorized
   613  	}
   614  //如果我们是最近的签名者,请等待下一个块
   615  	for seen, recent := range snap.Recents {
   616  		if recent == signer {
   617  //签名者在Recents中,只有在当前块不将其移出时才等待
   618  			if limit := uint64(len(snap.Signers)/2 + 1); number < limit || seen > number-limit {
   619  				log.Info("Signed recently, must wait for others")
   620  				<-stop
   621  				return nil, nil
   622  			}
   623  		}
   624  	}
   625  //太好了,协议允许我们签字,等我们的时间
   626  delay := time.Unix(header.Time.Int64(), 0).Sub(time.Now()) //诺林:天哪
   627  	if header.Difficulty.Cmp(diffNoTurn) == 0 {
   628  //现在轮到我们明确签名了,请稍等一下。
   629  		wiggle := time.Duration(len(snap.Signers)/2+1) * wiggleTime
   630  		delay += time.Duration(rand.Int63n(int64(wiggle)))
   631  
   632  		log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle))
   633  	}
   634  	log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay))
   635  
   636  	select {
   637  	case <-stop:
   638  		return nil, nil
   639  	case <-time.After(delay):
   640  	}
   641  //在所有东西上签名!
   642  	sighash, err := signFn(accounts.Account{Address: signer}, sigHash(header).Bytes())
   643  	if err != nil {
   644  		return nil, err
   645  	}
   646  	copy(header.Extra[len(header.Extra)-extraSeal:], sighash)
   647  
   648  	return block.WithSeal(header), nil
   649  }
   650  
   651  //计算难度是难度调整算法。它又回到了困难中
   652  //一个新的块应该基于链中以前的块和
   653  //当前签名者。
   654  func (c *Clique) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
   655  	snap, err := c.snapshot(chain, parent.Number.Uint64(), parent.Hash(), nil)
   656  	if err != nil {
   657  		return nil
   658  	}
   659  	return CalcDifficulty(snap, c.signer)
   660  }
   661  
   662  //计算难度是难度调整算法。它又回到了困难中
   663  //一个新的块应该基于链中以前的块和
   664  //当前签名者。
   665  func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int {
   666  	if snap.inturn(snap.Number+1, signer) {
   667  		return new(big.Int).Set(diffInTurn)
   668  	}
   669  	return new(big.Int).Set(diffNoTurn)
   670  }
   671  
   672  //CLOSE实现共识引擎。这是一个没有背景线的小集团的noop。
   673  func (c *Clique) Close() error {
   674  	return nil
   675  }
   676  
   677  //API实现共识引擎,返回面向用户的RPC API以允许
   678  //控制签名者投票。
   679  func (c *Clique) APIs(chain consensus.ChainReader) []rpc.API {
   680  	return []rpc.API{{
   681  		Namespace: "clique",
   682  		Version:   "1.0",
   683  		Service:   &API{chain: chain, clique: c},
   684  		Public:    false,
   685  	}}
   686  }
   687