github.com/amazechain/amc@v0.1.3/internal/consensus/apos/apos.go (about) 1 // Copyright 2022 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain 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 AmazeChain 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 AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package APos implements the proof-of-authority consensus engine. 18 19 package apos 20 21 import ( 22 "bytes" 23 "context" 24 "errors" 25 "fmt" 26 "github.com/amazechain/amc/internal/consensus/misc" 27 "github.com/holiman/uint256" 28 29 "github.com/amazechain/amc/common/crypto/bls" 30 "github.com/amazechain/amc/internal/api" 31 "github.com/amazechain/amc/modules/rawdb" 32 33 "github.com/amazechain/amc/accounts" 34 amcCommon "github.com/amazechain/amc/common" 35 "github.com/amazechain/amc/common/block" 36 "github.com/amazechain/amc/common/crypto" 37 "github.com/amazechain/amc/common/hexutil" 38 "github.com/amazechain/amc/common/transaction" 39 "github.com/amazechain/amc/common/types" 40 "github.com/amazechain/amc/internal/avm/common" 41 "github.com/amazechain/amc/internal/avm/rlp" 42 mvm_types "github.com/amazechain/amc/internal/avm/types" 43 44 "io" 45 "math/rand" 46 "sync" 47 "time" 48 49 "github.com/amazechain/amc/internal/consensus" 50 "github.com/amazechain/amc/log" 51 "github.com/amazechain/amc/modules/rpc/jsonrpc" 52 "github.com/amazechain/amc/modules/state" 53 "github.com/amazechain/amc/params" 54 "github.com/ledgerwatch/erigon-lib/kv" 55 56 lru "github.com/hashicorp/golang-lru" 57 "golang.org/x/crypto/sha3" 58 ) 59 60 const ( 61 checkpointInterval = 2048 // Number of blocks after which to save the vote snapshot to the database 62 inmemorySnapshots = 128 // Number of recent vote snapshots to keep in memory 63 inmemorySignatures = 4096 // Number of recent block signatures to keep in memory 64 65 wiggleTime = 500 * time.Millisecond // Random delay (per signer) to allow concurrent signers 66 mergeSignMinTime = 4 // min time for merge sign 67 ) 68 69 // APos proof-of-authority protocol constants. 70 var ( 71 epochLength = uint64(30000) // Default number of blocks after which to checkpoint and reset the pending votes 72 73 extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity 74 extraSeal = crypto.SignatureLength // Fixed number of extra-data suffix bytes reserved for signer seal 75 76 nonceAuthVote = hexutil.MustDecode("0xffffffffffffffff") // Magic nonce number to vote on adding a new signer 77 nonceDropVote = hexutil.MustDecode("0x0000000000000000") // Magic nonce number to vote on removing a signer. 78 79 //uncleHash = mvm_types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW. 80 81 diffInTurn = uint256.NewInt(2) // Block difficulty for in-turn signatures 82 diffNoTurn = uint256.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 signers is requested for a block 91 // that is not part of the local blockchain. 92 errUnknownBlock = errors.New("unknown block") 93 94 // errInvalidCheckpointBeneficiary is returned if a checkpoint/epoch transition 95 // block has a beneficiary set to non-zeroes. 96 errInvalidCheckpointBeneficiary = errors.New("beneficiary in checkpoint block non-zero") 97 98 // errInvalidVote is returned if a nonce value is something else that the two 99 // allowed constants of 0x00..0 or 0xff..f. 100 errInvalidVote = errors.New("vote nonce not 0x00..0 or 0xff..f") 101 102 // errInvalidCheckpointVote is returned if a checkpoint/epoch transition block 103 // has a vote nonce set to non-zeroes. 104 errInvalidCheckpointVote = errors.New("vote nonce in checkpoint block non-zero") 105 106 // errMissingVanity is returned if a block's extra-data section is shorter than 107 // 32 bytes, which is required to store the signer vanity. 108 errMissingVanity = errors.New("extra-data 32 byte vanity prefix missing") 109 110 // errMissingSignature is returned if a block's extra-data section doesn't seem 111 // to contain a 65 byte secp256k1 signature. 112 errMissingSignature = errors.New("extra-data 65 byte signature suffix missing") 113 114 // errExtraSigners is returned if non-checkpoint block contain signer data in 115 // their extra-data fields. 116 errExtraSigners = errors.New("non-checkpoint block contains extra signer list") 117 118 // errInvalidCheckpointSigners is returned if a checkpoint block contains an 119 // invalid list of signers (i.e. non divisible by 20 bytes). 120 errInvalidCheckpointSigners = errors.New("invalid signer list on checkpoint block") 121 122 // errMismatchingCheckpointSigners is returned if a checkpoint block contains a 123 // list of signers different than the one the local node calculated. 124 errMismatchingCheckpointSigners = errors.New("mismatching signer list on checkpoint block") 125 126 // errInvalidMixDigest is returned if a block's mix digest is non-zero. 127 errInvalidMixDigest = errors.New("non-zero mix digest") 128 129 // errInvalidUncleHash is returned if a block contains an non-empty uncle list. 130 errInvalidUncleHash = errors.New("non empty uncle hash") 131 132 // errInvalidDifficulty is returned if the difficulty of a block neither 1 or 2. 133 errInvalidDifficulty = errors.New("invalid difficulty") 134 135 // errWrongDifficulty is returned if the difficulty of a block doesn't match the 136 // turn of the signer. 137 errWrongDifficulty = errors.New("wrong difficulty") 138 139 // errInvalidTimestamp is returned if the timestamp of a block is lower than 140 // the previous block's timestamp + the minimum block period. 141 errInvalidTimestamp = errors.New("invalid timestamp") 142 143 // errInvalidVotingChain is returned if an authorization list is attempted to 144 // be modified via out-of-range or non-contiguous headers. 145 errInvalidVotingChain = errors.New("invalid voting chain") 146 147 // errUnauthorizedSigner is returned if a header is signed by a non-authorized entity. 148 errUnauthorizedSigner = errors.New("unauthorized signer") 149 150 // errRecentlySigned is returned if a header is signed by an authorized entity 151 // that already signed a header recently, thus is temporarily not allowed to. 152 errRecentlySigned = errors.New("recently signed") 153 ) 154 155 // SignerFn hashes and signs the data to be signed by a backing account. 156 // todo types.address to account 157 type SignerFn func(signer accounts.Account, mimeType string, message []byte) ([]byte, error) 158 159 // ecrecover extracts the Ethereum account address from a signed header. 160 func ecrecover(iHeader block.IHeader, sigcache *lru.ARCCache) (types.Address, error) { 161 header := iHeader.(*block.Header) 162 // If the signature's already cached, return that 163 hash := header.Hash() 164 if address, known := sigcache.Get(hash); known { 165 return address.(types.Address), nil 166 } 167 // Retrieve the signature from the header extra-data 168 if len(header.Extra) < extraSeal { 169 return types.Address{}, errMissingSignature 170 } 171 signature := header.Extra[len(header.Extra)-extraSeal:] 172 173 //Recover the public key and the Ethereum(AMC) address 174 pubkey, err := crypto.Ecrecover(SealHash(header).Bytes(), signature) 175 if err != nil { 176 return types.Address{}, err 177 } 178 var signer types.Address 179 copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) 180 181 sigcache.Add(hash, signer) 182 return signer, nil 183 } 184 185 // APos is the proof-of-authority consensus engine proposed to support the 186 // Ethereum testnet following the Ropsten attacks. 187 type APos struct { 188 config *params.APosConfig // Consensus engine configuration parameters 189 chainConfig *params.ChainConfig 190 db kv.RwDB // Database to store and retrieve snapshot checkpoints 191 192 recents *lru.ARCCache // Snapshots for recent block to speed up reorgs 193 signatures *lru.ARCCache // Signatures of recent blocks to speed up mining 194 195 proposals map[types.Address]bool // Current list of proposals we are pushing 196 197 signer types.Address // Ethereum address of the signing key 198 signFn SignerFn // Signer function to authorize hashes with 199 lock sync.RWMutex // Protects the signer and proposals fields 200 201 // The fields below are for testing only 202 fakeDiff bool // Skip difficulty verifications 203 204 bc amcCommon.IBlockChain 205 } 206 207 // New creates a APos proof-of-authority consensus engine with the initial 208 // signers set to the ones provided by the user. 209 func New(config *params.APosConfig, db kv.RwDB, chainConfig *params.ChainConfig) consensus.Engine { 210 // Set any missing consensus parameters to their defaults 211 conf := *config 212 if conf.Epoch == 0 { 213 conf.Epoch = epochLength 214 } 215 // GenesisAlloc the snapshot caches and create the engine 216 recents, _ := lru.NewARC(inmemorySnapshots) 217 signatures, _ := lru.NewARC(inmemorySignatures) 218 219 return &APos{ 220 config: &conf, 221 chainConfig: chainConfig, 222 db: db, 223 recents: recents, 224 signatures: signatures, 225 proposals: make(map[types.Address]bool), 226 } 227 } 228 229 // Author implements consensus.Engine, returning the Ethereum address recovered 230 // from the signature in the header's extra-data section. 231 func (c *APos) Author(header block.IHeader) (types.Address, error) { 232 return ecrecover(header, c.signatures) 233 } 234 235 func (c *APos) SetBlockChain(bc amcCommon.IBlockChain) { 236 c.bc = bc 237 } 238 239 // VerifyHeader checks whether a header conforms to the consensus rules. 240 func (c *APos) VerifyHeader(chain consensus.ChainHeaderReader, header block.IHeader, seal bool) error { 241 return c.verifyHeader(chain, header, nil) 242 } 243 244 // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The 245 // method returns a quit channel to abort the operations and a results channel to 246 // retrieve the async verifications (the order is that of the input slice). 247 func (c *APos) VerifyHeaders(chain consensus.ChainHeaderReader, headers []block.IHeader, seals []bool) (chan<- struct{}, <-chan error) { 248 abort := make(chan struct{}) 249 results := make(chan error, len(headers)) 250 251 go func() { 252 for i, header := range headers { 253 err := c.verifyHeader(chain, header, headers[:i]) 254 255 select { 256 case <-abort: 257 return 258 case results <- err: 259 } 260 } 261 }() 262 return abort, results 263 } 264 265 // verifyHeader checks whether a header conforms to the consensus rules.The 266 // caller may optionally pass in a batch of parents (ascending order) to avoid 267 // looking those up from the database. This is useful for concurrently verifying 268 // a batch of new headers. 269 func (c *APos) verifyHeader(chain consensus.ChainHeaderReader, iHeader block.IHeader, parents []block.IHeader) error { 270 header := iHeader.(*block.Header) 271 if header.Number.IsZero() { 272 return errUnknownBlock 273 } 274 number := header.Number.Uint64() 275 276 // Don't waste time checking blocks from the future 277 if header.Time > uint64(time.Now().Unix()) { 278 return errors.New("block in the future") 279 } 280 // Checkpoint blocks need to enforce zero beneficiary 281 checkpoint := (number % c.config.Epoch) == 0 282 if checkpoint && header.Coinbase != (types.Address{}) { 283 return errInvalidCheckpointBeneficiary 284 } 285 // Nonces must be 0x00..0 or 0xff..f, zeroes enforced on checkpoints 286 if !bytes.Equal(header.Nonce[:], nonceAuthVote) && !bytes.Equal(header.Nonce[:], nonceDropVote) { 287 return errInvalidVote 288 } 289 if checkpoint && !bytes.Equal(header.Nonce[:], nonceDropVote) { 290 return errInvalidCheckpointVote 291 } 292 // Check that the extra-data contains both the vanity and signature 293 if len(header.Extra) < extraVanity { 294 return errMissingVanity 295 } 296 if len(header.Extra) < extraVanity+extraSeal { 297 return errMissingSignature 298 } 299 // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise 300 signersBytes := len(header.Extra) - extraVanity - extraSeal 301 if !checkpoint && signersBytes != 0 { 302 return errExtraSigners 303 } 304 if checkpoint && signersBytes%types.AddressLength != 0 { 305 return errInvalidCheckpointSigners 306 } 307 // Ensure that the mix digest is zero as we don't have fork protection currently 308 //if header.MixDigest != (types.Hash{}) { 309 // return errInvalidMixDigest 310 //} 311 // Ensure that the block doesn't contain any uncles which are meaningless in PoA 312 //if header.UncleHash != uncleHash { 313 // return errInvalidUncleHash 314 //} 315 // Ensure that the block's difficulty is meaningful (may not be correct at this point) 316 if number > 0 { 317 if header.Difficulty.IsZero() || (header.Difficulty.Cmp(diffInTurn) != 0 && header.Difficulty.Cmp(diffNoTurn) != 0) { 318 return errInvalidDifficulty 319 } 320 } 321 // Verify that the gas limit is <= 2^63-1 322 if header.GasLimit > params.MaxGasLimit { 323 return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, params.MaxGasLimit) 324 } 325 // If all checks passed, validate any special fields for hard forks 326 //todo 327 //if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil { 328 // return err 329 //} 330 // All basic checks passed, verify cascading fields 331 return c.verifyCascadingFields(chain, header, parents) 332 } 333 334 // verifyCascadingFields verifies all the header fields that are not standalone, 335 // rather depend on a batch of previous headers. The caller may optionally pass 336 // in a batch of parents (ascending order) to avoid looking those up from the 337 // database. This is useful for concurrently verifying a batch of new headers. 338 func (c *APos) verifyCascadingFields(chain consensus.ChainHeaderReader, iHeader block.IHeader, parents []block.IHeader) error { 339 header := iHeader.(*block.Header) 340 // The genesis block is the always valid dead-end 341 number := header.Number.Uint64() 342 if number == 0 { 343 return nil 344 } 345 // Ensure that the block's timestamp isn't too close to its parent 346 var parent block.IHeader 347 if len(parents) > 0 { 348 parent = parents[len(parents)-1] 349 } else { 350 parent = chain.GetHeader(header.ParentHash, uint256.NewInt(number-1)) 351 } 352 if parent == nil || parent.(*block.Header) == nil || parent.Number64().Uint64() != number-1 || parent.Hash() != header.ParentHash { 353 return errUnknownBlock 354 } 355 // todo 356 rawParent := parent.(*block.Header) 357 if rawParent.Time+c.config.Period > header.Time { 358 return errInvalidTimestamp 359 } 360 // Verify that the gasUsed is <= gasLimit 361 if header.GasUsed > header.GasLimit { 362 return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit) 363 } 364 if !chain.Config().IsLondon(header.Number.Uint64()) { 365 // Verify BaseFee not present before EIP-1559 fork. 366 if header.BaseFee != nil { 367 return fmt.Errorf("invalid baseFee before fork: have %d, want <nil>", header.BaseFee) 368 } 369 if err := misc.VerifyGaslimit(parent.(*block.Header).GasLimit, header.GasLimit); err != nil { 370 return err 371 } 372 } else if err := misc.VerifyEip1559Header(chain.Config(), parent.(*block.Header), header); err != nil { 373 // Verify the header's EIP-1559 attributes. 374 return err 375 } 376 // Retrieve the snapshot needed to verify this header and cache it 377 snap, err := c.snapshot(chain, number-1, header.ParentHash, parents) 378 if err != nil { 379 return err 380 } 381 // If the block is a checkpoint block, verify the signer list 382 if number%c.config.Epoch == 0 { 383 signers := make([]byte, len(snap.Signers)*types.AddressLength) 384 for i, signer := range snap.signers() { 385 copy(signers[i*types.AddressLength:], signer[:]) 386 } 387 extraSuffix := len(header.Extra) - extraSeal 388 if !bytes.Equal(header.Extra[extraVanity:extraSuffix], signers) { 389 return errMismatchingCheckpointSigners 390 } 391 } 392 // All basic checks passed, verify the seal and return 393 return c.verifySeal(snap, header, parents) 394 } 395 396 // snapshot retrieves the authorization snapshot at a given point in time. 397 func (c *APos) snapshot(chain consensus.ChainHeaderReader, number uint64, hash types.Hash, parents []block.IHeader) (*Snapshot, error) { 398 // Search for a snapshot in memory or on disk for checkpoints 399 var ( 400 headers []block.IHeader 401 snap *Snapshot 402 ) 403 for snap == nil { 404 // If an in-memory snapshot was found, use that 405 if s, ok := c.recents.Get(hash); ok { 406 snap = s.(*Snapshot) 407 break 408 } 409 // If an on-disk checkpoint snapshot can be found, use that 410 if number%checkpointInterval == 0 { 411 if err := c.db.View(context.Background(), func(tx kv.Tx) error { 412 var err error 413 s, err := loadSnapshot(c.config, c.signatures, tx, hash) 414 if err == nil { 415 log.Debug("Loaded voting snapshot from disk", "number", number, "hash", hash) 416 snap = s 417 } 418 return err 419 }); nil == err { 420 break 421 } 422 } 423 // If we're at the genesis, snapshot the initial state. Alternatively if we're 424 // at a checkpoint block without a parent (light client CHT), or we have piled 425 // up more headers than allowed to be reorged (chain reinit from a freezer), 426 // consider the checkpoint trusted and snapshot it. 427 h := chain.GetHeaderByNumber(uint256.NewInt(number - 1)) 428 if number == 0 || (number%c.config.Epoch == 0 && (len(headers) > params.FullImmutabilityThreshold || h == nil)) { 429 checkpoint := chain.GetHeaderByNumber(uint256.NewInt(number)) 430 if checkpoint != nil { 431 rawCheckpoint := checkpoint.(*block.Header) 432 hash := checkpoint.Hash() 433 434 signers := make([]types.Address, (len(rawCheckpoint.Extra)-extraVanity-extraSeal)/types.AddressLength) 435 for i := 0; i < len(signers); i++ { 436 copy(signers[i][:], rawCheckpoint.Extra[extraVanity+i*types.AddressLength:]) 437 } 438 snap = newSnapshot(c.config, c.signatures, number, hash, signers) 439 if err := c.db.Update(context.Background(), func(tx kv.RwTx) error { 440 if err := snap.store(tx); err != nil { 441 return err 442 } 443 return nil 444 }); nil != err { 445 return nil, err 446 } 447 log.Info("Stored checkpoint snapshot to disk", "number", number, "hash", hash) 448 break 449 } 450 } 451 // No snapshot for this header, gather the header and move backward 452 var header block.IHeader 453 if len(parents) > 0 { 454 // If we have explicit parents, pick from there (enforced) 455 header = parents[len(parents)-1] 456 if header.Hash() != hash || header.Number64().Uint64() != number { 457 return nil, errUnknownBlock 458 } 459 parents = parents[:len(parents)-1] 460 } else { 461 // No explicit parents (or no more left), reach out to the database 462 header = chain.GetHeader(hash, uint256.NewInt(number)) 463 if header == nil { 464 return nil, errUnknownBlock 465 } 466 } 467 headers = append(headers, header) 468 number, hash = number-1, header.(*block.Header).ParentHash 469 } 470 // Previous snapshot found, apply any pending headers on top of it 471 for i := 0; i < len(headers)/2; i++ { 472 headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i] 473 } 474 snap, err := snap.apply(headers) 475 if err != nil { 476 return nil, err 477 } 478 c.recents.Add(snap.Hash, snap) 479 480 // If we've generated a new checkpoint snapshot, save to disk 481 if snap.Number%checkpointInterval == 0 && len(headers) > 0 { 482 if err = c.db.Update(context.Background(), func(tx kv.RwTx) error { 483 if err := snap.store(tx); err != nil { 484 return err 485 } 486 return nil 487 }); nil != err { 488 return nil, err 489 } 490 491 log.Debug("Stored voting snapshot to disk", "number", snap.Number, "hash", snap.Hash) 492 } 493 return snap, err 494 } 495 496 // VerifyUncles implements consensus.Engine, always returning an error for any 497 // uncles as this consensus mechanism doesn't permit uncles. 498 func (c *APos) VerifyUncles(chain consensus.ChainReader, block block.IBlock) error { 499 //if len(block.Uncles()) > 0 { 500 // return errors.New("uncles not allowed") 501 //} 502 return nil 503 } 504 505 // verifySeal checks whether the signature contained in the header satisfies the 506 // consensus protocol requirements. The method accepts an optional list of parent 507 // headers that aren't yet part of the local blockchain to generate the snapshots 508 // from. 509 func (c *APos) verifySeal(snap *Snapshot, h block.IHeader, parents []block.IHeader) error { 510 // Verifying the genesis block is not supported 511 header := h.(*block.Header) 512 number := header.Number.Uint64() 513 if number == 0 { 514 return errUnknownBlock 515 } 516 // Resolve the authorization key and check against signers 517 signer, err := ecrecover(header, c.signatures) 518 if err != nil { 519 return err 520 } 521 if _, ok := snap.Signers[signer]; !ok { 522 log.Infof("err signer: %s, ", signer.String()) 523 return errUnauthorizedSigner 524 } 525 for seen, recent := range snap.Recents { 526 if recent == signer { 527 // Signer is among recents, only fail if the current block doesn't shift it out 528 if limit := uint64(len(snap.Signers)/2 + 1); seen > number-limit { 529 return errRecentlySigned 530 } 531 } 532 } 533 // Ensure that the difficulty corresponds to the turn-ness of the signer 534 if !c.fakeDiff { 535 inturn := snap.inturn(header.Number.Uint64(), signer) 536 if inturn && header.Difficulty.Cmp(diffInTurn) != 0 { 537 return errWrongDifficulty 538 } 539 if !inturn && header.Difficulty.Cmp(diffNoTurn) != 0 { 540 return errWrongDifficulty 541 } 542 } 543 return nil 544 } 545 546 // Prepare implements consensus.Engine, preparing all the consensus fields of the 547 // header for running the transactions on top. 548 func (c *APos) Prepare(chain consensus.ChainHeaderReader, header block.IHeader) error { 549 rawHeader := header.(*block.Header) 550 // If the block isn't a checkpoint, cast a random vote (good enough for now) 551 rawHeader.Coinbase = types.Address{} 552 rawHeader.Nonce = block.BlockNonce{} 553 554 number := rawHeader.Number.Uint64() 555 // Assemble the voting snapshot to check which votes make sense 556 snap, err := c.snapshot(chain, number-1, rawHeader.ParentHash, nil) 557 if err != nil { 558 return err 559 } 560 c.lock.RLock() 561 if number%c.config.Epoch != 0 { 562 // Gather all the proposals that make sense voting on 563 addresses := make([]types.Address, 0, len(c.proposals)) 564 for address, authorize := range c.proposals { 565 if snap.validVote(address, authorize) { 566 addresses = append(addresses, address) 567 } 568 } 569 // If there's pending proposals, cast a vote on them 570 if len(addresses) > 0 { 571 rawHeader.Coinbase = addresses[rand.Intn(len(addresses))] 572 if c.proposals[rawHeader.Coinbase] { 573 copy(rawHeader.Nonce[:], nonceAuthVote) 574 } else { 575 copy(rawHeader.Nonce[:], nonceDropVote) 576 } 577 } 578 } 579 580 // Copy signer protected by mutex to avoid race condition 581 signer := c.signer 582 c.lock.RUnlock() 583 584 // Set the correct difficulty 585 rawHeader.Difficulty = calcDifficulty(snap, signer) 586 587 // Ensure the extra data has all its components 588 if len(rawHeader.Extra) < extraVanity { 589 rawHeader.Extra = append(rawHeader.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(rawHeader.Extra))...) 590 } 591 rawHeader.Extra = rawHeader.Extra[:extraVanity] 592 593 if number%c.config.Epoch == 0 { 594 for _, signer := range snap.signers() { 595 rawHeader.Extra = append(rawHeader.Extra, signer[:]...) 596 } 597 } 598 rawHeader.Extra = append(rawHeader.Extra, make([]byte, extraSeal)...) 599 600 // Mix digest is reserved for now, set to empty 601 rawHeader.MixDigest = types.Hash{} 602 603 // Ensure the timestamp has the correct delay 604 parent := chain.GetHeader(rawHeader.ParentHash, uint256.NewInt(0).Sub(rawHeader.Number, uint256.NewInt(1))) 605 if parent == nil { 606 return errors.New("unknown ancestor") 607 } 608 rawHeader.Time = parent.(*block.Header).Time + c.config.Period 609 if rawHeader.Time < uint64(time.Now().Unix())+mergeSignMinTime { 610 rawHeader.Time = uint64(time.Now().Unix()) + mergeSignMinTime 611 } 612 return nil 613 } 614 615 func (c *APos) Rewards(tx kv.RwTx, header block.IHeader, state *state.IntraBlockState, setRewards bool) ([]*block.Reward, error) { 616 //calc rewards 617 var rewards []*block.Reward 618 619 beijing, _ := uint256.FromBig(c.chainConfig.BeijingBlock) 620 if new(uint256.Int).Mod(new(uint256.Int).Sub(header.Number64(), beijing), uint256.NewInt(c.config.RewardEpoch)). 621 Cmp(uint256.NewInt(0)) == 0 { 622 log.Info("begin setreward", "headnumber", header.Number64().ToBig().String()) 623 624 rewardService := newReward(c.chainConfig) 625 accRewards, err := rewardService.SetRewards(tx, header.Number64(), setRewards) 626 if err != nil { 627 log.Error("setreward error", "err", err) 628 return nil, err 629 } 630 631 for _, detail := range accRewards { 632 if detail.Value.Cmp(uint256.NewInt(0)) > 0 { 633 addr := detail.Account 634 if !state.Exist(addr) { 635 state.CreateAccount(addr, false) 636 } 637 638 state.AddBalance(addr, detail.Value) 639 rewards = append(rewards, &block.Reward{ 640 Address: addr, 641 Amount: detail.Value, 642 }) 643 644 log.Debug("set rewards balance:", "addr", addr, "value", detail.Value) 645 } 646 } 647 } 648 649 return rewards, nil 650 } 651 652 // Finalize implements consensus.Engine, ensuring no uncles are set, nor block 653 // rewards given. 654 func (c *APos) Finalize(chain consensus.ChainHeaderReader, header block.IHeader, state *state.IntraBlockState, txs []*transaction.Transaction, uncles []block.IHeader) ([]*block.Reward, map[types.Address]*uint256.Int, error) { 655 // No block rewards in PoA, so the state remains as is and uncles are dropped 656 //chain.Config().IsEIP158(header.Number) 657 658 rewards, unpayMap, err := doReward(c.chainConfig, state, header.(*block.Header), chain) 659 if err != nil { 660 return nil, nil, err 661 } 662 rawHeader := header.(*block.Header) 663 rawHeader.Root = state.IntermediateRoot() 664 // Todo can not verify author 665 rawHeader.MixDigest = state.BeforeStateRoot() 666 //todo 667 //rawHeader.UncleHash = types.CalcUncleHash(nil) 668 return rewards, unpayMap, nil 669 } 670 671 // FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set, 672 // nor block rewards given, and returns the final block. 673 func (c *APos) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header block.IHeader, state *state.IntraBlockState, txs []*transaction.Transaction, uncles []block.IHeader, receipts []*block.Receipt) (block.IBlock, []*block.Reward, map[types.Address]*uint256.Int, error) { 674 // Finalize block 675 rewards, unpay, err := c.Finalize(chain, header, state, txs, uncles) 676 if nil != err { 677 return nil, nil, nil, err 678 } 679 680 // Assemble and return the final block for sealing 681 block := block.NewBlockFromReceipt(header, txs, uncles, receipts, rewards) 682 return block, rewards, unpay, nil 683 } 684 685 // Authorize injects a private key into the consensus engine to mint new blocks 686 // with. 687 // todo init 688 func (c *APos) Authorize(signer types.Address, signFn SignerFn) { 689 c.lock.Lock() 690 defer c.lock.Unlock() 691 692 c.signer = signer 693 c.signFn = signFn 694 } 695 696 // Seal implements consensus.Engine, attempting to create a sealed block using 697 // the local signing credentials. 698 func (c *APos) Seal(chain consensus.ChainHeaderReader, b block.IBlock, results chan<- block.IBlock, stop <-chan struct{}) error { 699 header := b.Header().(*block.Header) 700 701 // Sealing the genesis block is not supported 702 number := header.Number.Uint64() 703 if number == 0 { 704 return errUnknownBlock 705 } 706 // For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing) 707 if c.config.Period == 0 && len(b.Transactions()) == 0 { 708 return errors.New("sealing paused while waiting for transactions") 709 } 710 // Don't hold the signer fields for the entire sealing procedure 711 c.lock.RLock() 712 signer, signFn := c.signer, c.signFn 713 c.lock.RUnlock() 714 715 // Bail out if we're unauthorized to sign a block 716 snap, err := c.snapshot(chain, number-1, header.ParentHash, nil) 717 if err != nil { 718 return err 719 } 720 if _, authorized := snap.Signers[signer]; !authorized { 721 log.Infof("err signer: %s, ", signer.String()) 722 return errUnauthorizedSigner 723 } 724 // If we're amongst the recent signers, wait for the next block 725 for seen, recent := range snap.Recents { 726 if recent == signer { 727 // Signer is among recents, only wait if the current block doesn't shift it out 728 if limit := uint64(len(snap.Signers)/2 + 1); number < limit || seen > number-limit { 729 ///limit 1 seen 9999 number 9999- 8919 730 return errors.New(fmt.Sprintf("signed recently, must wait for others %d %d %d %s", limit, seen, number, signer.String())) 731 } 732 } 733 } 734 735 // Sweet, the protocol permits us to sign the block, wait for our time 736 delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple 737 if header.Difficulty.Cmp(diffNoTurn) == 0 { 738 wiggle := time.Duration(len(snap.Signers)/2+1) * wiggleTime 739 delay += time.Duration(rand.Int63n(int64(wiggle))) 740 741 log.Infof("wiggle %s , time %s, number %d", common.PrettyDuration(wiggle), common.PrettyDuration(delay), header.Number.Uint64()) 742 log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle)) 743 } 744 745 if c.chainConfig.IsBeijing(header.Number.Uint64()) { 746 ctx, cancle := context.WithTimeout(context.Background(), delay) 747 defer cancle() 748 member := c.CountDepositor() 749 aggSign, verifiers, err := api.SignMerge(ctx, header, member) 750 if nil != err { 751 return err 752 } 753 ss := make([]bls.PublicKey, len(verifiers)) 754 for i, p := range verifiers { 755 blsP, err := bls.PublicKeyFromBytes(p.PublicKey[:]) 756 if nil != err { 757 return err 758 } 759 ss[i] = blsP 760 } 761 762 sig, err := bls.SignatureFromBytes(aggSign[:]) 763 if nil != err { 764 return err 765 } 766 if !sig.FastAggregateVerify(ss, header.Root) { 767 return fmt.Errorf("AggSignature verify falied") 768 } 769 770 header.Signature = aggSign 771 body := b.Body().(*block.Body) 772 body.Verifiers = verifiers 773 delay = time.Unix(int64(header.Time), 0).Sub(time.Now()) 774 } 775 776 // Sign all the things! 777 sighash, err := signFn(accounts.Account{Address: signer}, accounts.MimetypeClique, APosProto(header)) 778 if err != nil { 779 return err 780 } 781 782 copy(header.Extra[len(header.Extra)-extraSeal:], sighash) 783 // Wait until sealing is terminated or delay timeout. 784 log.Debug("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay)) 785 go func() { 786 select { 787 case <-stop: 788 return 789 case <-time.After(delay): 790 } 791 792 select { 793 case results <- b.WithSeal(header): 794 default: 795 log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header)) 796 } 797 }() 798 799 return nil 800 } 801 802 // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty 803 // that a new block should have: 804 // * DIFF_NOTURN(2) if BLOCK_NUMBER % SIGNER_COUNT != SIGNER_INDEX 805 // * DIFF_INTURN(1) if BLOCK_NUMBER % SIGNER_COUNT == SIGNER_INDEX 806 func (c *APos) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent block.IHeader) *uint256.Int { 807 snap, err := c.snapshot(chain, parent.Number64().Uint64(), parent.Hash(), nil) 808 if err != nil { 809 return uint256.NewInt(0) 810 } 811 c.lock.RLock() 812 signer := c.signer 813 c.lock.RUnlock() 814 return calcDifficulty(snap, signer) 815 } 816 817 func calcDifficulty(snap *Snapshot, signer types.Address) *uint256.Int { 818 if snap.inturn(snap.Number+1, signer) { 819 return diffInTurn 820 } 821 return diffNoTurn 822 } 823 824 // SealHash returns the hash of a block prior to it being sealed. 825 func (c *APos) SealHash(header block.IHeader) types.Hash { 826 return SealHash(header) 827 } 828 829 // Close implements consensus.Engine. It's a noop for Apoa as there are no background threads. 830 func (c *APos) Close() error { 831 return nil 832 } 833 834 // APIs implements consensus.Engine, returning the user facing RPC API to allow 835 // controlling the signer voting. 836 func (c *APos) APIs(chain consensus.ChainReader) []jsonrpc.API { 837 return []jsonrpc.API{{ 838 Namespace: "apos", 839 Service: &API{chain: chain, apos: c}, 840 Authenticated: true, 841 }} 842 } 843 844 func (c *APos) Type() params.ConsensusType { 845 return params.CliqueConsensus 846 } 847 848 // SealHash returns the hash of a block prior to it being sealed. 849 func SealHash(header block.IHeader) (hash types.Hash) { 850 hasher := sha3.NewLegacyKeccak256() 851 encodeSigHeader(hasher, header) 852 hasher.(crypto.KeccakState).Read(hash[:]) 853 return hash 854 } 855 856 func APosProto(header block.IHeader) []byte { 857 b := new(bytes.Buffer) 858 encodeSigHeader(b, header) 859 return b.Bytes() 860 } 861 862 func encodeSigHeader(w io.Writer, iHeader block.IHeader) { 863 header := mvm_types.FromAmcHeader(iHeader) 864 enc := []interface{}{ 865 header.ParentHash, 866 header.UncleHash, 867 header.Coinbase, 868 header.Root, 869 header.TxHash, 870 header.ReceiptHash, 871 header.Bloom, 872 header.Difficulty, 873 header.Number, 874 header.GasLimit, 875 header.GasUsed, 876 header.Time, 877 header.Extra[:len(header.Extra)-crypto.SignatureLength], // Yes, this will panic if extra is too short 878 header.MixDigest, 879 header.Nonce, 880 } 881 if header.BaseFee != nil { 882 enc = append(enc, header.BaseFee) 883 } 884 if err := rlp.Encode(w, enc); err != nil { 885 panic("can't encode: " + err.Error()) 886 } 887 } 888 889 func (c *APos) CountDepositor() uint64 { 890 var count uint64 891 if err := c.db.View(context.Background(), func(tx kv.Tx) error { 892 var err error 893 count, err = rawdb.DepositNum(tx) 894 if nil != err { 895 return err 896 } 897 return nil 898 }); nil != err { 899 log.Errorf("rawdb.DepositNum() failed, %v", err) 900 return 0 901 } 902 return count 903 } 904 905 func (c *APos) IsServiceTransaction(sender types.Address, syscall consensus.SystemCall) bool { 906 return false 907 }