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