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  }