gitlab.com/yannislg/go-pulse@v0.0.0-20210722055913-a3e24e95638d/consensus/parlia/parlia.go (about) 1 package parlia 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/hex" 7 "errors" 8 "fmt" 9 "io" 10 "math" 11 "math/big" 12 "math/rand" 13 "strings" 14 "sync" 15 "time" 16 17 lru "github.com/hashicorp/golang-lru" 18 "golang.org/x/crypto/sha3" 19 20 "github.com/ethereum/go-ethereum" 21 "github.com/ethereum/go-ethereum/accounts" 22 "github.com/ethereum/go-ethereum/accounts/abi" 23 "github.com/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/common/hexutil" 25 "github.com/ethereum/go-ethereum/consensus" 26 "github.com/ethereum/go-ethereum/consensus/ethash" 27 "github.com/ethereum/go-ethereum/consensus/misc" 28 "github.com/ethereum/go-ethereum/core" 29 "github.com/ethereum/go-ethereum/core/forkid" 30 "github.com/ethereum/go-ethereum/core/state" 31 "github.com/ethereum/go-ethereum/core/systemcontracts" 32 "github.com/ethereum/go-ethereum/core/types" 33 "github.com/ethereum/go-ethereum/core/vm" 34 "github.com/ethereum/go-ethereum/crypto" 35 "github.com/ethereum/go-ethereum/ethdb" 36 "github.com/ethereum/go-ethereum/internal/ethapi" 37 "github.com/ethereum/go-ethereum/log" 38 "github.com/ethereum/go-ethereum/params" 39 "github.com/ethereum/go-ethereum/rlp" 40 "github.com/ethereum/go-ethereum/rpc" 41 ) 42 43 const ( 44 inMemorySnapshots = 128 // Number of recent snapshots to keep in memory 45 inMemorySignatures = 4096 // Number of recent block signatures to keep in memory 46 47 checkpointInterval = 1024 // Number of blocks after which to save the snapshot to the database 48 defaultEpochLength = uint64(100) // Default number of blocks of checkpoint to update validatorSet from contract 49 50 extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity 51 extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal 52 nextForkHashSize = 4 // Fixed number of extra-data suffix bytes reserved for nextForkHash. 53 54 validatorBytesLength = common.AddressLength 55 wiggleTime = uint64(1) // second, Random delay (per signer) to allow concurrent signers 56 initialBackOffTime = uint64(1) // second 57 58 systemRewardPercent = 4 // it means 1/2^4 = 1/16 percentage of gas fee incoming will be distributed to system 59 60 ) 61 62 var ( 63 uncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW. 64 diffInTurn = big.NewInt(2) // Block difficulty for in-turn signatures 65 diffNoTurn = big.NewInt(1) // Block difficulty for out-of-turn signatures 66 // 100 native token 67 maxSystemBalance = new(big.Int).Mul(big.NewInt(100), big.NewInt(params.Ether)) 68 69 systemContracts = map[common.Address]bool{ 70 common.HexToAddress(systemcontracts.ValidatorContract): true, 71 common.HexToAddress(systemcontracts.SlashingContract): true, 72 common.HexToAddress(systemcontracts.StakingContract): true, 73 } 74 ) 75 76 // Various error messages to mark blocks invalid. These should be private to 77 // prevent engine specific errors from being referenced in the remainder of the 78 // codebase, inherently breaking if the engine is swapped out. Please put common 79 // error types into the consensus package. 80 var ( 81 // errUnknownBlock is returned when the list of validators is requested for a block 82 // that is not part of the local blockchain. 83 errUnknownBlock = errors.New("unknown block") 84 85 // errMissingVanity is returned if a block's extra-data section is shorter than 86 // 32 bytes, which is required to store the signer vanity. 87 errMissingVanity = errors.New("extra-data 32 byte vanity prefix missing") 88 89 // errMissingSignature is returned if a block's extra-data section doesn't seem 90 // to contain a 65 byte secp256k1 signature. 91 errMissingSignature = errors.New("extra-data 65 byte signature suffix missing") 92 93 // errExtraValidators is returned if non-sprint-end block contain validator data in 94 // their extra-data fields. 95 errExtraValidators = errors.New("non-sprint-end block contains extra validator list") 96 97 // errInvalidSpanValidators is returned if a block contains an 98 // invalid list of validators (i.e. non divisible by 20 bytes). 99 errInvalidSpanValidators = errors.New("invalid validator list on sprint end block") 100 101 // errInvalidMixDigest is returned if a block's mix digest is non-zero. 102 errInvalidMixDigest = errors.New("non-zero mix digest") 103 104 // errInvalidUncleHash is returned if a block contains an non-empty uncle list. 105 errInvalidUncleHash = errors.New("non empty uncle hash") 106 107 // errMismatchingEpochValidators is returned if a sprint block contains a 108 // list of validators different than the one the local node calculated. 109 errMismatchingEpochValidators = errors.New("mismatching validator list on epoch block") 110 111 // errInvalidDifficulty is returned if the difficulty of a block is missing. 112 errInvalidDifficulty = errors.New("invalid difficulty") 113 114 // errWrongDifficulty is returned if the difficulty of a block doesn't match the 115 // turn of the signer. 116 errWrongDifficulty = errors.New("wrong difficulty") 117 118 // errOutOfRangeChain is returned if an authorization list is attempted to 119 // be modified via out-of-range or non-contiguous headers. 120 errOutOfRangeChain = errors.New("out of range or non-contiguous chain") 121 122 // errBlockHashInconsistent is returned if an authorization list is attempted to 123 // insert an inconsistent block. 124 errBlockHashInconsistent = errors.New("the block hash is inconsistent") 125 126 // errUnauthorizedValidator is returned if a header is signed by a non-authorized entity. 127 errUnauthorizedValidator = errors.New("unauthorized validator") 128 129 // errCoinBaseMisMatch is returned if a header's coinbase do not match with signature 130 errCoinBaseMisMatch = errors.New("coinbase do not match with signature") 131 132 // errRecentlySigned is returned if a header is signed by an authorized entity 133 // that already signed a header recently, thus is temporarily not allowed to. 134 errRecentlySigned = errors.New("recently signed") 135 ) 136 137 // SignerFn is a signer callback function to request a header to be signed by a 138 // backing account. 139 type SignerFn func(accounts.Account, string, []byte) ([]byte, error) 140 type SignerTxFn func(accounts.Account, *types.Transaction, *big.Int) (*types.Transaction, error) 141 142 func isToSystemContract(to common.Address) bool { 143 return systemContracts[to] 144 } 145 146 // ecrecover extracts the Ethereum account address from a signed header. 147 func ecrecover(header *types.Header, sigCache *lru.ARCCache, chainId *big.Int) (common.Address, error) { 148 // If the signature's already cached, return that 149 hash := header.Hash() 150 if address, known := sigCache.Get(hash); known { 151 return address.(common.Address), nil 152 } 153 // Retrieve the signature from the header extra-data 154 if len(header.Extra) < extraSeal { 155 return common.Address{}, errMissingSignature 156 } 157 signature := header.Extra[len(header.Extra)-extraSeal:] 158 159 // Recover the public key and the Ethereum address 160 pubkey, err := crypto.Ecrecover(SealHash(header, chainId).Bytes(), signature) 161 if err != nil { 162 return common.Address{}, err 163 } 164 var signer common.Address 165 copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) 166 167 sigCache.Add(hash, signer) 168 return signer, nil 169 } 170 171 // ParliaRLP returns the rlp bytes which needs to be signed for the parlia 172 // sealing. The RLP to sign consists of the entire header apart from the 65 byte signature 173 // contained at the end of the extra data. 174 // 175 // Note, the method requires the extra data to be at least 65 bytes, otherwise it 176 // panics. This is done to avoid accidentally using both forms (signature present 177 // or not), which could be abused to produce different hashes for the same header. 178 func ParliaRLP(header *types.Header, chainId *big.Int) []byte { 179 b := new(bytes.Buffer) 180 encodeSigHeader(b, header, chainId) 181 return b.Bytes() 182 } 183 184 // Parlia is the consensus engine of BSC 185 type Parlia struct { 186 chainConfig *params.ChainConfig // Chain config 187 config *params.ParliaConfig // Consensus engine configuration parameters for parlia consensus 188 genesisHash common.Hash 189 db ethdb.Database // Database to store and retrieve snapshot checkpoints 190 191 recentSnaps *lru.ARCCache // Snapshots for recent block to speed up 192 signatures *lru.ARCCache // Signatures of recent blocks to speed up mining 193 194 signer types.Signer 195 196 val common.Address // Ethereum address of the signing key 197 signFn SignerFn // Signer function to authorize hashes with 198 signTxFn SignerTxFn 199 200 lock sync.RWMutex // Protects the signer fields 201 202 ethAPI *ethapi.PublicBlockChainAPI 203 validatorSetABI abi.ABI 204 slashABI abi.ABI 205 stakingABI abi.ABI 206 207 // The fields below are for testing only 208 fakeDiff bool // Skip difficulty verifications 209 210 // Used for synchronizing pulse chain prior to the PrimordialPulseBlock 211 // Will be lazily instantiated as needed 212 makeEthash func() *ethash.Ethash 213 _ethash *ethash.Ethash // The lazily-loaded instance 214 } 215 216 // New creates a Parlia consensus engine. 217 func New( 218 chainConfig *params.ChainConfig, 219 db ethdb.Database, 220 ethAPI *ethapi.PublicBlockChainAPI, 221 genesisHash common.Hash, 222 makeEthash func() *ethash.Ethash, 223 ) *Parlia { 224 // get parlia config 225 parliaConfig := chainConfig.Parlia 226 227 // Set any missing consensus parameters to their defaults 228 if parliaConfig != nil && parliaConfig.Epoch == 0 { 229 parliaConfig.Epoch = defaultEpochLength 230 } 231 232 // Allocate the snapshot caches and create the engine 233 recentSnaps, err := lru.NewARC(inMemorySnapshots) 234 if err != nil { 235 panic(err) 236 } 237 signatures, err := lru.NewARC(inMemorySignatures) 238 if err != nil { 239 panic(err) 240 } 241 vABI, err := abi.JSON(strings.NewReader(validatorSetABI)) 242 if err != nil { 243 panic(err) 244 } 245 slABI, err := abi.JSON(strings.NewReader(slashingABI)) 246 if err != nil { 247 panic(err) 248 } 249 stABI, err := abi.JSON(strings.NewReader(stakingABI)) 250 if err != nil { 251 panic(err) 252 } 253 c := &Parlia{ 254 chainConfig: chainConfig, 255 config: parliaConfig, 256 genesisHash: genesisHash, 257 db: db, 258 ethAPI: ethAPI, 259 recentSnaps: recentSnaps, 260 signatures: signatures, 261 validatorSetABI: vABI, 262 slashABI: slABI, 263 stakingABI: stABI, 264 signer: types.NewEIP155Signer(chainConfig.ChainID), 265 makeEthash: makeEthash, 266 } 267 268 return c 269 } 270 271 func (p *Parlia) IsSystemTransaction(tx *types.Transaction, header *types.Header) (bool, error) { 272 // deploy a contract 273 if tx.To() == nil { 274 return false, nil 275 } 276 sender, err := types.Sender(p.signer, tx) 277 if err != nil { 278 return false, errors.New("UnAuthorized transaction") 279 } 280 if sender == header.Coinbase && isToSystemContract(*tx.To()) && tx.GasPrice().Cmp(big.NewInt(0)) == 0 { 281 return true, nil 282 } 283 return false, nil 284 } 285 286 func (p *Parlia) IsSystemContract(to *common.Address) bool { 287 if to == nil { 288 return false 289 } 290 return isToSystemContract(*to) 291 } 292 293 // Author implements consensus.Engine, returning the SystemAddress 294 func (p *Parlia) Author(header *types.Header) (common.Address, error) { 295 if p.chainConfig.PrimordialPulseAhead(header.Number) { 296 return p.ethash().Author(header) 297 } 298 return header.Coinbase, nil 299 } 300 301 // VerifyHeader checks whether a header conforms to the consensus rules. 302 func (p *Parlia) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { 303 if p.chainConfig.PrimordialPulseAhead(header.Number) { 304 return p.ethash().VerifyHeader(chain, header, seal) 305 } 306 return p.verifyHeader(chain, header, nil) 307 } 308 309 // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The 310 // method returns a quit channel to abort the operations and a results channel to 311 // retrieve the async verifications (the order is that of the input slice). 312 func (p *Parlia) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { 313 abort := make(chan struct{}) 314 results := make(chan error, len(headers)) 315 316 go func() { 317 forkAhead := p.chainConfig.PrimordialPulseAhead(headers[0].Number) 318 if forkAhead { 319 forkIdx := p.chainConfig.PrimordialPulseBlock.Uint64() - headers[0].Number.Uint64() 320 if forkIdx > uint64(len(headers)) { 321 forkIdx = uint64(len(headers)) 322 } 323 324 preforkHeaders := headers[:forkIdx] 325 _, res := p.ethash().VerifyHeaders(chain, preforkHeaders, seals) 326 for i := 0; i < len(preforkHeaders); i++ { 327 err := <-res 328 select { 329 case <-abort: 330 return 331 case results <- err: 332 } 333 } 334 335 if forkIdx == uint64(len(headers)) { 336 // all blocks are pre-fork, we can stop now 337 return 338 } 339 340 // we need to continue on the post-fork blocks with this consensus engine 341 // include the last prefork header for parent verification of first postfork block 342 headers = headers[forkIdx-1:] 343 } 344 345 for i, header := range headers { 346 if i == 0 && forkAhead { 347 // the list of headers includes prefork and postfork blocks 348 // the first block in this slice is the final (already verified) prefork block 349 // used only for parent verification of first postfork block 350 continue 351 } 352 err := p.verifyHeader(chain, header, headers[:i]) 353 354 select { 355 case <-abort: 356 return 357 case results <- err: 358 } 359 } 360 }() 361 return abort, results 362 } 363 364 // verifyHeader checks whether a header conforms to the consensus rules.The 365 // caller may optionally pass in a batch of parents (ascending order) to avoid 366 // looking those up from the database. This is useful for concurrently verifying 367 // a batch of new headers. 368 func (p *Parlia) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { 369 if header.Number == nil { 370 return errUnknownBlock 371 } 372 number := header.Number.Uint64() 373 374 // Don't waste time checking blocks from the future 375 if header.Time > uint64(time.Now().Unix()) { 376 return consensus.ErrFutureBlock 377 } 378 // Check that the extra-data contains the vanity, validators and signature. 379 if len(header.Extra) < extraVanity { 380 return errMissingVanity 381 } 382 if len(header.Extra) < extraVanity+extraSeal { 383 return errMissingSignature 384 } 385 // check extra data 386 isEpoch := number%p.config.Epoch == 0 387 388 // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise 389 signersBytes := len(header.Extra) - extraVanity - extraSeal 390 if !isEpoch && signersBytes != 0 { 391 return errExtraValidators 392 } 393 394 if isEpoch && signersBytes%validatorBytesLength != 0 { 395 return errInvalidSpanValidators 396 } 397 398 // Ensure that the mix digest is zero as we don't have fork protection currently 399 if header.MixDigest != (common.Hash{}) { 400 return errInvalidMixDigest 401 } 402 // Ensure that the block doesn't contain any uncles which are meaningless in PoA 403 if header.UncleHash != uncleHash { 404 return errInvalidUncleHash 405 } 406 // Ensure that the block's difficulty is meaningful (may not be correct at this point) 407 if number > 0 { 408 if header.Difficulty == nil { 409 return errInvalidDifficulty 410 } 411 } 412 // If all checks passed, validate any special fields for hard forks 413 if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil { 414 return err 415 } 416 // All basic checks passed, verify cascading fields 417 return p.verifyCascadingFields(chain, header, parents) 418 } 419 420 // verifyCascadingFields verifies all the header fields that are not standalone, 421 // rather depend on a batch of previous headers. The caller may optionally pass 422 // in a batch of parents (ascending order) to avoid looking those up from the 423 // database. This is useful for concurrently verifying a batch of new headers. 424 func (p *Parlia) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { 425 // The genesis block is the always valid dead-end 426 number := header.Number.Uint64() 427 if number == 0 { 428 return nil 429 } 430 431 var parent *types.Header 432 if len(parents) > 0 { 433 parent = parents[len(parents)-1] 434 } else { 435 parent = chain.GetHeader(header.ParentHash, number-1) 436 } 437 438 if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash { 439 return consensus.ErrUnknownAncestor 440 } 441 442 snap, err := p.snapshot(chain, number-1, header.ParentHash, parents) 443 if err != nil { 444 return err 445 } 446 447 err = p.blockTimeVerifyForRamanujanFork(snap, header, parent) 448 if err != nil { 449 return err 450 } 451 452 // Verify that the gas limit is <= 2^63-1 453 capacity := uint64(0x7fffffffffffffff) 454 if header.GasLimit > capacity { 455 return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, capacity) 456 } 457 // Verify that the gasUsed is <= gasLimit 458 if header.GasUsed > header.GasLimit { 459 return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit) 460 } 461 462 // Verify that the gas limit remains within allowed bounds 463 diff := int64(parent.GasLimit) - int64(header.GasLimit) 464 if diff < 0 { 465 diff *= -1 466 } 467 limit := parent.GasLimit / params.GasLimitBoundDivisor 468 469 if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit { 470 return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit) 471 } 472 473 // All basic checks passed, verify the seal and return 474 return p.verifySeal(chain, header, parents) 475 } 476 477 func (p *Parlia) ethash() *ethash.Ethash { 478 if p._ethash != nil { 479 log.Debug("Deferring to ethash") 480 return p._ethash 481 } 482 log.Debug("Instantiating ethash") 483 p._ethash = p.makeEthash() 484 return p._ethash 485 } 486 487 // snapshot retrieves the authorization snapshot at a given point in time. 488 func (p *Parlia) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) { 489 // Search for a snapshot in memory or on disk for checkpoints 490 var ( 491 headers []*types.Header 492 snap *Snapshot 493 ) 494 495 for snap == nil { 496 // If an in-memory snapshot was found, use that 497 if s, ok := p.recentSnaps.Get(hash); ok { 498 snap = s.(*Snapshot) 499 break 500 } 501 502 // If an on-disk checkpoint snapshot can be found, use that 503 if number%checkpointInterval == 0 { 504 if s, err := loadSnapshot(p.config, p.signatures, p.db, hash, p.ethAPI); err == nil { 505 log.Trace("Loaded snapshot from disk", "number", number, "hash", hash) 506 snap = s 507 break 508 } 509 } 510 511 // If we're at the genesis, snapshot the initial state. 512 if number == 0 { 513 checkpoint := chain.GetHeaderByNumber(number) 514 if checkpoint != nil { 515 // get checkpoint data 516 hash := checkpoint.Hash() 517 518 if p.chainConfig.PrimordialPulseAhead(common.Big0) { 519 // If we're at the genesis, but there is a PrimordialPulse fork in our future, 520 // this implies that we're behind the forked chain. Suppose an empty set of validators 521 // and wait for chain synchronization. 522 snap = newSnapshot(p.config, p.signatures, number, hash, []common.Address{{}}, p.ethAPI) 523 } else { 524 // Initialize the validators from the genesis block extra-data. 525 validatorBytes := checkpoint.Extra[extraVanity : len(checkpoint.Extra)-extraSeal] 526 validators, err := ParseValidators(validatorBytes) 527 if err != nil { 528 return nil, err 529 } 530 531 snap = newSnapshot(p.config, p.signatures, number, hash, validators, p.ethAPI) 532 } 533 534 if err := snap.store(p.db); err != nil { 535 return nil, err 536 } 537 log.Info("Stored checkpoint snapshot to disk", "number", number, "hash", hash) 538 break 539 } 540 } 541 542 // If we're at the PrimordialPulseBlock, snapshot the initial state from the validator contract. 543 // This will only occur for a non-zero primordial block, which indicates a fork of an existing chain. 544 // In such a case we initialize the validator snapshot from ParliaConfig instead of genesis block headers. 545 // Offset by one since this is function is looking for the snapshot based on previous block. 546 if p.chainConfig.IsPrimordialPulseBlock(number + 1) { 547 validators, err := p.initPulsors() 548 if err != nil { 549 return nil, err 550 } 551 552 snap = newSnapshot(p.config, p.signatures, number, hash, validators, p.ethAPI) 553 554 // Store the snapshot to cache instead of disk since the block may or may not fall on the checkpointInterval. 555 // The snap will load from cache, or worst case be reconstructed from config again. 556 p.recentSnaps.Add(snap.Hash, snap) 557 log.Info("Added primordial pulse snapshot to cache", "number", number, "hash", hash) 558 break 559 } 560 561 // No snapshot for this header, gather the header and move backward 562 var header *types.Header 563 if len(parents) > 0 { 564 // If we have explicit parents, pick from there (enforced) 565 header = parents[len(parents)-1] 566 if header.Hash() != hash || header.Number.Uint64() != number { 567 return nil, consensus.ErrUnknownAncestor 568 } 569 parents = parents[:len(parents)-1] 570 } else { 571 // No explicit parents (or no more left), reach out to the database 572 header = chain.GetHeader(hash, number) 573 if header == nil { 574 return nil, consensus.ErrUnknownAncestor 575 } 576 } 577 headers = append(headers, header) // headers appended in descending order 578 number, hash = number-1, header.ParentHash 579 } 580 581 // check if snapshot is nil 582 if snap == nil { 583 return nil, fmt.Errorf("unknown error while retrieving snapshot at block number %v", number) 584 } 585 586 // Previous snapshot found, apply any pending headers on top of it 587 for i := 0; i < len(headers)/2; i++ { 588 // reverse the order of the headers array (sort ascending) 589 headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i] 590 } 591 592 snap, err := snap.apply(headers, chain, parents, p.chainConfig.ChainID) 593 if err != nil { 594 return nil, err 595 } 596 p.recentSnaps.Add(snap.Hash, snap) 597 598 // If we've generated a new checkpoint snapshot, save to disk 599 if snap.Number%checkpointInterval == 0 && len(headers) > 0 { 600 if err = snap.store(p.db); err != nil { 601 return nil, err 602 } 603 log.Trace("Stored snapshot to disk", "number", snap.Number, "hash", snap.Hash) 604 } 605 return snap, err 606 } 607 608 // VerifyUncles implements consensus.Engine, always returning an error for any 609 // uncles as this consensus mechanism doesn't permit uncles. 610 func (p *Parlia) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { 611 if p.chainConfig.PrimordialPulseAhead(block.Header().Number) { 612 return p.ethash().VerifyUncles(chain, block) 613 } 614 if len(block.Uncles()) > 0 { 615 return errors.New("uncles not allowed") 616 } 617 return nil 618 } 619 620 // VerifySeal implements consensus.Engine, checking whether the signature contained 621 // in the header satisfies the consensus protocol requirements. 622 func (p *Parlia) VerifySeal(chain consensus.ChainReader, header *types.Header) error { 623 return p.verifySeal(chain, header, nil) 624 } 625 626 // verifySeal checks whether the signature contained in the header satisfies the 627 // consensus protocol requirements. The method accepts an optional list of parent 628 // headers that aren't yet part of the local blockchain to generate the snapshots 629 // from. 630 func (p *Parlia) verifySeal(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { 631 // Verifying the genesis block is not supported 632 number := header.Number.Uint64() 633 if number == 0 { 634 return errUnknownBlock 635 } 636 // Retrieve the snapshot needed to verify this header and cache it 637 snap, err := p.snapshot(chain, number-1, header.ParentHash, parents) 638 if err != nil { 639 return err 640 } 641 642 // Resolve the authorization key and check against validators 643 signer, err := ecrecover(header, p.signatures, p.chainConfig.ChainID) 644 if err != nil { 645 return err 646 } 647 648 if signer != header.Coinbase { 649 return errCoinBaseMisMatch 650 } 651 652 if _, ok := snap.Validators[signer]; !ok { 653 return errUnauthorizedValidator 654 } 655 656 for seen, recent := range snap.Recents { 657 if recent == signer { 658 // Signer is among recents, only fail if the current block doesn't shift it out 659 if limit := uint64(len(snap.Validators)/2 + 1); seen > number-limit { 660 return errRecentlySigned 661 } 662 } 663 } 664 665 // Ensure that the difficulty corresponds to the turn-ness of the signer 666 if !p.fakeDiff { 667 inturn := snap.inturn(signer) 668 if inturn && header.Difficulty.Cmp(diffInTurn) != 0 { 669 return errWrongDifficulty 670 } 671 if !inturn && header.Difficulty.Cmp(diffNoTurn) != 0 { 672 return errWrongDifficulty 673 } 674 } 675 676 return nil 677 } 678 679 // Prepare implements consensus.Engine, preparing all the consensus fields of the 680 // header for running the transactions on top. 681 func (p *Parlia) Prepare(chain consensus.ChainReader, header *types.Header) error { 682 header.Coinbase = p.val 683 header.Nonce = types.BlockNonce{} 684 685 number := header.Number.Uint64() 686 snap, err := p.snapshot(chain, number-1, header.ParentHash, nil) 687 if err != nil { 688 return err 689 } 690 691 // Set the correct difficulty 692 header.Difficulty = calcDifficulty(snap, p.val) 693 694 // Ensure the extra data has all it's components 695 if len(header.Extra) < extraVanity-nextForkHashSize { 696 header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-nextForkHashSize-len(header.Extra))...) 697 } 698 header.Extra = header.Extra[:extraVanity-nextForkHashSize] 699 nextForkHash := forkid.NextForkHash(p.chainConfig, p.genesisHash, number) 700 header.Extra = append(header.Extra, nextForkHash[:]...) 701 702 if number%p.config.Epoch == 0 { 703 newValidatorBytes, err := p.getEpochValidatorBytes(header, snap) 704 if err != nil { 705 return err 706 } 707 708 header.Extra = append(header.Extra, newValidatorBytes...) 709 } 710 711 // add extra seal space 712 header.Extra = append(header.Extra, make([]byte, extraSeal)...) 713 714 // Mix digest is reserved for now, set to empty 715 header.MixDigest = common.Hash{} 716 717 // Ensure the timestamp has the correct delay 718 parent := chain.GetHeader(header.ParentHash, number-1) 719 if parent == nil { 720 return consensus.ErrUnknownAncestor 721 } 722 header.Time = p.blockTimeForRamanujanFork(snap, header, parent) 723 if header.Time < uint64(time.Now().Unix()) { 724 header.Time = uint64(time.Now().Unix()) 725 } 726 return nil 727 } 728 729 // Finalize implements consensus.Engine, ensuring no uncles are set, nor block 730 // rewards given. 731 func (p *Parlia) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs *[]*types.Transaction, 732 uncles []*types.Header, receipts *[]*types.Receipt, systemTxs *[]*types.Transaction, usedGas *uint64) error { 733 if p.chainConfig.PrimordialPulseAhead(header.Number) { 734 return p.ethash().Finalize(chain, header, state, txs, uncles, receipts, systemTxs, usedGas) 735 } 736 // warn if not in majority fork 737 number := header.Number.Uint64() 738 snap, err := p.snapshot(chain, number-1, header.ParentHash, nil) 739 if err != nil { 740 panic(err) 741 } 742 nextForkHash := forkid.NextForkHash(p.chainConfig, p.genesisHash, number) 743 if !snap.isMajorityFork(hex.EncodeToString(nextForkHash[:])) { 744 log.Debug("there is a possible fork, and your client is not the majority. Please check...", "nextForkHash", hex.EncodeToString(nextForkHash[:])) 745 } 746 747 // If the block is an epoch start block, verify the validator list 748 // The verification can only be done when the state is ready, it can't be done in VerifyHeader. 749 if number%p.config.Epoch == 0 { 750 validatorsBytes, err := p.getEpochValidatorBytes(header, snap) 751 if err != nil { 752 return err 753 } 754 755 extraSuffix := len(header.Extra) - extraSeal 756 if !bytes.Equal(header.Extra[extraVanity:extraSuffix], validatorsBytes) { 757 return errMismatchingEpochValidators 758 } 759 } 760 761 // No block rewards in PoA, so the state remains as is and uncles are dropped 762 cx := chainContext{Chain: chain, parlia: p} 763 if header.Number.Cmp(common.Big1) == 0 || p.chainConfig.IsPrimordialPulseBlock(number) { 764 log.Info("Initializing system contracts", "number", number) 765 if err := p.initContracts(state, header, cx, txs, receipts, systemTxs, usedGas, false); err != nil { 766 log.Error("Failed to initialize system contracts") 767 } 768 769 if p.chainConfig.IsPrimordialPulseBlock(number) { 770 // handle initial allocations for the primordialPulse fork 771 if err := p.primordialPulseAlloctions(state); err != nil { 772 panic(err) 773 } 774 } 775 } 776 777 // trigger the validator rotation on the last block of the era 778 // on the next block (epoch), the authorization snapshot will be updated 779 if (number+1)%(p.config.Epoch*p.config.Era) == 0 { 780 log.Info("Triggering staked validator rotation", "number", number) 781 err = p.rotateValidators(state, header, cx, txs, receipts, systemTxs, usedGas, false) 782 if err != nil { 783 log.Error("Staked validator rotation failed", "number", number) 784 } 785 } 786 787 if header.Difficulty.Cmp(diffInTurn) != 0 { 788 spoiledVal := snap.supposeValidator() 789 signedRecently := false 790 for _, recent := range snap.Recents { 791 if recent == spoiledVal { 792 signedRecently = true 793 break 794 } 795 } 796 if !signedRecently { 797 log.Trace("slash validator", "block hash", header.Hash(), "address", spoiledVal) 798 err = p.slash(spoiledVal, state, header, cx, txs, receipts, systemTxs, usedGas, false) 799 if err != nil { 800 // it is possible that slash validator failed because of the slash channel is disabled. 801 log.Error("slash validator failed", "block hash", header.Hash(), "address", spoiledVal) 802 } 803 } 804 } 805 806 val := header.Coinbase 807 if err := p.distributeIncoming(val, state, header, cx, txs, receipts, systemTxs, usedGas, false); err != nil { 808 panic(err) 809 } 810 if len(*systemTxs) > 0 { 811 return errors.New("the length of systemTxs do not match") 812 } 813 header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) 814 header.UncleHash = types.CalcUncleHash(nil) 815 return nil 816 } 817 818 // FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set, 819 // nor block rewards given, and returns the final block. 820 func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainReader, header *types.Header, state *state.StateDB, 821 txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, []*types.Receipt, error) { 822 // No block rewards in PoA, so the state remains as is and uncles are dropped 823 cx := chainContext{Chain: chain, parlia: p} 824 if txs == nil { 825 txs = make([]*types.Transaction, 0) 826 } 827 if receipts == nil { 828 receipts = make([]*types.Receipt, 0) 829 } 830 831 number := header.Number.Uint64() 832 if header.Number.Cmp(common.Big1) == 0 || p.chainConfig.IsPrimordialPulseBlock(number) { 833 log.Info("Initializing system contracts", "number", header.Number) 834 if err := p.initContracts(state, header, cx, &txs, &receipts, nil, &header.GasUsed, true); err != nil { 835 log.Error("Failed to initialize system contracts") 836 } 837 838 if p.chainConfig.IsPrimordialPulseBlock(number) { 839 // handle initial allocations for the primordialPulse fork 840 if err := p.primordialPulseAlloctions(state); err != nil { 841 panic(err) 842 } 843 } 844 } 845 846 // trigger the validator rotation on the last block of the era 847 // on the next block (epoch), the authorization snapshot will be updated 848 if (number+1)%(p.config.Epoch*p.config.Era) == 0 { 849 log.Info("Triggering staked validator rotation", "number", number) 850 err := p.rotateValidators(state, header, cx, &txs, &receipts, nil, &header.GasUsed, true) 851 if err != nil { 852 log.Error("Staked validator rotation failed", "number", number) 853 } 854 } 855 856 if header.Difficulty.Cmp(diffInTurn) != 0 { 857 snap, err := p.snapshot(chain, number-1, header.ParentHash, nil) 858 if err != nil { 859 panic(err) 860 } 861 spoiledVal := snap.supposeValidator() 862 signedRecently := false 863 for _, recent := range snap.Recents { 864 if recent == spoiledVal { 865 signedRecently = true 866 break 867 } 868 } 869 if !signedRecently { 870 err = p.slash(spoiledVal, state, header, cx, &txs, &receipts, nil, &header.GasUsed, true) 871 if err != nil { 872 // it is possible that slash validator failed because of the slash channel is disabled. 873 log.Error("slash validator failed", "block hash", header.Hash(), "address", spoiledVal) 874 } 875 } 876 } 877 878 err := p.distributeIncoming(p.val, state, header, cx, &txs, &receipts, nil, &header.GasUsed, true) 879 if err != nil { 880 panic(err) 881 } 882 // should not happen. Once happen, stop the node is better than broadcast the block 883 if header.GasLimit < header.GasUsed { 884 panic("Gas consumption of system txs exceed the gas limit") 885 } 886 header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) 887 header.UncleHash = types.CalcUncleHash(nil) 888 889 // Assemble and return the final block for sealing 890 return types.NewBlock(header, txs, nil, receipts), receipts, nil 891 } 892 893 // Authorize injects a private key into the consensus engine to mint new blocks 894 // with. 895 func (p *Parlia) Authorize(val common.Address, signFn SignerFn, signTxFn SignerTxFn) { 896 p.lock.Lock() 897 defer p.lock.Unlock() 898 899 p.val = val 900 p.signFn = signFn 901 p.signTxFn = signTxFn 902 } 903 904 // Seal implements consensus.Engine, attempting to create a sealed block using 905 // the local signing credentials. 906 func (p *Parlia) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { 907 header := block.Header() 908 909 // Sealing the genesis block is not supported 910 number := header.Number.Uint64() 911 if number == 0 { 912 return errUnknownBlock 913 } 914 // For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing) 915 if p.config.Period == 0 && len(block.Transactions()) == 0 { 916 log.Info("Sealing paused, waiting for transactions") 917 return nil 918 } 919 // Don't hold the val fields for the entire sealing procedure 920 p.lock.RLock() 921 val, signFn := p.val, p.signFn 922 p.lock.RUnlock() 923 924 snap, err := p.snapshot(chain, number-1, header.ParentHash, nil) 925 if err != nil { 926 return err 927 } 928 929 // Bail out if we're unauthorized to sign a block 930 if _, authorized := snap.Validators[val]; !authorized { 931 return errUnauthorizedValidator 932 } 933 934 // If we're amongst the recent signers, wait for the next block 935 for seen, recent := range snap.Recents { 936 if recent == val { 937 // Signer is among recents, only wait if the current block doesn't shift it out 938 if limit := uint64(len(snap.Validators)/2 + 1); number < limit || seen > number-limit { 939 log.Info("Signed recently, must wait for others") 940 return nil 941 } 942 } 943 } 944 945 // Sweet, the protocol permits us to sign the block, wait for our time 946 delay := p.delayForRamanujanFork(snap, header) 947 948 log.Info("Sealing block with", "number", number, "delay", delay, "headerDifficulty", header.Difficulty, "val", val.Hex()) 949 950 // Sign all the things! 951 sig, err := signFn(accounts.Account{Address: val}, accounts.MimetypeParlia, ParliaRLP(header, p.chainConfig.ChainID)) 952 if err != nil { 953 return err 954 } 955 copy(header.Extra[len(header.Extra)-extraSeal:], sig) 956 957 // Wait until sealing is terminated or delay timeout. 958 log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay)) 959 go func() { 960 select { 961 case <-stop: 962 return 963 case <-time.After(delay): 964 } 965 966 select { 967 case results <- block.WithSeal(header): 968 default: 969 log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header, p.chainConfig.ChainID)) 970 } 971 }() 972 973 return nil 974 } 975 976 // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty 977 // that a new block should have based on the previous blocks in the chain and the 978 // current signer. 979 func (p *Parlia) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int { 980 if p.chainConfig.PrimordialPulseAhead(new(big.Int).Add(parent.Number, common.Big1)) { 981 return p.ethash().CalcDifficulty(chain, time, parent) 982 } 983 snap, err := p.snapshot(chain, parent.Number.Uint64(), parent.Hash(), nil) 984 if err != nil { 985 return nil 986 } 987 return calcDifficulty(snap, p.val) 988 } 989 990 // calcDifficulty is the difficulty adjustment algorithm. It returns the difficulty 991 // that a new block should have based on the previous blocks in the chain and the 992 // current signer. 993 func calcDifficulty(snap *Snapshot, signer common.Address) *big.Int { 994 if snap.inturn(signer) { 995 return new(big.Int).Set(diffInTurn) 996 } 997 return new(big.Int).Set(diffNoTurn) 998 } 999 1000 // SealHash returns the hash of a block prior to it being sealed. 1001 func (p *Parlia) SealHash(header *types.Header) common.Hash { 1002 return SealHash(header, p.chainConfig.ChainID) 1003 } 1004 1005 // APIs implements consensus.Engine, returning the user facing RPC API to query snapshot. 1006 func (p *Parlia) APIs(chain consensus.ChainReader) []rpc.API { 1007 return []rpc.API{{ 1008 Namespace: "parlia", 1009 Version: "1.0", 1010 Service: &API{chain: chain, parlia: p}, 1011 Public: false, 1012 }} 1013 } 1014 1015 // Close implements consensus.Engine. It's a noop for parlia as there are no background threads. 1016 func (p *Parlia) Close() error { 1017 return nil 1018 } 1019 1020 // ========================== interaction with contract/account ========= 1021 1022 // getCurrentValidators get current validators 1023 func (p *Parlia) getCurrentValidators(blockHash common.Hash) ([]common.Address, error) { 1024 // block 1025 blockNr := rpc.BlockNumberOrHashWithHash(blockHash, false) 1026 1027 // method 1028 method := "getValidators" 1029 1030 ctx, cancel := context.WithCancel(context.Background()) 1031 defer cancel() // cancel when we are finished consuming integers 1032 1033 data, err := p.validatorSetABI.Pack(method) 1034 if err != nil { 1035 log.Error("Unable to pack tx for getValidators", "error", err) 1036 return nil, err 1037 } 1038 // call 1039 msgData := (hexutil.Bytes)(data) 1040 toAddress := common.HexToAddress(systemcontracts.ValidatorContract) 1041 gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) 1042 result, err := p.ethAPI.Call(ctx, ethapi.CallArgs{ 1043 Gas: &gas, 1044 To: &toAddress, 1045 Data: &msgData, 1046 }, blockNr, nil) 1047 if err != nil { 1048 return nil, err 1049 } 1050 1051 var ( 1052 ret0 = new([]common.Address) 1053 ) 1054 out := ret0 1055 1056 if err := p.validatorSetABI.Unpack(out, method, result); err != nil { 1057 return nil, err 1058 } 1059 1060 valz := make([]common.Address, len(*ret0)) 1061 for i, a := range *ret0 { 1062 valz[i] = a 1063 } 1064 return valz, nil 1065 } 1066 1067 // distribute incoming accrued fees 1068 func (p *Parlia) distributeIncoming(val common.Address, state *state.StateDB, header *types.Header, chain core.ChainContext, 1069 txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error { 1070 coinbase := header.Coinbase 1071 balance := state.GetBalance(consensus.SystemAddress) 1072 if balance.Cmp(common.Big0) <= 0 { 1073 return nil 1074 } 1075 state.SetBalance(consensus.SystemAddress, big.NewInt(0)) 1076 1077 burn := big.NewInt(0) 1078 if p.config.BurnRate > 0 { 1079 burn = burn.Div(balance, big.NewInt(int64(p.config.BurnRate))) 1080 state.AddBalance(common.HexToAddress(systemcontracts.FeeBurnContract), burn) 1081 log.Debug("🔥 transaction fee burn", "number", header.Number, "amount", burn) 1082 } 1083 1084 reward := new(big.Int).Sub(balance, burn) 1085 state.AddBalance(coinbase, reward) 1086 log.Trace("distribute to validator contract", "block hash", header.Hash(), "amount", reward) 1087 return p.distributeToValidator(reward, val, state, header, chain, txs, receipts, receivedTxs, usedGas, mining) 1088 } 1089 1090 // rotateValidators triggers the staked validator rotation 1091 func (p *Parlia) rotateValidators(state *state.StateDB, header *types.Header, chain core.ChainContext, 1092 txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error { 1093 // method 1094 method := "rotateValidators" 1095 1096 // get packed data 1097 data, err := p.stakingABI.Pack(method) 1098 if err != nil { 1099 log.Error("Unable to pack tx for staking contract", "error", err) 1100 return err 1101 } 1102 // get system message 1103 msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.StakingContract), data, common.Big0) 1104 // apply message 1105 return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining) 1106 } 1107 1108 // slash spoiled validators 1109 func (p *Parlia) slash(spoiledVal common.Address, state *state.StateDB, header *types.Header, chain core.ChainContext, 1110 txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error { 1111 // method 1112 method := "slash" 1113 1114 // get packed data 1115 data, err := p.slashABI.Pack(method, 1116 spoiledVal, 1117 ) 1118 if err != nil { 1119 log.Error("Unable to pack tx for slash contract", "error", err) 1120 return err 1121 } 1122 // get system message 1123 msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.SlashingContract), data, common.Big0) 1124 // apply message 1125 return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining) 1126 } 1127 1128 // init contracts 1129 func (p *Parlia) initContracts(state *state.StateDB, header *types.Header, chain core.ChainContext, 1130 txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error { 1131 // method 1132 method := "init" 1133 // contracts 1134 contracts := []string{ 1135 // slash contract does not require initialization 1136 systemcontracts.ValidatorContract, 1137 systemcontracts.StakingContract, 1138 } 1139 // get packed data 1140 data, err := p.validatorSetABI.Pack(method) 1141 if err != nil { 1142 log.Error("Unable to pack tx for init validator set", "error", err) 1143 return err 1144 } 1145 for _, c := range contracts { 1146 msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(c), data, common.Big0) 1147 // apply message 1148 log.Trace("init contract", "block hash", header.Hash(), "contract", c) 1149 err = p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining) 1150 if err != nil { 1151 return err 1152 } 1153 } 1154 return nil 1155 } 1156 1157 // award funds to the validator 1158 func (p *Parlia) distributeToValidator(amount *big.Int, validator common.Address, 1159 state *state.StateDB, header *types.Header, chain core.ChainContext, 1160 txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error { 1161 // method 1162 method := "deposit" 1163 1164 // get packed data 1165 data, err := p.validatorSetABI.Pack(method, 1166 validator, 1167 ) 1168 if err != nil { 1169 log.Error("Unable to pack tx for deposit", "error", err) 1170 return err 1171 } 1172 // get system message 1173 msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.ValidatorContract), data, amount) 1174 // apply message 1175 return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining) 1176 } 1177 1178 // get system message 1179 func (p *Parlia) getSystemMessage(from, toAddress common.Address, data []byte, value *big.Int) callmsg { 1180 return callmsg{ 1181 ethereum.CallMsg{ 1182 From: from, 1183 Gas: math.MaxUint64 / 2, 1184 GasPrice: big.NewInt(0), 1185 Value: value, 1186 To: &toAddress, 1187 Data: data, 1188 }, 1189 } 1190 } 1191 1192 func (p *Parlia) applyTransaction( 1193 msg callmsg, 1194 state *state.StateDB, 1195 header *types.Header, 1196 chainContext core.ChainContext, 1197 txs *[]*types.Transaction, receipts *[]*types.Receipt, 1198 receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool, 1199 ) (err error) { 1200 nonce := state.GetNonce(msg.From()) 1201 expectedTx := types.NewTransaction(nonce, *msg.To(), msg.Value(), msg.Gas(), msg.GasPrice(), msg.Data()) 1202 expectedHash := p.signer.Hash(expectedTx) 1203 1204 if msg.From() == p.val && mining { 1205 expectedTx, err = p.signTxFn(accounts.Account{Address: msg.From()}, expectedTx, p.chainConfig.ChainID) 1206 if err != nil { 1207 return err 1208 } 1209 } else { 1210 if receivedTxs == nil || len(*receivedTxs) == 0 || (*receivedTxs)[0] == nil { 1211 return errors.New("supposed to get a actual transaction, but get none") 1212 } 1213 actualTx := (*receivedTxs)[0] 1214 if !bytes.Equal(p.signer.Hash(actualTx).Bytes(), expectedHash.Bytes()) { 1215 return fmt.Errorf("expected tx hash %v, get %v", expectedHash.String(), actualTx.Hash().String()) 1216 } 1217 expectedTx = actualTx 1218 // move to next 1219 *receivedTxs = (*receivedTxs)[1:] 1220 } 1221 state.Prepare(expectedTx.Hash(), common.Hash{}, len(*txs)) 1222 gasUsed, err := applyMessage(msg, state, header, p.chainConfig, chainContext) 1223 if err != nil { 1224 return err 1225 } 1226 *txs = append(*txs, expectedTx) 1227 var root []byte 1228 if p.chainConfig.IsByzantium(header.Number) { 1229 state.Finalise(true) 1230 } else { 1231 root = state.IntermediateRoot(p.chainConfig.IsEIP158(header.Number)).Bytes() 1232 } 1233 *usedGas += gasUsed 1234 receipt := types.NewReceipt(root, false, *usedGas) 1235 receipt.TxHash = expectedTx.Hash() 1236 receipt.GasUsed = gasUsed 1237 1238 // Set the receipt logs and create a bloom for filtering 1239 receipt.Logs = state.GetLogs(expectedTx.Hash()) 1240 receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) 1241 receipt.BlockHash = state.BlockHash() 1242 receipt.BlockNumber = header.Number 1243 receipt.TransactionIndex = uint(state.TxIndex()) 1244 *receipts = append(*receipts, receipt) 1245 state.SetNonce(msg.From(), nonce+1) 1246 return nil 1247 } 1248 1249 // =========================== utility function ========================== 1250 // SealHash returns the hash of a block prior to it being sealed. 1251 func SealHash(header *types.Header, chainId *big.Int) (hash common.Hash) { 1252 hasher := sha3.NewLegacyKeccak256() 1253 encodeSigHeader(hasher, header, chainId) 1254 hasher.Sum(hash[:0]) 1255 return hash 1256 } 1257 1258 func encodeSigHeader(w io.Writer, header *types.Header, chainId *big.Int) { 1259 err := rlp.Encode(w, []interface{}{ 1260 chainId, 1261 header.ParentHash, 1262 header.UncleHash, 1263 header.Coinbase, 1264 header.Root, 1265 header.TxHash, 1266 header.ReceiptHash, 1267 header.Bloom, 1268 header.Difficulty, 1269 header.Number, 1270 header.GasLimit, 1271 header.GasUsed, 1272 header.Time, 1273 header.Extra[:len(header.Extra)-65], // this will panic if extra is too short, should check before calling encodeSigHeader 1274 header.MixDigest, 1275 header.Nonce, 1276 }) 1277 if err != nil { 1278 panic("can't encode: " + err.Error()) 1279 } 1280 } 1281 1282 func backOffTime(snap *Snapshot, val common.Address) uint64 { 1283 if snap.inturn(val) { 1284 return 0 1285 } else { 1286 idx := snap.indexOfVal(val) 1287 if idx < 0 { 1288 // The backOffTime does not matter when a validator is not authorized. 1289 return 0 1290 } 1291 s := rand.NewSource(int64(snap.Number)) 1292 r := rand.New(s) 1293 n := len(snap.Validators) 1294 backOffSteps := make([]uint64, 0, n) 1295 for idx := uint64(0); idx < uint64(n); idx++ { 1296 backOffSteps = append(backOffSteps, idx) 1297 } 1298 r.Shuffle(n, func(i, j int) { 1299 backOffSteps[i], backOffSteps[j] = backOffSteps[j], backOffSteps[i] 1300 }) 1301 delay := initialBackOffTime + backOffSteps[idx]*wiggleTime 1302 return delay 1303 } 1304 } 1305 1306 // chain context 1307 type chainContext struct { 1308 Chain consensus.ChainReader 1309 parlia consensus.Engine 1310 } 1311 1312 func (c chainContext) Engine() consensus.Engine { 1313 return c.parlia 1314 } 1315 1316 func (c chainContext) GetHeader(hash common.Hash, number uint64) *types.Header { 1317 return c.Chain.GetHeader(hash, number) 1318 } 1319 1320 // callmsg implements core.Message to allow passing it as a transaction simulator. 1321 type callmsg struct { 1322 ethereum.CallMsg 1323 } 1324 1325 func (m callmsg) From() common.Address { return m.CallMsg.From } 1326 func (m callmsg) Nonce() uint64 { return 0 } 1327 func (m callmsg) CheckNonce() bool { return false } 1328 func (m callmsg) To() *common.Address { return m.CallMsg.To } 1329 func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice } 1330 func (m callmsg) Gas() uint64 { return m.CallMsg.Gas } 1331 func (m callmsg) Value() *big.Int { return m.CallMsg.Value } 1332 func (m callmsg) Data() []byte { return m.CallMsg.Data } 1333 1334 // apply message 1335 func applyMessage( 1336 msg callmsg, 1337 state *state.StateDB, 1338 header *types.Header, 1339 chainConfig *params.ChainConfig, 1340 chainContext core.ChainContext, 1341 ) (uint64, error) { 1342 // Create a new context to be used in the EVM environment 1343 context := core.NewEVMContext(msg, header, chainContext, nil) 1344 // Create a new environment which holds all relevant information 1345 // about the transaction and calling mechanisms. 1346 vmenv := vm.NewEVM(context, state, chainConfig, vm.Config{}) 1347 // Apply the transaction to the current state (included in the env) 1348 ret, returnGas, err := vmenv.Call( 1349 vm.AccountRef(msg.From()), 1350 *msg.To(), 1351 msg.Data(), 1352 msg.Gas(), 1353 msg.Value(), 1354 ) 1355 if err != nil { 1356 log.Error("apply message failed", "msg", string(ret), "err", err) 1357 } 1358 return msg.Gas() - returnGas, err 1359 }