github.com/Gessiux/neatchain@v1.3.1/chain/consensus/neatcon/engine.go (about)

     1  package neatcon
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"math/big"
     8  	"time"
     9  
    10  	"github.com/Gessiux/go-wire"
    11  	"github.com/Gessiux/neatchain/chain/consensus"
    12  	"github.com/Gessiux/neatchain/chain/consensus/neatcon/epoch"
    13  	ntcTypes "github.com/Gessiux/neatchain/chain/consensus/neatcon/types"
    14  	"github.com/Gessiux/neatchain/chain/core/state"
    15  	"github.com/Gessiux/neatchain/chain/core/types"
    16  	"github.com/Gessiux/neatchain/network/rpc"
    17  	"github.com/Gessiux/neatchain/params"
    18  	"github.com/Gessiux/neatchain/utilities/common"
    19  	lru "github.com/hashicorp/golang-lru"
    20  )
    21  
    22  const (
    23  	// fetcherID is the ID indicates the block is from NeatCon engine
    24  	fetcherID = "neatcon"
    25  )
    26  
    27  var (
    28  	// errInvalidProposal is returned when a prposal is malformed.
    29  	errInvalidProposal = errors.New("invalid proposal")
    30  	// errInvalidSignature is returned when given signature is not signed by given
    31  	// address.
    32  	errInvalidSignature = errors.New("invalid signature")
    33  	// errUnknownBlock is returned when the list of validators is requested for a block
    34  	// that is not part of the local blockchain.
    35  	errUnknownBlock = errors.New("unknown block")
    36  	// errUnauthorized is returned if a header is signed by a non authorized entity.
    37  	errUnauthorized = errors.New("unauthorized")
    38  	// errInvalidDifficulty is returned if the difficulty of a block is not 1
    39  	errInvalidDifficulty = errors.New("invalid difficulty")
    40  	// errInvalidExtraDataFormat is returned when the extra data format is incorrect
    41  	errInvalidExtraDataFormat = errors.New("invalid extra data format")
    42  	// errInvalidMixDigest is returned if a block's mix digest is not Istanbul digest.
    43  	errInvalidMixDigest = errors.New("invalid NeatCon mix digest")
    44  	// errInvalidNonce is returned if a block's nonce is invalid
    45  	errInvalidNonce = errors.New("invalid nonce")
    46  	// errInvalidUncleHash is returned if a block contains an non-empty uncle list.
    47  	errInvalidUncleHash = errors.New("non empty uncle hash")
    48  	// errInconsistentValidatorSet is returned if the validator set is inconsistent
    49  	errInconsistentValidatorSet = errors.New("inconsistent validator set")
    50  	// errInvalidTimestamp is returned if the timestamp of a block is lower than the previous block's timestamp + the minimum block period.
    51  	errInvalidTimestamp = errors.New("invalid timestamp")
    52  	// errInvalidVotingChain is returned if an authorization list is attempted to
    53  	// be modified via out-of-range or non-contiguous headers.
    54  	errInvalidVotingChain = errors.New("invalid voting chain")
    55  	// errInvalidVote is returned if a nonce value is something else that the two
    56  	// allowed constants of 0x00..0 or 0xff..f.
    57  	errInvalidVote = errors.New("vote nonce not 0x00..0 or 0xff..f")
    58  	// errInvalidCommittedSeals is returned if the committed seal is not signed by any of parent validators.
    59  	errInvalidCommittedSeals = errors.New("invalid committed seals")
    60  	// errEmptyCommittedSeals is returned if the field of committed seals is zero.
    61  	errEmptyCommittedSeals = errors.New("zero committed seals")
    62  	// errMismatchTxhashes is returned if the TxHash in header is mismatch.
    63  	errMismatchTxhashes = errors.New("mismatch transactions hashes")
    64  
    65  	// errInvalidMainChainNumber is returned when side chain block doesn't contain the valid main chain height
    66  	errInvalidMainChainNumber = errors.New("invalid Main Chain Height")
    67  	// errMainChainNotCatchup is returned if side chain wait more than 300 seconds for main chain to catch up
    68  	errMainChainNotCatchup = errors.New("unable proceed the block due to main chain not catch up by waiting for more than 300 seconds, please catch up the main chain first")
    69  )
    70  
    71  var (
    72  	now = time.Now
    73  
    74  	inmemoryAddresses  = 20 // Number of recent addresses from ecrecover
    75  	recentAddresses, _ = lru.NewARC(inmemoryAddresses)
    76  
    77  	_ consensus.Engine = (*backend)(nil)
    78  
    79  	// Address for Side Chain Reward
    80  	sideChainRewardAddress = common.StringToAddress("NEAToND9QsiAFbMan5tqVg899qAv2EsQ")
    81  )
    82  
    83  // APIs returns the RPC APIs this consensus engine provides.
    84  func (sb *backend) APIs(chain consensus.ChainReader) []rpc.API {
    85  	return []rpc.API{{
    86  		Namespace: "neat",
    87  		Version:   "1.0",
    88  		Service:   &API{chain: chain, neatcon: sb},
    89  		Public:    true,
    90  	}}
    91  }
    92  
    93  // Start implements consensus.NeatCon.Start
    94  func (sb *backend) Start(chain consensus.ChainReader, currentBlock func() *types.Block, hasBadBlock func(hash common.Hash) bool) error {
    95  
    96  	sb.logger.Info("NeatCon backend Start")
    97  
    98  	sb.coreMu.Lock()
    99  	defer sb.coreMu.Unlock()
   100  	if sb.coreStarted {
   101  		return ErrStartedEngine
   102  	}
   103  
   104  	// clear previous data
   105  	sb.proposedBlockHash = common.Hash{}
   106  	if sb.commitCh != nil {
   107  		close(sb.commitCh)
   108  	}
   109  	sb.commitCh = make(chan *types.Block, 1)
   110  	if sb.vcommitCh != nil {
   111  		close(sb.vcommitCh)
   112  	}
   113  	sb.vcommitCh = make(chan *ntcTypes.IntermediateBlockResult, 1)
   114  
   115  	sb.chain = chain
   116  	fmt.Printf("neatcon backend start chain %v\n", chain)
   117  	sb.currentBlock = currentBlock
   118  	sb.hasBadBlock = hasBadBlock
   119  
   120  	if _, err := sb.core.Start(); err != nil {
   121  		return err
   122  	}
   123  
   124  	sb.coreStarted = true
   125  
   126  	return nil
   127  }
   128  
   129  // Stop implements consensus.NeatCon.Stop
   130  func (sb *backend) Stop() error {
   131  
   132  	sb.logger.Info("NeatCon backend stop")
   133  
   134  	//debug.PrintStack()
   135  
   136  	sb.coreMu.Lock()
   137  	defer sb.coreMu.Unlock()
   138  	if !sb.coreStarted {
   139  		return ErrStoppedEngine
   140  	}
   141  	if !sb.core.Stop() {
   142  		return errors.New("neatcon stop error")
   143  	}
   144  	sb.coreStarted = false
   145  
   146  	return nil
   147  }
   148  
   149  func (sb *backend) Close() error {
   150  	sb.core.epochDB.Close()
   151  	return nil
   152  }
   153  
   154  // Author retrieves the Ethereum address of the account that minted the given
   155  // block, which may be different from the header's coinbase if a consensus
   156  // engine is based on signatures.
   157  func (sb *backend) Author(header *types.Header) (common.Address, error) {
   158  	return header.Coinbase, nil
   159  }
   160  
   161  // VerifyHeader checks whether a header conforms to the consensus rules of a
   162  // given engine. Verifying the seal may be done optionally here, or explicitly
   163  // via the VerifySeal method.
   164  func (sb *backend) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
   165  
   166  	sb.logger.Info("Your node is synchronized. This is Neat!")
   167  
   168  	return sb.verifyHeader(chain, header, nil)
   169  }
   170  
   171  // verifyHeader checks whether a header conforms to the consensus rules.The
   172  // caller may optionally pass in a batch of parents (ascending order) to avoid
   173  // looking those up from the database. This is useful for concurrently verifying
   174  // a batch of new headers.
   175  func (sb *backend) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   176  
   177  	if header.Number == nil {
   178  		return errUnknownBlock
   179  	}
   180  
   181  	//if header.Number.Uint64() == 0 {
   182  	//	return nil // Ignore verify for genesis block
   183  	//}
   184  
   185  	// Don't waste time checking blocks from the future
   186  	if header.Time.Cmp(big.NewInt(now().Unix())) > 0 {
   187  		sb.logger.Warnf("date/time different between different nodes. block from future with time:%v, bigger than now:%v", header.Time.Uint64(), now().Unix())
   188  		//in neatchain, avoid the time difference to tolerate time gap between nodes
   189  		//return consensus.ErrFutureBlock
   190  	}
   191  
   192  	// Ensure that the extra data format is satisfied
   193  	if _, err := ntcTypes.ExtractNeatConExtra(header); err != nil {
   194  		return errInvalidExtraDataFormat
   195  	}
   196  
   197  	// Ensure that the coinbase is valid
   198  	if header.Nonce != (types.NeatConEmptyNonce) && !bytes.Equal(header.Nonce[:], types.NeatConNonce) {
   199  		return errInvalidNonce
   200  	}
   201  	// Ensure that the mix digest is zero as we don't have fork protection currently
   202  	if header.MixDigest != types.NeatConDigest {
   203  		return errInvalidMixDigest
   204  	}
   205  	// Ensure that the block doesn't contain any uncles which are meaningless in Istanbul
   206  	if header.UncleHash != types.NeatConNilUncleHash {
   207  		return errInvalidUncleHash
   208  	}
   209  	// Ensure that the block's difficulty is meaningful (may not be correct at this point)
   210  	if header.Difficulty == nil || header.Difficulty.Cmp(types.NeatConDefaultDifficulty) != 0 {
   211  		return errInvalidDifficulty
   212  	}
   213  
   214  	// In case of Epoch switch, we have to wait for the Epoch switched first, then verify the following fields
   215  	if header.Number.Uint64() > sb.GetEpoch().EndBlock {
   216  		for {
   217  			duration := 2 * time.Second
   218  			sb.logger.Infof("NeatCon VerifyHeader, Epoch Switch, wait for %v then try again", duration)
   219  			time.Sleep(duration)
   220  
   221  			if header.Number.Uint64() <= sb.GetEpoch().EndBlock {
   222  				break
   223  			}
   224  		}
   225  	}
   226  
   227  	if fieldError := sb.verifyCascadingFields(chain, header, parents); fieldError != nil {
   228  		return fieldError
   229  	}
   230  
   231  	// Check the MainChainNumber if on Side Chain
   232  	if !sb.chainConfig.IsMainChain() {
   233  		if header.MainChainNumber == nil {
   234  			return errInvalidMainChainNumber
   235  		}
   236  
   237  		tried := 0
   238  		for {
   239  			// Check our main chain has already run ahead
   240  			ourMainChainHeight := sb.core.cch.GetHeightFromMainChain()
   241  			if ourMainChainHeight.Cmp(header.MainChainNumber) >= 0 {
   242  				break
   243  			}
   244  
   245  			if tried == 10 {
   246  				sb.logger.Warnf("NeatCon VerifyHeader, Main Chain Number mismatch, after retried %d times", tried)
   247  				return errMainChainNotCatchup
   248  			}
   249  
   250  			// Sleep for a while and check again
   251  			duration := 30 * time.Second
   252  			tried++
   253  			sb.logger.Infof("NeatCon VerifyHeader, Main Chain Number mismatch, wait for %v then try again (count %d)", duration, tried)
   254  			time.Sleep(duration)
   255  		}
   256  	}
   257  
   258  	return nil
   259  }
   260  
   261  // verifyCascadingFields verifies all the header fields that are not standalone,
   262  // rather depend on a batch of previous headers. The caller may optionally pass
   263  // in a batch of parents (ascending order) to avoid looking those up from the
   264  // database. This is useful for concurrently verifying a batch of new headers.
   265  func (sb *backend) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   266  	// The genesis block is the always valid dead-end
   267  
   268  	number := header.Number.Uint64()
   269  	if number == 0 {
   270  		return nil
   271  	}
   272  	// Ensure that the block's timestamp isn't too close to it's parent
   273  	var parent *types.Header
   274  	if len(parents) > 0 {
   275  		parent = parents[len(parents)-1]
   276  	} else {
   277  		parent = chain.GetHeader(header.ParentHash, number-1)
   278  	}
   279  	if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash {
   280  		return consensus.ErrUnknownAncestor
   281  	}
   282  
   283  	err := sb.verifyCommittedSeals(chain, header, parents)
   284  	return err
   285  }
   286  
   287  func (sb *backend) VerifyHeaderBeforeConsensus(chain consensus.ChainReader, header *types.Header, seal bool) error {
   288  	sb.logger.Info("NeatCon backend verify header before consensus")
   289  
   290  	if header.Number == nil {
   291  		return errUnknownBlock
   292  	}
   293  
   294  	// Don't waste time checking blocks from the future
   295  	if header.Time.Cmp(big.NewInt(now().Unix())) > 0 {
   296  		sb.logger.Warnf("date/time different between different nodes. block from future with time:%v, bigger than now:%v", header.Time.Uint64(), now().Unix())
   297  		//in neatchain, avoid the time difference to tolerate time gap between nodes
   298  		//return consensus.ErrFutureBlock
   299  	}
   300  
   301  	// Ensure that the coinbase is valid
   302  	if header.Nonce != (types.NeatConEmptyNonce) && !bytes.Equal(header.Nonce[:], types.NeatConNonce) {
   303  		return errInvalidNonce
   304  	}
   305  	// Ensure that the mix digest is zero as we don't have fork protection currently
   306  	if header.MixDigest != types.NeatConDigest {
   307  		return errInvalidMixDigest
   308  	}
   309  	// Ensure that the block doesn't contain any uncles which are meaningless in Istanbul
   310  	if header.UncleHash != types.NeatConNilUncleHash {
   311  		return errInvalidUncleHash
   312  	}
   313  	// Ensure that the block's difficulty is meaningful (may not be correct at this point)
   314  	if header.Difficulty == nil || header.Difficulty.Cmp(types.NeatConDefaultDifficulty) != 0 {
   315  		return errInvalidDifficulty
   316  	}
   317  
   318  	return nil
   319  }
   320  
   321  // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
   322  // concurrently. The method returns a quit channel to abort the operations and
   323  // a results channel to retrieve the async verifications (the order is that of
   324  // the input slice).
   325  func (sb *backend) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
   326  	abort := make(chan struct{})
   327  	results := make(chan error, len(headers))
   328  
   329  	//sb.logger.Info("NeatCon is verifying headers")
   330  
   331  	go func() {
   332  		for i, header := range headers {
   333  			err := sb.verifyHeader(chain, header, headers[:i])
   334  			select {
   335  			case <-abort:
   336  				return
   337  			case results <- err:
   338  			}
   339  		}
   340  	}()
   341  
   342  	return abort, results
   343  }
   344  
   345  // VerifyUncles verifies that the given block's uncles conform to the consensus
   346  // rules of a given engine.
   347  func (sb *backend) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
   348  
   349  	if len(block.Uncles()) > 0 {
   350  		return errInvalidUncleHash
   351  	}
   352  	return nil
   353  }
   354  
   355  // verifyCommittedSeals checks whether every committed seal is signed by one of the parent's validators
   356  func (sb *backend) verifyCommittedSeals(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
   357  
   358  	ncExtra, err := ntcTypes.ExtractNeatConExtra(header)
   359  	if err != nil {
   360  		return errInvalidExtraDataFormat
   361  	}
   362  
   363  	epoch := sb.core.consensusState.Epoch
   364  	if epoch == nil || epoch.Validators == nil {
   365  		sb.logger.Errorf("verifyCommittedSeals error. Epoch %v", epoch)
   366  		return errInconsistentValidatorSet
   367  	}
   368  
   369  	epoch = epoch.GetEpochByBlockNumber(header.Number.Uint64())
   370  	if epoch == nil || epoch.Validators == nil {
   371  		sb.logger.Errorf("verifyCommittedSeals error. Epoch %v", epoch)
   372  		return errInconsistentValidatorSet
   373  	}
   374  
   375  	valSet := epoch.Validators
   376  	if !bytes.Equal(valSet.Hash(), ncExtra.ValidatorsHash) {
   377  		sb.logger.Errorf("verifyCommittedSeals error. Our Validator Set %x, ncExtra Valdiator %x", valSet.Hash(), ncExtra.ValidatorsHash)
   378  		sb.logger.Errorf("verifyCommittedSeals error. epoch validator set %v, extra data %v", valSet.String(), ncExtra.String())
   379  		return errInconsistentValidatorSet
   380  	}
   381  
   382  	seenCommit := ncExtra.SeenCommit
   383  	if !bytes.Equal(ncExtra.SeenCommitHash, seenCommit.Hash()) {
   384  		sb.logger.Errorf("verifyCommittedSeals SeenCommit is %#+v", seenCommit)
   385  		sb.logger.Errorf("verifyCommittedSeals error. Our SeenCommitHash %x, ncExtra SeenCommitHash %x", seenCommit.Hash(), ncExtra.SeenCommitHash)
   386  		return errInvalidCommittedSeals
   387  	}
   388  
   389  	if err = valSet.VerifyCommit(ncExtra.ChainID, ncExtra.Height, seenCommit); err != nil {
   390  		sb.logger.Errorf("verifyCommittedSeals verify commit err %v", err)
   391  		return errInvalidSignature
   392  	}
   393  
   394  	return nil
   395  }
   396  
   397  // VerifySeal checks whether the crypto seal on a header is valid according to
   398  // the consensus rules of the given engine.
   399  func (sb *backend) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
   400  	// get parent header and ensure the signer is in parent's validator set
   401  	number := header.Number.Uint64()
   402  	if number == 0 {
   403  		return errUnknownBlock
   404  	}
   405  
   406  	// ensure that the difficulty equals to defaultDifficulty
   407  	if header.Difficulty.Cmp(types.NeatConDefaultDifficulty) != 0 {
   408  		return errInvalidDifficulty
   409  	}
   410  
   411  	return nil
   412  }
   413  
   414  // Prepare initializes the consensus fields of a block header according to the
   415  // rules of a particular engine. The changes are executed inline.
   416  func (sb *backend) Prepare(chain consensus.ChainReader, header *types.Header) error {
   417  
   418  	header.Nonce = types.NeatConEmptyNonce
   419  	header.MixDigest = types.NeatConDigest
   420  
   421  	// copy the parent extra data as the header extra data
   422  	number := header.Number.Uint64()
   423  	parent := chain.GetHeader(header.ParentHash, number-1)
   424  	if parent == nil {
   425  		return consensus.ErrUnknownAncestor
   426  	}
   427  	// use the same difficulty for all blocks
   428  	header.Difficulty = types.NeatConDefaultDifficulty
   429  
   430  	// add validators in snapshot to extraData's validators section
   431  	extra, err := prepareExtra(header, nil)
   432  	if err != nil {
   433  		return err
   434  	}
   435  	header.Extra = extra
   436  
   437  	// set header's timestamp
   438  	//header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(sb.config.BlockPeriod))
   439  	//if header.Time.Int64() < time.Now().Unix() {
   440  	header.Time = big.NewInt(time.Now().Unix())
   441  	//}
   442  
   443  	// Add Main Chain Height if running on Side Chain
   444  	if sb.chainConfig.NeatChainId != params.MainnetChainConfig.NeatChainId && sb.chainConfig.NeatChainId != params.TestnetChainConfig.NeatChainId {
   445  		header.MainChainNumber = sb.core.cch.GetHeightFromMainChain()
   446  	}
   447  
   448  	return nil
   449  }
   450  
   451  // Finalize runs any post-transaction state modifications (e.g. block rewards)
   452  // and assembles the final block.
   453  //
   454  // Note, the block header and state database might be updated to reflect any
   455  // consensus rules that happen at finalization (e.g. block rewards).
   456  func (sb *backend) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
   457  	totalGasFee *big.Int, uncles []*types.Header, receipts []*types.Receipt, ops *types.PendingOps) (*types.Block, error) {
   458  
   459  	sb.logger.Debugf("NeatCon Finalize, receipts are: %v", receipts)
   460  
   461  	// Check if any Side Chain need to be launch and Update their account balance accordingly
   462  	if sb.chainConfig.NeatChainId == params.MainnetChainConfig.NeatChainId || sb.chainConfig.NeatChainId == params.TestnetChainConfig.NeatChainId {
   463  		// Check the Side Chain Start
   464  		readyId, updateBytes, removedId := sb.core.cch.ReadyForLaunchSideChain(header.Number, state)
   465  		if len(readyId) > 0 || updateBytes != nil || len(removedId) > 0 {
   466  			if ok := ops.Append(&types.LaunchSideChainsOp{
   467  				SideChainIds:       readyId,
   468  				NewPendingIdx:      updateBytes,
   469  				DeleteSideChainIds: removedId,
   470  			}); !ok {
   471  				// This should not happened
   472  				sb.logger.Error("NeatCon Finalize, Fail to append LaunchSideChainsOp, only one LaunchSideChainsOp is allowed in each block")
   473  			}
   474  		}
   475  	}
   476  
   477  	curBlockNumber := header.Number.Uint64()
   478  	epoch := sb.GetEpoch().GetEpochByBlockNumber(curBlockNumber)
   479  
   480  	// Calculate the rewards
   481  	accumulateRewards(sb.chainConfig, state, header, epoch, totalGasFee)
   482  
   483  	// update validator status include participating consensus block times and forbidden
   484  	if header.Number.Uint64() > 1 {
   485  		//TODO use chain instead of sb.chain
   486  		prevHeader := chain.GetHeaderByNumber(header.Number.Uint64() - 1)
   487  		if prevHeader != nil {
   488  			extra, err := ntcTypes.ExtractNeatConExtra(prevHeader)
   489  			if err == nil {
   490  				epoch.UpdateForbiddenState(header, prevHeader, extra.SeenCommit, state)
   491  			}
   492  		}
   493  	}
   494  
   495  	// Check the Epoch switch and update their account balance accordingly (Refund the Locked Balance)
   496  	if ok, newValidators, _ := epoch.ShouldEnterNewEpoch(header.Number.Uint64(), state); ok {
   497  		ops.Append(&ntcTypes.SwitchEpochOp{
   498  			ChainId:       sb.chainConfig.NeatChainId,
   499  			NewValidators: newValidators,
   500  		})
   501  
   502  	}
   503  
   504  	header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   505  	header.UncleHash = types.NeatConNilUncleHash
   506  	// Assemble and return the final block for sealing
   507  	return types.NewBlock(header, txs, nil, receipts), nil
   508  }
   509  
   510  // Seal generates a new block for the given input block with the local miner's
   511  // seal place on top.
   512  func (sb *backend) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (interface{}, error) {
   513  
   514  	sb.logger.Info("NeatCon backend seal")
   515  	// update the block header timestamp and signature and propose the block to core engine
   516  	header := block.Header()
   517  	number := header.Number.Uint64()
   518  	parent := chain.GetHeader(header.ParentHash, number-1)
   519  	if parent == nil {
   520  		return nil, consensus.ErrUnknownAncestor
   521  	}
   522  	block, err := sb.updateBlock(parent, block)
   523  	if err != nil {
   524  		return nil, err
   525  	}
   526  	// wait for the timestamp of header, use this to adjust the block period
   527  	delay := time.Unix(block.Header().Time.Int64(), 0).Sub(now())
   528  	select {
   529  	case <-time.After(delay):
   530  	case <-stop:
   531  		return nil, nil
   532  	}
   533  	// get the proposed block hash and clear it if the seal() is completed.
   534  	sb.sealMu.Lock()
   535  	sb.proposedBlockHash = block.Hash()
   536  	clear := func() {
   537  		sb.proposedBlockHash = common.Hash{}
   538  		sb.sealMu.Unlock()
   539  	}
   540  	defer clear()
   541  
   542  	// post block into NeatCon engine
   543  	sb.logger.Infof("NeatCon Seal, before fire event with block height: %d", block.NumberU64())
   544  	go ntcTypes.FireEventRequest(sb.core.EventSwitch(), ntcTypes.EventDataRequest{Proposal: block})
   545  	//go sb.EventMux().Post(ntcTypes.RequestEvent{
   546  	//	Proposal: block,
   547  	//})
   548  
   549  	for {
   550  		select {
   551  		case result, ok := <-sb.commitCh:
   552  
   553  			if ok {
   554  				sb.logger.Debugf("NeatCon Seal, got result with block.Hash: %x, result.Hash: %x", block.Hash(), result.Hash())
   555  				// if the block hash and the hash from channel are the same,
   556  				// return the result. Otherwise, keep waiting the next hash.
   557  				if block.Hash() == result.Hash() {
   558  					return result, nil
   559  				}
   560  				sb.logger.Debug("NeatCon Seal, hash are different")
   561  			} else {
   562  				sb.logger.Debug("NeatCon Seal, has been restart, just return")
   563  				return nil, nil
   564  			}
   565  
   566  		case iresult, ok := <-sb.vcommitCh:
   567  
   568  			if ok {
   569  				sb.logger.Debugf("NeatCon Seal, v got result with block.Hash: %x, result.Hash: %x", block.Hash(), iresult.Block.Hash())
   570  				if block.Hash() != iresult.Block.Hash() {
   571  					return iresult, nil
   572  				}
   573  				sb.logger.Debug("NeatCon Seal, v hash are the same")
   574  			} else {
   575  				sb.logger.Debug("NeatCon Seal, v has been restart, just return")
   576  				return nil, nil
   577  			}
   578  
   579  		case <-stop:
   580  			sb.logger.Debug("NeatCon Seal, stop")
   581  			return nil, nil
   582  		}
   583  	}
   584  
   585  	return nil, nil
   586  }
   587  
   588  // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
   589  // that a new block should have based on the previous blocks in the chain and the
   590  // current signer.
   591  func (sb *backend) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
   592  
   593  	return types.NeatConDefaultDifficulty
   594  }
   595  
   596  // Commit implements istanbul.Backend.Commit
   597  func (sb *backend) Commit(proposal *ntcTypes.NCBlock, seals [][]byte, isProposer func() bool) error {
   598  	// Check if the proposal is a valid block
   599  	block := proposal.Block
   600  
   601  	h := block.Header()
   602  	// Append seals into extra-data
   603  	err := writeCommittedSeals(h, proposal.NTCExtra)
   604  	if err != nil {
   605  		return err
   606  	}
   607  	// update block's header
   608  	block = block.WithSeal(h)
   609  
   610  	sb.logger.Debugf("NeatCon Commit, hash: %x, number: %v", block.Hash(), block.Number().Int64())
   611  	sb.logger.Debugf("NeatCon Commit, block: %s", block.String())
   612  
   613  	// - if the proposed and committed blocks are the same, send the proposed hash
   614  	//   to commit channel, which is being watched inside the engine.Seal() function.
   615  	// - otherwise, we try to insert the block.
   616  	// -- if success, the ChainHeadEvent event will be broadcasted, try to build
   617  	//    the next block and the previous Seal() will be stopped.
   618  	// -- otherwise, a error will be returned and a round change event will be fired.
   619  	if isProposer() && (sb.proposedBlockHash == block.Hash()) { // for proposer
   620  		// feed block hash to Seal() and wait the Seal() result
   621  		sb.logger.Debugf("NeatCon Commit, proposer | feed to Seal: %x", block.Hash())
   622  		sb.commitCh <- block
   623  		return nil
   624  	} else { // for other validators
   625  		if proposal.IntermediateResult != nil {
   626  			sb.logger.Debugf("NeatCon Commit, validator | feed to Seal: %x", block.Hash())
   627  			proposal.IntermediateResult.Block = block
   628  			sb.vcommitCh <- proposal.IntermediateResult
   629  		} else {
   630  			sb.logger.Debugf("NeatCon Commit, validator | fetcher enqueue: %x", block.Hash())
   631  			if sb.broadcaster != nil {
   632  				sb.broadcaster.Enqueue(fetcherID, block)
   633  			}
   634  		}
   635  		return nil
   636  	}
   637  }
   638  
   639  // Stop implements consensus.Istanbul.Stop
   640  func (sb *backend) ChainReader() consensus.ChainReader {
   641  
   642  	return sb.chain
   643  }
   644  
   645  func (sb *backend) ShouldStart() bool {
   646  	return sb.shouldStart
   647  }
   648  
   649  func (sb *backend) IsStarted() bool {
   650  	sb.coreMu.RLock()
   651  	start := sb.coreStarted
   652  	sb.coreMu.RUnlock()
   653  
   654  	return start
   655  }
   656  
   657  func (sb *backend) ForceStart() {
   658  	sb.shouldStart = true
   659  }
   660  
   661  // GetEpoch Get Epoch from NeatCon Engine
   662  func (sb *backend) GetEpoch() *epoch.Epoch {
   663  	return sb.core.consensusState.Epoch
   664  }
   665  
   666  // SetEpoch Set Epoch to NeatCon Engine
   667  func (sb *backend) SetEpoch(ep *epoch.Epoch) {
   668  	sb.core.consensusState.Epoch = ep
   669  }
   670  
   671  // Return the private validator address of consensus
   672  func (sb *backend) PrivateValidator() common.Address {
   673  	if sb.core.privValidator != nil {
   674  		return sb.core.privValidator.Address
   675  	}
   676  	return common.Address{}
   677  }
   678  
   679  // update timestamp and signature of the block based on its number of transactions
   680  func (sb *backend) updateBlock(parent *types.Header, block *types.Block) (*types.Block, error) {
   681  
   682  	sb.logger.Debug("NeatCon backend update block")
   683  
   684  	header := block.Header()
   685  	/*
   686  		//sign the hash
   687  		seal, err := sb.Sign(sigHash(header).Bytes())
   688  		if err != nil {
   689  		    return nil, err
   690  		}
   691  	*/
   692  	//err := writeSeal(header, seal)
   693  	err := writeSeal(header, []byte{})
   694  	if err != nil {
   695  		return nil, err
   696  	}
   697  
   698  	return block.WithSeal(header), nil
   699  }
   700  
   701  // prepareExtra returns a extra-data of the given header and validators
   702  func prepareExtra(header *types.Header, vals []common.Address) ([]byte, error) {
   703  
   704  	//logger.Info("NeatCon (backend) prepare extra ")
   705  
   706  	header.Extra = types.MagicExtra
   707  	return nil, nil
   708  }
   709  
   710  // writeSeal writes the extra-data field of the given header with the given seals.
   711  // suggest to rename to writeSeal.
   712  func writeSeal(h *types.Header, seal []byte) error {
   713  
   714  	//logger.Info("NeatCon backend write seal")
   715  	payload := types.MagicExtra
   716  	h.Extra = payload
   717  	return nil
   718  }
   719  
   720  // writeCommittedSeals writes the extra-data field of a block header with given committed seals.
   721  func writeCommittedSeals(h *types.Header, ncExtra *ntcTypes.NeatConExtra) error {
   722  
   723  	//logger.Info("NeatCon backend write committed seals")
   724  	h.Extra = wire.BinaryBytes(*ncExtra)
   725  	return nil
   726  }
   727  
   728  // AccumulateRewards credits the coinbase of the given block with the mining reward.
   729  // Main Chain:
   730  // The total reward consists of the static block reward of the Epoch and total tx gas fee.
   731  // Side Chain:
   732  // The total reward consists of the static block reward of Owner setup and total tx gas fee.
   733  //
   734  // If the coinbase is Candidate, divide the rewards by weight
   735  func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, ep *epoch.Epoch, totalGasFee *big.Int) {
   736  	// Total Reward = Block Reward + Total Gas Fee
   737  	var coinbaseReward *big.Int
   738  	if config.NeatChainId == params.MainnetChainConfig.NeatChainId || config.NeatChainId == params.TestnetChainConfig.NeatChainId {
   739  		// Main Chain
   740  
   741  		rewardPerBlock := ep.RewardPerBlock
   742  		if rewardPerBlock != nil && rewardPerBlock.Sign() == 1 {
   743  			coinbaseReward = big.NewInt(0)
   744  			coinbaseReward.Add(rewardPerBlock, totalGasFee)
   745  		} else {
   746  			coinbaseReward = totalGasFee
   747  		}
   748  	} else {
   749  		// Side Chain
   750  		rewardPerBlock := state.GetSideChainRewardPerBlock()
   751  		if rewardPerBlock != nil && rewardPerBlock.Sign() == 1 {
   752  			sideChainRewardBalance := state.GetBalance(sideChainRewardAddress)
   753  			if sideChainRewardBalance.Cmp(rewardPerBlock) == -1 {
   754  				rewardPerBlock = sideChainRewardBalance
   755  			}
   756  			// sub balance from sideChainRewardAddress, reward per blocks
   757  			state.SubBalance(sideChainRewardAddress, rewardPerBlock)
   758  
   759  			coinbaseReward = new(big.Int).Add(rewardPerBlock, totalGasFee)
   760  		} else {
   761  			coinbaseReward = totalGasFee
   762  		}
   763  	}
   764  
   765  	// Coinbase Reward   = Self Reward + Delegate Reward (if Deposit Proxied Balance > 0)
   766  	//
   767  	// IF commission > 0
   768  	// Self Reward       = Self Reward + Commission Reward
   769  	// Commission Reward = Delegate Reward * Commission / 100
   770  
   771  	// Deposit Part
   772  	selfDeposit := state.GetDepositBalance(header.Coinbase)
   773  	totalProxiedDeposit := state.GetTotalDepositProxiedBalance(header.Coinbase)
   774  	totalDeposit := new(big.Int).Add(selfDeposit, totalProxiedDeposit)
   775  
   776  	var selfReward, delegateReward *big.Int
   777  	if totalProxiedDeposit.Sign() == 0 {
   778  		selfReward = coinbaseReward
   779  	} else {
   780  		selfReward = new(big.Int)
   781  		// selfPercent = selfDeposit / totalDeposit
   782  		selfPercent := new(big.Float).Quo(new(big.Float).SetInt(selfDeposit), new(big.Float).SetInt(totalDeposit))
   783  
   784  		// selftReward = coinbaseReward * selfPercent
   785  		new(big.Float).Mul(new(big.Float).SetInt(coinbaseReward), selfPercent).Int(selfReward)
   786  
   787  		// delegateReward = coinbaseReward - selfReward
   788  		delegateReward = new(big.Int).Sub(coinbaseReward, selfReward)
   789  		commission := state.GetCommission(header.Coinbase)
   790  		if commission > 0 {
   791  			// commissionReward = delegateReward * commission / 100
   792  			commissionReward := new(big.Int).Mul(delegateReward, big.NewInt(int64(commission)))
   793  			commissionReward.Quo(commissionReward, big.NewInt(100))
   794  
   795  			// Add the commission to self reward  selfReward = selfReward + commissionReward
   796  			selfReward.Add(selfReward, commissionReward)
   797  
   798  			// Sub the commission from delegate reward  delegateReward = delegateReward - commissionReward
   799  			delegateReward.Sub(delegateReward, commissionReward)
   800  		}
   801  	}
   802  
   803  	// Move the self reward to Reward Trie
   804  	//divideRewardByEpoch(state, header.Coinbase, ep.Number, selfReward)
   805  	state.AddRewardBalanceByDelegateAddress(header.Coinbase, header.Coinbase, selfReward)
   806  	//state.MarkAddressReward(header.Coinbase)
   807  
   808  	// Calculate the Delegate Reward
   809  	if delegateReward != nil && delegateReward.Sign() > 0 {
   810  		totalIndividualReward := big.NewInt(0)
   811  		// Split the reward based on Weight stack
   812  		state.ForEachProxied(header.Coinbase, func(key common.Address, proxiedBalance, depositProxiedBalance, pendingRefundBalance *big.Int) bool {
   813  			if depositProxiedBalance.Sign() == 1 {
   814  				// deposit * delegateReward / total deposit
   815  				individualReward := new(big.Int).Quo(new(big.Int).Mul(depositProxiedBalance, delegateReward), totalProxiedDeposit)
   816  				//divideRewardByEpoch(state, key, ep.Number, individualReward)
   817  				state.AddRewardBalanceByDelegateAddress(key, header.Coinbase, individualReward)
   818  				//state.MarkAddressReward(key)
   819  				totalIndividualReward.Add(totalIndividualReward, individualReward)
   820  			}
   821  			return true
   822  		})
   823  		// Recheck the Total Individual Reward, Float the difference
   824  		cmp := delegateReward.Cmp(totalIndividualReward)
   825  		if cmp == 1 {
   826  			// if delegate reward > actual given reward, give remaining reward to Candidate
   827  			diff := new(big.Int).Sub(delegateReward, totalIndividualReward)
   828  			//state.AddRewardBalanceByEpochNumber(header.Coinbase, ep.Number, diff)
   829  			state.AddRewardBalanceByDelegateAddress(header.Coinbase, header.Coinbase, diff)
   830  		} else if cmp == -1 {
   831  			// if delegate reward < actual given reward, subtract the diff from Candidate
   832  			diff := new(big.Int).Sub(totalIndividualReward, delegateReward)
   833  			//state.SubRewardBalanceByEpochNumber(header.Coinbase, ep.Number, diff)
   834  			state.SubRewardBalanceByDelegateAddress(header.Coinbase, header.Coinbase, diff)
   835  		}
   836  	}
   837  }
   838  
   839  //func divideRewardByEpoch(state *state.StateDB, addr common.Address, epochNumber uint64, reward *big.Int) {
   840  //	epochReward := new(big.Int).Quo(reward, big.NewInt(12))
   841  //	lastEpochReward := new(big.Int).Set(reward)
   842  //	for i := epochNumber; i < epochNumber+12; i++ {
   843  //		if i == epochNumber+11 {
   844  //			state.AddRewardBalanceByEpochNumber(addr, i, lastEpochReward)
   845  //		} else {
   846  //			state.AddRewardBalanceByEpochNumber(addr, i, epochReward)
   847  //			lastEpochReward.Sub(lastEpochReward, epochReward)
   848  //		}
   849  //	}
   850  //	state.MarkAddressReward(addr)
   851  //}