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