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