github.com/aswedchain/aswed@v1.0.1/consensus/congress/congress.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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 go-ethereum 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package congress implements the proof-of-stake-authority consensus engine. 18 package congress 19 20 import ( 21 "bytes" 22 "encoding/binary" 23 "errors" 24 "github.com/aswedchain/aswed/metrics" 25 "io" 26 "math" 27 "math/big" 28 "math/rand" 29 "sort" 30 "sync" 31 "time" 32 33 "github.com/aswedchain/aswed/accounts" 34 "github.com/aswedchain/aswed/accounts/abi" 35 "github.com/aswedchain/aswed/common" 36 "github.com/aswedchain/aswed/consensus" 37 "github.com/aswedchain/aswed/consensus/congress/systemcontract" 38 "github.com/aswedchain/aswed/consensus/congress/vmcaller" 39 "github.com/aswedchain/aswed/consensus/misc" 40 "github.com/aswedchain/aswed/core/state" 41 "github.com/aswedchain/aswed/core/types" 42 "github.com/aswedchain/aswed/crypto" 43 "github.com/aswedchain/aswed/ethdb" 44 "github.com/aswedchain/aswed/log" 45 "github.com/aswedchain/aswed/params" 46 "github.com/aswedchain/aswed/rlp" 47 "github.com/aswedchain/aswed/rpc" 48 "github.com/aswedchain/aswed/trie" 49 lru "github.com/hashicorp/golang-lru" 50 "golang.org/x/crypto/sha3" 51 ) 52 53 const ( 54 checkpointInterval = 1024 // Number of blocks after which to save the vote snapshot to the database 55 inmemorySnapshots = 128 // Number of recent vote snapshots to keep in memory 56 inmemorySignatures = 4096 // Number of recent block signatures to keep in memory 57 58 wiggleTime = 500 * time.Millisecond // Random delay (per validator) to allow concurrent validators 59 maxValidators = 21 // Max validators allowed to seal. 60 61 inmemoryBlacklist = 21 // Number of recent blacklist snapshots to keep in memory 62 ) 63 64 type blacklistDirection uint 65 66 const ( 67 DirectionFrom blacklistDirection = iota 68 DirectionTo 69 DirectionBoth 70 ) 71 72 // Congress proof-of-stake-authority protocol constants. 73 var ( 74 epochLength = uint64(30000) // Default number of blocks after which to checkpoint and reset the pending votes 75 76 extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for validator vanity 77 extraSeal = crypto.SignatureLength // Fixed number of extra-data suffix bytes reserved for validator seal 78 79 uncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW. 80 81 diffInTurn = big.NewInt(2) // Block difficulty for in-turn signatures 82 diffNoTurn = big.NewInt(1) // Block difficulty for out-of-turn signatures 83 ) 84 85 // Various error messages to mark blocks invalid. These should be private to 86 // prevent engine specific errors from being referenced in the remainder of the 87 // codebase, inherently breaking if the engine is swapped out. Please put common 88 // error types into the consensus package. 89 var ( 90 // errUnknownBlock is returned when the list of validators is requested for a block 91 // that is not part of the local blockchain. 92 errUnknownBlock = errors.New("unknown block") 93 94 // errMissingVanity is returned if a block's extra-data section is shorter than 95 // 32 bytes, which is required to store the validator vanity. 96 errMissingVanity = errors.New("extra-data 32 byte vanity prefix missing") 97 98 // errMissingSignature is returned if a block's extra-data section doesn't seem 99 // to contain a 65 byte secp256k1 signature. 100 errMissingSignature = errors.New("extra-data 65 byte signature suffix missing") 101 102 // errExtraValidators is returned if non-checkpoint block contain validator data in 103 // their extra-data fields. 104 errExtraValidators = errors.New("non-checkpoint block contains extra validator list") 105 106 // errInvalidExtraValidators is returned if validator data in extra-data field is invalid. 107 errInvalidExtraValidators = errors.New("Invalid extra validators in extra data field") 108 109 // errInvalidCheckpointValidators is returned if a checkpoint block contains an 110 // invalid list of validators (i.e. non divisible by 20 bytes). 111 errInvalidCheckpointValidators = errors.New("invalid validator list on checkpoint block") 112 113 // errMismatchingCheckpointValidators is returned if a checkpoint block contains a 114 // list of validators different than the one the local node calculated. 115 errMismatchingCheckpointValidators = errors.New("mismatching validator list on checkpoint block") 116 117 // errInvalidMixDigest is returned if a block's mix digest is non-zero. 118 errInvalidMixDigest = errors.New("non-zero mix digest") 119 120 // errInvalidUncleHash is returned if a block contains an non-empty uncle list. 121 errInvalidUncleHash = errors.New("non empty uncle hash") 122 123 // errInvalidDifficulty is returned if the difficulty of a block neither 1 or 2. 124 errInvalidDifficulty = errors.New("invalid difficulty") 125 126 // errWrongDifficulty is returned if the difficulty of a block doesn't match the 127 // turn of the validator. 128 errWrongDifficulty = errors.New("wrong difficulty") 129 130 // errInvalidTimestamp is returned if the timestamp of a block is lower than 131 // the previous block's timestamp + the minimum block period. 132 errInvalidTimestamp = errors.New("invalid timestamp") 133 134 // ErrInvalidTimestamp is returned if the timestamp of a block is lower than 135 // the previous block's timestamp + the minimum block period. 136 ErrInvalidTimestamp = errors.New("invalid timestamp") 137 138 // errInvalidVotingChain is returned if an authorization list is attempted to 139 // be modified via out-of-range or non-contiguous headers. 140 errInvalidVotingChain = errors.New("invalid voting chain") 141 142 // errUnauthorizedValidator is returned if a header is signed by a non-authorized entity. 143 errUnauthorizedValidator = errors.New("unauthorized validator") 144 145 // errRecentlySigned is returned if a header is signed by an authorized entity 146 // that already signed a header recently, thus is temporarily not allowed to. 147 errRecentlySigned = errors.New("recently signed") 148 149 // errInvalidValidatorLen is returned if validators length is zero or bigger than maxValidators. 150 errInvalidValidatorsLength = errors.New("Invalid validators length") 151 152 // errInvalidCoinbase is returned if the coinbase isn't the validator of the block. 153 errInvalidCoinbase = errors.New("Invalid coin base") 154 155 errInvalidSysGovCount = errors.New("invalid system governance tx count") 156 ) 157 158 var ( 159 getblacklistTimer = metrics.NewRegisteredTimer("congress/blacklist/get", nil) 160 ) 161 162 // StateFn gets state by the state root hash. 163 type StateFn func(hash common.Hash) (*state.StateDB, error) 164 165 // ValidatorFn hashes and signs the data to be signed by a backing account. 166 type ValidatorFn func(validator accounts.Account, mimeType string, message []byte) ([]byte, error) 167 type SignTxFn func(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) 168 169 // ecrecover extracts the Ethereum account address from a signed header. 170 func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) { 171 // If the signature's already cached, return that 172 hash := header.Hash() 173 if address, known := sigcache.Get(hash); known { 174 return address.(common.Address), nil 175 } 176 // Retrieve the signature from the header extra-data 177 if len(header.Extra) < extraSeal { 178 return common.Address{}, errMissingSignature 179 } 180 signature := header.Extra[len(header.Extra)-extraSeal:] 181 182 // Recover the public key and the Ethereum address 183 pubkey, err := crypto.Ecrecover(SealHash(header).Bytes(), signature) 184 if err != nil { 185 return common.Address{}, err 186 } 187 var validator common.Address 188 copy(validator[:], crypto.Keccak256(pubkey[1:])[12:]) 189 190 sigcache.Add(hash, validator) 191 return validator, nil 192 } 193 194 // Congress is the proof-of-stake-authority consensus engine proposed to support the 195 // Ethereum testnet following the Ropsten attacks. 196 type Congress struct { 197 chainConfig *params.ChainConfig // ChainConfig to execute evm 198 config *params.CongressConfig // Consensus engine configuration parameters 199 db ethdb.Database // Database to store and retrieve snapshot checkpoints 200 201 recents *lru.ARCCache // Snapshots for recent block to speed up reorgs 202 signatures *lru.ARCCache // Signatures of recent blocks to speed up mining 203 204 blacklists *lru.ARCCache // Blacklist snapshots for recent blocks to speed up transactions validation 205 blLock sync.Mutex // Make sure only get blacklist once for each block 206 207 proposals map[common.Address]bool // Current list of proposals we are pushing 208 209 signer types.Signer // the signer instance to recover tx sender 210 211 validator common.Address // Ethereum address of the signing key 212 signFn ValidatorFn // Validator function to authorize hashes with 213 signTxFn SignTxFn 214 lock sync.RWMutex // Protects the validator fields 215 216 stateFn StateFn // Function to get state by state root 217 218 abi map[string]abi.ABI // Interactive with system contracts 219 220 // The fields below are for testing only 221 fakeDiff bool // Skip difficulty verifications 222 } 223 224 // New creates a Congress proof-of-stake-authority consensus engine with the initial 225 // validators set to the ones provided by the user. 226 func New(chainConfig *params.ChainConfig, db ethdb.Database) *Congress { 227 // Set any missing consensus parameters to their defaults 228 conf := *chainConfig.Congress 229 if conf.Epoch == 0 { 230 conf.Epoch = epochLength 231 } 232 // Allocate the snapshot caches and create the engine 233 recents, _ := lru.NewARC(inmemorySnapshots) 234 signatures, _ := lru.NewARC(inmemorySignatures) 235 blacklists, _ := lru.NewARC(inmemoryBlacklist) 236 237 abi := systemcontract.GetInteractiveABI() 238 239 return &Congress{ 240 chainConfig: chainConfig, 241 config: &conf, 242 db: db, 243 recents: recents, 244 signatures: signatures, 245 blacklists: blacklists, 246 proposals: make(map[common.Address]bool), 247 abi: abi, 248 signer: types.NewEIP155Signer(chainConfig.ChainID), 249 } 250 } 251 252 // SetStateFn sets the function to get state. 253 func (c *Congress) SetStateFn(fn StateFn) { 254 c.stateFn = fn 255 } 256 257 // Author implements consensus.Engine, returning the Ethereum address recovered 258 // from the signature in the header's extra-data section. 259 func (c *Congress) Author(header *types.Header) (common.Address, error) { 260 return header.Coinbase, nil 261 // return ecrecover(header, c.signatures) 262 } 263 264 // VerifyHeader checks whether a header conforms to the consensus rules. 265 func (c *Congress) VerifyHeader(chain consensus.ChainHeaderReader, header *types.Header, seal bool) error { 266 return c.verifyHeader(chain, header, nil) 267 } 268 269 // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The 270 // method returns a quit channel to abort the operations and a results channel to 271 // retrieve the async verifications (the order is that of the input slice). 272 func (c *Congress) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { 273 abort := make(chan struct{}) 274 results := make(chan error, len(headers)) 275 276 go func() { 277 for i, header := range headers { 278 err := c.verifyHeader(chain, header, headers[:i]) 279 280 select { 281 case <-abort: 282 return 283 case results <- err: 284 } 285 } 286 }() 287 return abort, results 288 } 289 290 // verifyHeader checks whether a header conforms to the consensus rules.The 291 // caller may optionally pass in a batch of parents (ascending order) to avoid 292 // looking those up from the database. This is useful for concurrently verifying 293 // a batch of new headers. 294 func (c *Congress) verifyHeader(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error { 295 if header.Number == nil { 296 return errUnknownBlock 297 } 298 number := header.Number.Uint64() 299 300 // Don't waste time checking blocks from the future 301 if header.Time > uint64(time.Now().Unix()) { 302 return consensus.ErrFutureBlock 303 } 304 // Check that the extra-data contains the vanity, validators and signature. 305 if len(header.Extra) < extraVanity { 306 return errMissingVanity 307 } 308 if len(header.Extra) < extraVanity+extraSeal { 309 return errMissingSignature 310 } 311 // check extra data 312 isEpoch := number%c.config.Epoch == 0 313 314 // Ensure that the extra-data contains a validator list on checkpoint, but none otherwise 315 validatorsBytes := len(header.Extra) - extraVanity - extraSeal 316 if !isEpoch && validatorsBytes != 0 { 317 return errExtraValidators 318 } 319 // Ensure that the validator bytes length is valid 320 if isEpoch && validatorsBytes%common.AddressLength != 0 { 321 return errExtraValidators 322 } 323 324 // Ensure that the mix digest is zero as we don't have fork protection currently 325 if header.MixDigest != (common.Hash{}) { 326 return errInvalidMixDigest 327 } 328 // Ensure that the block doesn't contain any uncles which are meaningless in PoA 329 if header.UncleHash != uncleHash { 330 return errInvalidUncleHash 331 } 332 // Ensure that the block's difficulty is meaningful (may not be correct at this point) 333 if number > 0 && header.Difficulty == nil { 334 return errInvalidDifficulty 335 } 336 // If all checks passed, validate any special fields for hard forks 337 if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil { 338 return err 339 } 340 // All basic checks passed, verify cascading fields 341 return c.verifyCascadingFields(chain, header, parents) 342 } 343 344 // verifyCascadingFields verifies all the header fields that are not standalone, 345 // rather depend on a batch of previous headers. The caller may optionally pass 346 // in a batch of parents (ascending order) to avoid looking those up from the 347 // database. This is useful for concurrently verifying a batch of new headers. 348 func (c *Congress) verifyCascadingFields(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error { 349 // The genesis block is the always valid dead-end 350 number := header.Number.Uint64() 351 if number == 0 { 352 return nil 353 } 354 355 var parent *types.Header 356 if len(parents) > 0 { 357 parent = parents[len(parents)-1] 358 } else { 359 parent = chain.GetHeader(header.ParentHash, number-1) 360 } 361 if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash { 362 return consensus.ErrUnknownAncestor 363 } 364 365 if parent.Time+c.config.Period > header.Time { 366 return ErrInvalidTimestamp 367 } 368 369 // All basic checks passed, verify the seal and return 370 return c.verifySeal(chain, header, parents) 371 } 372 373 // snapshot retrieves the authorization snapshot at a given point in time. 374 func (c *Congress) snapshot(chain consensus.ChainHeaderReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) { 375 // Search for a snapshot in memory or on disk for checkpoints 376 var ( 377 headers []*types.Header 378 snap *Snapshot 379 ) 380 for snap == nil { 381 // If an in-memory snapshot was found, use that 382 if s, ok := c.recents.Get(hash); ok { 383 snap = s.(*Snapshot) 384 break 385 } 386 // If an on-disk checkpoint snapshot can be found, use that 387 if number%checkpointInterval == 0 { 388 if s, err := loadSnapshot(c.config, c.signatures, c.db, hash); err == nil { 389 log.Trace("Loaded voting snapshot from disk", "number", number, "hash", hash) 390 snap = s 391 break 392 } 393 } 394 // If we're at the genesis, snapshot the initial state. Alternatively if we're 395 // at a checkpoint block without a parent (light client CHT), or we have piled 396 // up more headers than allowed to be reorged (chain reinit from a freezer), 397 // consider the checkpoint trusted and snapshot it. 398 if number == 0 || (number%c.config.Epoch == 0 && (len(headers) > params.FullImmutabilityThreshold || chain.GetHeaderByNumber(number-1) == nil)) { 399 checkpoint := chain.GetHeaderByNumber(number) 400 if checkpoint != nil { 401 hash := checkpoint.Hash() 402 403 validators := make([]common.Address, (len(checkpoint.Extra)-extraVanity-extraSeal)/common.AddressLength) 404 for i := 0; i < len(validators); i++ { 405 copy(validators[i][:], checkpoint.Extra[extraVanity+i*common.AddressLength:]) 406 } 407 snap = newSnapshot(c.config, c.signatures, number, hash, validators) 408 if err := snap.store(c.db); err != nil { 409 return nil, err 410 } 411 log.Info("Stored checkpoint snapshot to disk", "number", number, "hash", hash) 412 break 413 } 414 } 415 // No snapshot for this header, gather the header and move backward 416 var header *types.Header 417 if len(parents) > 0 { 418 // If we have explicit parents, pick from there (enforced) 419 header = parents[len(parents)-1] 420 if header.Hash() != hash || header.Number.Uint64() != number { 421 return nil, consensus.ErrUnknownAncestor 422 } 423 parents = parents[:len(parents)-1] 424 } else { 425 // No explicit parents (or no more left), reach out to the database 426 header = chain.GetHeader(hash, number) 427 if header == nil { 428 return nil, consensus.ErrUnknownAncestor 429 } 430 } 431 headers = append(headers, header) 432 number, hash = number-1, header.ParentHash 433 } 434 // Previous snapshot found, apply any pending headers on top of it 435 for i := 0; i < len(headers)/2; i++ { 436 headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i] 437 } 438 snap, err := snap.apply(headers, chain, parents) 439 if err != nil { 440 return nil, err 441 } 442 c.recents.Add(snap.Hash, snap) 443 444 // If we've generated a new checkpoint snapshot, save to disk 445 if snap.Number%checkpointInterval == 0 && len(headers) > 0 { 446 if err = snap.store(c.db); err != nil { 447 return nil, err 448 } 449 log.Trace("Stored voting snapshot to disk", "number", snap.Number, "hash", snap.Hash) 450 } 451 return snap, err 452 } 453 454 // VerifyUncles implements consensus.Engine, always returning an error for any 455 // uncles as this consensus mechanism doesn't permit uncles. 456 func (c *Congress) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { 457 if len(block.Uncles()) > 0 { 458 return errors.New("uncles not allowed") 459 } 460 return nil 461 } 462 463 // VerifySeal implements consensus.Engine, checking whether the signature contained 464 // in the header satisfies the consensus protocol requirements. 465 func (c *Congress) VerifySeal(chain consensus.ChainHeaderReader, header *types.Header) error { 466 return c.verifySeal(chain, header, nil) 467 } 468 469 // verifySeal checks whether the signature contained in the header satisfies the 470 // consensus protocol requirements. The method accepts an optional list of parent 471 // headers that aren't yet part of the local blockchain to generate the snapshots 472 // from. 473 func (c *Congress) verifySeal(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error { 474 // Verifying the genesis block is not supported 475 number := header.Number.Uint64() 476 if number == 0 { 477 return errUnknownBlock 478 } 479 // Retrieve the snapshot needed to verify this header and cache it 480 snap, err := c.snapshot(chain, number-1, header.ParentHash, parents) 481 if err != nil { 482 return err 483 } 484 485 // Resolve the authorization key and check against validators 486 signer, err := ecrecover(header, c.signatures) 487 if err != nil { 488 return err 489 } 490 if signer != header.Coinbase { 491 return errInvalidCoinbase 492 } 493 494 if _, ok := snap.Validators[signer]; !ok { 495 return errUnauthorizedValidator 496 } 497 498 for seen, recent := range snap.Recents { 499 if recent == signer { 500 // Validator is among recents, only fail if the current block doesn't shift it out 501 if limit := uint64(len(snap.Validators)/2 + 1); seen > number-limit { 502 return errRecentlySigned 503 } 504 } 505 } 506 507 // Ensure that the difficulty corresponds to the turn-ness of the signer 508 if !c.fakeDiff { 509 inturn := snap.inturn(header.Number.Uint64(), signer) 510 if inturn && header.Difficulty.Cmp(diffInTurn) != 0 { 511 return errWrongDifficulty 512 } 513 if !inturn && header.Difficulty.Cmp(diffNoTurn) != 0 { 514 return errWrongDifficulty 515 } 516 } 517 518 return nil 519 } 520 521 // Prepare implements consensus.Engine, preparing all the consensus fields of the 522 // header for running the transactions on top. 523 func (c *Congress) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error { 524 // If the block isn't a checkpoint, cast a random vote (good enough for now) 525 header.Coinbase = c.validator 526 header.Nonce = types.BlockNonce{} 527 528 number := header.Number.Uint64() 529 snap, err := c.snapshot(chain, number-1, header.ParentHash, nil) 530 if err != nil { 531 return err 532 } 533 534 // Set the correct difficulty 535 header.Difficulty = calcDifficulty(snap, c.validator) 536 537 // Ensure the extra data has all its components 538 if len(header.Extra) < extraVanity { 539 header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...) 540 } 541 header.Extra = header.Extra[:extraVanity] 542 543 if number%c.config.Epoch == 0 { 544 newSortedValidators, err := c.getTopValidators(chain, header) 545 if err != nil { 546 return err 547 } 548 549 for _, validator := range newSortedValidators { 550 header.Extra = append(header.Extra, validator.Bytes()...) 551 } 552 } 553 header.Extra = append(header.Extra, make([]byte, extraSeal)...) 554 555 // Mix digest is reserved for now, set to empty 556 header.MixDigest = common.Hash{} 557 558 // Ensure the timestamp has the correct delay 559 parent := chain.GetHeader(header.ParentHash, number-1) 560 if parent == nil { 561 return consensus.ErrUnknownAncestor 562 } 563 header.Time = parent.Time + c.config.Period 564 if header.Time < uint64(time.Now().Unix()) { 565 header.Time = uint64(time.Now().Unix()) 566 } 567 return nil 568 } 569 570 // Finalize implements consensus.Engine, ensuring no uncles are set, nor block 571 // rewards given. 572 func (c *Congress) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs *[]*types.Transaction, uncles []*types.Header, receipts *[]*types.Receipt, systemTxs []*types.Transaction) error { 573 // Initialize all system contracts at block 1. 574 if header.Number.Cmp(common.Big1) == 0 { 575 if err := c.initializeSystemContracts(chain, header, state); err != nil { 576 log.Error("Initialize system contracts failed", "err", err) 577 return err 578 } 579 } 580 581 if header.Difficulty.Cmp(diffInTurn) != 0 { 582 if err := c.tryPunishValidator(chain, header, state); err != nil { 583 return err 584 } 585 } 586 587 // avoid nil pointer 588 if txs == nil { 589 s := make([]*types.Transaction, 0) 590 txs = &s 591 } 592 if receipts == nil { 593 rs := make([]*types.Receipt, 0) 594 receipts = &rs 595 } 596 597 // execute block reward tx. 598 if len(*txs) > 0 { 599 if err := c.trySendBlockReward(chain, header, state); err != nil { 600 return err 601 } 602 } 603 604 // do epoch thing at the end, because it will update active validators 605 if header.Number.Uint64()%c.config.Epoch == 0 { 606 newValidators, err := c.doSomethingAtEpoch(chain, header, state) 607 if err != nil { 608 return err 609 } 610 611 validatorsBytes := make([]byte, len(newValidators)*common.AddressLength) 612 for i, validator := range newValidators { 613 copy(validatorsBytes[i*common.AddressLength:], validator.Bytes()) 614 } 615 616 extraSuffix := len(header.Extra) - extraSeal 617 if !bytes.Equal(header.Extra[extraVanity:extraSuffix], validatorsBytes) { 618 return errInvalidExtraValidators 619 } 620 } 621 622 //handle system governance Proposal 623 if chain.Config().IsRedCoast(header.Number) { 624 proposalCount, err := c.getPassedProposalCount(chain, header, state) 625 if err != nil { 626 return err 627 } 628 if proposalCount != uint32(len(systemTxs)) { 629 return errInvalidSysGovCount 630 } 631 // Due to the logics of the finish operation of contract `governance`, when finishing a proposal which 632 // is not the last passed proposal, it will change the sequence. So in here we must first executes all 633 // passed proposals, and then finish then all. 634 pIds := make([]*big.Int, 0, proposalCount) 635 for i := uint32(0); i < proposalCount; i++ { 636 prop, err := c.getPassedProposalByIndex(chain, header, state, i) 637 if err != nil { 638 return err 639 } 640 // execute the system governance Proposal 641 tx := systemTxs[int(i)] 642 receipt, err := c.replayProposal(chain, header, state, prop, len(*txs), tx) 643 if err != nil { 644 return err 645 } 646 *txs = append(*txs, tx) 647 *receipts = append(*receipts, receipt) 648 // set 649 pIds = append(pIds, prop.Id) 650 } 651 // Finish all proposal 652 for i := uint32(0); i < proposalCount; i++ { 653 err = c.finishProposalById(chain, header, state, pIds[i]) 654 if err != nil { 655 return err 656 } 657 } 658 } 659 660 // No block rewards in PoA, so the state remains as is and uncles are dropped 661 header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) 662 header.UncleHash = types.CalcUncleHash(nil) 663 664 return nil 665 } 666 667 // FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set, 668 // nor block rewards given, and returns the final block. 669 func (c *Congress) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (b *types.Block, rs []*types.Receipt, err error) { 670 defer func() { 671 if err != nil { 672 log.Warn("FinalizeAndAssemble failed", "err", err) 673 } 674 }() 675 // Initialize all system contracts at block 1. 676 if header.Number.Cmp(common.Big1) == 0 { 677 if err := c.initializeSystemContracts(chain, header, state); err != nil { 678 panic(err) 679 } 680 } 681 682 // punish validator if necessary 683 if header.Difficulty.Cmp(diffInTurn) != 0 { 684 if err := c.tryPunishValidator(chain, header, state); err != nil { 685 panic(err) 686 } 687 } 688 689 // deposit block reward if any tx exists. 690 if len(txs) > 0 { 691 if err := c.trySendBlockReward(chain, header, state); err != nil { 692 panic(err) 693 } 694 } 695 696 // do epoch thing at the end, because it will update active validators 697 if header.Number.Uint64()%c.config.Epoch == 0 { 698 if _, err := c.doSomethingAtEpoch(chain, header, state); err != nil { 699 panic(err) 700 } 701 } 702 703 //handle system governance Proposal 704 // 705 // Note: 706 // Even if the miner is not `running`, it's still working, 707 // the 'miner.worker' will try to FinalizeAndAssemble a block, 708 // in this case, the signTxFn is not set. A `non-miner node` can't execute system governance proposal. 709 if c.signTxFn != nil && chain.Config().IsRedCoast(header.Number) { 710 proposalCount, err := c.getPassedProposalCount(chain, header, state) 711 if err != nil { 712 return nil, nil, err 713 } 714 715 // Due to the logics of the finish operation of contract `governance`, when finishing a proposal which 716 // is not the last passed proposal, it will change the sequence. So in here we must first executes all 717 // passed proposals, and then finish then all. 718 pIds := make([]*big.Int, 0, proposalCount) 719 for i := uint32(0); i < proposalCount; i++ { 720 prop, err := c.getPassedProposalByIndex(chain, header, state, i) 721 if err != nil { 722 return nil, nil, err 723 } 724 // execute the system governance Proposal 725 tx, receipt, err := c.executeProposal(chain, header, state, prop, len(txs)) 726 if err != nil { 727 return nil, nil, err 728 } 729 txs = append(txs, tx) 730 receipts = append(receipts, receipt) 731 // set 732 pIds = append(pIds, prop.Id) 733 } 734 // Finish all proposal 735 for i := uint32(0); i < proposalCount; i++ { 736 err = c.finishProposalById(chain, header, state, pIds[i]) 737 if err != nil { 738 return nil, nil, err 739 } 740 } 741 } 742 743 // No block rewards in PoA, so the state remains as is and uncles are dropped 744 header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) 745 header.UncleHash = types.CalcUncleHash(nil) 746 747 // Assemble and return the final block for sealing 748 return types.NewBlock(header, txs, nil, receipts, new(trie.Trie)), receipts, nil 749 } 750 751 func (c *Congress) trySendBlockReward(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB) error { 752 fee := state.GetBalance(consensus.FeeRecoder) 753 if fee.Cmp(common.Big0) <= 0 { 754 return nil 755 } 756 757 // Miner will send tx to deposit block fees to contract, add to his balance first. 758 state.AddBalance(header.Coinbase, fee) 759 // reset fee 760 state.SetBalance(consensus.FeeRecoder, common.Big0) 761 762 method := "distributeBlockReward" 763 data, err := c.abi[systemcontract.ValidatorsContractName].Pack(method) 764 if err != nil { 765 log.Error("Can't pack data for distributeBlockReward", "err", err) 766 return err 767 } 768 769 nonce := state.GetNonce(header.Coinbase) 770 msg := types.NewMessage(header.Coinbase, systemcontract.GetValidatorAddr(header.Number, c.chainConfig), nonce, fee, math.MaxUint64, new(big.Int), data, true) 771 772 if _, err := vmcaller.ExecuteMsg(msg, state, header, newChainContext(chain, c), c.chainConfig); err != nil { 773 return err 774 } 775 776 return nil 777 } 778 779 func (c *Congress) tryPunishValidator(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB) error { 780 number := header.Number.Uint64() 781 snap, err := c.snapshot(chain, number-1, header.ParentHash, nil) 782 if err != nil { 783 return err 784 } 785 validators := snap.validators() 786 outTurnValidator := validators[number%uint64(len(validators))] 787 // check sigend recently or not 788 signedRecently := false 789 for _, recent := range snap.Recents { 790 if recent == outTurnValidator { 791 signedRecently = true 792 break 793 } 794 } 795 if !signedRecently { 796 if err := c.punishValidator(outTurnValidator, chain, header, state); err != nil { 797 return err 798 } 799 } 800 801 return nil 802 } 803 804 func (c *Congress) doSomethingAtEpoch(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB) ([]common.Address, error) { 805 newSortedValidators, err := c.getTopValidators(chain, header) 806 if err != nil { 807 return []common.Address{}, err 808 } 809 810 // update contract new validators if new set exists 811 if err := c.updateValidators(newSortedValidators, chain, header, state); err != nil { 812 return []common.Address{}, err 813 } 814 // decrease validator missed blocks counter at epoch 815 if err := c.decreaseMissedBlocksCounter(chain, header, state); err != nil { 816 return []common.Address{}, err 817 } 818 819 return newSortedValidators, nil 820 } 821 822 // initializeSystemContracts initializes all genesis system contracts. 823 func (c *Congress) initializeSystemContracts(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB) error { 824 snap, err := c.snapshot(chain, 0, header.ParentHash, nil) 825 if err != nil { 826 return err 827 } 828 829 genesisValidators := snap.validators() 830 if len(genesisValidators) == 0 || len(genesisValidators) > maxValidators { 831 return errInvalidValidatorsLength 832 } 833 834 method := "initialize" 835 contracts := []struct { 836 addr common.Address 837 packFun func() ([]byte, error) 838 }{ 839 {systemcontract.ValidatorsContractAddr, func() ([]byte, error) { 840 return c.abi[systemcontract.ValidatorsContractName].Pack(method, genesisValidators) 841 }}, 842 {systemcontract.PunishContractAddr, func() ([]byte, error) { return c.abi[systemcontract.PunishContractName].Pack(method) }}, 843 {systemcontract.ProposalAddr, func() ([]byte, error) { 844 return c.abi[systemcontract.ProposalContractName].Pack(method, genesisValidators) 845 }}, 846 } 847 848 for _, contract := range contracts { 849 data, err := contract.packFun() 850 if err != nil { 851 return err 852 } 853 854 nonce := state.GetNonce(header.Coinbase) 855 msg := types.NewMessage(header.Coinbase, &contract.addr, nonce, new(big.Int), math.MaxUint64, new(big.Int), data, true) 856 857 if _, err := vmcaller.ExecuteMsg(msg, state, header, newChainContext(chain, c), c.chainConfig); err != nil { 858 return err 859 } 860 } 861 862 return nil 863 } 864 865 // call this at epoch block to get top validators based on the state of epoch block - 1 866 func (c *Congress) getTopValidators(chain consensus.ChainHeaderReader, header *types.Header) ([]common.Address, error) { 867 parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) 868 if parent == nil { 869 return []common.Address{}, consensus.ErrUnknownAncestor 870 } 871 statedb, err := c.stateFn(parent.Root) 872 if err != nil { 873 return []common.Address{}, err 874 } 875 876 method := "getTopValidators" 877 data, err := c.abi[systemcontract.ValidatorsContractName].Pack(method) 878 if err != nil { 879 log.Error("Can't pack data for getTopValidators", "error", err) 880 return []common.Address{}, err 881 } 882 883 msg := types.NewMessage(header.Coinbase, systemcontract.GetValidatorAddr(parent.Number, c.chainConfig), 0, new(big.Int), math.MaxUint64, new(big.Int), data, false) 884 885 // use parent 886 result, err := vmcaller.ExecuteMsg(msg, statedb, parent, newChainContext(chain, c), c.chainConfig) 887 if err != nil { 888 return []common.Address{}, err 889 } 890 891 // unpack data 892 ret, err := c.abi[systemcontract.ValidatorsContractName].Unpack(method, result) 893 if err != nil { 894 return []common.Address{}, err 895 } 896 if len(ret) != 1 { 897 return []common.Address{}, errors.New("Invalid params length") 898 } 899 validators, ok := ret[0].([]common.Address) 900 if !ok { 901 return []common.Address{}, errors.New("Invalid validators format") 902 } 903 sort.Sort(validatorsAscending(validators)) 904 return validators, err 905 } 906 907 func (c *Congress) updateValidators(vals []common.Address, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB) error { 908 // method 909 method := "updateActiveValidatorSet" 910 data, err := c.abi[systemcontract.ValidatorsContractName].Pack(method, vals, new(big.Int).SetUint64(c.config.Epoch)) 911 if err != nil { 912 log.Error("Can't pack data for updateActiveValidatorSet", "error", err) 913 return err 914 } 915 916 // call contract 917 nonce := state.GetNonce(header.Coinbase) 918 msg := types.NewMessage(header.Coinbase, systemcontract.GetValidatorAddr(header.Number, c.chainConfig), nonce, new(big.Int), math.MaxUint64, new(big.Int), data, true) 919 if _, err := vmcaller.ExecuteMsg(msg, state, header, newChainContext(chain, c), c.chainConfig); err != nil { 920 log.Error("Can't update validators to contract", "err", err) 921 return err 922 } 923 924 return nil 925 } 926 927 func (c *Congress) punishValidator(val common.Address, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB) error { 928 // method 929 method := "punish" 930 data, err := c.abi[systemcontract.PunishContractName].Pack(method, val) 931 if err != nil { 932 log.Error("Can't pack data for punish", "error", err) 933 return err 934 } 935 936 // call contract 937 nonce := state.GetNonce(header.Coinbase) 938 msg := types.NewMessage(header.Coinbase, systemcontract.GetPunishAddr(header.Number, c.chainConfig), nonce, new(big.Int), math.MaxUint64, new(big.Int), data, true) 939 if _, err := vmcaller.ExecuteMsg(msg, state, header, newChainContext(chain, c), c.chainConfig); err != nil { 940 log.Error("Can't punish validator", "err", err) 941 return err 942 } 943 944 return nil 945 } 946 947 func (c *Congress) decreaseMissedBlocksCounter(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB) error { 948 // method 949 method := "decreaseMissedBlocksCounter" 950 data, err := c.abi[systemcontract.PunishContractName].Pack(method, new(big.Int).SetUint64(c.config.Epoch)) 951 if err != nil { 952 log.Error("Can't pack data for decreaseMissedBlocksCounter", "error", err) 953 return err 954 } 955 956 // call contract 957 nonce := state.GetNonce(header.Coinbase) 958 msg := types.NewMessage(header.Coinbase, systemcontract.GetPunishAddr(header.Number, c.chainConfig), nonce, new(big.Int), math.MaxUint64, new(big.Int), data, true) 959 if _, err := vmcaller.ExecuteMsg(msg, state, header, newChainContext(chain, c), c.chainConfig); err != nil { 960 log.Error("Can't decrease missed blocks counter for validator", "err", err) 961 return err 962 } 963 964 return nil 965 } 966 967 // Authorize injects a private key into the consensus engine to mint new blocks 968 // with. 969 func (c *Congress) Authorize(validator common.Address, signFn ValidatorFn, signTxFn SignTxFn) { 970 c.lock.Lock() 971 defer c.lock.Unlock() 972 973 c.validator = validator 974 c.signFn = signFn 975 c.signTxFn = signTxFn 976 } 977 978 // Seal implements consensus.Engine, attempting to create a sealed block using 979 // the local signing credentials. 980 func (c *Congress) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { 981 header := block.Header() 982 983 // Sealing the genesis block is not supported 984 number := header.Number.Uint64() 985 if number == 0 { 986 return errUnknownBlock 987 } 988 // For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing) 989 if c.config.Period == 0 && len(block.Transactions()) == 0 { 990 log.Info("Sealing paused, waiting for transactions") 991 return nil 992 } 993 // Don't hold the val fields for the entire sealing procedure 994 c.lock.RLock() 995 val, signFn := c.validator, c.signFn 996 c.lock.RUnlock() 997 998 // Bail out if we're unauthorized to sign a block 999 snap, err := c.snapshot(chain, number-1, header.ParentHash, nil) 1000 if err != nil { 1001 return err 1002 } 1003 if _, authorized := snap.Validators[val]; !authorized { 1004 return errUnauthorizedValidator 1005 } 1006 // If we're amongst the recent validators, wait for the next block 1007 for seen, recent := range snap.Recents { 1008 if recent == val { 1009 // Validator is among recents, only wait if the current block doesn't shift it out 1010 if limit := uint64(len(snap.Validators)/2 + 1); number < limit || seen > number-limit { 1011 log.Info("Signed recently, must wait for others") 1012 return nil 1013 } 1014 } 1015 } 1016 1017 // Sweet, the protocol permits us to sign the block, wait for our time 1018 delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple 1019 if header.Difficulty.Cmp(diffNoTurn) == 0 { 1020 // It's not our turn explicitly to sign, delay it a bit 1021 wiggle := time.Duration(len(snap.Validators)/2+1) * wiggleTime 1022 delay += time.Duration(rand.Int63n(int64(wiggle))) 1023 1024 log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle)) 1025 } 1026 // Sign all the things! 1027 sighash, err := signFn(accounts.Account{Address: val}, accounts.MimetypeCongress, CongressRLP(header)) 1028 if err != nil { 1029 return err 1030 } 1031 copy(header.Extra[len(header.Extra)-extraSeal:], sighash) 1032 // Wait until sealing is terminated or delay timeout. 1033 log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay)) 1034 go func() { 1035 select { 1036 case <-stop: 1037 return 1038 case <-time.After(delay): 1039 } 1040 1041 select { 1042 case results <- block.WithSeal(header): 1043 default: 1044 log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header)) 1045 } 1046 }() 1047 1048 return nil 1049 } 1050 1051 // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty 1052 // that a new block should have: 1053 // * DIFF_NOTURN(2) if BLOCK_NUMBER % validator_COUNT != validator_INDEX 1054 // * DIFF_INTURN(1) if BLOCK_NUMBER % validator_COUNT == validator_INDEX 1055 func (c *Congress) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int { 1056 snap, err := c.snapshot(chain, parent.Number.Uint64(), parent.Hash(), nil) 1057 if err != nil { 1058 return nil 1059 } 1060 return calcDifficulty(snap, c.validator) 1061 } 1062 1063 func calcDifficulty(snap *Snapshot, validator common.Address) *big.Int { 1064 if snap.inturn(snap.Number+1, validator) { 1065 return new(big.Int).Set(diffInTurn) 1066 } 1067 return new(big.Int).Set(diffNoTurn) 1068 } 1069 1070 // SealHash returns the hash of a block prior to it being sealed. 1071 func (c *Congress) SealHash(header *types.Header) common.Hash { 1072 return SealHash(header) 1073 } 1074 1075 // Close implements consensus.Engine. It's a noop for congress as there are no background threads. 1076 func (c *Congress) Close() error { 1077 return nil 1078 } 1079 1080 // APIs implements consensus.Engine, returning the user facing RPC API to allow 1081 // controlling the validator voting. 1082 func (c *Congress) APIs(chain consensus.ChainHeaderReader) []rpc.API { 1083 return []rpc.API{{ 1084 Namespace: "congress", 1085 Version: "1.0", 1086 Service: &API{chain: chain, congress: c}, 1087 Public: false, 1088 }} 1089 } 1090 1091 // SealHash returns the hash of a block prior to it being sealed. 1092 func SealHash(header *types.Header) (hash common.Hash) { 1093 hasher := sha3.NewLegacyKeccak256() 1094 encodeSigHeader(hasher, header) 1095 hasher.Sum(hash[:0]) 1096 return hash 1097 } 1098 1099 // CongressRLP returns the rlp bytes which needs to be signed for the proof-of-stake-authority 1100 // sealing. The RLP to sign consists of the entire header apart from the 65 byte signature 1101 // contained at the end of the extra data. 1102 // 1103 // Note, the method requires the extra data to be at least 65 bytes, otherwise it 1104 // panics. This is done to avoid accidentally using both forms (signature present 1105 // or not), which could be abused to produce different hashes for the same header. 1106 func CongressRLP(header *types.Header) []byte { 1107 b := new(bytes.Buffer) 1108 encodeSigHeader(b, header) 1109 return b.Bytes() 1110 } 1111 1112 func encodeSigHeader(w io.Writer, header *types.Header) { 1113 err := rlp.Encode(w, []interface{}{ 1114 header.ParentHash, 1115 header.UncleHash, 1116 header.Coinbase, 1117 header.Root, 1118 header.TxHash, 1119 header.ReceiptHash, 1120 header.Bloom, 1121 header.Difficulty, 1122 header.Number, 1123 header.GasLimit, 1124 header.GasUsed, 1125 header.Time, 1126 header.Extra[:len(header.Extra)-crypto.SignatureLength], // Yes, this will panic if extra is too short 1127 header.MixDigest, 1128 header.Nonce, 1129 }) 1130 if err != nil { 1131 panic("can't encode: " + err.Error()) 1132 } 1133 } 1134 1135 func (c *Congress) PreHandle(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB) error { 1136 if c.chainConfig.RedCoastBlock != nil && c.chainConfig.RedCoastBlock.Cmp(header.Number) == 0 { 1137 return systemcontract.ApplySystemContractUpgrade(state, header, newChainContext(chain, c), c.chainConfig) 1138 } 1139 return nil 1140 } 1141 1142 // IsSysTransaction checks whether a specific transaction is a system transaction. 1143 func (c *Congress) IsSysTransaction(tx *types.Transaction, header *types.Header) (bool, error) { 1144 if tx.To() == nil { 1145 return false, nil 1146 } 1147 1148 sender, err := types.Sender(c.signer, tx) 1149 if err != nil { 1150 return false, errors.New("UnAuthorized transaction") 1151 } 1152 to := tx.To() 1153 if sender == header.Coinbase && *to == systemcontract.SysGovToAddr && tx.GasPrice().Sign() == 0 { 1154 return true, nil 1155 } 1156 // Make sure the miner can NOT call the system contract through a normal transaction. 1157 if sender == header.Coinbase && *to == systemcontract.SysGovContractAddr { 1158 return true, nil 1159 } 1160 return false, nil 1161 } 1162 1163 // CanCreate determines where a given address can create a new contract. 1164 // 1165 // This will queries the system Developers contract, by DIRECTLY to get the target slot value of the contract, 1166 // it means that it's strongly relative to the layout of the Developers contract's state variables 1167 func (c *Congress) CanCreate(state consensus.StateReader, addr common.Address, height *big.Int) bool { 1168 if c.chainConfig.IsRedCoast(height) && c.config.EnableDevVerification { 1169 if isDeveloperVerificationEnabled(state) { 1170 slot := calcSlotOfDevMappingKey(addr) 1171 valueHash := state.GetState(systemcontract.AddressListContractAddr, slot) 1172 // none zero value means true 1173 return valueHash.Big().Sign() > 0 1174 } 1175 } 1176 return true 1177 } 1178 1179 // ValidateTx do a consensus-related validation on the given transaction at the given header and state. 1180 // the parentState must be the state of the header's parent block. 1181 func (c *Congress) ValidateTx(tx *types.Transaction, header *types.Header, parentState *state.StateDB) error { 1182 // Must use the parent state for current validation, 1183 // so we must starting the validation after redCoastBlock 1184 if c.chainConfig.RedCoastBlock != nil && c.chainConfig.RedCoastBlock.Cmp(header.Number) < 0 { 1185 from, err := types.Sender(c.signer, tx) 1186 if err != nil { 1187 return err 1188 } 1189 m, err := c.getBlacklist(header, parentState) 1190 if err != nil { 1191 log.Error("can't get blacklist", "err", err) 1192 return err 1193 } 1194 if d, exist := m[from]; exist && (d != DirectionTo) { 1195 return errors.New("address denied") 1196 } 1197 if to := tx.To(); to != nil { 1198 if d, exist := m[*to]; exist && (d != DirectionFrom) { 1199 return errors.New("address denied") 1200 } 1201 } 1202 } 1203 return nil 1204 } 1205 1206 func (c *Congress) getBlacklist(header *types.Header, parentState *state.StateDB) (map[common.Address]blacklistDirection, error) { 1207 defer func(start time.Time) { 1208 getblacklistTimer.UpdateSince(start) 1209 }(time.Now()) 1210 1211 if v, ok := c.blacklists.Get(header.ParentHash); ok { 1212 return v.(map[common.Address]blacklistDirection), nil 1213 } 1214 1215 c.blLock.Lock() 1216 defer c.blLock.Unlock() 1217 if v, ok := c.blacklists.Get(header.ParentHash); ok { 1218 return v.(map[common.Address]blacklistDirection), nil 1219 } 1220 1221 abi := c.abi[systemcontract.AddressListContractName] 1222 get := func(method string) ([]common.Address, error) { 1223 data, err := abi.Pack(method) 1224 if err != nil { 1225 log.Error("Can't pack data ", "method", method, "err", err) 1226 return []common.Address{}, err 1227 } 1228 1229 msg := types.NewMessage(header.Coinbase, &systemcontract.AddressListContractAddr, 0, new(big.Int), math.MaxUint64, new(big.Int), data, false) 1230 1231 // Note: It's safe to use minimalChainContext for executing AddressListContract 1232 result, err := vmcaller.ExecuteMsg(msg, parentState, header, newMinimalChainContext(c), c.chainConfig) 1233 if err != nil { 1234 return []common.Address{}, err 1235 } 1236 1237 // unpack data 1238 ret, err := abi.Unpack(method, result) 1239 if err != nil { 1240 return []common.Address{}, err 1241 } 1242 if len(ret) != 1 { 1243 return []common.Address{}, errors.New("invalid params length") 1244 } 1245 blacks, ok := ret[0].([]common.Address) 1246 if !ok { 1247 return []common.Address{}, errors.New("invalid blacklist format") 1248 } 1249 return blacks, nil 1250 } 1251 froms, err := get("getBlacksFrom") 1252 if err != nil { 1253 return nil, err 1254 } 1255 tos, err := get("getBlacksTo") 1256 if err != nil { 1257 return nil, err 1258 } 1259 1260 m := make(map[common.Address]blacklistDirection) 1261 for _, from := range froms { 1262 m[from] = DirectionFrom 1263 } 1264 for _, to := range tos { 1265 if _, exist := m[to]; exist { 1266 m[to] = DirectionBoth 1267 } else { 1268 m[to] = DirectionTo 1269 } 1270 } 1271 c.blacklists.Add(header.ParentHash, m) 1272 return m, nil 1273 } 1274 1275 // Since the state variables are as follow: 1276 // bool public initialized; 1277 // bool public enabled; 1278 // address public admin; 1279 // address public pendingAdmin; 1280 // mapping(address => bool) private devs; 1281 // 1282 // according to [Layout of State Variables in Storage](https://docs.soliditylang.org/en/v0.8.4/internals/layout_in_storage.html), 1283 // and after optimizer enabled, the `initialized`, `enabled` and `admin` will be packed, and stores at slot 0, 1284 // `pendingAdmin` stores at slot 1, and the position for `devs` is 2. 1285 func isDeveloperVerificationEnabled(state consensus.StateReader) bool { 1286 compactValue := state.GetState(systemcontract.AddressListContractAddr, common.Hash{}) 1287 log.Debug("isDeveloperVerificationEnabled", "raw", compactValue.String()) 1288 // Layout of slot 0: 1289 // [0 - 9][10-29][ 30 ][ 31 ] 1290 // [zero bytes][admin][enabled][initialized] 1291 enabledByte := compactValue.Bytes()[common.HashLength-2] 1292 return enabledByte == 0x01 1293 } 1294 1295 func calcSlotOfDevMappingKey(addr common.Address) common.Hash { 1296 p := make([]byte, common.HashLength) 1297 binary.BigEndian.PutUint16(p[common.HashLength-2:], uint16(systemcontract.DevMappingPosition)) 1298 return crypto.Keccak256Hash(addr.Hash().Bytes(), p) 1299 }