github.com/nnlgsakib/mind-dpos@v0.0.0-20230606105614-f3c8ca06f808/consensus/alien/alien.go (about) 1 // Copyright 2018 The gttc Authors 2 // This file is part of the gttc library. 3 // 4 // The gttc 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 Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The gttc 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 gttc library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package alien implements the delegated-proof-of-stake consensus engine. 18 package alien 19 20 import ( 21 "bytes" 22 "errors" 23 "fmt" 24 "math/big" 25 "strings" 26 "sync" 27 "time" 28 29 "github.com/TTCECO/gttc/accounts" 30 "github.com/TTCECO/gttc/common" 31 "github.com/TTCECO/gttc/consensus" 32 "github.com/TTCECO/gttc/core/state" 33 "github.com/TTCECO/gttc/core/types" 34 "github.com/TTCECO/gttc/crypto" 35 "github.com/TTCECO/gttc/crypto/sha3" 36 "github.com/TTCECO/gttc/ethdb" 37 "github.com/TTCECO/gttc/log" 38 "github.com/TTCECO/gttc/params" 39 "github.com/TTCECO/gttc/rlp" 40 "github.com/TTCECO/gttc/rpc" 41 "github.com/hashicorp/golang-lru" 42 ) 43 44 const ( 45 inMemorySnapshots = 128 // Number of recent vote snapshots to keep in memory 46 inMemorySignatures = 4096 // Number of recent block signatures to keep in memory 47 secondsPerYear = 365 * 24 * 3600 // Number of seconds for one year 48 checkpointInterval = 360 // About N hours if config.period is N 49 scUnconfirmLoop = 3 // First count of Loop not send confirm tx to main chain 50 ) 51 52 // Alien delegated-proof-of-stake protocol constants. 53 var ( 54 totalBlockReward = new(big.Int).Mul(big.NewInt(1e+18), big.NewInt(2.5e+8)) // Block reward in wei 55 defaultEpochLength = uint64(201600) // Default number of blocks after which vote's period of validity, About one week if period is 3 56 defaultBlockPeriod = uint64(3) // Default minimum difference between two consecutive block's timestamps 57 defaultMaxSignerCount = uint64(21) // 58 minVoterBalance = new(big.Int).Mul(big.NewInt(100), big.NewInt(1e+18)) 59 extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity 60 extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal 61 uncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW. 62 defaultDifficulty = big.NewInt(1) // Default difficulty 63 defaultLoopCntRecalculateSigners = uint64(10) // Default loop count to recreate signers from top tally 64 minerRewardPerThousand = uint64(618) // Default reward for miner in each block from block reward (618/1000) 65 candidateNeedPD = false // is new candidate need Proposal & Declare process 66 mcNetVersion = uint64(0) // the net version of main chain 67 mcLoopStartTime = uint64(0) // the loopstarttime of main chain 68 mcPeriod = uint64(0) // the period of main chain 69 mcSignerLength = uint64(0) // the maxsinger of main chain config 70 mcNonce = uint64(0) // the current Nonce of coinbase on main chain 71 mcTxDefaultGasPrice = big.NewInt(30000000) // default gas price to build transaction for main chain 72 mcTxDefaultGasLimit = uint64(3000000) // default limit to build transaction for main chain 73 proposalDeposit = new(big.Int).Mul(big.NewInt(1e+18), big.NewInt(1e+4)) // default current proposalDeposit 74 scRentLengthRecommend = uint64(0) // block number for split each side chain rent fee 75 ) 76 77 // Various error messages to mark blocks invalid. These should be private to 78 // prevent engine specific errors from being referenced in the remainder of the 79 // codebase, inherently breaking if the engine is swapped out. Please put common 80 // error types into the consensus package. 81 var ( 82 // errUnknownBlock is returned when the list of signers is requested for a block 83 // that is not part of the local blockchain. 84 errUnknownBlock = errors.New("unknown block") 85 86 // errMissingVanity is returned if a block's extra-data section is shorter than 87 // 32 bytes, which is required to store the signer vanity. 88 errMissingVanity = errors.New("extra-data 32 byte vanity prefix missing") 89 90 // errMissingSignature is returned if a block's extra-data section doesn't seem 91 // to contain a 65 byte secp256k1 signature. 92 errMissingSignature = errors.New("extra-data 65 byte suffix signature missing") 93 94 // errInvalidMixDigest is returned if a block's mix digest is non-zero. 95 errInvalidMixDigest = errors.New("non-zero mix digest") 96 97 // errInvalidUncleHash is returned if a block contains an non-empty uncle list. 98 errInvalidUncleHash = errors.New("non empty uncle hash") 99 100 // ErrInvalidTimestamp is returned if the timestamp of a block is lower than 101 // the previous block's timestamp + the minimum block period. 102 ErrInvalidTimestamp = errors.New("invalid timestamp") 103 104 // errInvalidVotingChain is returned if an authorization list is attempted to 105 // be modified via out-of-range or non-contiguous headers. 106 errInvalidVotingChain = errors.New("invalid voting chain") 107 108 // errUnauthorized is returned if a header is signed by a non-authorized entity. 109 errUnauthorized = errors.New("unauthorized") 110 111 // errPunishedMissing is returned if a header calculate punished signer is wrong. 112 errPunishedMissing = errors.New("punished signer missing") 113 114 // errWaitTransactions is returned if an empty block is attempted to be sealed 115 // on an instant chain (0 second period). It's important to refuse these as the 116 // block reward is zero, so an empty block just bloats the chain... fast. 117 errWaitTransactions = errors.New("waiting for transactions") 118 119 // errUnclesNotAllowed is returned if uncles exists 120 errUnclesNotAllowed = errors.New("uncles not allowed") 121 122 // errCreateSignerQueueNotAllowed is returned if called in (block number + 1) % maxSignerCount != 0 123 errCreateSignerQueueNotAllowed = errors.New("create signer queue not allowed") 124 125 // errInvalidSignerQueue is returned if verify SignerQueue fail 126 errInvalidSignerQueue = errors.New("invalid signer queue") 127 128 // errSignerQueueEmpty is returned if no signer when calculate 129 errSignerQueueEmpty = errors.New("signer queue is empty") 130 131 // errGetLastLoopInfoFail is returned if get last loop info fail 132 errGetLastLoopInfoFail = errors.New("get last loop info fail") 133 134 // errInvalidNeighborSigner is returned if two neighbor block signed by same miner and time diff less period 135 errInvalidNeighborSigner = errors.New("invalid neighbor signer") 136 137 // errMissingGenesisLightConfig is returned only in light syncmode if light config missing 138 errMissingGenesisLightConfig = errors.New("light config in genesis is missing") 139 140 // errLastLoopHeaderFail is returned when try to get header of last loop fail 141 errLastLoopHeaderFail = errors.New("get last loop header fail") 142 ) 143 144 // Alien is the delegated-proof-of-stake consensus engine. 145 type Alien struct { 146 config *params.AlienConfig // Consensus engine configuration parameters 147 db ethdb.Database // Database to store and retrieve snapshot checkpoints 148 recents *lru.ARCCache // Snapshots for recent block to speed up reorgs 149 signatures *lru.ARCCache // Signatures of recent blocks to speed up mining 150 signer common.Address // Ethereum address of the signing key 151 signFn SignerFn // Signer function to authorize hashes with 152 signTxFn SignTxFn // Sign transaction function to sign tx 153 lock sync.RWMutex // Protects the signer fields 154 lcsc uint64 // Last confirmed side chain 155 } 156 157 // SignerFn is a signer callback function to request a hash to be signed by a 158 // backing account. 159 type SignerFn func(accounts.Account, []byte) ([]byte, error) 160 161 // SignTxFn is a signTx 162 type SignTxFn func(accounts.Account, *types.Transaction, *big.Int) (*types.Transaction, error) 163 164 // sigHash returns the hash which is used as input for the delegated-proof-of-stake 165 // signing. It is the hash of the entire header apart from the 65 byte signature 166 // contained at the end of the extra data. 167 // 168 // Note, the method requires the extra data to be at least 65 bytes, otherwise it 169 // panics. This is done to avoid accidentally using both forms (signature present 170 // or not), which could be abused to produce different hashes for the same header. 171 func sigHash(header *types.Header) (hash common.Hash, err error) { 172 hasher := sha3.NewKeccak256() 173 if err := rlp.Encode(hasher, []interface{}{ 174 header.ParentHash, 175 header.UncleHash, 176 header.Coinbase, 177 header.Root, 178 header.TxHash, 179 header.ReceiptHash, 180 header.Bloom, 181 header.Difficulty, 182 header.Number, 183 header.GasLimit, 184 header.GasUsed, 185 header.Time, 186 header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short 187 header.MixDigest, 188 header.Nonce, 189 }); err != nil { 190 return common.Hash{}, err 191 } 192 193 hasher.Sum(hash[:0]) 194 return hash, nil 195 } 196 197 // ecrecover extracts the Ethereum account address from a signed header. 198 func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) { 199 // If the signature's already cached, return that 200 hash := header.Hash() 201 if address, known := sigcache.Get(hash); known { 202 return address.(common.Address), nil 203 } 204 // Retrieve the signature from the header extra-data 205 if len(header.Extra) < extraSeal { 206 return common.Address{}, errMissingSignature 207 } 208 signature := header.Extra[len(header.Extra)-extraSeal:] 209 210 // Recover the public key and the Ethereum address 211 headerSigHash, err := sigHash(header) 212 if err != nil { 213 return common.Address{}, err 214 } 215 pubkey, err := crypto.Ecrecover(headerSigHash.Bytes(), signature) 216 if err != nil { 217 return common.Address{}, err 218 } 219 var signer common.Address 220 copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) 221 222 sigcache.Add(hash, signer) 223 return signer, nil 224 } 225 226 // New creates a Alien delegated-proof-of-stake consensus engine with the initial 227 // signers set to the ones provided by the user. 228 func New(config *params.AlienConfig, db ethdb.Database) *Alien { 229 // Set any missing consensus parameters to their defaults 230 conf := *config 231 if conf.Epoch == 0 { 232 conf.Epoch = defaultEpochLength 233 } 234 if conf.Period == 0 { 235 conf.Period = defaultBlockPeriod 236 } 237 if conf.MaxSignerCount == 0 { 238 conf.MaxSignerCount = defaultMaxSignerCount 239 } 240 if conf.MinVoterBalance.Uint64() > 0 { 241 minVoterBalance = conf.MinVoterBalance 242 } 243 244 // Allocate the snapshot caches and create the engine 245 recents, _ := lru.NewARC(inMemorySnapshots) 246 signatures, _ := lru.NewARC(inMemorySignatures) 247 248 return &Alien{ 249 config: &conf, 250 db: db, 251 recents: recents, 252 signatures: signatures, 253 } 254 } 255 256 // Author implements consensus.Engine, returning the Ethereum address recovered 257 // from the signature in the header's extra-data section. 258 func (a *Alien) Author(header *types.Header) (common.Address, error) { 259 return ecrecover(header, a.signatures) 260 } 261 262 // VerifyHeader checks whether a header conforms to the consensus rules. 263 func (a *Alien) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { 264 return a.verifyHeader(chain, header, nil) 265 } 266 267 // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The 268 // method returns a quit channel to abort the operations and a results channel to 269 // retrieve the async verifications (the order is that of the input slice). 270 func (a *Alien) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { 271 abort := make(chan struct{}) 272 results := make(chan error, len(headers)) 273 274 go func() { 275 for i, header := range headers { 276 err := a.verifyHeader(chain, header, headers[:i]) 277 278 select { 279 case <-abort: 280 return 281 case results <- err: 282 } 283 } 284 }() 285 return abort, results 286 } 287 288 // verifyHeader checks whether a header conforms to the consensus rules.The 289 // caller may optionally pass in a batch of parents (ascending order) to avoid 290 // looking those up from the database. This is useful for concurrently verifying 291 // a batch of new headers. 292 func (a *Alien) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { 293 if header.Number == nil { 294 return errUnknownBlock 295 } 296 297 // Don't waste time checking blocks from the future 298 if header.Time.Cmp(big.NewInt(time.Now().Unix())) > 0 { 299 return consensus.ErrFutureBlock 300 } 301 302 // Check that the extra-data contains both the vanity and signature 303 if len(header.Extra) < extraVanity { 304 return errMissingVanity 305 } 306 if len(header.Extra) < extraVanity+extraSeal { 307 return errMissingSignature 308 } 309 310 // Ensure that the mix digest is zero as we don't have fork protection currently 311 if header.MixDigest != (common.Hash{}) { 312 return errInvalidMixDigest 313 } 314 // Ensure that the block doesn't contain any uncles which are meaningless in PoA 315 if header.UncleHash != uncleHash { 316 return errInvalidUncleHash 317 } 318 319 // All basic checks passed, verify cascading fields 320 return a.verifyCascadingFields(chain, header, parents) 321 } 322 323 // verifyCascadingFields verifies all the header fields that are not standalone, 324 // rather depend on a batch of previous headers. The caller may optionally pass 325 // in a batch of parents (ascending order) to avoid looking those up from the 326 // database. This is useful for concurrently verifying a batch of new headers. 327 func (a *Alien) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { 328 // The genesis block is the always valid dead-end 329 number := header.Number.Uint64() 330 if number == 0 { 331 return nil 332 } 333 // Ensure that the block's timestamp isn't too close to it's parent 334 var parent *types.Header 335 if len(parents) > 0 { 336 parent = parents[len(parents)-1] 337 } else { 338 parent = chain.GetHeader(header.ParentHash, number-1) 339 } 340 if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash { 341 return consensus.ErrUnknownAncestor 342 } 343 if parent.Time.Uint64() > header.Time.Uint64() { 344 return ErrInvalidTimestamp 345 } 346 // Retrieve the snapshot needed to verify this header and cache it 347 _, err := a.snapshot(chain, number-1, header.ParentHash, parents, nil, defaultLoopCntRecalculateSigners) 348 if err != nil { 349 return err 350 } 351 352 // All basic checks passed, verify the seal and return 353 return a.verifySeal(chain, header, parents) 354 } 355 356 // snapshot retrieves the authorization snapshot at a given point in time. 357 func (a *Alien) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header, genesisVotes []*Vote, lcrs uint64) (*Snapshot, error) { 358 // Don't keep snapshot for side chain 359 //if chain.Config().Alien.SideChain { 360 // return nil, nil 361 //} 362 // Search for a snapshot in memory or on disk for checkpoints 363 var ( 364 headers []*types.Header 365 snap *Snapshot 366 ) 367 368 for snap == nil { 369 // If an in-memory snapshot was found, use that 370 if s, ok := a.recents.Get(hash); ok { 371 snap = s.(*Snapshot) 372 break 373 } 374 // If an on-disk checkpoint snapshot can be found, use that 375 if number%checkpointInterval == 0 { 376 if s, err := loadSnapshot(a.config, a.signatures, a.db, hash); err == nil { 377 log.Trace("Loaded voting snapshot from disk", "number", number, "hash", hash) 378 snap = s 379 break 380 } 381 } 382 // If we're at block zero, make a snapshot 383 if number == 0 { 384 genesis := chain.GetHeaderByNumber(0) 385 if err := a.VerifyHeader(chain, genesis, false); err != nil { 386 return nil, err 387 } 388 a.config.Period = chain.Config().Alien.Period 389 snap = newSnapshot(a.config, a.signatures, genesis.Hash(), genesisVotes, lcrs) 390 if err := snap.store(a.db); err != nil { 391 return nil, err 392 } 393 log.Trace("Stored genesis voting snapshot to disk") 394 break 395 } 396 // No snapshot for this header, gather the header and move backward 397 var header *types.Header 398 if len(parents) > 0 { 399 // If we have explicit parents, pick from there (enforced) 400 header = parents[len(parents)-1] 401 if header.Hash() != hash || header.Number.Uint64() != number { 402 return nil, consensus.ErrUnknownAncestor 403 } 404 parents = parents[:len(parents)-1] 405 } else { 406 // No explicit parents (or no more left), reach out to the database 407 header = chain.GetHeader(hash, number) 408 if header == nil { 409 return nil, consensus.ErrUnknownAncestor 410 } 411 } 412 headers = append(headers, header) 413 number, hash = number-1, header.ParentHash 414 } 415 // Previous snapshot found, apply any pending headers on top of it 416 for i := 0; i < len(headers)/2; i++ { 417 headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i] 418 } 419 420 snap, err := snap.apply(headers) 421 if err != nil { 422 return nil, err 423 } 424 425 a.recents.Add(snap.Hash, snap) 426 427 // If we've generated a new checkpoint snapshot, save to disk 428 if snap.Number%checkpointInterval == 0 && len(headers) > 0 { 429 if err = snap.store(a.db); err != nil { 430 return nil, err 431 } 432 log.Trace("Stored voting snapshot to disk", "number", snap.Number, "hash", snap.Hash) 433 } 434 return snap, err 435 } 436 437 // VerifyUncles implements consensus.Engine, always returning an error for any 438 // uncles as this consensus mechanism doesn't permit uncles. 439 func (a *Alien) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { 440 if len(block.Uncles()) > 0 { 441 return errUnclesNotAllowed 442 } 443 return nil 444 } 445 446 // VerifySeal implements consensus.Engine, checking whether the signature contained 447 // in the header satisfies the consensus protocol requirements. 448 func (a *Alien) VerifySeal(chain consensus.ChainReader, header *types.Header) error { 449 return a.verifySeal(chain, header, nil) 450 } 451 452 // verifySeal checks whether the signature contained in the header satisfies the 453 // consensus protocol requirements. The method accepts an optional list of parent 454 // headers that aren't yet part of the local blockchain to generate the snapshots 455 // from. 456 func (a *Alien) verifySeal(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { 457 // Verifying the genesis block is not supported 458 number := header.Number.Uint64() 459 if number == 0 { 460 return errUnknownBlock 461 } 462 // Retrieve the snapshot needed to verify this header and cache it 463 snap, err := a.snapshot(chain, number-1, header.ParentHash, parents, nil, defaultLoopCntRecalculateSigners) 464 if err != nil { 465 return err 466 } 467 468 // Resolve the authorization key and check against signers 469 signer, err := ecrecover(header, a.signatures) 470 if err != nil { 471 return err 472 } 473 474 // check the coinbase == signer 475 if header.Number.Cmp(big.NewInt(bugFixBlockNumber)) > 0 { 476 if signer != header.Coinbase { 477 return errUnauthorized 478 } 479 } 480 481 if !chain.Config().Alien.SideChain { 482 483 if number > a.config.MaxSignerCount { 484 var parent *types.Header 485 if len(parents) > 0 { 486 parent = parents[len(parents)-1] 487 } else { 488 parent = chain.GetHeader(header.ParentHash, number-1) 489 } 490 parentHeaderExtra := HeaderExtra{} 491 err = decodeHeaderExtra(a.config, parent.Number, parent.Extra[extraVanity:len(parent.Extra)-extraSeal], &parentHeaderExtra) 492 if err != nil { 493 log.Info("Fail to decode parent header", "err", err) 494 return err 495 } 496 currentHeaderExtra := HeaderExtra{} 497 err = decodeHeaderExtra(a.config, header.Number, header.Extra[extraVanity:len(header.Extra)-extraSeal], ¤tHeaderExtra) 498 if err != nil { 499 log.Info("Fail to decode header", "err", err) 500 return err 501 } 502 // verify signerqueue 503 if number%a.config.MaxSignerCount == 0 { 504 err := snap.verifySignerQueue(currentHeaderExtra.SignerQueue) 505 if err != nil { 506 return err 507 } 508 509 } else { 510 for i := 0; i < int(a.config.MaxSignerCount); i++ { 511 if parentHeaderExtra.SignerQueue[i] != currentHeaderExtra.SignerQueue[i] { 512 return errInvalidSignerQueue 513 } 514 } 515 if signer == parent.Coinbase && header.Time.Uint64()-parent.Time.Uint64() < chain.Config().Alien.Period { 516 return errInvalidNeighborSigner 517 } 518 519 } 520 521 // verify missing signer for punish 522 var parentSignerMissing []common.Address 523 if a.config.IsTrantor(header.Number) { 524 var grandParentHeaderExtra HeaderExtra 525 if number%a.config.MaxSignerCount == 1 { 526 var grandParent *types.Header 527 if len(parents) > 1 { 528 grandParent = parents[len(parents)-2] 529 } else { 530 grandParent = chain.GetHeader(parent.ParentHash, number-2) 531 } 532 if grandParent == nil { 533 return errLastLoopHeaderFail 534 } 535 err := decodeHeaderExtra(a.config, grandParent.Number, grandParent.Extra[extraVanity:len(grandParent.Extra)-extraSeal], &grandParentHeaderExtra) 536 if err != nil { 537 log.Info("Fail to decode parent header", "err", err) 538 return err 539 } 540 } 541 parentSignerMissing = getSignerMissingTrantor(parent.Coinbase, header.Coinbase, &parentHeaderExtra, &grandParentHeaderExtra) 542 } else { 543 newLoop := false 544 if number%a.config.MaxSignerCount == 0 { 545 newLoop = true 546 } 547 parentSignerMissing = getSignerMissing(parent.Coinbase, header.Coinbase, parentHeaderExtra, newLoop) 548 } 549 550 if len(parentSignerMissing) != len(currentHeaderExtra.SignerMissing) { 551 return errPunishedMissing 552 } 553 for i, signerMissing := range currentHeaderExtra.SignerMissing { 554 if parentSignerMissing[i] != signerMissing { 555 return errPunishedMissing 556 } 557 } 558 } 559 560 if !snap.inturn(signer, header.Time.Uint64()) { 561 return errUnauthorized 562 } 563 } else { 564 if notice, loopStartTime, period, signerLength, _, err := a.mcSnapshot(chain, signer, header.Time.Uint64()); err != nil { 565 return err 566 } else { 567 mcLoopStartTime = loopStartTime 568 mcPeriod = period 569 mcSignerLength = signerLength 570 // check gas charging 571 if notice != nil { 572 currentHeaderExtra := HeaderExtra{} 573 err = decodeHeaderExtra(a.config, header.Number, header.Extra[extraVanity:len(header.Extra)-extraSeal], ¤tHeaderExtra) 574 if err != nil { 575 return err 576 } 577 if len(notice.CurrentCharging) != len(currentHeaderExtra.SideChainCharging) { 578 return errMCGasChargingInvalid 579 } else { 580 for _, charge := range currentHeaderExtra.SideChainCharging { 581 if v, ok := notice.CurrentCharging[charge.Hash]; !ok { 582 return err 583 } else { 584 if v.Volume != charge.Volume || v.Target != charge.Target { 585 return errMCGasChargingInvalid 586 } 587 } 588 } 589 } 590 591 } 592 } 593 } 594 595 return nil 596 } 597 598 // Prepare implements consensus.Engine, preparing all the consensus fields of the 599 // header for running the transactions on top. 600 func (a *Alien) Prepare(chain consensus.ChainReader, header *types.Header) error { 601 602 // Set the correct difficulty 603 header.Difficulty = new(big.Int).Set(defaultDifficulty) 604 number := header.Number.Uint64() 605 // Ensure the timestamp has the correct delay 606 parent := chain.GetHeader(header.ParentHash, number-1) 607 if parent == nil { 608 return consensus.ErrUnknownAncestor 609 } 610 header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(a.config.Period)) 611 if header.Time.Int64() < time.Now().Unix() { 612 header.Time = big.NewInt(time.Now().Unix()) 613 } 614 // If now is later than genesis timestamp, skip prepare 615 if a.config.GenesisTimestamp < uint64(time.Now().Unix()) { 616 return nil 617 } 618 // Count down for start 619 if header.Number.Uint64() == 1 { 620 for { 621 delay := time.Unix(int64(a.config.GenesisTimestamp-2), 0).Sub(time.Now()) 622 if delay <= time.Duration(0) { 623 log.Info("Ready for seal block", "time", time.Now()) 624 break 625 } else if delay > time.Duration(a.config.Period)*time.Second { 626 delay = time.Duration(a.config.Period) * time.Second 627 } 628 log.Info("Waiting for seal block", "delay", common.PrettyDuration(time.Unix(int64(a.config.GenesisTimestamp-2), 0).Sub(time.Now()))) 629 select { 630 case <-time.After(delay): 631 continue 632 } 633 } 634 } 635 636 return nil 637 } 638 639 // get the snapshot info from main chain and check if current signer inturn, if inturn then update the info 640 func (a *Alien) mcSnapshot(chain consensus.ChainReader, signer common.Address, headerTime uint64) (*CCNotice, uint64, uint64, uint64, uint64, error) { 641 642 if chain.Config().Alien.SideChain { 643 chainHash := chain.GetHeaderByNumber(0).ParentHash 644 ms, err := a.getMainChainSnapshotByTime(chain, headerTime, chainHash) 645 if err != nil { 646 return nil, 0, 0, 0, 0, err 647 } else if len(ms.Signers) == 0 { 648 return nil, 0, 0, 0, 0, errSignerQueueEmpty 649 } else if ms.Period == 0 { 650 return nil, 0, 0, 0, 0, errMCPeriodMissing 651 } 652 653 loopIndex := int((headerTime-ms.LoopStartTime)/ms.Period) % len(ms.Signers) 654 if loopIndex >= len(ms.Signers) { 655 return nil, 0, 0, 0, 0, errInvalidSignerQueue 656 } else if *ms.Signers[loopIndex] != signer { 657 return nil, 0, 0, 0, 0, errUnauthorized 658 } 659 notice := &CCNotice{} 660 if mcNotice, ok := ms.SCNoticeMap[chainHash]; ok { 661 notice = mcNotice 662 } 663 return notice, ms.LoopStartTime, ms.Period, uint64(len(ms.Signers)), ms.Number, nil 664 } 665 return nil, 0, 0, 0, 0, errNotSideChain 666 } 667 668 func (a *Alien) parseNoticeInfo(notice *CCNotice) string { 669 // if other notice exist, return string may be more than one 670 if notice != nil { 671 var charging []string 672 for hash := range notice.CurrentCharging { 673 charging = append(charging, hash.Hex()) 674 } 675 return strings.Join(charging, "#") 676 } 677 return "" 678 } 679 680 func (a *Alien) getLastLoopInfo(chain consensus.ChainReader, header *types.Header) (string, error) { 681 if chain.Config().Alien.SideChain && mcLoopStartTime != 0 && mcPeriod != 0 && a.config.Period != 0 { 682 var loopHeaderInfo []string 683 inLastLoop := false 684 extraTime := (header.Time.Uint64() - mcLoopStartTime) % (mcPeriod * mcSignerLength) 685 for i := uint64(0); i < a.config.MaxSignerCount*2*(mcPeriod/a.config.Period); i++ { 686 header = chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) 687 if header == nil { 688 return "", consensus.ErrUnknownAncestor 689 } 690 newTime := (header.Time.Uint64() - mcLoopStartTime) % (mcPeriod * mcSignerLength) 691 if newTime > extraTime { 692 if !inLastLoop { 693 inLastLoop = true 694 } else { 695 break 696 } 697 } 698 extraTime = newTime 699 if inLastLoop { 700 loopHeaderInfo = append(loopHeaderInfo, fmt.Sprintf("%d#%s", header.Number.Uint64(), header.Coinbase.Hex())) 701 } 702 } 703 if len(loopHeaderInfo) > 0 { 704 return strings.Join(loopHeaderInfo, "#"), nil 705 } 706 } 707 return "", errGetLastLoopInfoFail 708 } 709 710 func (a *Alien) mcConfirmBlock(chain consensus.ChainReader, header *types.Header, notice *CCNotice) { 711 712 a.lock.RLock() 713 signer, signTxFn := a.signer, a.signTxFn 714 a.lock.RUnlock() 715 716 if signer != (common.Address{}) { 717 // todo update gaslimit , gasprice ,and get ChainID need to get from mainchain 718 if header.Number.Uint64() > a.lcsc && header.Number.Uint64() > a.config.MaxSignerCount*scUnconfirmLoop { 719 nonce, err := a.getTransactionCountFromMainChain(chain, signer) 720 if err != nil { 721 log.Info("Confirm tx sign fail", "err", err) 722 return 723 } 724 725 lastLoopInfo, err := a.getLastLoopInfo(chain, header) 726 if err != nil { 727 log.Info("Confirm tx sign fail", "err", err) 728 return 729 } 730 731 chargingInfo := a.parseNoticeInfo(notice) 732 733 txData := a.buildSCEventConfirmData(chain.GetHeaderByNumber(0).ParentHash, header.Number, header.Time, lastLoopInfo, chargingInfo) 734 tx := types.NewTransaction(nonce, header.Coinbase, big.NewInt(0), mcTxDefaultGasLimit, mcTxDefaultGasPrice, txData) 735 736 if mcNetVersion == 0 { 737 mcNetVersion, err = a.getNetVersionFromMainChain(chain) 738 if err != nil { 739 log.Info("Query main chain net version fail", "err", err) 740 } 741 } 742 743 signedTx, err := signTxFn(accounts.Account{Address: signer}, tx, big.NewInt(int64(mcNetVersion))) 744 if err != nil { 745 log.Info("Confirm tx sign fail", "err", err) 746 } 747 txHash, err := a.sendTransactionToMainChain(chain, signedTx) 748 if err != nil { 749 log.Info("Confirm tx send fail", "err", err) 750 } else { 751 log.Info("Confirm tx result", "txHash", txHash) 752 a.lcsc = header.Number.Uint64() 753 } 754 } 755 } 756 757 } 758 759 // Finalize implements consensus.Engine, ensuring no uncles are set, nor block 760 // rewards given, and returns the final block. 761 func (a *Alien) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { 762 763 764 // Mix digest is reserved for now, set to empty 765 header.MixDigest = common.Hash{} 766 number := header.Number.Uint64() 767 parent := chain.GetHeader(header.ParentHash, number-1) 768 if parent == nil { 769 return nil, consensus.ErrUnknownAncestor 770 } 771 772 773 // Ensure the extra data has all it's components 774 if len(header.Extra) < extraVanity { 775 header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...) 776 } 777 header.Extra = header.Extra[:extraVanity] 778 779 // genesisVotes write direct into snapshot, which number is 1 780 var genesisVotes []*Vote 781 parentHeaderExtra := HeaderExtra{} 782 currentHeaderExtra := HeaderExtra{} 783 784 if number == 1 { 785 alreadyVote := make(map[common.Address]struct{}) 786 for _, unPrefixVoter := range a.config.SelfVoteSigners { 787 voter := common.Address(unPrefixVoter) 788 if _, ok := alreadyVote[voter]; !ok { 789 genesisVotes = append(genesisVotes, &Vote{ 790 Voter: voter, 791 Candidate: voter, 792 Stake: state.GetBalance(voter), 793 }) 794 alreadyVote[voter] = struct{}{} 795 } 796 } 797 } else { 798 // decode extra from last header.extra 799 err := decodeHeaderExtra(a.config, parent.Number, parent.Extra[extraVanity:len(parent.Extra)-extraSeal], &parentHeaderExtra) 800 if err != nil { 801 log.Info("Fail to decode parent header", "err", err) 802 return nil, err 803 } 804 currentHeaderExtra.ConfirmedBlockNumber = parentHeaderExtra.ConfirmedBlockNumber 805 currentHeaderExtra.SignerQueue = parentHeaderExtra.SignerQueue 806 currentHeaderExtra.LoopStartTime = parentHeaderExtra.LoopStartTime 807 808 if a.config.IsTrantor(header.Number) { 809 var grandParentHeaderExtra HeaderExtra 810 if number%a.config.MaxSignerCount == 1 { 811 grandParent := chain.GetHeader(parent.ParentHash, number-2) 812 if grandParent == nil { 813 return nil, errLastLoopHeaderFail 814 } 815 err := decodeHeaderExtra(a.config, grandParent.Number, grandParent.Extra[extraVanity:len(grandParent.Extra)-extraSeal], &grandParentHeaderExtra) 816 if err != nil { 817 log.Info("Fail to decode parent header", "err", err) 818 return nil, err 819 } 820 } 821 currentHeaderExtra.SignerMissing = getSignerMissingTrantor(parent.Coinbase, header.Coinbase, &parentHeaderExtra, &grandParentHeaderExtra) 822 } else { 823 newLoop := false 824 if number%a.config.MaxSignerCount == 0 { 825 newLoop = true 826 } 827 currentHeaderExtra.SignerMissing = getSignerMissing(parent.Coinbase, header.Coinbase, parentHeaderExtra, newLoop) 828 } 829 830 } 831 832 // Assemble the voting snapshot to check which votes make sense 833 snap, err := a.snapshot(chain, number-1, header.ParentHash, nil, genesisVotes, defaultLoopCntRecalculateSigners) 834 if err != nil { 835 return nil, err 836 } 837 if !chain.Config().Alien.SideChain { 838 // calculate votes write into header.extra 839 mcCurrentHeaderExtra, refundGas, err := a.processCustomTx(currentHeaderExtra, chain, header, state, txs, receipts) 840 if err != nil { 841 return nil, err 842 } 843 currentHeaderExtra = mcCurrentHeaderExtra 844 currentHeaderExtra.ConfirmedBlockNumber = snap.getLastConfirmedBlockNumber(currentHeaderExtra.CurrentBlockConfirmations).Uint64() 845 // write signerQueue in first header, from self vote signers in genesis block 846 if number == 1 { 847 currentHeaderExtra.LoopStartTime = a.config.GenesisTimestamp 848 if len(a.config.SelfVoteSigners) > 0 { 849 for i := 0; i < int(a.config.MaxSignerCount); i++ { 850 currentHeaderExtra.SignerQueue = append(currentHeaderExtra.SignerQueue, common.Address(a.config.SelfVoteSigners[i%len(a.config.SelfVoteSigners)])) 851 } 852 } 853 } else if number%a.config.MaxSignerCount == 0 { 854 //currentHeaderExtra.LoopStartTime = header.Time.Uint64() 855 currentHeaderExtra.LoopStartTime = currentHeaderExtra.LoopStartTime + a.config.Period*a.config.MaxSignerCount 856 // create random signersQueue in currentHeaderExtra by snapshot.Tally 857 currentHeaderExtra.SignerQueue = []common.Address{} 858 newSignerQueue, err := snap.createSignerQueue() 859 if err != nil { 860 return nil, err 861 } 862 currentHeaderExtra.SignerQueue = newSignerQueue 863 } 864 865 // Accumulate any block rewards and commit the final state root 866 if err := accumulateRewards(chain.Config(), state, header, snap, refundGas); err != nil { 867 return nil, errUnauthorized 868 } 869 } else { 870 // use currentHeaderExtra.SignerQueue as signer queue 871 currentHeaderExtra.SignerQueue = append([]common.Address{header.Coinbase}, parentHeaderExtra.SignerQueue...) 872 if len(currentHeaderExtra.SignerQueue) > int(a.config.MaxSignerCount) { 873 currentHeaderExtra.SignerQueue = currentHeaderExtra.SignerQueue[:int(a.config.MaxSignerCount)] 874 } 875 sideChainRewards(chain.Config(), state, header, snap) 876 } 877 // encode header.extra 878 currentHeaderExtraEnc, err := encodeHeaderExtra(a.config, header.Number, currentHeaderExtra) 879 if err != nil { 880 return nil, err 881 } 882 883 header.Extra = append(header.Extra, currentHeaderExtraEnc...) 884 header.Extra = append(header.Extra, make([]byte, extraSeal)...) 885 886 // Set the correct difficulty 887 header.Difficulty = new(big.Int).Set(defaultDifficulty) 888 889 header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) 890 // No uncle block 891 header.UncleHash = types.CalcUncleHash(nil) 892 893 // Assemble and return the final block for sealing 894 return types.NewBlock(header, txs, nil, receipts), nil 895 } 896 897 // Authorize injects a private key into the consensus engine to mint new blocks with. 898 func (a *Alien) Authorize(signer common.Address, signFn SignerFn, signTxFn SignTxFn) { 899 a.lock.Lock() 900 defer a.lock.Unlock() 901 902 a.signer = signer 903 a.signFn = signFn 904 a.signTxFn = signTxFn 905 } 906 907 // ApplyGenesis 908 func (a *Alien) ApplyGenesis(chain consensus.ChainReader, genesisHash common.Hash) error { 909 if a.config.LightConfig != nil { 910 var genesisVotes []*Vote 911 alreadyVote := make(map[common.Address]struct{}) 912 for _, unPrefixVoter := range a.config.SelfVoteSigners { 913 voter := common.Address(unPrefixVoter) 914 if genesisAccount, ok := a.config.LightConfig.Alloc[unPrefixVoter]; ok { 915 if _, ok := alreadyVote[voter]; !ok { 916 stake := new(big.Int) 917 stake.UnmarshalText([]byte(genesisAccount.Balance)) 918 genesisVotes = append(genesisVotes, &Vote{ 919 Voter: voter, 920 Candidate: voter, 921 Stake: stake, 922 }) 923 alreadyVote[voter] = struct{}{} 924 } 925 } 926 } 927 // Assemble the voting snapshot to check which votes make sense 928 if _, err := a.snapshot(chain, 0, genesisHash, nil, genesisVotes, defaultLoopCntRecalculateSigners); err != nil { 929 return err 930 } 931 return nil 932 } 933 return errMissingGenesisLightConfig 934 } 935 936 // Seal implements consensus.Engine, attempting to create a sealed block using 937 // the local signing credentials. 938 func (a *Alien) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) { 939 header := block.Header() 940 941 // Sealing the genesis block is not supported 942 number := header.Number.Uint64() 943 if number == 0 { 944 return nil, errUnknownBlock 945 } 946 947 // For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing) 948 if a.config.Period == 0 && len(block.Transactions()) == 0 { 949 return nil, errWaitTransactions 950 } 951 // Don't hold the signer fields for the entire sealing procedure 952 a.lock.RLock() 953 signer, signFn := a.signer, a.signFn 954 a.lock.RUnlock() 955 956 // Bail out if we're unauthorized to sign a block 957 snap, err := a.snapshot(chain, number-1, header.ParentHash, nil, nil, defaultLoopCntRecalculateSigners) 958 if err != nil { 959 return nil, err 960 } 961 962 if !chain.Config().Alien.SideChain { 963 if !snap.inturn(signer, header.Time.Uint64()) { 964 <-stop 965 return nil, errUnauthorized 966 } 967 } else { 968 if notice, loopStartTime, period, signerLength, _, err := a.mcSnapshot(chain, signer, header.Time.Uint64()); err != nil { 969 <-stop 970 return nil, err 971 } else { 972 mcLoopStartTime = loopStartTime 973 mcPeriod = period 974 mcSignerLength = signerLength 975 if notice != nil { 976 // rebuild the header.Extra for gas charging 977 currentHeaderExtra := HeaderExtra{} 978 if err = decodeHeaderExtra(a.config, header.Number, header.Extra[extraVanity:len(header.Extra)-extraSeal], ¤tHeaderExtra); err != nil { 979 return nil, err 980 } 981 for _, charge := range notice.CurrentCharging { 982 currentHeaderExtra.SideChainCharging = append(currentHeaderExtra.SideChainCharging, charge) 983 } 984 currentHeaderExtraEnc, err := encodeHeaderExtra(a.config, header.Number, currentHeaderExtra) 985 if err != nil { 986 return nil, err 987 } 988 header.Extra = header.Extra[:extraVanity] 989 header.Extra = append(header.Extra, currentHeaderExtraEnc...) 990 header.Extra = append(header.Extra, make([]byte, extraSeal)...) 991 } 992 // send tx to main chain to confirm this block 993 a.mcConfirmBlock(chain, header, notice) 994 } 995 } 996 997 // correct the time 998 delay := time.Unix(header.Time.Int64(), 0).Sub(time.Now()) 999 1000 select { 1001 case <-stop: 1002 return nil, nil 1003 case <-time.After(delay): 1004 } 1005 1006 // Sign all the things! 1007 headerSigHash, err := sigHash(header) 1008 if err != nil { 1009 return nil, err 1010 } 1011 1012 sighash, err := signFn(accounts.Account{Address: signer}, headerSigHash.Bytes()) 1013 if err != nil { 1014 return nil, err 1015 } 1016 1017 copy(header.Extra[len(header.Extra)-extraSeal:], sighash) 1018 1019 return block.WithSeal(header), nil 1020 } 1021 1022 // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty 1023 // that a new block should have based on the previous blocks in the chain and the 1024 // current signer. 1025 func (a *Alien) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int { 1026 1027 return new(big.Int).Set(defaultDifficulty) 1028 } 1029 1030 // APIs implements consensus.Engine, returning the user facing RPC API to allow 1031 // controlling the signer voting. 1032 func (a *Alien) APIs(chain consensus.ChainReader) []rpc.API { 1033 return []rpc.API{{ 1034 Namespace: "alien", 1035 Version: ufoVersion, 1036 Service: &API{chain: chain, alien: a}, 1037 Public: false, 1038 }} 1039 } 1040 1041 func sideChainRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, snap *Snapshot) { 1042 // vanish gas fee 1043 gasUsed := new(big.Int).SetUint64(header.GasUsed) 1044 if state.GetBalance(header.Coinbase).Cmp(gasUsed) >= 0 { 1045 state.SubBalance(header.Coinbase, gasUsed) 1046 } 1047 // gas charging 1048 for target, volume := range snap.calculateGasCharging() { 1049 state.AddBalance(target, volume) 1050 } 1051 } 1052 1053 // AccumulateRewards credits the coinbase of the given block with the mining reward. 1054 func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, snap *Snapshot, refundGas RefundGas) error { 1055 // Calculate the block reword by year 1056 blockNumPerYear := secondsPerYear / config.Alien.Period 1057 initSignerBlockReward := new(big.Int).Div(totalBlockReward, big.NewInt(int64(2*blockNumPerYear))) 1058 yearCount := header.Number.Uint64() / blockNumPerYear 1059 blockReward := new(big.Int).Rsh(initSignerBlockReward, uint(yearCount)) 1060 1061 minerReward := new(big.Int).Set(blockReward) 1062 minerReward.Mul(minerReward, new(big.Int).SetUint64(snap.MinerReward)) 1063 minerReward.Div(minerReward, big.NewInt(1000)) // cause the reward is calculate by cnt per thousand 1064 1065 votersReward := blockReward.Sub(blockReward, minerReward) 1066 1067 // rewards for the voters 1068 voteRewardMap, err := snap.calculateVoteReward(header.Coinbase, votersReward) 1069 if err != nil { 1070 return err 1071 } 1072 for voter, reward := range voteRewardMap { 1073 state.AddBalance(voter, reward) 1074 } 1075 1076 // calculate for proposal refund 1077 for proposer, refund := range snap.calculateProposalRefund() { 1078 state.AddBalance(proposer, refund) 1079 } 1080 1081 scReward, minerLeft := snap.calculateSCReward(minerReward) 1082 minerReward.Set(minerLeft) 1083 // rewards for the side chain coinbase 1084 for scCoinbase, reward := range scReward { 1085 state.AddBalance(scCoinbase, reward) 1086 } 1087 // refund gas for custom txs 1088 for sender, gas := range refundGas { 1089 state.AddBalance(sender, gas) 1090 minerReward.Sub(minerReward, gas) 1091 } 1092 1093 // rewards for the miner, check minerReward value for refund gas 1094 if minerReward.Cmp(big.NewInt(0)) > 0 { 1095 state.AddBalance(header.Coinbase, minerReward) 1096 } 1097 1098 return nil 1099 } 1100 1101 // Get the signer missing from last signer till header.Coinbase 1102 func getSignerMissing(lastSigner common.Address, currentSigner common.Address, extra HeaderExtra, newLoop bool) []common.Address { 1103 1104 var signerMissing []common.Address 1105 1106 if newLoop { 1107 for i, qlen := 0, len(extra.SignerQueue); i < len(extra.SignerQueue); i++ { 1108 if lastSigner == extra.SignerQueue[qlen-1-i] { 1109 break 1110 } else { 1111 signerMissing = append(signerMissing, extra.SignerQueue[qlen-1-i]) 1112 } 1113 } 1114 } else { 1115 recordMissing := false 1116 for _, signer := range extra.SignerQueue { 1117 if signer == lastSigner { 1118 recordMissing = true 1119 continue 1120 } 1121 if signer == currentSigner { 1122 break 1123 } 1124 if recordMissing { 1125 signerMissing = append(signerMissing, signer) 1126 } 1127 } 1128 1129 } 1130 1131 return signerMissing 1132 } 1133 1134 // Get the signer missing from last signer till header.Coinbase 1135 func getSignerMissingTrantor(lastSigner common.Address, currentSigner common.Address, extra *HeaderExtra, gpExtra *HeaderExtra) []common.Address { 1136 1137 var signerMissing []common.Address 1138 signerQueue := append(extra.SignerQueue, extra.SignerQueue...) 1139 if gpExtra != nil { 1140 for i, v := range gpExtra.SignerQueue { 1141 if v == lastSigner { 1142 signerQueue[i] = lastSigner 1143 signerQueue = signerQueue[i:] 1144 break 1145 } 1146 } 1147 } 1148 1149 recordMissing := false 1150 for _, signer := range signerQueue { 1151 if !recordMissing && signer == lastSigner { 1152 recordMissing = true 1153 continue 1154 } 1155 if recordMissing && signer == currentSigner { 1156 break 1157 } 1158 if recordMissing { 1159 signerMissing = append(signerMissing, signer) 1160 } 1161 } 1162 1163 return signerMissing 1164 1165 }