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