github.com/insight-chain/inb-go@v1.1.3-0.20191221022159-da049980ae38/consensus/vdpos/vdpos.go (about) 1 // Copyright 2019 The inb-go Authors 2 // This file is part of the inb-go library. 3 // 4 // The inb-go library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software MiningReward, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The inb-go library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the inb-go library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package vdpos implements the delegated-proof-of-stake consensus engine. 18 package vdpos 19 20 import ( 21 "bytes" 22 "errors" 23 "math/big" 24 "sync" 25 "time" 26 27 "github.com/hashicorp/golang-lru" 28 "github.com/insight-chain/inb-go/accounts" 29 "github.com/insight-chain/inb-go/common" 30 "github.com/insight-chain/inb-go/consensus" 31 "github.com/insight-chain/inb-go/core/state" 32 "github.com/insight-chain/inb-go/core/types" 33 "github.com/insight-chain/inb-go/crypto" 34 "github.com/insight-chain/inb-go/crypto/sha3" 35 "github.com/insight-chain/inb-go/ethdb" 36 "github.com/insight-chain/inb-go/log" 37 "github.com/insight-chain/inb-go/params" 38 "github.com/insight-chain/inb-go/rlp" 39 "github.com/insight-chain/inb-go/rpc" 40 ) 41 42 const ( 43 inMemorySnapshots = 128 // Number of recent vote snapshots to keep in memory 44 inMemorySignatures = 4096 // Number of recent block signatures to keep in memory 45 ) 46 47 var ( 48 DefaultMiningRewardOneYear = new(big.Int).Mul(big.NewInt(1e+8), big.NewInt(params.Inber)) 49 DefaultAllianceRewardOneYear = new(big.Int).Mul(big.NewInt(1e+8), big.NewInt(params.Inber)) 50 DefaultSealRewardOneYear = new(big.Int).Mul(big.NewInt(1e+8), big.NewInt(params.Inber)) 51 DefaultTeamRewardOneYear = new(big.Int).Mul(big.NewInt(1e+8), big.NewInt(params.Inber)) 52 DefaultMarketingRewardOneYear = new(big.Int).Mul(big.NewInt(1e+8), big.NewInt(params.Inber)) 53 54 55 //OneWeekHeight = new(big.Int).Mul(big.NewInt(86400/2), big.NewInt(7)) 56 OneYearBySec = int64(365 * 86400) 57 defaultBlockPeriod = uint64(2) // default minimum difference between two consecutive block's timestamps 58 defaultSignerPeriod = uint64(2) // default minimum difference between two signer's timestamps 59 defaultSignerBlocks = uint64(6) // default number of blocks every signer created 60 defaultMaxSignerCount = uint64(21) // default max signers 61 extraVanity = 32 // fixed number of extra-data prefix bytes reserved for signer vanity 62 extraSeal = 65 // fixed number of extra-data suffix bytes reserved for signer seal 63 uncleHash = types.CalcUncleHash(nil) // always Keccak256(RLP([])) as uncles are meaningless outside of PoW. 64 defaultDifficulty = big.NewInt(1) // default difficulty 65 defaultLoopCntRecalculateSigners = uint64(1024) // default stake of selfVoteSigners in first LOOP 66 selfVoteSignersStake = new(big.Int).Mul(big.NewInt(500000), big.NewInt(params.Inber)) // default stake of selfVoteSigners in first LOOP 67 DefaultMinerReward = big.NewInt(12683) // default min mortgage INB of candidates 68 BeVotedNeedINB = new(big.Int).Mul(big.NewInt(10000), big.NewInt(params.Inber)) // default min mortgage INB of candidates 69 70 ) 71 72 // various error messages to mark blocks invalid. These should be private to 73 // prevent engine specific errors from being referenced in the remainder of the 74 // codebase, inherently breaking if the engine is swapped out. Please put common 75 // error types into the consensus package. 76 var ( 77 // errUnknownBlock is returned when the list of signers is requested for a block 78 // that is not part of the local blockchain. 79 errUnknownBlock = errors.New("unknown block") 80 81 // errMissingVanity is returned if a block's extra-data section is shorter than 82 // 32 bytes, which is required to store the signer vanity. 83 errMissingVanity = errors.New("extra-data 32 byte vanity prefix missing") 84 85 // errMissingSignature is returned if a block's extra-data section doesn't seem 86 // to contain a 65 byte secp256k1 signature. 87 errMissingSignature = errors.New("extra-data 65 byte suffix signature missing") 88 89 // errInvalidMixDigest is returned if a block's mix digest is non-zero. 90 errInvalidMixDigest = errors.New("non-zero mix digest") 91 92 // errInvalidUncleHash is returned if a block contains an non-empty uncle list. 93 errInvalidUncleHash = errors.New("non empty uncle hash") 94 95 // ErrInvalidTimestamp is returned if the timestamp of a block is lower than 96 // the previous block's timestamp + the minimum block period. 97 ErrInvalidTimestamp = errors.New("invalid timestamp") 98 99 // errUnauthorizedSigner is returned if a header is signed by a non-authorized entity. 100 errUnauthorizedSigner = errors.New("unauthorized signer") 101 102 // errUnclesNotAllowed is returned if uncles exists 103 errUnclesNotAllowed = errors.New("uncles not allowed") 104 105 // errCreateSignersPoolNotAllowed is returned if called in (block number + 1) % maxSignerCount != 0 106 errCreateSignersPoolNotAllowed = errors.New("create signers pool not allowed") 107 108 // errInvalidSignersPool is returned if verify Signers fail 109 errInvalidSignersPool = errors.New("invalid signers pool") 110 111 // errSignersPoolEmpty is returned if no signer when calculate 112 //errSignersPoolEmpty = errors.New("signers pool is empty") 113 ) 114 115 // SignerFn is a signer callback function to request a hash to be signed by a 116 // backing account. 117 type SignerFn func(accounts.Account, []byte) ([]byte, error) 118 119 // SignTxFn is a signTx 120 type SignTxFn func(accounts.Account, *types.Transaction, *big.Int) (*types.Transaction, error) 121 122 type Vdpos struct { 123 config *params.VdposConfig // Consensus engine configuration parameters 124 db ethdb.Database // Database to store and retrieve snapshot checkpoints 125 recents *lru.ARCCache // Snapshots for recent block to speed up reorgs 126 signatures *lru.ARCCache // Signatures of recent blocks to speed up mining 127 signer common.Address // Ethereum address of the signing key 128 signFn SignerFn // Signer function to authorize hashes with 129 signTxFn SignTxFn // Sign transaction function to sign tx 130 lock sync.RWMutex // Protects the signer fields 131 } 132 133 // New creates a Vdpos delegated-proof-of-stake consensus engine with the initial 134 // signers set to the ones provided by the user. 135 func New(config *params.VdposConfig, db ethdb.Database) *Vdpos { 136 // set any missing consensus parameters to their defaults 137 conf := *config 138 if conf.Period == 0 { 139 conf.Period = defaultBlockPeriod 140 } 141 if conf.SignerPeriod == 0 { 142 conf.SignerPeriod = defaultSignerPeriod 143 } 144 if conf.SignerBlocks == 0 { 145 conf.SignerBlocks = defaultSignerBlocks 146 } 147 if conf.LoopCntRecalculate == 0 { 148 conf.LoopCntRecalculate = defaultLoopCntRecalculateSigners 149 } 150 if conf.MaxSignerCount == 0 { 151 conf.MaxSignerCount = defaultMaxSignerCount 152 } 153 154 // allocate the snapshot caches and create the engine 155 recents, _ := lru.NewARC(inMemorySnapshots) 156 signatures, _ := lru.NewARC(inMemorySignatures) 157 158 return &Vdpos{ 159 config: &conf, 160 db: db, 161 recents: recents, 162 signatures: signatures, 163 } 164 } 165 166 // Author implements consensus.Engine, returning the Ethereum address recovered 167 // from the signature in the header's extra-data section. 168 func (v *Vdpos) Author(header *types.Header) (common.Address, error) { 169 return ecrecover(header, v.signatures) 170 } 171 172 // VerifyHeader checks whether a header conforms to the consensus rules. 173 func (v *Vdpos) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { 174 return v.verifyHeader(chain, header, nil) 175 } 176 177 // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The 178 // method returns a quit channel to abort the operations and a results channel to 179 // retrieve the async verifications (the order is that of the input slice). 180 func (v *Vdpos) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { 181 abort := make(chan struct{}) 182 results := make(chan error, len(headers)) 183 184 go func() { 185 for i, header := range headers { 186 err := v.verifyHeader(chain, header, headers[:i]) 187 188 select { 189 case <-abort: 190 return 191 case results <- err: 192 } 193 } 194 }() 195 196 return abort, results 197 } 198 199 // verifyHeader checks whether a header conforms to the consensus rules.The 200 // caller may optionally pass in a batch of parents (ascending order) to avoid 201 // looking those up from the database. This is useful for concurrently verifying 202 // a batch of new headers. 203 func (v *Vdpos) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { 204 if header.Number == nil { 205 return errUnknownBlock 206 } 207 208 // don't waste time checking blocks from the future 209 if header.Time.Cmp(big.NewInt(time.Now().Unix())) > 0 { 210 return consensus.ErrFutureBlock 211 } 212 213 // check that the extra-data contains both the vanity and signature 214 if len(header.Extra) < extraVanity { 215 return errMissingVanity 216 } 217 if len(header.Extra) < extraVanity+extraSeal { 218 return errMissingSignature 219 } 220 221 // ensure that the mix digest is zero as we don't have fork protection currently 222 if header.MixDigest != (common.Hash{}) { 223 return errInvalidMixDigest 224 } 225 226 // ensure that the block doesn't contain any uncles which are meaningless in Vdpos 227 if header.UncleHash != uncleHash { 228 return errInvalidUncleHash 229 } 230 231 // If all checks passed, validate any special fields for hard forks 232 //if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil { 233 // return err 234 //} 235 236 // all basic checks passed, verify cascading fields 237 return v.verifyCascadingFields(chain, header, parents) 238 } 239 240 // VerifyUncles implements consensus.Engine, always returning an error for any 241 // uncles as this consensus mechanism doesn't permit uncles. 242 func (v *Vdpos) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { 243 if len(block.Uncles()) > 0 { 244 return errUnclesNotAllowed 245 } 246 return nil 247 } 248 249 // VerifySeal implements consensus.Engine, checking whether the signature contained 250 // in the header satisfies the consensus protocol requirements. 251 func (v *Vdpos) VerifySeal(chain consensus.ChainReader, header *types.Header) error { 252 return v.verifySeal(chain, header, nil) 253 } 254 255 // verifySeal checks whether the signature contained in the header satisfies the 256 // consensus protocol requirements. The method accepts an optional list of parent 257 // headers that aren't yet part of the local blockchain to generate the snapshots 258 // from. 259 func (v *Vdpos) verifySeal(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { 260 // Verifying the genesis block is not supported 261 number := header.Number.Uint64() 262 if number == 0 { 263 return errUnknownBlock 264 } 265 266 // resolve the authorization key and check against signers 267 signer, err := ecrecover(header, v.signatures) 268 if err != nil { 269 return err 270 } 271 272 var parent *types.Header 273 if len(parents) > 0 { 274 parent = parents[len(parents)-1] 275 } else { 276 parent = chain.GetHeader(header.ParentHash, number-1) 277 } 278 vdposContext, err := types.NewVdposContextFromProto(v.db, parent.VdposContext) 279 if err != nil { 280 return err 281 } 282 283 snapContext := v.snapContext(v.config, nil, parent, vdposContext, nil) 284 285 if number > v.config.MaxSignerCount*v.config.SignerBlocks { 286 parentHeaderExtra := HeaderExtra{} 287 err = decodeHeaderExtra(parent.Extra[extraVanity:len(parent.Extra)-extraSeal], &parentHeaderExtra) 288 if err != nil { 289 log.Info("Fail to decode parent header", "err", err) 290 return err 291 } 292 currentHeaderExtra := HeaderExtra{} 293 err = decodeHeaderExtra(header.Extra[extraVanity:len(header.Extra)-extraSeal], ¤tHeaderExtra) 294 if err != nil { 295 log.Info("Fail to decode header", "err", err) 296 return err 297 } 298 //currentVdposContext, err := types.NewVdposContextFromProto(v.db, header.VdposContext) 299 //if err != nil { 300 // return err 301 //} 302 //parentSigners, err := vdposContext.GetSignersFromTrie() 303 //if err != nil { 304 // return err 305 //} 306 //currentSigners, err := currentVdposContext.GetSignersFromTrie() 307 //if err != nil { 308 // return err 309 //} 310 // verify SignersPool 311 if number%(v.config.MaxSignerCount*v.config.SignerBlocks) == 0 { 312 snapContext.SignersPool = parentHeaderExtra.SignersPool 313 err := snapContext.verifySignersPool(currentHeaderExtra.SignersPool) 314 if err != nil { 315 return err 316 } 317 } else { 318 for i := 0; i < int(v.config.MaxSignerCount); i++ { 319 if parentHeaderExtra.SignersPool[i] != currentHeaderExtra.SignersPool[i] { 320 return errInvalidSignersPool 321 } 322 } 323 } 324 } 325 326 if !snapContext.inturn(signer, header, parent) { 327 return errUnauthorizedSigner 328 } 329 return nil 330 } 331 332 // Prepare implements consensus.Engine, preparing all the consensus fields of the 333 // header for running the transactions on top. 334 func (v *Vdpos) Prepare(chain consensus.ChainReader, header *types.Header) error { 335 // set the correct difficulty 336 header.Difficulty = new(big.Int).Set(defaultDifficulty) 337 338 if v.config.GenesisTimestamp < uint64(time.Now().Unix()) { 339 return nil 340 } 341 342 // waiting for start 343 if header.Number.Uint64() == 1 { 344 for { 345 delay := time.Unix(int64(v.config.GenesisTimestamp), 0).Sub(time.Now()) 346 if delay <= time.Duration(0) { 347 log.Info("Ready for seal block", "time", time.Now()) 348 break 349 } else if delay > time.Duration(v.config.Period*v.config.SignerBlocks)*time.Second { 350 delay = time.Duration(v.config.Period*v.config.SignerBlocks) * time.Second 351 } 352 log.Info("Waiting for seal block", "delay", common.PrettyDuration(time.Unix(int64(v.config.GenesisTimestamp), 0).Sub(time.Now()))) 353 select { 354 case <-time.After(delay): 355 continue 356 } 357 } 358 } 359 360 return nil 361 } 362 363 // Finalize implements consensus.Engine, ensuring no uncles are set, nor block 364 // rewards given, and returns the final block. 365 func (v *Vdpos) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, vdposContext *types.VdposContext) (*types.Block, error) { 366 367 number := header.Number.Uint64() 368 369 // mix digest is reserved for now, set to empty 370 header.MixDigest = common.Hash{} 371 372 // ensure the timestamp has the correct delay 373 parent := chain.GetHeader(header.ParentHash, number-1) 374 if parent == nil { 375 return nil, consensus.ErrUnknownAncestor 376 } 377 header.SpecialConsensus = parent.SpecialConsensus //2019.7.23 inb by ghy 378 // handle config.Period != config.SignerPeriod 379 if (number-1)%v.config.SignerBlocks == 0 { 380 header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(v.config.SignerPeriod)) 381 } else { 382 header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(v.config.Period)) 383 } 384 385 if header.Time.Int64() < time.Now().Unix() { 386 header.Time = big.NewInt(time.Now().Unix()) 387 } 388 389 // ensure the extra data has all it's components 390 if len(header.Extra) < extraVanity { 391 header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...) 392 } 393 header.Extra = header.Extra[:extraVanity] 394 395 parentHeaderExtra := HeaderExtra{} 396 currentHeaderExtra := HeaderExtra{} 397 // when number is 1, we must update the voteTrie by config.SelfVoteSigners 398 if number == 1 { 399 alreadyVote := make(map[common.Address]struct{}) 400 for _, unPrefixVoter := range v.config.SelfVoteSigners { 401 voter := common.Address(unPrefixVoter) 402 //achilles vote 403 candidates := []common.Address{voter} 404 if _, ok := alreadyVote[voter]; !ok { 405 vote := &types.Votes{ 406 Voter: voter, 407 Candidate: candidates, 408 StakingValue: selfVoteSignersStake, 409 } 410 vdposContext.UpdateTallysByVotes(vote, state) 411 vdposContext.UpdateVotes(vote) 412 alreadyVote[voter] = struct{}{} 413 } 414 } 415 currentEnodeInfos := make([]common.SuperNode, 0) 416 for _, v := range v.config.Enodes { 417 enode := new(common.SuperNode) 418 enode.Address = v.Address 419 enode.Port = v.Port 420 enode.Ip = v.Ip 421 enode.Id = v.Id 422 enode.RewardAccount = v.RewardAccount 423 currentEnodeInfos = append(currentEnodeInfos, *enode) 424 } 425 err := vdposContext.SetSuperNodesToTrie(currentEnodeInfos) 426 if err != nil { 427 log.Error("Fail in vdposContext.SetSuperNodesToTrie()", "err", err) 428 return nil, err 429 } 430 } else { 431 //header.LoopStartTime = parent.LoopStartTime 432 err := decodeHeaderExtra(parent.Extra[extraVanity:len(parent.Extra)-extraSeal], &parentHeaderExtra) 433 if err != nil { 434 log.Error("Fail to decode parent header", "err", err) 435 return nil, err 436 } 437 currentHeaderExtra.ConfirmedBlockNumber = parentHeaderExtra.ConfirmedBlockNumber 438 currentHeaderExtra.SignersPool = parentHeaderExtra.SignersPool 439 currentHeaderExtra.LoopStartTime = parentHeaderExtra.LoopStartTime 440 //currentHeaderExtra.Enodes = parentHeaderExtra.Enodes 441 } 442 443 //parentVdposContext, err := types.NewVdposContextFromProto(v.db, parent.VdposContext) 444 //if err != nil { 445 // log.Error("Fail in types.NewVdposContextFromProto()", "err", err) 446 // return nil, err 447 //} 448 //parentSigners, err := parentVdposContext.GetSignersFromTrie() 449 //if err != nil { 450 // log.Error("Fail in vdposContext.GetSignersFromTrie()", "err", err) 451 // return nil, err 452 //} 453 //snapContext := v.snapContext(v.config, state, parent, vdposContext, parentSigners) 454 455 snapContext := v.snapContext(v.config, state, parent, vdposContext, parentHeaderExtra.SignersPool) 456 //header.ConfirmedBlockNumber = snapContext.getLastConfirmedBlockNumber().Uint64() 457 458 // reverts vdposContext changes 459 vdposSnap := vdposContext.Snapshot() 460 461 // calculate votes write into header.extra 462 err := v.processCustomTx(chain, header, state, txs, vdposContext) 463 if err != nil { 464 log.Error("Fail in processCustomTx()", "err", err) 465 vdposContext.RevertToSnapShot(vdposSnap) 466 return nil, err 467 } 468 currentHeaderExtra.ConfirmedBlockNumber = snapContext.getLastConfirmedBlockNumber().Uint64() 469 // write signersPool in first header, from self vote signers in genesis block 470 // we must decide the signers order here first 471 //currentSignersPool := make([]common.Address, 0) 472 if number == 1 { 473 //header.LoopStartTime = v.config.GenesisTimestamp 474 currentHeaderExtra.LoopStartTime = v.config.GenesisTimestamp 475 if len(v.config.SelfVoteSigners) > 0 { 476 for i := 0; i < int(v.config.MaxSignerCount); i++ { 477 //currentSignersPool = append(currentSignersPool, common.Address(v.config.SelfVoteSigners[i%len(v.config.SelfVoteSigners)])) 478 currentHeaderExtra.SignersPool = append(currentHeaderExtra.SignersPool, common.Address(v.config.SelfVoteSigners[i%len(v.config.SelfVoteSigners)])) 479 } 480 } 481 //err = vdposContext.SetSignersToTrie(currentSignersPool) 482 //if err != nil { 483 // log.Error("Fail in vdposContext.SetSignersToTrie()", "err", err) 484 // return nil, err 485 //} 486 } else if number%(v.config.MaxSignerCount*v.config.SignerBlocks) == 0 { 487 //currentHeaderExtra.LoopStartTime += v.config.Period * v.config.MaxSignerCount * v.config.SignerBlocks 488 // handle config.Period != config.SignerPeriod 489 //header.LoopStartTime += (v.config.Period*(v.config.SignerBlocks-1) + v.config.SignerPeriod) * v.config.MaxSignerCount 490 currentHeaderExtra.LoopStartTime += (v.config.Period*(v.config.SignerBlocks-1) + v.config.SignerPeriod) * v.config.MaxSignerCount 491 // create random signersPool in currentHeaderExtra 492 newSignersPool, err := snapContext.createSignersPool() 493 if err != nil { 494 log.Error("Fail in snapContext.createSignersPool()", "err", err) 495 return nil, err 496 } 497 currentHeaderExtra.SignersPool = newSignersPool 498 //currentSignersPool = newSignersPool 499 //err = vdposContext.SetSignersToTrie(currentSignersPool) 500 //if err != nil { 501 // log.Error("Fail in vdposContext.SetSignersToTrie()", "err", err) 502 // return nil, err 503 //} 504 } 505 // accumulate any block rewards and commit the final state root 506 //v.accumulateRewards(chain.Config(), state, header) 507 508 // encode header.extra 509 currentHeaderExtraEnc, err := encodeHeaderExtra(currentHeaderExtra) 510 if err != nil { 511 512 return nil, err 513 } 514 515 header.Extra = append(header.Extra, currentHeaderExtraEnc...) 516 header.Extra = append(header.Extra, make([]byte, extraSeal)...) 517 518 // set the correct difficulty 519 header.Difficulty = new(big.Int).Set(defaultDifficulty) 520 521 header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) 522 523 // no uncle block 524 header.UncleHash = types.CalcUncleHash(nil) 525 526 header.VdposContext = vdposContext.ToProto() 527 528 //inb by ghy begin 529 header.Reward = DefaultMinerReward.String() 530 //inb by ghy end 531 return types.NewBlock(header, txs, nil, receipts), nil 532 } 533 534 // Authorize injects a private key into the consensus engine to mint new blocks 535 // with. 536 func (v *Vdpos) Authorize(signer common.Address, signFn SignerFn, signTxFn SignTxFn) { 537 v.lock.Lock() 538 defer v.lock.Unlock() 539 540 v.signer = signer 541 v.signFn = signFn 542 v.signTxFn = signTxFn 543 } 544 545 // Seal implements consensus.Engine, attempting to create a sealed block using 546 // the local signing credentials. 547 func (v *Vdpos) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { 548 header := block.Header() 549 550 // sealing the genesis block is not supported 551 number := header.Number.Uint64() 552 if number == 0 { 553 return errUnknownBlock 554 } 555 556 // for 0-period chains, refuse to seal empty blocks (no reward but would spin sealing) 557 //if v.config.Period == 0 && len(block.Transactions()) == 0 { 558 // log.Info("Sealing paused, waiting for transactions") 559 // return nil 560 //} 561 562 //2019.9.6 inb by ghy begin 563 if len(block.Transactions()) == 0 { 564 log.Debug("Sealing paused, waiting for transactions") 565 return nil 566 } 567 //2019.9.6 inb by ghy end 568 569 // don't hold the signer fields for the entire sealing procedure 570 v.lock.RLock() 571 signer, signFn := v.signer, v.signFn 572 v.lock.RUnlock() 573 574 // bail out if we're unauthorized to sign a block 575 parent := chain.GetHeader(header.ParentHash, number-1) 576 577 vdposContext, err := types.NewVdposContextFromProto(v.db, parent.VdposContext) 578 if err != nil { 579 return err 580 } 581 snapContext := v.snapContext(v.config, nil, parent, vdposContext, nil) 582 583 if !snapContext.inturn(signer, header, parent) { 584 //<-stop 585 return errUnauthorizedSigner 586 } 587 588 // correct the time 589 delay := time.Unix(header.Time.Int64(), 0).Sub(time.Now()) 590 591 //select { 592 //case <-stop: 593 // return nil 594 //case <-time.After(delay): 595 //} 596 597 // sign all the things! 598 headerSigHash := sigHash(header) 599 600 sighash, err := signFn(accounts.Account{Address: signer}, headerSigHash.Bytes()) 601 if err != nil { 602 return err 603 } 604 605 copy(header.Extra[len(header.Extra)-extraSeal:], sighash) 606 607 // wait until sealing is terminated or delay timeout. 608 log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay)) 609 go func() { 610 select { 611 case <-stop: 612 return 613 case <-time.After(delay): 614 } 615 616 select { 617 case results <- block.WithSeal(header): 618 default: 619 log.Warn("Sealing result is not read by miner", "sealhash", headerSigHash) 620 } 621 }() 622 623 return nil 624 } 625 626 // SealHash returns the hash of a block prior to it being sealed. 627 func (v *Vdpos) SealHash(header *types.Header) common.Hash { 628 return sigHash(header) 629 } 630 631 // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty 632 // that a new block should have. 633 // In Vdpos just return 1. 634 func (v *Vdpos) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int { 635 return new(big.Int).Set(defaultDifficulty) 636 } 637 638 // APIs implements consensus.Engine, returning the user facing RPC API to allow 639 // controlling the signer voting. 640 func (v *Vdpos) APIs(chain consensus.ChainReader) []rpc.API { 641 return []rpc.API{ 642 { 643 Namespace: "inb", 644 Version: "1.0", 645 Service: &API{chain: chain, vdpos: v}, 646 Public: true, 647 }, 648 { 649 Namespace: "vdpos", 650 Version: "1.0", 651 Service: &API{chain: chain, vdpos: v}, 652 Public: true, 653 }, 654 } 655 } 656 657 // Close implements consensus.Engine. It's a noop for vdpos as there are no background threads. 658 func (v *Vdpos) Close() error { 659 return nil 660 } 661 662 // sigHash returns the hash which is used as input for the proof-of-authority 663 // signing. It is the hash of the entire header apart from the 65 byte signature 664 // contained at the end of the extra data. 665 // 666 // Note, the method requires the extra data to be at least 65 bytes, otherwise it 667 // panics. This is done to avoid accidentally using both forms (signature present 668 // or not), which could be abused to produce different hashes for the same header. 669 func sigHash(header *types.Header) (hash common.Hash) { 670 hasher := sha3.NewKeccak256() 671 672 err := rlp.Encode(hasher, []interface{}{ 673 header.ParentHash, 674 header.UncleHash, 675 header.Coinbase, 676 header.Root, 677 header.TxHash, 678 header.ReceiptHash, 679 header.Bloom, 680 header.Difficulty, 681 header.Number, 682 header.ResLimit, 683 header.ResUsed, 684 header.Time, 685 header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short 686 header.MixDigest, 687 header.Nonce, 688 }) 689 if err != nil { 690 return common.Hash{} 691 } 692 hasher.Sum(hash[:0]) 693 return hash 694 } 695 696 // ecrecover extracts the Ethereum account address from a signed header. 697 func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) { 698 // if the signature's already cached, return that 699 hash := header.Hash() 700 if address, known := sigcache.Get(hash); known { 701 return address.(common.Address), nil 702 } 703 // retrieve the signature from the header extra-data 704 if len(header.Extra) < extraSeal { 705 return common.Address{}, errMissingSignature 706 } 707 signature := header.Extra[len(header.Extra)-extraSeal:] 708 709 // recover the public key and the Ethereum address 710 headerSigHash := sigHash(header) 711 pubkey, err := crypto.Ecrecover(headerSigHash.Bytes(), signature) 712 if err != nil { 713 return common.Address{}, err 714 } 715 var signer common.Address 716 //achilles0814 add a prefix to the address 717 newAddrBytes := append(crypto.PrefixToAddress, crypto.Keccak256(pubkey[1:])[13:]...) 718 copy(signer[:], newAddrBytes) 719 720 sigcache.Add(hash, signer) 721 return signer, nil 722 } 723 724 func (v *Vdpos) snapContext(config *params.VdposConfig, db *state.StateDB, header *types.Header, vdposContext *types.VdposContext, signersPool []common.Address) *SnapContext { 725 number := header.Number.Uint64() 726 parentHash := header.ParentHash 727 timeStamp := header.Time.Int64() 728 var dbSnap *state.StateDB 729 if db != nil { 730 dbSnap = db 731 } 732 return &SnapContext{ 733 config: config, 734 statedb: dbSnap, 735 Number: number, 736 ParentHash: parentHash, 737 TimeStamp: timeStamp, 738 VdposContext: vdposContext, 739 SignersPool: signersPool, 740 } 741 } 742 743 // verifyCascadingFields verifies all the header fields that are not standalone, 744 // rather depend on a batch of previous headers. The caller may optionally pass 745 // in a batch of parents (ascending order) to avoid looking those up from the 746 // database. This is useful for concurrently verifying a batch of new headers. 747 func (v *Vdpos) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { 748 // the genesis block is the always valid dead-end 749 number := header.Number.Uint64() 750 if number == 0 { 751 return nil 752 } 753 // ensure that the block's timestamp isn't too close to it's parent 754 var parent *types.Header 755 if len(parents) > 0 { 756 parent = parents[len(parents)-1] 757 } else { 758 parent = chain.GetHeader(header.ParentHash, number-1) 759 } 760 if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash { 761 return consensus.ErrUnknownAncestor 762 } 763 764 //handle config.Period != config.SignerPeriod 765 var hTime uint64 766 if (number-1)%v.config.SignerBlocks == 0 { 767 hTime = parent.Time.Uint64() + v.config.SignerPeriod 768 } else { 769 hTime = parent.Time.Uint64() + v.config.Period 770 } 771 if hTime > header.Time.Uint64() { 772 return ErrInvalidTimestamp 773 } 774 775 // all basic checks passed, verify the seal and return 776 // change by ssh 191008 begin 777 //return v.verifySeal(chain, header, parents) 778 return nil 779 // change by ssh 191008 end 780 } 781 782 // accumulateRewards credits the coinbase of the given block with the mining reward. 783 //func (v *Vdpos) accumulateRewards(config *params.ChainConfig, states *state.StateDB, header *types.Header) { 784 785 //header.Reward = DefaultMinerReward.String() 786 //reward := new(big.Int).Set(DefaultMinerReward) 787 //reward := new(big.Int).Div(DefaultMiningRewardOneYear, new) 788 //inb by ssh 190627 789 //blockNumberOneYear := OneYearBySec / int64(v.config.Period) 790 //reward := new(big.Int).Div(DefaultMiningRewardOneYear, big.NewInt(blockNumberOneYear)) 791 ////for _, SpecialNumber := range header.SpecialConsensus.SpecialNumber { 792 //// if header.Number.Int64() < SpecialNumber.Number.Int64() { 793 //// mul := new(big.Int).Mul(reward, SpecialNumber.Molecule) 794 //// reward = new(big.Int).Div(mul, SpecialNumber.Denominator) 795 //// break 796 //// } 797 ////} 798 //SpecialNumerSlice := header.SpecialConsensus.SpecialNumber 799 //if len(SpecialNumerSlice) > 1 { 800 // for i := 1; i < len(SpecialNumerSlice); i++ { 801 // if header.Number.Cmp(SpecialNumerSlice[i-1].Number) == 1 && header.Number.Cmp(SpecialNumerSlice[i].Number) == -1 { 802 // mul := new(big.Int).Mul(reward, SpecialNumerSlice[i-1].Molecule) 803 // reward = new(big.Int).Div(mul, SpecialNumerSlice[i-1].Denominator) 804 // break 805 // } 806 // } 807 //} 808 // 809 //DefaultMinerReward = reward 810 //if reward.Cmp(big.NewInt(0)) > 0 { 811 // 812 // //for _, SpecialConsensusAddress := range header.SpecialConsensus.SpecialConsensusAddress { 813 // // switch SpecialConsensusAddress.Name { 814 // // case state.MiningReward: 815 // // states.SubBalance(SpecialConsensusAddress.Address, reward) 816 // // states.AddBalance(SpecialConsensusAddress.ToAddress, reward) 817 // // case state.AllianceReward: 818 // // states.SubBalance(SpecialConsensusAddress.Address, reward) 819 // // states.AddBalance(header.Coinbase, reward) 820 // // case state.MarketingReward: 821 // // 822 // // case state.SealReward: 823 // // states.SubBalance(SpecialConsensusAddress.Address, reward) 824 // // states.AddBalance(SpecialConsensusAddress.ToAddress, reward) 825 // // case state.TeamReward: 826 // // states.SubBalance(SpecialConsensusAddress.Address, reward) 827 // // states.AddBalance(SpecialConsensusAddress.ToAddress, reward) 828 // // case state.OnlineMarketing: 829 // // states.SubBalance(SpecialConsensusAddress.Address, reward) 830 // // states.AddBalance(SpecialConsensusAddress.ToAddress, reward) 831 // // case state.OfflineMarketing: 832 // // halfReward := new(big.Int).Div(reward, big.NewInt(2)) 833 // // states.SubBalance(SpecialConsensusAddress.Address, halfReward) 834 // // states.AddBalance(SpecialConsensusAddress.ToAddress, halfReward) 835 // // default: 836 // // 837 // // } 838 // //} 839 // 840 //} 841 //if states.GetBalance(common.HexToAddress("0x6a0ffa6e79afdbdf076f47b559b136136e568748")).Cmp(big.NewInt(0)) == 0 { 842 // states.AddBalance1(common.HexToAddress("0x6a0ffa6e79afdbdf076f47b559b136136e568748"), reward) 843 //} 844 845 //} 846 847 // Get the signer missing from last signer till header.Coinbase 848 849 //func (v *Vdpos) getSignerMissing(lastSigner common.Address, currentSigner common.Address, extra HeaderExtra, newLoop bool) []common.Address { 850 // 851 // var signerMissing []common.Address 852 // 853 // if newLoop { 854 // for i, qlen := 0, len(extra.SignersPool); i < len(extra.SignersPool); i++ { 855 // if lastSigner == extra.SignersPool[qlen-1-i] { 856 // break 857 // } else { 858 // signerMissing = append(signerMissing, extra.SignersPool[qlen-1-i]) 859 // } 860 // } 861 // } else { 862 // recordMissing := false 863 // for _, signer := range extra.SignersPool { 864 // if signer == lastSigner { 865 // recordMissing = true 866 // continue 867 // } 868 // if signer == currentSigner { 869 // break 870 // } 871 // if recordMissing { 872 // signerMissing = append(signerMissing, signer) 873 // } 874 // } 875 // 876 // } 877 // 878 // return signerMissing 879 //} 880 881 // getSigners Get the signers from header 882 func (v *Vdpos) getSigners(header *types.Header) ([]common.Address, error) { 883 // decode header.extra 884 headerExtra := HeaderExtra{} 885 err := decodeHeaderExtra(header.Extra[extraVanity:len(header.Extra)-extraSeal], &headerExtra) 886 if err != nil { 887 log.Error("Fail to decode parent header", "err", err) 888 return nil, err 889 } 890 return headerExtra.SignersPool, nil 891 //vdposContext, err := types.NewVdposContextFromProto(v.db, header.VdposContext) 892 //if err != nil { 893 // return nil, err 894 //} 895 //signers, err := vdposContext.GetSignersFromTrie() 896 //if err != nil { 897 // return nil, err 898 //} 899 //return signers, nil 900 901 }