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 }