github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/consensus/tribe/tribe.go (about) 1 // Copyright 2018 The Spectrum Authors 2 package tribe 3 4 import ( 5 "bytes" 6 "encoding/hex" 7 "errors" 8 "math/big" 9 "math/rand" 10 "time" 11 12 "crypto/ecdsa" 13 "fmt" 14 15 "github.com/SmartMeshFoundation/Spectrum/accounts" 16 "github.com/SmartMeshFoundation/Spectrum/accounts/abi/bind" 17 "github.com/SmartMeshFoundation/Spectrum/common" 18 "github.com/SmartMeshFoundation/Spectrum/common/math" 19 "github.com/SmartMeshFoundation/Spectrum/consensus" 20 "github.com/SmartMeshFoundation/Spectrum/consensus/misc" 21 "github.com/SmartMeshFoundation/Spectrum/core/state" 22 "github.com/SmartMeshFoundation/Spectrum/core/types" 23 "github.com/SmartMeshFoundation/Spectrum/crypto" 24 "github.com/SmartMeshFoundation/Spectrum/crypto/sha3" 25 "github.com/SmartMeshFoundation/Spectrum/ethdb" 26 "github.com/SmartMeshFoundation/Spectrum/log" 27 "github.com/SmartMeshFoundation/Spectrum/params" 28 "github.com/SmartMeshFoundation/Spectrum/rlp" 29 "github.com/SmartMeshFoundation/Spectrum/rpc" 30 lru "github.com/hashicorp/golang-lru" 31 ) 32 33 // sigHash returns the hash which is used as input for the proof-of-authority 34 // signing. It is the hash of the entire header apart from the 65 byte signature 35 // contained at the end of the extra data. 36 // 37 // Note, the method requires the extra data to be at least 65 bytes, otherwise it 38 // panics. This is done to avoid accidentally using both forms (signature present 39 // or not), which could be abused to produce different hashes for the same header. 40 func sigHash(header *types.Header) (hash common.Hash) { 41 hasher := sha3.NewKeccak256() 42 43 err := rlp.Encode(hasher, []interface{}{ 44 header.ParentHash, 45 header.UncleHash, 46 header.Coinbase, 47 header.Root, 48 header.TxHash, 49 header.ReceiptHash, 50 header.Bloom, 51 header.Difficulty, 52 header.Number, 53 header.GasLimit, 54 header.GasUsed, 55 header.Time, 56 header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short 57 header.MixDigest, 58 header.Nonce, 59 }) 60 if err != nil { 61 panic(err) 62 } 63 hasher.Sum(hash[:0]) 64 return hash 65 } 66 67 func ecrecoverPubkey(header *types.Header, signature []byte) ([]byte, error) { 68 pubkey, err := crypto.Ecrecover(sigHash(header).Bytes(), signature) 69 return pubkey, err 70 } 71 72 // ecrecover extracts the Ethereum account address from a signed header. 73 func ecrecover(header *types.Header, t *Tribe) (common.Address, error) { 74 // XXXX : 掐头去尾 ,约定创世区块只能指定一个签名人,因为第一个块要部署合约 75 extraVanity := extraVanityFn(header.Number) 76 if header.Number.Uint64() == 0 { 77 signer := common.Address{} 78 copy(signer[:], header.Extra[extraVanity:]) 79 t.Status.loadSigners([]*Signer{{signer, 3}}) 80 return signer, nil 81 } 82 sigcache := t.sigcache 83 84 // If the signature's already cached, return that 85 hash := header.Hash() 86 if sigcache != nil { 87 if address, known := sigcache.Get(hash); known { 88 return address.(common.Address), nil 89 } 90 } 91 // Retrieve the signature from the header extra-data 92 if len(header.Extra) < extraSeal { 93 return common.Address{}, errMissingSignature 94 } 95 // Recover the public key and the Ethereum address 96 pubkey, err := ecrecoverPubkey(header, header.Extra[len(header.Extra)-extraSeal:]) 97 98 //pubkey, err := crypto.Ecrecover(sigHash(header).Bytes(), signature) 99 if err != nil { 100 return common.Address{}, err 101 } 102 var signer common.Address 103 copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) 104 if sigcache != nil { 105 sigcache.Add(hash, signer) 106 } 107 108 return signer, nil 109 } 110 111 // signers set to the ones provided by the user. 112 func New(accman *accounts.Manager, config *params.TribeConfig, _ ethdb.Database) *Tribe { 113 status := NewTribeStatus() 114 sigcache, err := lru.NewARC(historyLimit) 115 if err != nil { 116 panic(err) 117 } 118 conf := *config 119 if conf.Period <= 0 { 120 conf.Period = blockPeriod 121 } 122 tribe := &Tribe{ 123 accman: accman, 124 config: &conf, 125 Status: status, 126 sigcache: sigcache, 127 } 128 status.SetTribe(tribe) 129 return tribe 130 } 131 132 func (t *Tribe) Init() { 133 go func() { 134 t.lock.Lock() 135 defer t.lock.Unlock() 136 if t.isInit { 137 return 138 } 139 <-params.InitTribeStatus 140 rtn := params.SendToMsgBox("GetNodeKey") 141 success := <-rtn 142 t.Status.nodeKey = success.Entity.(*ecdsa.PrivateKey) 143 if params.InitTribe != nil { 144 close(params.InitTribe) 145 } 146 t.isInit = true 147 log.Info("init tribe.status success.") 148 }() 149 } 150 func (t *Tribe) GetConfig() *params.TribeConfig { 151 return t.config 152 } 153 func (t *Tribe) SetConfig(config *params.TribeConfig) { 154 t.config = config 155 } 156 157 // Author implements consensus.Engine, returning the Ethereum address recovered 158 // from the signature in the header's extra-data section. 159 func (t *Tribe) Author(header *types.Header) (common.Address, error) { 160 var ( 161 coinbase common.Address 162 err error 163 ) 164 if header.Coinbase == coinbase { 165 coinbase, err = ecrecover(header, t) 166 } else { 167 coinbase = header.Coinbase 168 } 169 log.Debug("<<Tribe.Author>>", "num", header.Number, "coinbase", coinbase.Hex()) 170 return coinbase, err 171 } 172 173 // VerifyHeader checks whether a header conforms to the consensus rules. 174 func (t *Tribe) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { 175 err := t.verifyHeader(chain, header, nil) 176 if err == nil { 177 //p := chain.GetHeaderByHash(header.ParentHash) 178 //t.Status.LoadSignersFromChief(p.Hash(), p.Number) 179 } 180 return err 181 } 182 183 // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The 184 // method returns a quit channel to abort the operations and a results channel to 185 // retrieve the async verifications (the order is that of the input slice). 186 func (t *Tribe) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { 187 abort := make(chan struct{}) 188 results := make(chan error) 189 log.Debug("==> VerifyHeaders ", "currentNum", chain.CurrentHeader().Number.Int64(), "headers.len", len(headers)) 190 go func() { 191 for i, header := range headers { 192 err := t.verifyHeader(chain, header, headers[:i]) 193 select { 194 case <-abort: 195 return 196 case results <- err: 197 } 198 } 199 }() 200 return abort, results 201 } 202 203 // verifyHeader checks whether a header conforms to the consensus rules.The 204 // caller may optionally pass in a batch of parents (ascending order) to avoid 205 // looking those up from the database. This is useful for concurrently verifying 206 // a batch of new headers. 207 func (t *Tribe) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) (err error) { 208 defer func() { 209 if err != nil { 210 log.Info(fmt.Sprintf("verifyHeader err return number=%s,err=%s", header.Number, err)) 211 } 212 }() 213 if header.Number == nil { 214 return errUnknownBlock 215 } 216 extraVanity := extraVanityFn(header.Number) 217 number := header.Number.Uint64() 218 219 // Don't waste time checking blocks from the future 220 if header.Time.Cmp(big.NewInt(time.Now().Unix())) > 0 { 221 return consensus.ErrFutureBlock 222 } 223 // Nonces must be 0x00..0 or 0xff..f, zeroes enforced on checkpoints 224 if !bytes.Equal(header.Nonce[:], nonceSync) && !bytes.Equal(header.Nonce[:], nonceAsync) { 225 return errInvalidNonce 226 } 227 228 // Check that the extra-data contains both the vanity and signature 229 if len(header.Extra) < extraVanity { 230 return errMissingVanity 231 } 232 if len(header.Extra) < extraVanity+extraSeal { 233 return errMissingSignature 234 } 235 // Ensure that the mix digest is zero as we don't have fork protection currently 236 if header.MixDigest != (common.Hash{}) { 237 return errInvalidMixDigest 238 } 239 // Ensure that the block doesn't contain any uncles which are meaningless in PoA 240 if header.UncleHash != uncleHash { 241 return errInvalidUncleHash 242 } 243 // Ensure that the block's difficulty is meaningful (may not be correct at this point) 244 if number > 0 && !params.IsBeforeChief100block(header.Number) { 245 if ci := params.GetChiefInfo(header.Number); ci != nil { 246 switch ci.Version { 247 case "1.0.0": 248 //TODO max value is a var ??? 249 if header.Difficulty == nil || header.Difficulty.Cmp(big.NewInt(6)) > 0 || header.Difficulty.Cmp(diffNoTurn) < 0 { 250 log.Error("** verifyHeader ERROR CHIEF.v1.0.0 **", "diff", header.Difficulty.String(), "err", errInvalidDifficulty) 251 return errInvalidDifficulty 252 } 253 default: 254 if header.Difficulty == nil || (header.Difficulty.Cmp(diffInTurnMain) != 0 && header.Difficulty.Cmp(diffInTurn) != 0 && header.Difficulty.Cmp(diffNoTurn) != 0) { 255 log.Error("** verifyHeader ERROR **", "diff", header.Difficulty.String(), "err", errInvalidDifficulty) 256 return errInvalidDifficulty 257 } 258 } 259 } 260 } 261 // If all checks passed, validate any special fields for hard forks 262 if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil { 263 return err 264 } 265 // All basic checks passed, verify cascading fields 266 err = t.verifyCascadingFields(chain, header, parents) 267 if err != nil { 268 log.Error("verifyCascadingFields", "num", header.Number.Int64(), "err", err) 269 } 270 return err 271 } 272 273 // verifyCascadingFields verifies all the header fields that are not standalone, 274 // rather depend on a batch of previous headers. The caller may optionally pass 275 // in a batch of parents (ascending order) to avoid looking those up from the 276 // database. This is useful for concurrently verifying a batch of new headers. 277 func (t *Tribe) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) (err error) { 278 // The genesis block is the always valid dead-end 279 number := header.Number.Uint64() 280 if number == 0 { 281 return nil 282 } 283 // Ensure that the block's timestamp isn't too close to it's parent 284 var parent *types.Header 285 286 verifyTime := func() error { 287 if params.IsSIP002Block(header.Number) { 288 // first verification 289 // second verification block time in validateSigner function 290 // the min limit period is config.Period - 1 291 if parent.Time.Uint64()+(t.config.Period-1) > header.Time.Uint64() { 292 return ErrInvalidTimestampSIP002 293 } 294 } else { 295 if parent.Time.Uint64()+t.config.Period > header.Time.Uint64() { 296 return ErrInvalidTimestamp 297 } 298 } 299 return nil 300 } 301 302 if len(parents) > 0 { 303 parent = parents[len(parents)-1] 304 if err := verifyTime(); err != nil { 305 return err 306 } 307 } else { 308 parent = chain.GetHeader(header.ParentHash, number-1) 309 if parent == nil || parent.Time == nil { 310 e := errors.New(fmt.Sprintf("nil_parent_current_num=%d", header.Number.Int64())) 311 log.Error("-->bad_block-->", "err", e) 312 return e 313 } 314 if err := verifyTime(); err != nil { 315 return err 316 } 317 } 318 if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash { 319 return consensus.ErrUnknownAncestor 320 } 321 322 /* TODO timestamp unit second , how to do this logic ? 323 if header.Difficulty.Cmp(diffNoTurn) == 0 && parent.Time.Uint64()+t.config.Period == header.Time.Uint64() { 324 return ErrInvalidTimestamp 325 } 326 */ 327 328 // Verify that the gas limit is <= 2^63-1 329 if header.GasLimit.Cmp(math.MaxBig63) > 0 { 330 return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, math.MaxBig63) 331 } 332 // Verify that the gasUsed is <= gasLimit 333 if header.GasUsed.Cmp(header.GasLimit) > 0 { 334 return fmt.Errorf("invalid gasUsed: have %v, gasLimit %v", header.GasUsed, header.GasLimit) 335 } 336 337 // Verify that the gas limit remains within allowed bounds 338 diff := new(big.Int).Set(parent.GasLimit) 339 diff = diff.Sub(diff, header.GasLimit) 340 diff.Abs(diff) 341 342 limit := new(big.Int).Set(parent.GasLimit) 343 limit = limit.Div(limit, params.GasLimitBoundDivisor) 344 345 minGasLimit := params.MinGasLimit 346 347 /* 348 //sip004区块硬分叉开始,提升区块最小的gaslimit 349 sip004Block := params.MainnetChainConfig.Sip004Block 350 if params.IsTestnet() { 351 sip004Block = params.TestnetChainConfig.Sip004Block 352 } else if params.IsDevnet() { 353 sip004Block = params.DevnetChainConfig.Sip004Block 354 } 355 356 if header.Number.Cmp(sip004Block) >= 0 { 357 minGasLimit = params.Sip004GasLimit 358 } 359 360 if header.Number.Cmp(sip004Block) != 0 && (diff.Cmp(limit) >= 0 || header.GasLimit.Cmp(minGasLimit) < 0) { 361 return fmt.Errorf("invalid gas limit: have %v, want %v += %v", header.GasLimit, parent.GasLimit, limit) 362 } 363 */ 364 365 if params.IsSIP004Block(header.Number) { 366 minGasLimit = params.Sip004GasLimit 367 } 368 369 if !params.EqualSIP004Block(header.Number) && (diff.Cmp(limit) >= 0 || header.GasLimit.Cmp(minGasLimit) < 0) { 370 return fmt.Errorf("invalid gas limit: have %v, want %v += %v", header.GasLimit, parent.GasLimit, limit) 371 } 372 373 // Verify that the block number is parent's +1 374 if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 { 375 return consensus.ErrInvalidNumber 376 } 377 378 return 379 } 380 381 // VerifyUncles implements consensus.Engine, always returning an error for any 382 // uncles as this consensus mechanism doesn't permit uncles. 383 func (t *Tribe) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { 384 if len(block.Uncles()) > 0 { 385 return errors.New("uncles not allowed") 386 } 387 return nil 388 } 389 390 // VerifySeal implements consensus.Engine, checking whether the signature contained 391 // in the header satisfies the consensus protocol requirements. 392 // don't support remote miner agent, these code never reached 393 func (t *Tribe) VerifySeal(chain consensus.ChainReader, header *types.Header) error { 394 panic("never reach") 395 e := t.verifySeal(chain, header, nil) 396 if e != nil { 397 log.Error("Tribe.VerifySeal", "err", e) 398 } 399 return e 400 } 401 402 func (t *Tribe) verifySeal(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { 403 // Verifying the genesis block is not supported 404 number := header.Number.Int64() 405 if number == 0 { 406 return errUnknownBlock 407 } 408 // Resolve the authorization key and check against signers 409 signer, err := ecrecover(header, t) 410 if err != nil { 411 return err 412 } 413 log.Debug("verifySeal", "number", number, "signer", signer.Hex()) 414 415 if !t.Status.validateSigner(chain.GetHeaderByHash(header.ParentHash), header, signer) { 416 return errUnauthorized 417 } 418 419 if number > CHIEF_NUMBER && !params.IsBeforeChief100block(header.Number) { 420 difficulty := t.Status.InTurnForVerifyDiffculty(number, header.ParentHash, signer) 421 if difficulty.Cmp(header.Difficulty) != 0 { 422 log.Error("** verifySeal ERROR **", "diff", header.Difficulty.String(), "err", errInvalidDifficulty) 423 return errInvalidDifficulty 424 } 425 } 426 return nil 427 } 428 429 // Prepare implements consensus.Engine, preparing all the consensus fields of the 430 // header for running the transactions on top. 431 func (t *Tribe) Prepare(chain consensus.ChainReader, header *types.Header) error { 432 //t.Status.LoadStatusFromChief(header.ParentHash, header.Number) 433 err := t.Status.LoadStatusFromChief(header.ParentHash, header.Number) 434 if err != nil { 435 return err 436 } 437 number := header.Number.Uint64() 438 if f, _, err := params.AnmapBindInfo(t.Status.GetMinerAddress(), chain.CurrentHeader().Hash()); err == nil && f != common.HexToAddress("0x") { 439 header.Coinbase = f 440 } else { 441 header.Coinbase = t.Status.GetMinerAddress() 442 } 443 header.Nonce = types.BlockNonce{} 444 copy(header.Nonce[:], nonceAsync) 445 446 // Extra : append sig to last 65 bytes >>>> 447 if params.IsSIP100Block(header.Number) { 448 header.Extra = make([]byte, _extraVrf+extraSeal) 449 // append vrf to header.Extra before sign 450 parentHeader := chain.GetHeaderByHash(header.ParentHash) 451 msg := append(parentHeader.Number.Bytes(), parentHeader.Extra[:32]...) 452 vrfnp, err := crypto.SimpleVRF2Bytes(t.Status.nodeKey, msg) 453 log.Debug("Tribe.Prepare --> params.GetVRFByHash", "err", err, "hash", header.ParentHash.Hex(), "vrfn", hex.EncodeToString(vrfnp[:32])) 454 //vr, err := crypto.SimpleVRF2Bytes(t.Status.nodeKey, header.ParentHash.Bytes()) 455 if err != nil { 456 panic(err) 457 } 458 459 copy(header.Extra[:len(header.Extra)-extraSeal], vrfnp) 460 log.Debug("prepare_vrf", "num", header.Number, "parent_hash", header.ParentHash.Hex()) 461 log.Debug("prepare_vrf", "num", header.Number, "miner", crypto.PubkeyToAddress(t.Status.nodeKey.PublicKey).Hex()) 462 log.Debug("prepare_vrf", "num", header.Number, "err", err, "vrf", hex.EncodeToString(vrfnp)) 463 log.Debug("prepare_vrf", "num", header.Number, "extra", hex.EncodeToString(header.Extra)) 464 } else { 465 extraVanity := extraVanityFn(header.Number) 466 log.Debug("fix extra", "extra-len", len(header.Extra), "extraVanity", extraVanity) 467 if len(header.Extra) < extraVanity { 468 header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...) 469 } 470 header.Extra = header.Extra[:extraVanity] 471 header.Extra = append(header.Extra, make([]byte, extraSeal)...) 472 } 473 // Extra : append sig to last 65 bytes <<<< 474 475 // Mix digest is reserved for now, set to empty 476 header.MixDigest = common.Hash{} 477 478 // Ensure the timestamp has the correct delay 479 parent := chain.GetHeader(header.ParentHash, number-1) 480 if parent == nil { 481 return consensus.ErrUnknownAncestor 482 } 483 // Set the correct difficulty 484 header.Difficulty = t.CalcDifficulty(chain, header.Time.Uint64(), parent) 485 if params.IsSIP002Block(header.Number) { 486 //modify by liangc : change period rule 487 header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(t.GetPeriod(header, nil))) 488 } else { 489 header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(t.config.Period)) 490 } 491 if header.Time.Int64() < time.Now().Unix() { 492 header.Time = big.NewInt(time.Now().Unix()) 493 } 494 return nil 495 } 496 497 /* 498 这个数值是经验书数值,统计了过去一万块后得到的, 499 1. 在chief100以后此数值不起作用, 500 2. 在chief100之前,最好通过estimateGas来估算 501 */ 502 var chiefGasLimit = big.NewInt(4712388) 503 var chiefGasPrice = big.NewInt(18000000000) 504 505 /* 506 获取要插入的chief Tx 507 1.0之后是通过vrf来选择下一轮出块人 508 1.0之前因为没有奖励,所以是现有signer任意指定候选人 509 */ 510 func (t *Tribe) GetChiefUpdateTx(chain consensus.ChainReader, header *types.Header, state *state.StateDB) *types.Transaction { 511 if header.Number.Cmp(big.NewInt(CHIEF_NUMBER)) <= 0 { 512 return nil 513 } 514 parentHash := header.ParentHash 515 parentNumber := new(big.Int).Set(header.Number) 516 parentNumber.Sub(parentNumber, big.NewInt(1)) 517 var vrf *big.Int 518 if params.IsSIP100Block(parentNumber) { 519 vrf = new(big.Int).SetBytes(header.Extra[:32]) 520 } 521 nextRoundSigner := params.Chief100GetNextRoundSigner(parentHash, parentNumber, vrf) 522 nonce := state.GetNonce(t.Status.GetMinerAddress()) 523 txData, err := hex.DecodeString("1c1b8772000000000000000000000000") //这个是4字节chiefUpdate函数标识以及12字节的0 524 if err != nil { 525 panic(err) 526 } 527 txData = append(txData, nextRoundSigner[:]...) 528 rawTx := types.NewTransaction(nonce, params.GetChiefInfo(header.Number).Addr, big.NewInt(0), chiefGasLimit, chiefGasPrice, txData) 529 auth := bind.NewKeyedTransactor(t.Status.getNodekey()) 530 signedTx, err := auth.Signer(types.NewEIP155Signer(chain.Config().ChainId), auth.From, rawTx) 531 if err != nil { 532 panic(fmt.Sprintf("sign tx:%s", err)) 533 } 534 return signedTx 535 } 536 537 // Finalize implements consensus.Engine, ensuring no uncles are set, nor block 538 // rewards given, and returns the final block. 539 func (t *Tribe) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { 540 // Accumulate any block and uncle rewards and commit the final state root 541 accumulateRewards(chain.Config(), state, header) 542 //destroy SmartMeshFoundation 12% balance 543 destroySmartMeshFoundation12Balance(chain.Config(), state, header) 544 545 header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) 546 //there is no uncle in triple 547 header.UncleHash = types.CalcUncleHash(nil) 548 return types.NewBlock(header, txs, nil, receipts), nil 549 } 550 551 // Seal implements consensus.Engine, attempting to create a sealed block using 552 // the local signing credentials. 553 func (t *Tribe) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) { 554 if block.Number().Cmp(big.NewInt(CHIEF_NUMBER)) <= 0 { 555 return nil, errors.New("never mining block before #3") 556 } 557 if err := t.Status.ValidateBlock(chain.GetBlock(block.ParentHash(), block.NumberU64()-1), block, false); err != nil { 558 log.Error("Tribe_Seal", "number", block.Number().Int64(), "err", err) 559 //log.Error("Tribe_Seal", "retry", atomic.LoadUint32(&t.SealErrorCounter), "number", block.Number().Int64(), "err", err) 560 return nil, err 561 } 562 //atomic.StoreUint32(&t.SealErrorCounter, 0) 563 header := block.Header() 564 // Sealing the genesis block is not supported 565 number := header.Number.Int64() 566 // For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing) 567 if len(block.Transactions()) == 0 { 568 panic("at least one chief update tx") 569 } 570 571 if !t.Status.validateSigner(chain.GetHeaderByHash(block.ParentHash()), block.Header(), t.Status.GetMinerAddress()) { 572 return nil, errUnauthorized 573 } 574 575 now := time.Now() 576 delay := time.Unix(header.Time.Int64(), 0).Sub(now) 577 //fmt.Println(" ---->", "diff", header.Difficulty, "header.time=", header.Time.Int64(), "now=", now.Unix(), "delay=", delay) 578 log.Info(fmt.Sprintf("Seal -> num=%d, diff=%d, miner=%s, delay=%d", number, header.Difficulty, header.Coinbase.Hex(), delay)) 579 580 if !params.IsSIP100Block(header.Number) && header.Difficulty.Cmp(diffNoTurn) == 0 { 581 wiggle := time.Duration(len(t.Status.Signers)/2+1) * wiggleTime 582 delay += time.Duration(rand.Int63n(int64(wiggle))) 583 } 584 select { 585 case <-stop: 586 log.Warn(fmt.Sprintf("🐦 cancel -> num=%d, diff=%d, miner=%s, delay=%d", number, header.Difficulty, header.Coinbase.Hex(), delay)) 587 return nil, nil 588 case <-time.After(delay): 589 } 590 591 // Sign all the things! 592 hash := sigHash(header).Bytes() 593 sighash, err := crypto.Sign(hash, t.Status.nodeKey) 594 if err != nil { 595 return nil, err 596 } 597 copy(header.Extra[len(header.Extra)-extraSeal:], sighash) 598 blk := block.WithSeal(header) 599 return blk, nil 600 } 601 602 // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty 603 // that a new block should have based on the previous blocks in the chain and the 604 // current signer. 605 func (t *Tribe) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int { 606 log.Debug("CalcDifficulty", "ParentNumber", parent.Number.Int64(), "CurrentNumber:", chain.CurrentHeader().Number.Int64()) 607 currentNumber := new(big.Int).Add(parent.Number, big.NewInt(1)) 608 if ci := params.GetChiefInfo(currentNumber); ci != nil { 609 switch ci.Version { 610 case "1.0.0": 611 return t.Status.InTurnForCalcDiffcultyChief100(t.Status.GetMinerAddress(), parent) 612 } 613 } 614 return t.Status.InTurnForCalcDifficulty(t.Status.GetMinerAddress(), parent) 615 } 616 617 // APIs implements consensus.Engine, returning the user facing RPC API to allow 618 // controlling the signer voting. 619 func (t *Tribe) APIs(chain consensus.ChainReader) []rpc.API { 620 return []rpc.API{{ 621 Namespace: "tribe", 622 Version: "0.0.1", 623 Service: &API{accman: t.accman, chain: chain, tribe: t}, 624 Public: false, 625 }} 626 } 627 628 /* 629 GetPeriodChief100: 计算出块节点对应的延时时间 630 依据: 631 普通节点替补出块规则调整为当前常委会出块节点替补出块,当前常委会出块节点替补出块规则调整为常委会节点列表顺序替补出块,出块难度依次递减。 632 当普通节点出块时,难度为6->5->4->3->2->1;当常委会节点出块时,难度为6->5->4->3->2。每次替补出块时间都顺延4秒, 633 下一个区块将在当前区块产生以后的14秒+ 以后产生。 634 总共只有5个常委会节点,其排序固定 635 signers:[0,...,16] 0号对应的是常委会节点,1-16对应的是普通出块节点 636 场景1: 637 假设`header`中的块该signers[3]出, 638 如果signers[3]出,则延时14秒,否则只能由其他常委会节点替代 639 假设当前signers[0]对应的是常委2,那么如果常委2出则延时18,常委3出则延时22,...,如果常委1出则延时34 640 场景2: 641 假设`header`中的块该signers[0]出, 642 如果signers[0]出,则延时14秒,否则只能由其他常委会节点替代 643 假设当前signers[0]对应的是常委2,那么常委3出则延时18,常委4出则延时22,...常委1出则延时30 644 替补节点最多5个 645 */ 646 func (t *Tribe) GetPeriodChief100(header *types.Header, signers []*Signer) (p uint64) { 647 var ( 648 // 14 , 18 , 22 , 26 , 30 , 34 , 38(无出块资格的节点) 649 signature = header.Extra[len(header.Extra)-extraSeal:] 650 err error 651 miner common.Address 652 empty = make([]byte, len(signature)) 653 Main, Subs, Other, Else = t.config.Period - 1, t.config.Period + 3, t.config.Period + 7, t.config.Period - 1 + 4*6 654 number = header.Number 655 ) 656 657 p = Else 658 if bytes.Equal(signature, empty) { 659 miner = t.Status.GetMinerAddress() 660 } else { 661 miner, err = ecrecover(header, t) 662 if err != nil { 663 log.Error("ecrecover on getPeriod", "header", header, "err", err) 664 return 665 } 666 } 667 668 if signers == nil { 669 signers = t.Status.Signers 670 } 671 sl := len(signers) 672 if sl == 0 { 673 log.Error("GetPeriod_signers_cannot_empty") 674 return 675 } 676 677 // normal 678 idx_m := number.Int64() % int64(sl) 679 if miner == signers[idx_m].Address { 680 p = Main 681 return 682 } 683 684 // first leader 685 if miner == signers[0].Address { 686 p = Subs 687 return 688 } 689 690 // other leader 691 if leaders, err := leaderSort(signers[0].Address, t.Status.Leaders); err == nil { 692 for i, leader := range leaders { 693 if miner == leader && number.Int64()%int64(sl) == 0 { 694 p = Subs + uint64(i)*(Subs-Main) 695 return 696 } else if miner == leader { 697 p = Other + uint64(i)*(Subs-Main) 698 return 699 } 700 } 701 } 702 703 return 704 } 705 706 func (t *Tribe) GetPeriod(header *types.Header, signers []*Signer) (p uint64) { 707 if ci := params.GetChiefInfo(header.Number); ci != nil { 708 switch ci.Version { 709 case "1.0.0": 710 p = t.GetPeriodChief100(header, signers) 711 log.Debug("<<GetPeriodSIP005>>", "num", header.Number, "period", p) 712 return 713 } 714 } 715 // 14 , 18 , 22(random add 0~4.5s) 716 signature := header.Extra[len(header.Extra)-extraSeal:] 717 var ( 718 err error 719 miner common.Address 720 empty = make([]byte, len(signature)) 721 /* 722 替补出块按照顺序依次增加4秒的延迟 723 */ 724 Main, Subs, Other = t.config.Period - 1, t.config.Period + 3, t.config.Period + 7 725 number = header.Number 726 ) 727 728 p = Other 729 if bytes.Equal(signature, empty) { 730 miner = t.Status.GetMinerAddress() 731 } else { 732 miner, err = ecrecover(header, t) 733 if err != nil { 734 log.Error("ecrecover on getPeriod", "header", header, "err", err) 735 return 736 } 737 } 738 739 if number.Int64() <= 3 { 740 p = Subs 741 return 742 } 743 744 if signers == nil { 745 signers = t.Status.Signers 746 } 747 748 sl := len(signers) 749 if sl == 0 { 750 log.Error("GetPeriod_signers_cannot_empty") 751 p = Other 752 return 753 } 754 755 idx_m, idx_s := number.Int64()%int64(sl), (number.Int64()+1)%int64(sl) 756 757 if miner == signers[idx_m].Address { 758 p = Main 759 return 760 } 761 762 if miner == signers[idx_s].Address { 763 p = Subs 764 return 765 } 766 767 return 768 } 769 770 // AccumulateRewards credits the coinbase of the given block with the mining 771 // reward. The total reward consists of the static block reward and rewards for 772 // included uncles. The coinbase of each uncle block is also rewarded. 773 // add by liangc : no reward 774 func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header) { 775 if config.Chief100Block == nil || header.Number.Cmp(config.Chief100Block) < 0 { 776 return 777 } 778 // Select the correct block reward based on chain progression 779 blockReward := new(big.Int).Set(Chief100BlockReward) 780 781 // Accumulate the rewards for the miner and any included uncles 782 number := new(big.Int).Set(header.Number) 783 number = number.Sub(number, config.Chief100Block) 784 number = number.Div(number, big.NewInt(int64(BlockRewardReducedInterval))) 785 blockReward = blockReward.Rsh(blockReward, uint(number.Int64())) 786 state.AddBalance(header.Coinbase, blockReward) 787 } 788 789 // 790 //销毁基金会账户12% token 791 //Destroy 12% token of Foundation Account 792 793 func destroySmartMeshFoundation12Balance(config *params.ChainConfig, state *state.StateDB, header *types.Header) { 794 if !params.IsDevnet() && !params.IsTestnet() && config.Chief100Block != nil && header.Number.Cmp(config.Chief100Block) == 0 { 795 ob := state.GetBalance(SmartMeshFoundationAccount) 796 if ob.Cmp(SmartMeshFoundationAccountDestroyBalance) >= 0 { 797 state.SubBalance(SmartMeshFoundationAccount, SmartMeshFoundationAccountDestroyBalance) 798 } else { 799 state.SubBalance(SmartMeshFoundationAccount, ob) 800 } 801 802 } 803 }