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  }