github.com/nnlgsakib/mind-dpos@v0.0.0-20230606105614-f3c8ca06f808/consensus/alien/alien.go (about)

     1  // Copyright 2018 The gttc Authors
     2  // This file is part of the gttc library.
     3  //
     4  // The gttc 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 gttc 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 gttc library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Package alien implements the delegated-proof-of-stake consensus engine.
    18  package alien
    19  
    20  import (
    21  	"bytes"
    22  	"errors"
    23  	"fmt"
    24  	"math/big"
    25  	"strings"
    26  	"sync"
    27  	"time"
    28  
    29  	"github.com/TTCECO/gttc/accounts"
    30  	"github.com/TTCECO/gttc/common"
    31  	"github.com/TTCECO/gttc/consensus"
    32  	"github.com/TTCECO/gttc/core/state"
    33  	"github.com/TTCECO/gttc/core/types"
    34  	"github.com/TTCECO/gttc/crypto"
    35  	"github.com/TTCECO/gttc/crypto/sha3"
    36  	"github.com/TTCECO/gttc/ethdb"
    37  	"github.com/TTCECO/gttc/log"
    38  	"github.com/TTCECO/gttc/params"
    39  	"github.com/TTCECO/gttc/rlp"
    40  	"github.com/TTCECO/gttc/rpc"
    41  	"github.com/hashicorp/golang-lru"
    42  )
    43  
    44  const (
    45  	inMemorySnapshots  = 128             // Number of recent vote snapshots to keep in memory
    46  	inMemorySignatures = 4096            // Number of recent block signatures to keep in memory
    47  	secondsPerYear     = 365 * 24 * 3600 // Number of seconds for one year
    48  	checkpointInterval = 360             // About N hours if config.period is N
    49  	scUnconfirmLoop    = 3               // First count of Loop not send confirm tx to main chain
    50  )
    51  
    52  // Alien delegated-proof-of-stake protocol constants.
    53  var (
    54  	totalBlockReward                 = new(big.Int).Mul(big.NewInt(1e+18), big.NewInt(2.5e+8)) // Block reward in wei
    55  	defaultEpochLength               = uint64(201600)                                          // Default number of blocks after which vote's period of validity, About one week if period is 3
    56  	defaultBlockPeriod               = uint64(3)                                               // Default minimum difference between two consecutive block's timestamps
    57  	defaultMaxSignerCount            = uint64(21)                                              //
    58  	minVoterBalance                  = new(big.Int).Mul(big.NewInt(100), big.NewInt(1e+18))
    59  	extraVanity                      = 32                                                    // Fixed number of extra-data prefix bytes reserved for signer vanity
    60  	extraSeal                        = 65                                                    // Fixed number of extra-data suffix bytes reserved for signer seal
    61  	uncleHash                        = types.CalcUncleHash(nil)                              // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW.
    62  	defaultDifficulty                = big.NewInt(1)                                         // Default difficulty
    63  	defaultLoopCntRecalculateSigners = uint64(10)                                            // Default loop count to recreate signers from top tally
    64  	minerRewardPerThousand           = uint64(618)                                           // Default reward for miner in each block from block reward (618/1000)
    65  	candidateNeedPD                  = false                                                 // is new candidate need Proposal & Declare process
    66  	mcNetVersion                     = uint64(0)                                             // the net version of main chain
    67  	mcLoopStartTime                  = uint64(0)                                             // the loopstarttime of main chain
    68  	mcPeriod                         = uint64(0)                                             // the period of main chain
    69  	mcSignerLength                   = uint64(0)                                             // the maxsinger of main chain config
    70  	mcNonce                          = uint64(0)                                             // the current Nonce of coinbase on main chain
    71  	mcTxDefaultGasPrice              = big.NewInt(30000000)                                  // default gas price to build transaction for main chain
    72  	mcTxDefaultGasLimit              = uint64(3000000)                                       // default limit to build transaction for main chain
    73  	proposalDeposit                  = new(big.Int).Mul(big.NewInt(1e+18), big.NewInt(1e+4)) // default current proposalDeposit
    74  	scRentLengthRecommend            = uint64(0)                                             // block number for split each side chain rent fee
    75  )
    76  
    77  // Various error messages to mark blocks invalid. These should be private to
    78  // prevent engine specific errors from being referenced in the remainder of the
    79  // codebase, inherently breaking if the engine is swapped out. Please put common
    80  // error types into the consensus package.
    81  var (
    82  	// errUnknownBlock is returned when the list of signers is requested for a block
    83  	// that is not part of the local blockchain.
    84  	errUnknownBlock = errors.New("unknown block")
    85  
    86  	// errMissingVanity is returned if a block's extra-data section is shorter than
    87  	// 32 bytes, which is required to store the signer vanity.
    88  	errMissingVanity = errors.New("extra-data 32 byte vanity prefix missing")
    89  
    90  	// errMissingSignature is returned if a block's extra-data section doesn't seem
    91  	// to contain a 65 byte secp256k1 signature.
    92  	errMissingSignature = errors.New("extra-data 65 byte suffix signature missing")
    93  
    94  	// errInvalidMixDigest is returned if a block's mix digest is non-zero.
    95  	errInvalidMixDigest = errors.New("non-zero mix digest")
    96  
    97  	// errInvalidUncleHash is returned if a block contains an non-empty uncle list.
    98  	errInvalidUncleHash = errors.New("non empty uncle hash")
    99  
   100  	// ErrInvalidTimestamp is returned if the timestamp of a block is lower than
   101  	// the previous block's timestamp + the minimum block period.
   102  	ErrInvalidTimestamp = errors.New("invalid timestamp")
   103  
   104  	// errInvalidVotingChain is returned if an authorization list is attempted to
   105  	// be modified via out-of-range or non-contiguous headers.
   106  	errInvalidVotingChain = errors.New("invalid voting chain")
   107  
   108  	// errUnauthorized is returned if a header is signed by a non-authorized entity.
   109  	errUnauthorized = errors.New("unauthorized")
   110  
   111  	// errPunishedMissing is returned if a header calculate punished signer is wrong.
   112  	errPunishedMissing = errors.New("punished signer missing")
   113  
   114  	// errWaitTransactions is returned if an empty block is attempted to be sealed
   115  	// on an instant chain (0 second period). It's important to refuse these as the
   116  	// block reward is zero, so an empty block just bloats the chain... fast.
   117  	errWaitTransactions = errors.New("waiting for transactions")
   118  
   119  	// errUnclesNotAllowed is returned if uncles exists
   120  	errUnclesNotAllowed = errors.New("uncles not allowed")
   121  
   122  	// errCreateSignerQueueNotAllowed is returned if called in (block number + 1) % maxSignerCount != 0
   123  	errCreateSignerQueueNotAllowed = errors.New("create signer queue not allowed")
   124  
   125  	// errInvalidSignerQueue is returned if verify SignerQueue fail
   126  	errInvalidSignerQueue = errors.New("invalid signer queue")
   127  
   128  	// errSignerQueueEmpty is returned if no signer when calculate
   129  	errSignerQueueEmpty = errors.New("signer queue is empty")
   130  
   131  	// errGetLastLoopInfoFail is returned if get last loop info fail
   132  	errGetLastLoopInfoFail = errors.New("get last loop info fail")
   133  
   134  	// errInvalidNeighborSigner is returned if two neighbor block signed by same miner and time diff less period
   135  	errInvalidNeighborSigner = errors.New("invalid neighbor signer")
   136  
   137  	// errMissingGenesisLightConfig is returned only in light syncmode if light config missing
   138  	errMissingGenesisLightConfig = errors.New("light config in genesis is missing")
   139  
   140  	// errLastLoopHeaderFail is returned when try to get header of last loop fail
   141  	errLastLoopHeaderFail = errors.New("get last loop header fail")
   142  )
   143  
   144  // Alien is the delegated-proof-of-stake consensus engine.
   145  type Alien struct {
   146  	config     *params.AlienConfig // Consensus engine configuration parameters
   147  	db         ethdb.Database      // Database to store and retrieve snapshot checkpoints
   148  	recents    *lru.ARCCache       // Snapshots for recent block to speed up reorgs
   149  	signatures *lru.ARCCache       // Signatures of recent blocks to speed up mining
   150  	signer     common.Address      // Ethereum address of the signing key
   151  	signFn     SignerFn            // Signer function to authorize hashes with
   152  	signTxFn   SignTxFn            // Sign transaction function to sign tx
   153  	lock       sync.RWMutex        // Protects the signer fields
   154  	lcsc       uint64              // Last confirmed side chain
   155  }
   156  
   157  // SignerFn is a signer callback function to request a hash to be signed by a
   158  // backing account.
   159  type SignerFn func(accounts.Account, []byte) ([]byte, error)
   160  
   161  // SignTxFn is a signTx
   162  type SignTxFn func(accounts.Account, *types.Transaction, *big.Int) (*types.Transaction, error)
   163  
   164  // sigHash returns the hash which is used as input for the delegated-proof-of-stake
   165  // signing. It is the hash of the entire header apart from the 65 byte signature
   166  // contained at the end of the extra data.
   167  //
   168  // Note, the method requires the extra data to be at least 65 bytes, otherwise it
   169  // panics. This is done to avoid accidentally using both forms (signature present
   170  // or not), which could be abused to produce different hashes for the same header.
   171  func sigHash(header *types.Header) (hash common.Hash, err error) {
   172  	hasher := sha3.NewKeccak256()
   173  	if err := rlp.Encode(hasher, []interface{}{
   174  		header.ParentHash,
   175  		header.UncleHash,
   176  		header.Coinbase,
   177  		header.Root,
   178  		header.TxHash,
   179  		header.ReceiptHash,
   180  		header.Bloom,
   181  		header.Difficulty,
   182  		header.Number,
   183  		header.GasLimit,
   184  		header.GasUsed,
   185  		header.Time,
   186  		header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short
   187  		header.MixDigest,
   188  		header.Nonce,
   189  	}); err != nil {
   190  		return common.Hash{}, err
   191  	}
   192  
   193  	hasher.Sum(hash[:0])
   194  	return hash, nil
   195  }
   196  
   197  // ecrecover extracts the Ethereum account address from a signed header.
   198  func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
   199  	// If the signature's already cached, return that
   200  	hash := header.Hash()
   201  	if address, known := sigcache.Get(hash); known {
   202  		return address.(common.Address), nil
   203  	}
   204  	// Retrieve the signature from the header extra-data
   205  	if len(header.Extra) < extraSeal {
   206  		return common.Address{}, errMissingSignature
   207  	}
   208  	signature := header.Extra[len(header.Extra)-extraSeal:]
   209  
   210  	// Recover the public key and the Ethereum address
   211  	headerSigHash, err := sigHash(header)
   212  	if err != nil {
   213  		return common.Address{}, err
   214  	}
   215  	pubkey, err := crypto.Ecrecover(headerSigHash.Bytes(), signature)
   216  	if err != nil {
   217  		return common.Address{}, err
   218  	}
   219  	var signer common.Address
   220  	copy(signer[:], crypto.Keccak256(pubkey[1:])[12:])
   221  
   222  	sigcache.Add(hash, signer)
   223  	return signer, nil
   224  }
   225  
   226  // New creates a Alien delegated-proof-of-stake consensus engine with the initial
   227  // signers set to the ones provided by the user.
   228  func New(config *params.AlienConfig, db ethdb.Database) *Alien {
   229  	// Set any missing consensus parameters to their defaults
   230  	conf := *config
   231  	if conf.Epoch == 0 {
   232  		conf.Epoch = defaultEpochLength
   233  	}
   234  	if conf.Period == 0 {
   235  		conf.Period = defaultBlockPeriod
   236  	}
   237  	if conf.MaxSignerCount == 0 {
   238  		conf.MaxSignerCount = defaultMaxSignerCount
   239  	}
   240  	if conf.MinVoterBalance.Uint64() > 0 {
   241  		minVoterBalance = conf.MinVoterBalance
   242  	}
   243  
   244  	// Allocate the snapshot caches and create the engine
   245  	recents, _ := lru.NewARC(inMemorySnapshots)
   246  	signatures, _ := lru.NewARC(inMemorySignatures)
   247  
   248  	return &Alien{
   249  		config:     &conf,
   250  		db:         db,
   251  		recents:    recents,
   252  		signatures: signatures,
   253  	}
   254  }
   255  
   256  // Author implements consensus.Engine, returning the Ethereum address recovered
   257  // from the signature in the header's extra-data section.
   258  func (a *Alien) Author(header *types.Header) (common.Address, error) {
   259  	return ecrecover(header, a.signatures)
   260  }
   261  
   262  // VerifyHeader checks whether a header conforms to the consensus rules.
   263  func (a *Alien) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
   264  	return a.verifyHeader(chain, header, nil)
   265  }
   266  
   267  // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The
   268  // method returns a quit channel to abort the operations and a results channel to
   269  // retrieve the async verifications (the order is that of the input slice).
   270  func (a *Alien) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
   271  	abort := make(chan struct{})
   272  	results := make(chan error, len(headers))
   273  
   274  	go func() {
   275  		for i, header := range headers {
   276  			err := a.verifyHeader(chain, header, headers[:i])
   277  
   278  			select {
   279  			case <-abort:
   280  				return
   281  			case results <- err:
   282  			}
   283  		}
   284  	}()
   285  	return abort, results
   286  }
   287  
   288  // verifyHeader checks whether a header conforms to the consensus rules.The
   289  // caller may optionally pass in a batch of parents (ascending order) to avoid
   290  // looking those up from the database. This is useful for concurrently verifying
   291  // a batch of new headers.
   292  func (a *Alien) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   293  	if header.Number == nil {
   294  		return errUnknownBlock
   295  	}
   296  
   297  	// Don't waste time checking blocks from the future
   298  	if header.Time.Cmp(big.NewInt(time.Now().Unix())) > 0 {
   299  		return consensus.ErrFutureBlock
   300  	}
   301  
   302  	// Check that the extra-data contains both the vanity and signature
   303  	if len(header.Extra) < extraVanity {
   304  		return errMissingVanity
   305  	}
   306  	if len(header.Extra) < extraVanity+extraSeal {
   307  		return errMissingSignature
   308  	}
   309  
   310  	// Ensure that the mix digest is zero as we don't have fork protection currently
   311  	if header.MixDigest != (common.Hash{}) {
   312  		return errInvalidMixDigest
   313  	}
   314  	// Ensure that the block doesn't contain any uncles which are meaningless in PoA
   315  	if header.UncleHash != uncleHash {
   316  		return errInvalidUncleHash
   317  	}
   318  
   319  	// All basic checks passed, verify cascading fields
   320  	return a.verifyCascadingFields(chain, header, parents)
   321  }
   322  
   323  // verifyCascadingFields verifies all the header fields that are not standalone,
   324  // rather depend on a batch of previous headers. The caller may optionally pass
   325  // in a batch of parents (ascending order) to avoid looking those up from the
   326  // database. This is useful for concurrently verifying a batch of new headers.
   327  func (a *Alien) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   328  	// The genesis block is the always valid dead-end
   329  	number := header.Number.Uint64()
   330  	if number == 0 {
   331  		return nil
   332  	}
   333  	// Ensure that the block's timestamp isn't too close to it's parent
   334  	var parent *types.Header
   335  	if len(parents) > 0 {
   336  		parent = parents[len(parents)-1]
   337  	} else {
   338  		parent = chain.GetHeader(header.ParentHash, number-1)
   339  	}
   340  	if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash {
   341  		return consensus.ErrUnknownAncestor
   342  	}
   343  	if parent.Time.Uint64() > header.Time.Uint64() {
   344  		return ErrInvalidTimestamp
   345  	}
   346  	// Retrieve the snapshot needed to verify this header and cache it
   347  	_, err := a.snapshot(chain, number-1, header.ParentHash, parents, nil, defaultLoopCntRecalculateSigners)
   348  	if err != nil {
   349  		return err
   350  	}
   351  
   352  	// All basic checks passed, verify the seal and return
   353  	return a.verifySeal(chain, header, parents)
   354  }
   355  
   356  // snapshot retrieves the authorization snapshot at a given point in time.
   357  func (a *Alien) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header, genesisVotes []*Vote, lcrs uint64) (*Snapshot, error) {
   358  	// Don't keep snapshot for side chain
   359  	//if chain.Config().Alien.SideChain {
   360  	//	return nil, nil
   361  	//}
   362  	// Search for a snapshot in memory or on disk for checkpoints
   363  	var (
   364  		headers []*types.Header
   365  		snap    *Snapshot
   366  	)
   367  
   368  	for snap == nil {
   369  		// If an in-memory snapshot was found, use that
   370  		if s, ok := a.recents.Get(hash); ok {
   371  			snap = s.(*Snapshot)
   372  			break
   373  		}
   374  		// If an on-disk checkpoint snapshot can be found, use that
   375  		if number%checkpointInterval == 0 {
   376  			if s, err := loadSnapshot(a.config, a.signatures, a.db, hash); err == nil {
   377  				log.Trace("Loaded voting snapshot from disk", "number", number, "hash", hash)
   378  				snap = s
   379  				break
   380  			}
   381  		}
   382  		// If we're at block zero, make a snapshot
   383  		if number == 0 {
   384  			genesis := chain.GetHeaderByNumber(0)
   385  			if err := a.VerifyHeader(chain, genesis, false); err != nil {
   386  				return nil, err
   387  			}
   388  			a.config.Period = chain.Config().Alien.Period
   389  			snap = newSnapshot(a.config, a.signatures, genesis.Hash(), genesisVotes, lcrs)
   390  			if err := snap.store(a.db); err != nil {
   391  				return nil, err
   392  			}
   393  			log.Trace("Stored genesis voting snapshot to disk")
   394  			break
   395  		}
   396  		// No snapshot for this header, gather the header and move backward
   397  		var header *types.Header
   398  		if len(parents) > 0 {
   399  			// If we have explicit parents, pick from there (enforced)
   400  			header = parents[len(parents)-1]
   401  			if header.Hash() != hash || header.Number.Uint64() != number {
   402  				return nil, consensus.ErrUnknownAncestor
   403  			}
   404  			parents = parents[:len(parents)-1]
   405  		} else {
   406  			// No explicit parents (or no more left), reach out to the database
   407  			header = chain.GetHeader(hash, number)
   408  			if header == nil {
   409  				return nil, consensus.ErrUnknownAncestor
   410  			}
   411  		}
   412  		headers = append(headers, header)
   413  		number, hash = number-1, header.ParentHash
   414  	}
   415  	// Previous snapshot found, apply any pending headers on top of it
   416  	for i := 0; i < len(headers)/2; i++ {
   417  		headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i]
   418  	}
   419  
   420  	snap, err := snap.apply(headers)
   421  	if err != nil {
   422  		return nil, err
   423  	}
   424  
   425  	a.recents.Add(snap.Hash, snap)
   426  
   427  	// If we've generated a new checkpoint snapshot, save to disk
   428  	if snap.Number%checkpointInterval == 0 && len(headers) > 0 {
   429  		if err = snap.store(a.db); err != nil {
   430  			return nil, err
   431  		}
   432  		log.Trace("Stored voting snapshot to disk", "number", snap.Number, "hash", snap.Hash)
   433  	}
   434  	return snap, err
   435  }
   436  
   437  // VerifyUncles implements consensus.Engine, always returning an error for any
   438  // uncles as this consensus mechanism doesn't permit uncles.
   439  func (a *Alien) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
   440  	if len(block.Uncles()) > 0 {
   441  		return errUnclesNotAllowed
   442  	}
   443  	return nil
   444  }
   445  
   446  // VerifySeal implements consensus.Engine, checking whether the signature contained
   447  // in the header satisfies the consensus protocol requirements.
   448  func (a *Alien) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
   449  	return a.verifySeal(chain, header, nil)
   450  }
   451  
   452  // verifySeal checks whether the signature contained in the header satisfies the
   453  // consensus protocol requirements. The method accepts an optional list of parent
   454  // headers that aren't yet part of the local blockchain to generate the snapshots
   455  // from.
   456  func (a *Alien) verifySeal(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   457  	// Verifying the genesis block is not supported
   458  	number := header.Number.Uint64()
   459  	if number == 0 {
   460  		return errUnknownBlock
   461  	}
   462  	// Retrieve the snapshot needed to verify this header and cache it
   463  	snap, err := a.snapshot(chain, number-1, header.ParentHash, parents, nil, defaultLoopCntRecalculateSigners)
   464  	if err != nil {
   465  		return err
   466  	}
   467  
   468  	// Resolve the authorization key and check against signers
   469  	signer, err := ecrecover(header, a.signatures)
   470  	if err != nil {
   471  		return err
   472  	}
   473  
   474  	// check the coinbase == signer
   475  	if header.Number.Cmp(big.NewInt(bugFixBlockNumber)) > 0 {
   476  		if signer != header.Coinbase {
   477  			return errUnauthorized
   478  		}
   479  	}
   480  
   481  	if !chain.Config().Alien.SideChain {
   482  
   483  		if number > a.config.MaxSignerCount {
   484  			var parent *types.Header
   485  			if len(parents) > 0 {
   486  				parent = parents[len(parents)-1]
   487  			} else {
   488  				parent = chain.GetHeader(header.ParentHash, number-1)
   489  			}
   490  			parentHeaderExtra := HeaderExtra{}
   491  			err = decodeHeaderExtra(a.config, parent.Number, parent.Extra[extraVanity:len(parent.Extra)-extraSeal], &parentHeaderExtra)
   492  			if err != nil {
   493  				log.Info("Fail to decode parent header", "err", err)
   494  				return err
   495  			}
   496  			currentHeaderExtra := HeaderExtra{}
   497  			err = decodeHeaderExtra(a.config, header.Number, header.Extra[extraVanity:len(header.Extra)-extraSeal], &currentHeaderExtra)
   498  			if err != nil {
   499  				log.Info("Fail to decode header", "err", err)
   500  				return err
   501  			}
   502  			// verify signerqueue
   503  			if number%a.config.MaxSignerCount == 0 {
   504  				err := snap.verifySignerQueue(currentHeaderExtra.SignerQueue)
   505  				if err != nil {
   506  					return err
   507  				}
   508  
   509  			} else {
   510  				for i := 0; i < int(a.config.MaxSignerCount); i++ {
   511  					if parentHeaderExtra.SignerQueue[i] != currentHeaderExtra.SignerQueue[i] {
   512  						return errInvalidSignerQueue
   513  					}
   514  				}
   515  				if signer == parent.Coinbase && header.Time.Uint64()-parent.Time.Uint64() < chain.Config().Alien.Period {
   516  					return errInvalidNeighborSigner
   517  				}
   518  
   519  			}
   520  
   521  			// verify missing signer for punish
   522  			var parentSignerMissing []common.Address
   523  			if a.config.IsTrantor(header.Number) {
   524  				var grandParentHeaderExtra HeaderExtra
   525  				if number%a.config.MaxSignerCount == 1 {
   526  					var grandParent *types.Header
   527  					if len(parents) > 1 {
   528  						grandParent = parents[len(parents)-2]
   529  					} else {
   530  						grandParent = chain.GetHeader(parent.ParentHash, number-2)
   531  					}
   532  					if grandParent == nil {
   533  						return errLastLoopHeaderFail
   534  					}
   535  					err := decodeHeaderExtra(a.config, grandParent.Number, grandParent.Extra[extraVanity:len(grandParent.Extra)-extraSeal], &grandParentHeaderExtra)
   536  					if err != nil {
   537  						log.Info("Fail to decode parent header", "err", err)
   538  						return err
   539  					}
   540  				}
   541  				parentSignerMissing = getSignerMissingTrantor(parent.Coinbase, header.Coinbase, &parentHeaderExtra, &grandParentHeaderExtra)
   542  			} else {
   543  				newLoop := false
   544  				if number%a.config.MaxSignerCount == 0 {
   545  					newLoop = true
   546  				}
   547  				parentSignerMissing = getSignerMissing(parent.Coinbase, header.Coinbase, parentHeaderExtra, newLoop)
   548  			}
   549  
   550  			if len(parentSignerMissing) != len(currentHeaderExtra.SignerMissing) {
   551  				return errPunishedMissing
   552  			}
   553  			for i, signerMissing := range currentHeaderExtra.SignerMissing {
   554  				if parentSignerMissing[i] != signerMissing {
   555  					return errPunishedMissing
   556  				}
   557  			}
   558  		}
   559  
   560  		if !snap.inturn(signer, header.Time.Uint64()) {
   561  			return errUnauthorized
   562  		}
   563  	} else {
   564  		if notice, loopStartTime, period, signerLength, _, err := a.mcSnapshot(chain, signer, header.Time.Uint64()); err != nil {
   565  			return err
   566  		} else {
   567  			mcLoopStartTime = loopStartTime
   568  			mcPeriod = period
   569  			mcSignerLength = signerLength
   570  			// check gas charging
   571  			if notice != nil {
   572  				currentHeaderExtra := HeaderExtra{}
   573  				err = decodeHeaderExtra(a.config, header.Number, header.Extra[extraVanity:len(header.Extra)-extraSeal], &currentHeaderExtra)
   574  				if err != nil {
   575  					return err
   576  				}
   577  				if len(notice.CurrentCharging) != len(currentHeaderExtra.SideChainCharging) {
   578  					return errMCGasChargingInvalid
   579  				} else {
   580  					for _, charge := range currentHeaderExtra.SideChainCharging {
   581  						if v, ok := notice.CurrentCharging[charge.Hash]; !ok {
   582  							return err
   583  						} else {
   584  							if v.Volume != charge.Volume || v.Target != charge.Target {
   585  								return errMCGasChargingInvalid
   586  							}
   587  						}
   588  					}
   589  				}
   590  
   591  			}
   592  		}
   593  	}
   594  
   595  	return nil
   596  }
   597  
   598  // Prepare implements consensus.Engine, preparing all the consensus fields of the
   599  // header for running the transactions on top.
   600  func (a *Alien) Prepare(chain consensus.ChainReader, header *types.Header) error {
   601  
   602  	// Set the correct difficulty
   603  	header.Difficulty = new(big.Int).Set(defaultDifficulty)
   604  	number := header.Number.Uint64()
   605  	// Ensure the timestamp has the correct delay
   606  	parent := chain.GetHeader(header.ParentHash, number-1)
   607  	if parent == nil {
   608  		return  consensus.ErrUnknownAncestor
   609  	}
   610  	header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(a.config.Period))
   611  	if header.Time.Int64() < time.Now().Unix() {
   612  		header.Time = big.NewInt(time.Now().Unix())
   613  	}
   614  	// If now is later than genesis timestamp, skip prepare
   615  	if a.config.GenesisTimestamp < uint64(time.Now().Unix()) {
   616  		return nil
   617  	}
   618  	// Count down for start
   619  	if header.Number.Uint64() == 1 {
   620  		for {
   621  			delay := time.Unix(int64(a.config.GenesisTimestamp-2), 0).Sub(time.Now())
   622  			if delay <= time.Duration(0) {
   623  				log.Info("Ready for seal block", "time", time.Now())
   624  				break
   625  			} else if delay > time.Duration(a.config.Period)*time.Second {
   626  				delay = time.Duration(a.config.Period) * time.Second
   627  			}
   628  			log.Info("Waiting for seal block", "delay", common.PrettyDuration(time.Unix(int64(a.config.GenesisTimestamp-2), 0).Sub(time.Now())))
   629  			select {
   630  			case <-time.After(delay):
   631  				continue
   632  			}
   633  		}
   634  	}
   635  
   636  	return nil
   637  }
   638  
   639  // get the snapshot info from main chain and check if current signer inturn, if inturn then update the info
   640  func (a *Alien) mcSnapshot(chain consensus.ChainReader, signer common.Address, headerTime uint64) (*CCNotice, uint64, uint64, uint64, uint64, error) {
   641  
   642  	if chain.Config().Alien.SideChain {
   643  		chainHash := chain.GetHeaderByNumber(0).ParentHash
   644  		ms, err := a.getMainChainSnapshotByTime(chain, headerTime, chainHash)
   645  		if err != nil {
   646  			return nil, 0, 0, 0, 0, err
   647  		} else if len(ms.Signers) == 0 {
   648  			return nil, 0, 0, 0, 0, errSignerQueueEmpty
   649  		} else if ms.Period == 0 {
   650  			return nil, 0, 0, 0, 0, errMCPeriodMissing
   651  		}
   652  
   653  		loopIndex := int((headerTime-ms.LoopStartTime)/ms.Period) % len(ms.Signers)
   654  		if loopIndex >= len(ms.Signers) {
   655  			return nil, 0, 0, 0, 0, errInvalidSignerQueue
   656  		} else if *ms.Signers[loopIndex] != signer {
   657  			return nil, 0, 0, 0, 0, errUnauthorized
   658  		}
   659  		notice := &CCNotice{}
   660  		if mcNotice, ok := ms.SCNoticeMap[chainHash]; ok {
   661  			notice = mcNotice
   662  		}
   663  		return notice, ms.LoopStartTime, ms.Period, uint64(len(ms.Signers)), ms.Number, nil
   664  	}
   665  	return nil, 0, 0, 0, 0, errNotSideChain
   666  }
   667  
   668  func (a *Alien) parseNoticeInfo(notice *CCNotice) string {
   669  	// if other notice exist, return string may be more than one
   670  	if notice != nil {
   671  		var charging []string
   672  		for hash := range notice.CurrentCharging {
   673  			charging = append(charging, hash.Hex())
   674  		}
   675  		return strings.Join(charging, "#")
   676  	}
   677  	return ""
   678  }
   679  
   680  func (a *Alien) getLastLoopInfo(chain consensus.ChainReader, header *types.Header) (string, error) {
   681  	if chain.Config().Alien.SideChain && mcLoopStartTime != 0 && mcPeriod != 0 && a.config.Period != 0 {
   682  		var loopHeaderInfo []string
   683  		inLastLoop := false
   684  		extraTime := (header.Time.Uint64() - mcLoopStartTime) % (mcPeriod * mcSignerLength)
   685  		for i := uint64(0); i < a.config.MaxSignerCount*2*(mcPeriod/a.config.Period); i++ {
   686  			header = chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
   687  			if header == nil {
   688  				return "", consensus.ErrUnknownAncestor
   689  			}
   690  			newTime := (header.Time.Uint64() - mcLoopStartTime) % (mcPeriod * mcSignerLength)
   691  			if newTime > extraTime {
   692  				if !inLastLoop {
   693  					inLastLoop = true
   694  				} else {
   695  					break
   696  				}
   697  			}
   698  			extraTime = newTime
   699  			if inLastLoop {
   700  				loopHeaderInfo = append(loopHeaderInfo, fmt.Sprintf("%d#%s", header.Number.Uint64(), header.Coinbase.Hex()))
   701  			}
   702  		}
   703  		if len(loopHeaderInfo) > 0 {
   704  			return strings.Join(loopHeaderInfo, "#"), nil
   705  		}
   706  	}
   707  	return "", errGetLastLoopInfoFail
   708  }
   709  
   710  func (a *Alien) mcConfirmBlock(chain consensus.ChainReader, header *types.Header, notice *CCNotice) {
   711  
   712  	a.lock.RLock()
   713  	signer, signTxFn := a.signer, a.signTxFn
   714  	a.lock.RUnlock()
   715  
   716  	if signer != (common.Address{}) {
   717  		// todo update gaslimit , gasprice ,and get ChainID need to get from mainchain
   718  		if header.Number.Uint64() > a.lcsc && header.Number.Uint64() > a.config.MaxSignerCount*scUnconfirmLoop {
   719  			nonce, err := a.getTransactionCountFromMainChain(chain, signer)
   720  			if err != nil {
   721  				log.Info("Confirm tx sign fail", "err", err)
   722  				return
   723  			}
   724  
   725  			lastLoopInfo, err := a.getLastLoopInfo(chain, header)
   726  			if err != nil {
   727  				log.Info("Confirm tx sign fail", "err", err)
   728  				return
   729  			}
   730  
   731  			chargingInfo := a.parseNoticeInfo(notice)
   732  
   733  			txData := a.buildSCEventConfirmData(chain.GetHeaderByNumber(0).ParentHash, header.Number, header.Time, lastLoopInfo, chargingInfo)
   734  			tx := types.NewTransaction(nonce, header.Coinbase, big.NewInt(0), mcTxDefaultGasLimit, mcTxDefaultGasPrice, txData)
   735  
   736  			if mcNetVersion == 0 {
   737  				mcNetVersion, err = a.getNetVersionFromMainChain(chain)
   738  				if err != nil {
   739  					log.Info("Query main chain net version fail", "err", err)
   740  				}
   741  			}
   742  
   743  			signedTx, err := signTxFn(accounts.Account{Address: signer}, tx, big.NewInt(int64(mcNetVersion)))
   744  			if err != nil {
   745  				log.Info("Confirm tx sign fail", "err", err)
   746  			}
   747  			txHash, err := a.sendTransactionToMainChain(chain, signedTx)
   748  			if err != nil {
   749  				log.Info("Confirm tx send fail", "err", err)
   750  			} else {
   751  				log.Info("Confirm tx result", "txHash", txHash)
   752  				a.lcsc = header.Number.Uint64()
   753  			}
   754  		}
   755  	}
   756  
   757  }
   758  
   759  // Finalize implements consensus.Engine, ensuring no uncles are set, nor block
   760  // rewards given, and returns the final block.
   761  func (a *Alien) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
   762  
   763  
   764  	// Mix digest is reserved for now, set to empty
   765  	header.MixDigest = common.Hash{}
   766  	number := header.Number.Uint64()
   767  	parent := chain.GetHeader(header.ParentHash, number-1)
   768  	if parent == nil {
   769  		return nil, consensus.ErrUnknownAncestor
   770  	}
   771  
   772  
   773  	// Ensure the extra data has all it's components
   774  	if len(header.Extra) < extraVanity {
   775  		header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...)
   776  	}
   777  	header.Extra = header.Extra[:extraVanity]
   778  
   779  	// genesisVotes write direct into snapshot, which number is 1
   780  	var genesisVotes []*Vote
   781  	parentHeaderExtra := HeaderExtra{}
   782  	currentHeaderExtra := HeaderExtra{}
   783  
   784  	if number == 1 {
   785  		alreadyVote := make(map[common.Address]struct{})
   786  		for _, unPrefixVoter := range a.config.SelfVoteSigners {
   787  			voter := common.Address(unPrefixVoter)
   788  			if _, ok := alreadyVote[voter]; !ok {
   789  				genesisVotes = append(genesisVotes, &Vote{
   790  					Voter:     voter,
   791  					Candidate: voter,
   792  					Stake:     state.GetBalance(voter),
   793  				})
   794  				alreadyVote[voter] = struct{}{}
   795  			}
   796  		}
   797  	} else {
   798  		// decode extra from last header.extra
   799  		err := decodeHeaderExtra(a.config, parent.Number, parent.Extra[extraVanity:len(parent.Extra)-extraSeal], &parentHeaderExtra)
   800  		if err != nil {
   801  			log.Info("Fail to decode parent header", "err", err)
   802  			return nil, err
   803  		}
   804  		currentHeaderExtra.ConfirmedBlockNumber = parentHeaderExtra.ConfirmedBlockNumber
   805  		currentHeaderExtra.SignerQueue = parentHeaderExtra.SignerQueue
   806  		currentHeaderExtra.LoopStartTime = parentHeaderExtra.LoopStartTime
   807  
   808  		if a.config.IsTrantor(header.Number) {
   809  			var grandParentHeaderExtra HeaderExtra
   810  			if number%a.config.MaxSignerCount == 1 {
   811  				grandParent := chain.GetHeader(parent.ParentHash, number-2)
   812  				if grandParent == nil {
   813  					return nil, errLastLoopHeaderFail
   814  				}
   815  				err := decodeHeaderExtra(a.config, grandParent.Number, grandParent.Extra[extraVanity:len(grandParent.Extra)-extraSeal], &grandParentHeaderExtra)
   816  				if err != nil {
   817  					log.Info("Fail to decode parent header", "err", err)
   818  					return nil, err
   819  				}
   820  			}
   821  			currentHeaderExtra.SignerMissing = getSignerMissingTrantor(parent.Coinbase, header.Coinbase, &parentHeaderExtra, &grandParentHeaderExtra)
   822  		} else {
   823  			newLoop := false
   824  			if number%a.config.MaxSignerCount == 0 {
   825  				newLoop = true
   826  			}
   827  			currentHeaderExtra.SignerMissing = getSignerMissing(parent.Coinbase, header.Coinbase, parentHeaderExtra, newLoop)
   828  		}
   829  
   830  	}
   831  
   832  	// Assemble the voting snapshot to check which votes make sense
   833  	snap, err := a.snapshot(chain, number-1, header.ParentHash, nil, genesisVotes, defaultLoopCntRecalculateSigners)
   834  	if err != nil {
   835  		return nil, err
   836  	}
   837  	if !chain.Config().Alien.SideChain {
   838  		// calculate votes write into header.extra
   839  		mcCurrentHeaderExtra, refundGas, err := a.processCustomTx(currentHeaderExtra, chain, header, state, txs, receipts)
   840  		if err != nil {
   841  			return nil, err
   842  		}
   843  		currentHeaderExtra = mcCurrentHeaderExtra
   844  		currentHeaderExtra.ConfirmedBlockNumber = snap.getLastConfirmedBlockNumber(currentHeaderExtra.CurrentBlockConfirmations).Uint64()
   845  		// write signerQueue in first header, from self vote signers in genesis block
   846  		if number == 1 {
   847  			currentHeaderExtra.LoopStartTime = a.config.GenesisTimestamp
   848  			if len(a.config.SelfVoteSigners) > 0 {
   849  				for i := 0; i < int(a.config.MaxSignerCount); i++ {
   850  					currentHeaderExtra.SignerQueue = append(currentHeaderExtra.SignerQueue, common.Address(a.config.SelfVoteSigners[i%len(a.config.SelfVoteSigners)]))
   851  				}
   852  			}
   853  		} else if number%a.config.MaxSignerCount == 0 {
   854  			//currentHeaderExtra.LoopStartTime = header.Time.Uint64()
   855  			currentHeaderExtra.LoopStartTime = currentHeaderExtra.LoopStartTime + a.config.Period*a.config.MaxSignerCount
   856  			// create random signersQueue in currentHeaderExtra by snapshot.Tally
   857  			currentHeaderExtra.SignerQueue = []common.Address{}
   858  			newSignerQueue, err := snap.createSignerQueue()
   859  			if err != nil {
   860  				return nil, err
   861  			}
   862  			currentHeaderExtra.SignerQueue = newSignerQueue
   863  		}
   864  
   865  		// Accumulate any block rewards and commit the final state root
   866  		if err := accumulateRewards(chain.Config(), state, header, snap, refundGas); err != nil {
   867  			return nil, errUnauthorized
   868  		}
   869  	} else {
   870  		// use currentHeaderExtra.SignerQueue as signer queue
   871  		currentHeaderExtra.SignerQueue = append([]common.Address{header.Coinbase}, parentHeaderExtra.SignerQueue...)
   872  		if len(currentHeaderExtra.SignerQueue) > int(a.config.MaxSignerCount) {
   873  			currentHeaderExtra.SignerQueue = currentHeaderExtra.SignerQueue[:int(a.config.MaxSignerCount)]
   874  		}
   875  		sideChainRewards(chain.Config(), state, header, snap)
   876  	}
   877  	// encode header.extra
   878  	currentHeaderExtraEnc, err := encodeHeaderExtra(a.config, header.Number, currentHeaderExtra)
   879  	if err != nil {
   880  		return nil, err
   881  	}
   882  
   883  	header.Extra = append(header.Extra, currentHeaderExtraEnc...)
   884  	header.Extra = append(header.Extra, make([]byte, extraSeal)...)
   885  
   886  	// Set the correct difficulty
   887  	header.Difficulty = new(big.Int).Set(defaultDifficulty)
   888  
   889  	header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   890  	// No uncle block
   891  	header.UncleHash = types.CalcUncleHash(nil)
   892  
   893  	// Assemble and return the final block for sealing
   894  	return types.NewBlock(header, txs, nil, receipts), nil
   895  }
   896  
   897  // Authorize injects a private key into the consensus engine to mint new blocks with.
   898  func (a *Alien) Authorize(signer common.Address, signFn SignerFn, signTxFn SignTxFn) {
   899  	a.lock.Lock()
   900  	defer a.lock.Unlock()
   901  
   902  	a.signer = signer
   903  	a.signFn = signFn
   904  	a.signTxFn = signTxFn
   905  }
   906  
   907  // ApplyGenesis
   908  func (a *Alien) ApplyGenesis(chain consensus.ChainReader, genesisHash common.Hash) error {
   909  	if a.config.LightConfig != nil {
   910  		var genesisVotes []*Vote
   911  		alreadyVote := make(map[common.Address]struct{})
   912  		for _, unPrefixVoter := range a.config.SelfVoteSigners {
   913  			voter := common.Address(unPrefixVoter)
   914  			if genesisAccount, ok := a.config.LightConfig.Alloc[unPrefixVoter]; ok {
   915  				if _, ok := alreadyVote[voter]; !ok {
   916  					stake := new(big.Int)
   917  					stake.UnmarshalText([]byte(genesisAccount.Balance))
   918  					genesisVotes = append(genesisVotes, &Vote{
   919  						Voter:     voter,
   920  						Candidate: voter,
   921  						Stake:     stake,
   922  					})
   923  					alreadyVote[voter] = struct{}{}
   924  				}
   925  			}
   926  		}
   927  		// Assemble the voting snapshot to check which votes make sense
   928  		if _, err := a.snapshot(chain, 0, genesisHash, nil, genesisVotes, defaultLoopCntRecalculateSigners); err != nil {
   929  			return err
   930  		}
   931  		return nil
   932  	}
   933  	return errMissingGenesisLightConfig
   934  }
   935  
   936  // Seal implements consensus.Engine, attempting to create a sealed block using
   937  // the local signing credentials.
   938  func (a *Alien) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) {
   939  	header := block.Header()
   940  
   941  	// Sealing the genesis block is not supported
   942  	number := header.Number.Uint64()
   943  	if number == 0 {
   944  		return nil, errUnknownBlock
   945  	}
   946  
   947  	// For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
   948  	if a.config.Period == 0 && len(block.Transactions()) == 0 {
   949  		return nil, errWaitTransactions
   950  	}
   951  	// Don't hold the signer fields for the entire sealing procedure
   952  	a.lock.RLock()
   953  	signer, signFn := a.signer, a.signFn
   954  	a.lock.RUnlock()
   955  
   956  	// Bail out if we're unauthorized to sign a block
   957  	snap, err := a.snapshot(chain, number-1, header.ParentHash, nil, nil, defaultLoopCntRecalculateSigners)
   958  	if err != nil {
   959  		return nil, err
   960  	}
   961  
   962  	if !chain.Config().Alien.SideChain {
   963  		if !snap.inturn(signer, header.Time.Uint64()) {
   964  			<-stop
   965  			return nil, errUnauthorized
   966  		}
   967  	} else {
   968  		if notice, loopStartTime, period, signerLength, _, err := a.mcSnapshot(chain, signer, header.Time.Uint64()); err != nil {
   969  			<-stop
   970  			return nil, err
   971  		} else {
   972  			mcLoopStartTime = loopStartTime
   973  			mcPeriod = period
   974  			mcSignerLength = signerLength
   975  			if notice != nil {
   976  				// rebuild the header.Extra for gas charging
   977  				currentHeaderExtra := HeaderExtra{}
   978  				if err = decodeHeaderExtra(a.config, header.Number, header.Extra[extraVanity:len(header.Extra)-extraSeal], &currentHeaderExtra); err != nil {
   979  					return nil, err
   980  				}
   981  				for _, charge := range notice.CurrentCharging {
   982  					currentHeaderExtra.SideChainCharging = append(currentHeaderExtra.SideChainCharging, charge)
   983  				}
   984  				currentHeaderExtraEnc, err := encodeHeaderExtra(a.config, header.Number, currentHeaderExtra)
   985  				if err != nil {
   986  					return nil, err
   987  				}
   988  				header.Extra = header.Extra[:extraVanity]
   989  				header.Extra = append(header.Extra, currentHeaderExtraEnc...)
   990  				header.Extra = append(header.Extra, make([]byte, extraSeal)...)
   991  			}
   992  			// send tx to main chain to confirm this block
   993  			a.mcConfirmBlock(chain, header, notice)
   994  		}
   995  	}
   996  
   997  	// correct the time
   998  	delay := time.Unix(header.Time.Int64(), 0).Sub(time.Now())
   999  
  1000  	select {
  1001  	case <-stop:
  1002  		return nil, nil
  1003  	case <-time.After(delay):
  1004  	}
  1005  
  1006  	// Sign all the things!
  1007  	headerSigHash, err := sigHash(header)
  1008  	if err != nil {
  1009  		return nil, err
  1010  	}
  1011  
  1012  	sighash, err := signFn(accounts.Account{Address: signer}, headerSigHash.Bytes())
  1013  	if err != nil {
  1014  		return nil, err
  1015  	}
  1016  
  1017  	copy(header.Extra[len(header.Extra)-extraSeal:], sighash)
  1018  
  1019  	return block.WithSeal(header), nil
  1020  }
  1021  
  1022  // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
  1023  // that a new block should have based on the previous blocks in the chain and the
  1024  // current signer.
  1025  func (a *Alien) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
  1026  
  1027  	return new(big.Int).Set(defaultDifficulty)
  1028  }
  1029  
  1030  // APIs implements consensus.Engine, returning the user facing RPC API to allow
  1031  // controlling the signer voting.
  1032  func (a *Alien) APIs(chain consensus.ChainReader) []rpc.API {
  1033  	return []rpc.API{{
  1034  		Namespace: "alien",
  1035  		Version:   ufoVersion,
  1036  		Service:   &API{chain: chain, alien: a},
  1037  		Public:    false,
  1038  	}}
  1039  }
  1040  
  1041  func sideChainRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, snap *Snapshot) {
  1042  	// vanish gas fee
  1043  	gasUsed := new(big.Int).SetUint64(header.GasUsed)
  1044  	if state.GetBalance(header.Coinbase).Cmp(gasUsed) >= 0 {
  1045  		state.SubBalance(header.Coinbase, gasUsed)
  1046  	}
  1047  	// gas charging
  1048  	for target, volume := range snap.calculateGasCharging() {
  1049  		state.AddBalance(target, volume)
  1050  	}
  1051  }
  1052  
  1053  // AccumulateRewards credits the coinbase of the given block with the mining reward.
  1054  func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, snap *Snapshot, refundGas RefundGas) error {
  1055  	// Calculate the block reword by year
  1056  	blockNumPerYear := secondsPerYear / config.Alien.Period
  1057  	initSignerBlockReward := new(big.Int).Div(totalBlockReward, big.NewInt(int64(2*blockNumPerYear)))
  1058  	yearCount := header.Number.Uint64() / blockNumPerYear
  1059  	blockReward := new(big.Int).Rsh(initSignerBlockReward, uint(yearCount))
  1060  
  1061  	minerReward := new(big.Int).Set(blockReward)
  1062  	minerReward.Mul(minerReward, new(big.Int).SetUint64(snap.MinerReward))
  1063  	minerReward.Div(minerReward, big.NewInt(1000)) // cause the reward is calculate by cnt per thousand
  1064  
  1065  	votersReward := blockReward.Sub(blockReward, minerReward)
  1066  
  1067  	// rewards for the voters
  1068  	voteRewardMap, err := snap.calculateVoteReward(header.Coinbase, votersReward)
  1069  	if err != nil {
  1070  		return err
  1071  	}
  1072  	for voter, reward := range voteRewardMap {
  1073  		state.AddBalance(voter, reward)
  1074  	}
  1075  
  1076  	// calculate for proposal refund
  1077  	for proposer, refund := range snap.calculateProposalRefund() {
  1078  		state.AddBalance(proposer, refund)
  1079  	}
  1080  
  1081  	scReward, minerLeft := snap.calculateSCReward(minerReward)
  1082  	minerReward.Set(minerLeft)
  1083  	// rewards for the side chain coinbase
  1084  	for scCoinbase, reward := range scReward {
  1085  		state.AddBalance(scCoinbase, reward)
  1086  	}
  1087  	// refund gas for custom txs
  1088  	for sender, gas := range refundGas {
  1089  		state.AddBalance(sender, gas)
  1090  		minerReward.Sub(minerReward, gas)
  1091  	}
  1092  
  1093  	// rewards for the miner, check minerReward value for refund gas
  1094  	if minerReward.Cmp(big.NewInt(0)) > 0 {
  1095  		state.AddBalance(header.Coinbase, minerReward)
  1096  	}
  1097  
  1098  	return nil
  1099  }
  1100  
  1101  // Get the signer missing from last signer till header.Coinbase
  1102  func getSignerMissing(lastSigner common.Address, currentSigner common.Address, extra HeaderExtra, newLoop bool) []common.Address {
  1103  
  1104  	var signerMissing []common.Address
  1105  
  1106  	if newLoop {
  1107  		for i, qlen := 0, len(extra.SignerQueue); i < len(extra.SignerQueue); i++ {
  1108  			if lastSigner == extra.SignerQueue[qlen-1-i] {
  1109  				break
  1110  			} else {
  1111  				signerMissing = append(signerMissing, extra.SignerQueue[qlen-1-i])
  1112  			}
  1113  		}
  1114  	} else {
  1115  		recordMissing := false
  1116  		for _, signer := range extra.SignerQueue {
  1117  			if signer == lastSigner {
  1118  				recordMissing = true
  1119  				continue
  1120  			}
  1121  			if signer == currentSigner {
  1122  				break
  1123  			}
  1124  			if recordMissing {
  1125  				signerMissing = append(signerMissing, signer)
  1126  			}
  1127  		}
  1128  
  1129  	}
  1130  
  1131  	return signerMissing
  1132  }
  1133  
  1134  // Get the signer missing from last signer till header.Coinbase
  1135  func getSignerMissingTrantor(lastSigner common.Address, currentSigner common.Address, extra *HeaderExtra, gpExtra *HeaderExtra) []common.Address {
  1136  
  1137  	var signerMissing []common.Address
  1138  	signerQueue := append(extra.SignerQueue, extra.SignerQueue...)
  1139  	if gpExtra != nil {
  1140  		for i, v := range gpExtra.SignerQueue {
  1141  			if v == lastSigner {
  1142  				signerQueue[i] = lastSigner
  1143  				signerQueue = signerQueue[i:]
  1144  				break
  1145  			}
  1146  		}
  1147  	}
  1148  
  1149  	recordMissing := false
  1150  	for _, signer := range signerQueue {
  1151  		if !recordMissing && signer == lastSigner {
  1152  			recordMissing = true
  1153  			continue
  1154  		}
  1155  		if recordMissing && signer == currentSigner {
  1156  			break
  1157  		}
  1158  		if recordMissing {
  1159  			signerMissing = append(signerMissing, signer)
  1160  		}
  1161  	}
  1162  
  1163  	return signerMissing
  1164  
  1165  }