github.com/aergoio/aergo@v1.3.1/chain/chainhandle.go (about)

     1  /**
     2   *  @file
     3   *  @copyright defined in aergo/LICENSE.txt
     4   */
     5  
     6  package chain
     7  
     8  import (
     9  	"bytes"
    10  	"container/list"
    11  	"encoding/json"
    12  	"errors"
    13  	"fmt"
    14  	"math/big"
    15  
    16  	"github.com/aergoio/aergo/consensus"
    17  	"github.com/aergoio/aergo/contract"
    18  	"github.com/aergoio/aergo/contract/name"
    19  	"github.com/aergoio/aergo/internal/common"
    20  	"github.com/aergoio/aergo/internal/enc"
    21  	"github.com/aergoio/aergo/message"
    22  	"github.com/aergoio/aergo/state"
    23  	"github.com/aergoio/aergo/types"
    24  	"github.com/golang/protobuf/proto"
    25  )
    26  
    27  var (
    28  	ErrorNoAncestor      = errors.New("not found ancestor")
    29  	ErrBlockOrphan       = errors.New("block is ohphan, so not connected in chain")
    30  	ErrBlockCachedErrLRU = errors.New("block is in errored blocks cache")
    31  	ErrStateNoMarker     = errors.New("statedb marker of block is not exists")
    32  
    33  	errBlockStale       = errors.New("produced block becomes stale")
    34  	errBlockInvalidFork = errors.New("invalid fork occured")
    35  	errBlockTimestamp   = errors.New("invalid timestamp")
    36  
    37  	InAddBlock = make(chan struct{}, 1)
    38  )
    39  
    40  type ErrReorg struct {
    41  	err error
    42  }
    43  
    44  func (ec *ErrReorg) Error() string {
    45  	return fmt.Sprintf("reorg failed. maybe need reconfiguration. error: %s", ec.err.Error())
    46  }
    47  
    48  type ErrBlock struct {
    49  	err   error
    50  	block *types.BlockInfo
    51  }
    52  
    53  func (ec *ErrBlock) Error() string {
    54  	return fmt.Sprintf("Error: %s. block(%s, %d)", ec.err.Error(), enc.ToString(ec.block.Hash), ec.block.No)
    55  }
    56  
    57  type ErrTx struct {
    58  	err error
    59  	tx  *types.Tx
    60  }
    61  
    62  func (ec *ErrTx) Error() string {
    63  	return fmt.Sprintf("error executing tx:%s, tx=%s", ec.err.Error(), enc.ToString(ec.tx.GetHash()))
    64  }
    65  
    66  func (cs *ChainService) getBestBlockNo() types.BlockNo {
    67  	return cs.cdb.getBestBlockNo()
    68  }
    69  
    70  // GetGenesisInfo returns the information on the genesis block.
    71  func (cs *ChainService) GetGenesisInfo() *types.Genesis {
    72  	return cs.cdb.GetGenesisInfo()
    73  }
    74  
    75  func (cs *ChainService) GetBestBlock() (*types.Block, error) {
    76  	return cs.cdb.GetBestBlock()
    77  }
    78  
    79  func (cs *ChainService) getBlockByNo(blockNo types.BlockNo) (*types.Block, error) {
    80  	return cs.cdb.GetBlockByNo(blockNo)
    81  }
    82  
    83  func (cs *ChainService) GetBlock(blockHash []byte) (*types.Block, error) {
    84  	return cs.getBlock(blockHash)
    85  }
    86  
    87  func (cs *ChainService) getBlock(blockHash []byte) (*types.Block, error) {
    88  	return cs.cdb.getBlock(blockHash)
    89  }
    90  
    91  func (cs *ChainService) GetHashByNo(blockNo types.BlockNo) ([]byte, error) {
    92  	return cs.getHashByNo(blockNo)
    93  }
    94  
    95  func (cs *ChainService) getHashByNo(blockNo types.BlockNo) ([]byte, error) {
    96  	return cs.cdb.getHashByNo(blockNo)
    97  }
    98  
    99  func (cs *ChainService) getTx(txHash []byte) (*types.Tx, *types.TxIdx, error) {
   100  	tx, txidx, err := cs.cdb.getTx(txHash)
   101  	if err != nil {
   102  		return nil, nil, err
   103  	}
   104  	block, err := cs.cdb.getBlock(txidx.BlockHash)
   105  	blockInMainChain, err := cs.cdb.GetBlockByNo(block.Header.BlockNo)
   106  	if !bytes.Equal(block.BlockHash(), blockInMainChain.BlockHash()) {
   107  		return tx, nil, errors.New("tx is not in the main chain")
   108  	}
   109  	return tx, txidx, err
   110  }
   111  
   112  func (cs *ChainService) getReceipt(txHash []byte) (*types.Receipt, error) {
   113  	tx, i, err := cs.cdb.getTx(txHash)
   114  	if err != nil {
   115  		return nil, err
   116  	}
   117  
   118  	block, err := cs.cdb.getBlock(i.BlockHash)
   119  	blockInMainChain, err := cs.cdb.GetBlockByNo(block.Header.BlockNo)
   120  	if !bytes.Equal(block.BlockHash(), blockInMainChain.BlockHash()) {
   121  		return nil, errors.New("cannot find a receipt")
   122  	}
   123  
   124  	r, err := cs.cdb.getReceipt(block.BlockHash(), block.GetHeader().BlockNo, i.Idx)
   125  	if err != nil {
   126  		return r, err
   127  	}
   128  	r.ContractAddress = types.AddressOrigin(r.ContractAddress)
   129  	r.From = tx.GetBody().GetAccount()
   130  	r.To = tx.GetBody().GetRecipient()
   131  	return r, nil
   132  }
   133  
   134  func (cs *ChainService) getEvents(events *[]*types.Event, blkNo types.BlockNo, filter *types.FilterInfo,
   135  	argFilter []types.ArgFilter) uint64 {
   136  	blkHash, err := cs.cdb.getHashByNo(blkNo)
   137  	if err != nil {
   138  		return 0
   139  	}
   140  	receipts, err := cs.cdb.getReceipts(blkHash, blkNo)
   141  	if err != nil {
   142  		return 0
   143  	}
   144  	if receipts.BloomFilter(filter) == false {
   145  		return 0
   146  	}
   147  	var totalSize uint64
   148  	for idx, r := range receipts.Get() {
   149  		if r.BloomFilter(filter) == false {
   150  			continue
   151  		}
   152  		for _, e := range r.Events {
   153  			if e.Filter(filter, argFilter) {
   154  				e.SetMemoryInfo(r, blkHash, blkNo, int32(idx))
   155  				*events = append(*events, e)
   156  				totalSize += uint64(proto.Size(e))
   157  			}
   158  		}
   159  	}
   160  	return totalSize
   161  }
   162  
   163  const MaxEventSize = 4 * 1024 * 1024
   164  
   165  func (cs *ChainService) listEvents(filter *types.FilterInfo) ([]*types.Event, error) {
   166  	from := filter.Blockfrom
   167  	to := filter.Blockto
   168  
   169  	if filter.RecentBlockCnt > 0 {
   170  		to = cs.cdb.getBestBlockNo()
   171  		if to <= uint64(filter.RecentBlockCnt) {
   172  			from = 0
   173  		} else {
   174  			from = to - uint64(filter.RecentBlockCnt)
   175  		}
   176  	} else {
   177  		if to == 0 {
   178  			to = cs.cdb.getBestBlockNo()
   179  		}
   180  	}
   181  	err := filter.ValidateCheck(to)
   182  	if err != nil {
   183  		return nil, err
   184  	}
   185  	argFilter, err := filter.GetExArgFilter()
   186  	if err != nil {
   187  		return nil, err
   188  	}
   189  	events := []*types.Event{}
   190  	var totalSize uint64
   191  	if filter.Desc {
   192  		for i := to; i >= from && i != 0; i-- {
   193  			totalSize += cs.getEvents(&events, types.BlockNo(i), filter, argFilter)
   194  			if totalSize > MaxEventSize {
   195  				return nil, errors.New(fmt.Sprintf("too large size of event (%v)", totalSize))
   196  			}
   197  		}
   198  	} else {
   199  		for i := from; i <= to; i++ {
   200  			totalSize += cs.getEvents(&events, types.BlockNo(i), filter, argFilter)
   201  			if totalSize > MaxEventSize {
   202  				return nil, errors.New(fmt.Sprintf("too large size of event (%v)", totalSize))
   203  			}
   204  		}
   205  	}
   206  	return events, nil
   207  }
   208  
   209  type chainProcessor struct {
   210  	*ChainService
   211  	block       *types.Block // starting block
   212  	lastBlock   *types.Block
   213  	state       *state.BlockState
   214  	mainChain   *list.List
   215  	isByBP      bool
   216  	isMainChain bool
   217  
   218  	add   func(blk *types.Block) error
   219  	apply func(blk *types.Block) error
   220  	run   func() error
   221  }
   222  
   223  func newChainProcessor(block *types.Block, state *state.BlockState, cs *ChainService) (*chainProcessor, error) {
   224  	var isMainChain bool
   225  	var err error
   226  
   227  	if isMainChain, err = cs.cdb.isMainChain(block); err != nil {
   228  		return nil, err
   229  	}
   230  
   231  	cp := &chainProcessor{
   232  		ChainService: cs,
   233  		block:        block,
   234  		state:        state,
   235  		isByBP:       (state != nil),
   236  		isMainChain:  isMainChain,
   237  	}
   238  
   239  	if cp.isMainChain {
   240  		cp.apply = cp.execute
   241  	} else {
   242  		cp.apply = cp.addBlock
   243  	}
   244  
   245  	if cp.isByBP {
   246  		cp.run = func() error {
   247  			blk := cp.block
   248  			cp.notifyBlockByBP(blk)
   249  			return cp.apply(blk)
   250  		}
   251  	} else {
   252  		cp.run = func() error {
   253  			blk := cp.block
   254  
   255  			for blk != nil {
   256  				if err = cp.apply(blk); err != nil {
   257  					return err
   258  				}
   259  
   260  				// Remove a block depnding on blk from the orphan cache.
   261  				if blk, err = cp.resolveOrphan(blk); err != nil {
   262  					return err
   263  				}
   264  			}
   265  			return nil
   266  		}
   267  	}
   268  
   269  	return cp, nil
   270  }
   271  
   272  func (cp *chainProcessor) addBlock(blk *types.Block) error {
   273  	dbTx := cp.cdb.store.NewTx()
   274  	defer dbTx.Discard()
   275  
   276  	if err := cp.cdb.addBlock(dbTx, blk); err != nil {
   277  		return err
   278  	}
   279  
   280  	dbTx.Commit()
   281  
   282  	if logger.IsDebugEnabled() {
   283  		logger.Debug().Bool("isMainChain", cp.isMainChain).
   284  			Uint64("latest", cp.cdb.getBestBlockNo()).
   285  			Uint64("blockNo", blk.BlockNo()).
   286  			Str("hash", blk.ID()).
   287  			Str("prev_hash", enc.ToString(blk.GetHeader().GetPrevBlockHash())).
   288  			Msg("block added to the block indices")
   289  	}
   290  	cp.lastBlock = blk
   291  
   292  	return nil
   293  }
   294  
   295  func (cp *chainProcessor) notifyBlockByBP(block *types.Block) {
   296  	if cp.isByBP {
   297  		cp.notifyBlock(block, true)
   298  	}
   299  }
   300  
   301  func (cp *chainProcessor) notifyBlockByOther(block *types.Block) {
   302  	if !cp.isByBP {
   303  		logger.Debug().Msg("notify block from other bp")
   304  		cp.notifyBlock(block, false)
   305  	}
   306  }
   307  
   308  func checkDebugSleep(isBP bool) {
   309  	if isBP {
   310  		_ = TestDebugger.Check(DEBUG_CHAIN_BP_SLEEP, 0, nil)
   311  	} else {
   312  		_ = TestDebugger.Check(DEBUG_CHAIN_OTHER_SLEEP, 0, nil)
   313  	}
   314  }
   315  
   316  func (cp *chainProcessor) executeBlock(block *types.Block) error {
   317  	checkDebugSleep(cp.isByBP)
   318  
   319  	err := cp.ChainService.executeBlock(cp.state, block)
   320  	cp.state = nil
   321  	return err
   322  }
   323  
   324  func (cp *chainProcessor) execute(block *types.Block) error {
   325  	if !cp.isMainChain {
   326  		return nil
   327  	}
   328  
   329  	var err error
   330  
   331  	err = cp.executeBlock(block)
   332  	if err != nil {
   333  		logger.Error().Str("error", err.Error()).Str("hash", block.ID()).
   334  			Msg("failed to execute block")
   335  		return err
   336  	}
   337  	//SyncWithConsensus :ga
   338  	// 	After executing MemPoolDel in the chain service, MemPoolGet must be executed on the consensus.
   339  	// 	To do this, cdb.setLatest() must be executed after MemPoolDel.
   340  	//	In this case, messages of mempool is synchronized in actor message queue.
   341  	if _, err = cp.connectToChain(block); err != nil {
   342  		return err
   343  	}
   344  
   345  	cp.notifyBlockByOther(block)
   346  
   347  	return nil
   348  }
   349  
   350  func (cp *chainProcessor) connectToChain(block *types.Block) (types.BlockNo, error) {
   351  	dbTx := cp.cdb.store.NewTx()
   352  	defer dbTx.Discard()
   353  
   354  	// skip to add hash/block if wal of block is already written
   355  	oldLatest := cp.cdb.connectToChain(dbTx, block, cp.isByBP && cp.HasWAL())
   356  	if err := cp.cdb.addTxsOfBlock(&dbTx, block.GetBody().GetTxs(), block.BlockHash()); err != nil {
   357  		return 0, err
   358  	}
   359  
   360  	dbTx.Commit()
   361  
   362  	return oldLatest, nil
   363  }
   364  
   365  func (cp *chainProcessor) reorganize() error {
   366  	// - Reorganize if new bestblock then process Txs
   367  	// - Add block if new bestblock then update context connect next orphan
   368  	if !cp.isMainChain && cp.needReorg(cp.lastBlock) {
   369  		err := cp.reorg(cp.lastBlock, nil)
   370  		if e, ok := err.(consensus.ErrorConsensus); ok {
   371  			logger.Info().Err(e).Msg("reorg stopped by consensus error")
   372  			return nil
   373  		}
   374  
   375  		if err != nil {
   376  			logger.Info().Err(err).Msg("reorg stopped by unexpected error")
   377  			return &ErrReorg{err: err}
   378  		}
   379  	}
   380  
   381  	return nil
   382  }
   383  
   384  func (cs *ChainService) addBlockInternal(newBlock *types.Block, usedBstate *state.BlockState, peerID types.PeerID) (err error, cache bool) {
   385  	if !cs.VerifyTimestamp(newBlock) {
   386  		return &ErrBlock{
   387  			err: errBlockTimestamp,
   388  			block: &types.BlockInfo{
   389  				Hash: newBlock.BlockHash(),
   390  				No:   newBlock.BlockNo(),
   391  			},
   392  		}, false
   393  	}
   394  
   395  	var (
   396  		bestBlock  *types.Block
   397  		savedBlock *types.Block
   398  	)
   399  
   400  	if bestBlock, err = cs.cdb.GetBestBlock(); err != nil {
   401  		return err, false
   402  	}
   403  
   404  	// The newly produced block becomes stale because the more block(s) are
   405  	// connected to the blockchain so that the best block is changed. In this
   406  	// case, newBlock is rejected because it is unlikely that newBlock belongs
   407  	// to the main branch. Warning: the condition 'usedBstate != nil' is used
   408  	// to check whether newBlock is produced by the current node itself. Later,
   409  	// more explicit condition may be needed instead of this.
   410  	if usedBstate != nil && newBlock.PrevID() != bestBlock.ID() {
   411  		return &ErrBlock{
   412  			err: errBlockStale,
   413  			block: &types.BlockInfo{
   414  				Hash: newBlock.BlockHash(),
   415  				No:   newBlock.BlockNo(),
   416  			},
   417  		}, false
   418  	}
   419  
   420  	//Fork should never occur in raft.
   421  	checkFork := func(block *types.Block) error {
   422  		if cs.IsForkEnable() {
   423  			return nil
   424  		}
   425  		if usedBstate != nil {
   426  			return nil
   427  		}
   428  
   429  		savedBlock, err = cs.getBlockByNo(newBlock.GetHeader().GetBlockNo())
   430  		if err == nil {
   431  			/* TODO change to error after testing */
   432  			logger.Fatal().Str("newblock", newBlock.ID()).Str("savedblock", savedBlock.ID()).Msg("drop block making invalid fork")
   433  			return &ErrBlock{
   434  				err:   errBlockInvalidFork,
   435  				block: &types.BlockInfo{Hash: newBlock.BlockHash(), No: newBlock.BlockNo()},
   436  			}
   437  		}
   438  
   439  		return nil
   440  	}
   441  
   442  	if err := checkFork(newBlock); err != nil {
   443  		return err, false
   444  	}
   445  
   446  	if !newBlock.ValidChildOf(bestBlock) {
   447  		return fmt.Errorf("invalid chain id - best: %v, current: %v",
   448  			bestBlock.GetHeader().GetChainID(), newBlock.GetHeader().GetChainID()), false
   449  	}
   450  
   451  	if err := cs.VerifySign(newBlock); err != nil {
   452  		return err, true
   453  	}
   454  
   455  	// handle orphan
   456  	if cs.isOrphan(newBlock) {
   457  		if usedBstate != nil {
   458  			return fmt.Errorf("block received from BP can not be orphan"), false
   459  		}
   460  		err := cs.handleOrphan(newBlock, bestBlock, peerID)
   461  		if err == nil {
   462  			return nil, false
   463  		}
   464  
   465  		return err, false
   466  	}
   467  
   468  	select {
   469  	case InAddBlock <- struct{}{}:
   470  	}
   471  	defer func() {
   472  		<-InAddBlock
   473  	}()
   474  
   475  	cp, err := newChainProcessor(newBlock, usedBstate, cs)
   476  	if err != nil {
   477  		return err, true
   478  	}
   479  
   480  	if err := cp.run(); err != nil {
   481  		return err, true
   482  	}
   483  
   484  	// TODO: reorganization should be done before chain execution to avoid an
   485  	// unnecessary chain execution & rollback.
   486  	if err := cp.reorganize(); err != nil {
   487  		return err, true
   488  	}
   489  
   490  	logger.Info().Uint64("best", cs.cdb.getBestBlockNo()).Msg("Block added successfully")
   491  
   492  	return nil, true
   493  }
   494  
   495  func (cs *ChainService) addBlock(newBlock *types.Block, usedBstate *state.BlockState, peerID types.PeerID) error {
   496  	hashID := types.ToHashID(newBlock.BlockHash())
   497  
   498  	if cs.errBlocks.Contains(hashID) {
   499  		return ErrBlockCachedErrLRU
   500  	}
   501  
   502  	var err error
   503  
   504  	if cs.IsConnectedBlock(newBlock) {
   505  		logger.Warn().Str("hash", newBlock.ID()).Uint64("no", newBlock.BlockNo()).Msg("block is already connected")
   506  		return nil
   507  	}
   508  
   509  	var needCache bool
   510  	err, needCache = cs.addBlockInternal(newBlock, usedBstate, peerID)
   511  	if err != nil {
   512  		if needCache {
   513  			evicted := cs.errBlocks.Add(hashID, newBlock)
   514  			logger.Error().Err(err).Bool("evicted", evicted).Uint64("no", newBlock.GetHeader().BlockNo).
   515  				Str("hash", newBlock.ID()).Msg("add errored block to errBlocks lru")
   516  		}
   517  		// err must be returned regardless of the value of needCache.
   518  		return err
   519  	}
   520  
   521  	return nil
   522  }
   523  
   524  func (cs *ChainService) CountTxsInChain() int {
   525  	var txCount int
   526  
   527  	blk, err := cs.GetBestBlock()
   528  	if err != nil {
   529  		return -1
   530  	}
   531  
   532  	var no uint64
   533  	for {
   534  		no = blk.GetHeader().GetBlockNo()
   535  		if no == 0 {
   536  			break
   537  		}
   538  
   539  		txCount += len(blk.GetBody().GetTxs())
   540  
   541  		blk, err = cs.getBlock(blk.GetHeader().GetPrevBlockHash())
   542  		if err != nil {
   543  			txCount = -1
   544  			break
   545  		}
   546  	}
   547  
   548  	return txCount
   549  }
   550  
   551  type TxExecFn func(bState *state.BlockState, tx types.Transaction) error
   552  type ValidatePostFn func() error
   553  type ValidateSignWaitFn func() error
   554  
   555  type blockExecutor struct {
   556  	*state.BlockState
   557  	sdb              *state.ChainStateDB
   558  	execTx           TxExecFn
   559  	txs              []*types.Tx
   560  	validatePost     ValidatePostFn
   561  	coinbaseAcccount []byte
   562  	commitOnly       bool
   563  	verifyOnly       bool
   564  	validateSignWait ValidateSignWaitFn
   565  }
   566  
   567  func newBlockExecutor(cs *ChainService, bState *state.BlockState, block *types.Block, verifyOnly bool) (*blockExecutor, error) {
   568  	var exec TxExecFn
   569  	var validateSignWait ValidateSignWaitFn
   570  
   571  	commitOnly := false
   572  
   573  	// The DPoS block factory excutes transactions during block generation. In
   574  	// such a case it send block with block state so that bState != nil. On the
   575  	// contrary, the block propagated from the network is not half-executed.
   576  	// Hence we need a new block state and tx executor (execTx).
   577  	if bState == nil {
   578  		if err := cs.validator.ValidateBlock(block); err != nil {
   579  			return nil, err
   580  		}
   581  
   582  		bState = state.NewBlockState(cs.sdb.OpenNewStateDB(cs.sdb.GetRoot()))
   583  
   584  		exec = NewTxExecutor(cs.ChainConsensus, cs.cdb, block.BlockNo(), block.GetHeader().GetTimestamp(), block.GetHeader().GetPrevBlockHash(), contract.ChainService, block.GetHeader().ChainID)
   585  
   586  		validateSignWait = func() error {
   587  			return cs.validator.WaitVerifyDone()
   588  		}
   589  	} else {
   590  		logger.Debug().Uint64("block no", block.BlockNo()).Msg("received block from block factory")
   591  		// In this case (bState != nil), the transactions has already been
   592  		// executed by the block factory.
   593  		commitOnly = true
   594  	}
   595  
   596  	return &blockExecutor{
   597  		BlockState:       bState,
   598  		sdb:              cs.sdb,
   599  		execTx:           exec,
   600  		txs:              block.GetBody().GetTxs(),
   601  		coinbaseAcccount: block.GetHeader().GetCoinbaseAccount(),
   602  		validatePost: func() error {
   603  			return cs.validator.ValidatePost(bState.GetRoot(), bState.Receipts(), block)
   604  		},
   605  		commitOnly:       commitOnly,
   606  		verifyOnly:       verifyOnly,
   607  		validateSignWait: validateSignWait,
   608  	}, nil
   609  }
   610  
   611  // NewTxExecutor returns a new TxExecFn.
   612  func NewTxExecutor(ccc consensus.ChainConsensusCluster, cdb contract.ChainAccessor, blockNo types.BlockNo, ts int64, prevBlockHash []byte, preLoadService int, chainID []byte) TxExecFn {
   613  	return func(bState *state.BlockState, tx types.Transaction) error {
   614  		if bState == nil {
   615  			logger.Error().Msg("bstate is nil in txexec")
   616  			return ErrGatherChain
   617  		}
   618  		snapshot := bState.Snapshot()
   619  
   620  		err := executeTx(ccc, cdb, bState, tx, blockNo, ts, prevBlockHash, preLoadService, common.Hasher(chainID))
   621  		if err != nil {
   622  			logger.Error().Err(err).Str("hash", enc.ToString(tx.GetHash())).Msg("tx failed")
   623  			if err2 := bState.Rollback(snapshot); err2 != nil {
   624  				logger.Panic().Err(err).Msg("faield to rollback block state")
   625  			}
   626  
   627  			return err
   628  		}
   629  		return nil
   630  	}
   631  }
   632  
   633  func (e *blockExecutor) execute() error {
   634  	// Receipt must be committed unconditionally.
   635  	if !e.commitOnly {
   636  		defer contract.CloseDatabase()
   637  		var preLoadTx *types.Tx
   638  		nCand := len(e.txs)
   639  		for i, tx := range e.txs {
   640  			if i != nCand-1 {
   641  				preLoadTx = e.txs[i+1]
   642  				contract.PreLoadRequest(e.BlockState, preLoadTx, tx, contract.ChainService)
   643  			}
   644  			if err := e.execTx(e.BlockState, types.NewTransaction(tx)); err != nil {
   645  				//FIXME maybe system error. restart or panic
   646  				// all txs have executed successfully in BP node
   647  				return err
   648  			}
   649  			contract.SetPreloadTx(preLoadTx, contract.ChainService)
   650  		}
   651  
   652  		if e.validateSignWait != nil {
   653  			if err := e.validateSignWait(); err != nil {
   654  				return err
   655  			}
   656  		}
   657  
   658  		//TODO check result of verifing txs
   659  		if err := SendRewardCoinbase(e.BlockState, e.coinbaseAcccount); err != nil {
   660  			return err
   661  		}
   662  
   663  		if err := contract.SaveRecoveryPoint(e.BlockState); err != nil {
   664  			return err
   665  		}
   666  
   667  		if err := e.Update(); err != nil {
   668  			return err
   669  		}
   670  	}
   671  
   672  	if err := e.validatePost(); err != nil {
   673  		return err
   674  	}
   675  
   676  	// TODO: sync status of bstate and cdb what to do if cdb.commit fails after
   677  
   678  	if !e.verifyOnly {
   679  		if err := e.commit(); err != nil {
   680  			return err
   681  		}
   682  	}
   683  
   684  	logger.Debug().Msg("block executor finished")
   685  	return nil
   686  }
   687  
   688  func (e *blockExecutor) commit() error {
   689  	if err := e.BlockState.Commit(); err != nil {
   690  		return err
   691  	}
   692  
   693  	//TODO: after implementing BlockRootHash, remove statedb.lastest
   694  	if err := e.sdb.UpdateRoot(e.BlockState); err != nil {
   695  		return err
   696  	}
   697  
   698  	return nil
   699  }
   700  
   701  // TODO: Refactoring: batch
   702  func (cs *ChainService) executeBlock(bstate *state.BlockState, block *types.Block) error {
   703  	// Caution: block must belong to the main chain.
   704  	logger.Debug().Str("hash", block.ID()).Uint64("no", block.GetHeader().BlockNo).Msg("start to execute")
   705  
   706  	var (
   707  		bestBlock *types.Block
   708  		err       error
   709  	)
   710  
   711  	if bestBlock, err = cs.cdb.GetBestBlock(); err != nil {
   712  		return err
   713  	}
   714  
   715  	// Check consensus info validity
   716  	if err = cs.IsBlockValid(block, bestBlock); err != nil {
   717  		return err
   718  	}
   719  
   720  	// TODO refactoring: receive execute function as argument (executeBlock or executeBlockReco)
   721  	ex, err := newBlockExecutor(cs, bstate, block, false)
   722  	if err != nil {
   723  		return err
   724  	}
   725  
   726  	// contract & state DB update is done during execution.
   727  	if err := ex.execute(); err != nil {
   728  		return err
   729  	}
   730  
   731  	if len(ex.BlockState.Receipts().Get()) != 0 {
   732  		cs.cdb.writeReceipts(block.BlockHash(), block.BlockNo(), ex.BlockState.Receipts())
   733  	}
   734  
   735  	cs.notifyEvents(block, ex.BlockState)
   736  
   737  	cs.Update(block)
   738  
   739  	logger.Debug().Uint64("no", block.GetHeader().BlockNo).Msg("end to execute")
   740  
   741  	return nil
   742  }
   743  
   744  // verifyBlock execute block and verify state root but doesn't save data to database.
   745  // ChainVerifier use this function.
   746  func (cs *ChainService) verifyBlock(block *types.Block) error {
   747  	var (
   748  		err error
   749  		ex  *blockExecutor
   750  	)
   751  
   752  	// Caution: block must belong to the main chain.
   753  	logger.Debug().Str("hash", block.ID()).Uint64("no", block.GetHeader().BlockNo).Msg("start to verify")
   754  
   755  	ex, err = newBlockExecutor(cs, nil, block, true)
   756  	if err != nil {
   757  		return err
   758  	}
   759  
   760  	// contract & state DB update is done during execution.
   761  	if err = ex.execute(); err != nil {
   762  		return err
   763  	}
   764  
   765  	// set root of sdb to block root hash
   766  	if err = cs.sdb.SetRoot(block.GetHeader().GetBlocksRootHash()); err != nil {
   767  		return fmt.Errorf("failed to set root of sdb(no=%d,hash=%v)", block.BlockNo(), block.ID())
   768  	}
   769  
   770  	logger.Debug().Uint64("no", block.GetHeader().BlockNo).Msg("end verify")
   771  
   772  	return nil
   773  }
   774  
   775  // TODO: Refactoring: batch
   776  func (cs *ChainService) executeBlockReco(_ *state.BlockState, block *types.Block) error {
   777  	// Caution: block must belong to the main chain.
   778  	logger.Debug().Str("hash", block.ID()).Uint64("no", block.GetHeader().BlockNo).Msg("start to execute for reco")
   779  
   780  	var (
   781  		bestBlock *types.Block
   782  		err       error
   783  	)
   784  
   785  	if bestBlock, err = cs.cdb.GetBestBlock(); err != nil {
   786  		return err
   787  	}
   788  
   789  	// Check consensus info validity
   790  	// TODO remove bestblock
   791  	if err = cs.IsBlockValid(block, bestBlock); err != nil {
   792  		return err
   793  	}
   794  
   795  	if !cs.sdb.GetStateDB().HasMarker(block.GetHeader().GetBlocksRootHash()) {
   796  		logger.Error().Str("hash", block.ID()).Uint64("no", block.GetHeader().GetBlockNo()).Msg("state marker does not exist")
   797  		return ErrStateNoMarker
   798  	}
   799  
   800  	// move stateroot
   801  	if err := cs.sdb.SetRoot(block.GetHeader().GetBlocksRootHash()); err != nil {
   802  		return fmt.Errorf("failed to set sdb(branchRoot:no=%d,hash=%v)", block.GetHeader().GetBlockNo(),
   803  			block.ID())
   804  	}
   805  
   806  	cs.Update(block)
   807  
   808  	logger.Debug().Uint64("no", block.GetHeader().BlockNo).Msg("end to execute for reco")
   809  
   810  	return nil
   811  }
   812  
   813  func (cs *ChainService) notifyEvents(block *types.Block, bstate *state.BlockState) {
   814  	blkNo := block.GetHeader().GetBlockNo()
   815  	blkHash := block.BlockHash()
   816  
   817  	logger.Debug().Uint64("no", blkNo).Msg("add event from executed block")
   818  
   819  	cs.RequestTo(message.MemPoolSvc, &message.MemPoolDel{
   820  		Block: block,
   821  	})
   822  
   823  	cs.TellTo(message.RPCSvc, block)
   824  
   825  	events := []*types.Event{}
   826  	for idx, receipt := range bstate.Receipts().Get() {
   827  		for _, e := range receipt.Events {
   828  			e.SetMemoryInfo(receipt, blkHash, blkNo, int32(idx))
   829  			events = append(events, e)
   830  		}
   831  	}
   832  
   833  	if len(events) != 0 {
   834  		cs.TellTo(message.RPCSvc, events)
   835  	}
   836  }
   837  
   838  const maxRetSize = 1024
   839  
   840  func adjustRv(ret string) string {
   841  	if len(ret) > maxRetSize {
   842  		modified, _ := json.Marshal(ret[:maxRetSize-4] + " ...")
   843  
   844  		return string(modified)
   845  	}
   846  	return ret
   847  }
   848  
   849  func executeTx(ccc consensus.ChainConsensusCluster, cdb contract.ChainAccessor, bs *state.BlockState, tx types.Transaction, blockNo uint64, ts int64, prevBlockHash []byte, preLoadService int, chainIDHash []byte) error {
   850  
   851  	txBody := tx.GetBody()
   852  
   853  	var account []byte
   854  	if tx.HasVerifedAccount() {
   855  		account = tx.GetVerifedAccount()
   856  		tx.RemoveVerifedAccount()
   857  		resolvedAccount := name.Resolve(bs, txBody.GetAccount())
   858  		if !bytes.Equal(account, resolvedAccount) {
   859  			return types.ErrSignNotMatch
   860  		}
   861  	} else {
   862  		account = name.Resolve(bs, txBody.GetAccount())
   863  	}
   864  
   865  	err := tx.Validate(chainIDHash, IsPublic())
   866  	if err != nil {
   867  		return err
   868  	}
   869  
   870  	sender, err := bs.GetAccountStateV(account)
   871  	if err != nil {
   872  		return err
   873  	}
   874  
   875  	err = tx.ValidateWithSenderState(sender.State())
   876  	if err != nil {
   877  		return err
   878  	}
   879  
   880  	recipient := name.Resolve(bs, txBody.Recipient)
   881  	var receiver *state.V
   882  	status := "SUCCESS"
   883  	if len(recipient) > 0 {
   884  		receiver, err = bs.GetAccountStateV(recipient)
   885  		if receiver != nil && txBody.Type == types.TxType_REDEPLOY {
   886  			status = "RECREATED"
   887  			receiver.SetRedeploy()
   888  		}
   889  	} else {
   890  		receiver, err = bs.CreateAccountStateV(contract.CreateContractID(txBody.Account, txBody.Nonce))
   891  		status = "CREATED"
   892  	}
   893  	if err != nil {
   894  		return err
   895  	}
   896  
   897  	var txFee *big.Int
   898  	var rv string
   899  	var events []*types.Event
   900  	switch txBody.Type {
   901  	case types.TxType_NORMAL, types.TxType_REDEPLOY:
   902  		rv, events, txFee, err = contract.Execute(bs, cdb, tx.GetTx(), blockNo, ts, prevBlockHash, sender, receiver, preLoadService)
   903  		sender.SubBalance(txFee)
   904  	case types.TxType_GOVERNANCE:
   905  		txFee = new(big.Int).SetUint64(0)
   906  		events, err = executeGovernanceTx(ccc, bs, txBody, sender, receiver, blockNo)
   907  		if err != nil {
   908  			logger.Warn().Err(err).Str("txhash", enc.ToString(tx.GetHash())).Msg("governance tx Error")
   909  		}
   910  	}
   911  
   912  	if err != nil {
   913  		if !contract.IsRuntimeError(err) {
   914  			return err
   915  		}
   916  		sender.Reset()
   917  		sender.SubBalance(txFee)
   918  		sender.SetNonce(txBody.Nonce)
   919  		sErr := sender.PutState()
   920  		if sErr != nil {
   921  			return sErr
   922  		}
   923  		status = "ERROR"
   924  		rv = err.Error()
   925  	} else {
   926  		sender.SetNonce(txBody.Nonce)
   927  		err = sender.PutState()
   928  		if err != nil {
   929  			return err
   930  		}
   931  		if sender.AccountID() != receiver.AccountID() {
   932  			err = receiver.PutState()
   933  			if err != nil {
   934  				return err
   935  			}
   936  		}
   937  		rv = adjustRv(rv)
   938  	}
   939  	bs.BpReward = new(big.Int).Add(new(big.Int).SetBytes(bs.BpReward), txFee).Bytes()
   940  
   941  	receipt := types.NewReceipt(receiver.ID(), status, rv)
   942  	receipt.FeeUsed = txFee.Bytes()
   943  	receipt.TxHash = tx.GetHash()
   944  	receipt.Events = events
   945  
   946  	return bs.AddReceipt(receipt)
   947  }
   948  
   949  func SendRewardCoinbase(bState *state.BlockState, coinbaseAccount []byte) error {
   950  	bpReward := new(big.Int).SetBytes(bState.BpReward)
   951  	if bpReward.Cmp(new(big.Int).SetUint64(0)) <= 0 || coinbaseAccount == nil {
   952  		logger.Debug().Str("reward", new(big.Int).SetBytes(bState.BpReward).String()).Msg("coinbase is skipped")
   953  		return nil
   954  	}
   955  
   956  	receiverID := types.ToAccountID(coinbaseAccount)
   957  	receiverState, err := bState.GetAccountState(receiverID)
   958  	if err != nil {
   959  		return err
   960  	}
   961  
   962  	receiverChange := types.State(*receiverState)
   963  	receiverChange.Balance = new(big.Int).Add(receiverChange.GetBalanceBigInt(), bpReward).Bytes()
   964  
   965  	err = bState.PutState(receiverID, &receiverChange)
   966  	if err != nil {
   967  		return err
   968  	}
   969  
   970  	logger.Debug().Str("reward", bpReward.String()).
   971  		Str("newbalance", receiverChange.GetBalanceBigInt().String()).Msg("send reward to coinbase account")
   972  
   973  	return nil
   974  }
   975  
   976  // find an orphan block which is the child of the added block
   977  func (cs *ChainService) resolveOrphan(block *types.Block) (*types.Block, error) {
   978  	hash := block.BlockHash()
   979  
   980  	orphanID := types.ToBlockID(hash)
   981  	orphan, exists := cs.op.cache[orphanID]
   982  	if !exists {
   983  		return nil, nil
   984  	}
   985  
   986  	orphanBlock := orphan.Block
   987  
   988  	if (block.GetHeader().GetBlockNo() + 1) != orphanBlock.GetHeader().GetBlockNo() {
   989  		return nil, fmt.Errorf("invalid orphan block no (p=%d, c=%d)", block.GetHeader().GetBlockNo(),
   990  			orphanBlock.GetHeader().GetBlockNo())
   991  	}
   992  
   993  	logger.Info().Str("parent", block.ID()).
   994  		Str("orphan", orphanBlock.ID()).
   995  		Msg("connect orphan")
   996  
   997  	if err := cs.op.removeOrphan(orphanID); err != nil {
   998  		return nil, err
   999  	}
  1000  
  1001  	return orphanBlock, nil
  1002  }
  1003  
  1004  func (cs *ChainService) isOrphan(block *types.Block) bool {
  1005  	prevhash := block.Header.PrevBlockHash
  1006  	_, err := cs.getBlock(prevhash)
  1007  
  1008  	return err != nil
  1009  }
  1010  
  1011  func (cs *ChainService) handleOrphan(block *types.Block, bestBlock *types.Block, peerID types.PeerID) error {
  1012  	err := cs.addOrphan(block)
  1013  	if err != nil {
  1014  		logger.Error().Err(err).Str("hash", block.ID()).Msg("add orphan block failed")
  1015  
  1016  		return err
  1017  	}
  1018  
  1019  	cs.RequestTo(message.SyncerSvc, &message.SyncStart{PeerID: peerID, TargetNo: block.GetHeader().GetBlockNo()})
  1020  
  1021  	return nil
  1022  }
  1023  
  1024  func (cs *ChainService) addOrphan(block *types.Block) error {
  1025  	return cs.op.addOrphan(block)
  1026  }
  1027  
  1028  func (cs *ChainService) findAncestor(Hashes [][]byte) (*types.BlockInfo, error) {
  1029  	// 1. check endpoint is on main chain (or, return nil)
  1030  	logger.Debug().Int("len", len(Hashes)).Msg("find ancestor")
  1031  
  1032  	var mainhash []byte
  1033  	var mainblock *types.Block
  1034  	var err error
  1035  	// 2. get the highest block of Hashes hash on main chain
  1036  	for _, hash := range Hashes {
  1037  		// need to be short
  1038  		mainblock, err = cs.cdb.getBlock(hash)
  1039  		if err != nil {
  1040  			mainblock = nil
  1041  			continue
  1042  		}
  1043  		// get main hash with same block height
  1044  		mainhash, err = cs.cdb.getHashByNo(
  1045  			types.BlockNo(mainblock.GetHeader().GetBlockNo()))
  1046  		if err != nil {
  1047  			mainblock = nil
  1048  			continue
  1049  		}
  1050  
  1051  		if bytes.Equal(mainhash, mainblock.BlockHash()) {
  1052  			break
  1053  		}
  1054  		mainblock = nil
  1055  	}
  1056  
  1057  	// TODO: handle the case that can't find the hash in main chain
  1058  	if mainblock == nil {
  1059  		logger.Debug().Msg("Can't search same ancestor")
  1060  		return nil, ErrorNoAncestor
  1061  	}
  1062  
  1063  	return &types.BlockInfo{Hash: mainblock.BlockHash(), No: mainblock.GetHeader().GetBlockNo()}, nil
  1064  }
  1065  
  1066  func (cs *ChainService) setSkipMempool(isSync bool) {
  1067  	//don't use mempool if sync is in progress
  1068  	cs.validator.signVerifier.SetSkipMempool(isSync)
  1069  }