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