github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/consensus/neatcon/state/execution.go (about)

     1  package state
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/neatlab/neatio/chain/consensus"
     8  	ep "github.com/neatlab/neatio/chain/consensus/neatcon/epoch"
     9  	"github.com/neatlab/neatio/chain/consensus/neatcon/types"
    10  	"github.com/neatlab/neatio/chain/core"
    11  	neatTypes "github.com/neatlab/neatio/chain/core/types"
    12  )
    13  
    14  func (s *State) ValidateBlock(block *types.NCBlock) error {
    15  	return s.validateBlock(block)
    16  }
    17  
    18  func (s *State) validateBlock(block *types.NCBlock) error {
    19  	err := block.ValidateBasic(s.NTCExtra)
    20  	if err != nil {
    21  		return err
    22  	}
    23  
    24  	epoch := s.Epoch.GetEpochByBlockNumber(block.NTCExtra.Height)
    25  	if epoch == nil || epoch.Validators == nil {
    26  		return errors.New("no epoch for current block height")
    27  	}
    28  
    29  	valSet := epoch.Validators
    30  	err = valSet.VerifyCommit(block.NTCExtra.ChainID, block.NTCExtra.Height,
    31  		block.NTCExtra.SeenCommit)
    32  	if err != nil {
    33  		return err
    34  	}
    35  
    36  	return nil
    37  }
    38  
    39  func init() {
    40  	core.RegisterInsertBlockCb("UpdateLocalEpoch", updateLocalEpoch)
    41  	core.RegisterInsertBlockCb("AutoStartMining", autoStartMining)
    42  }
    43  
    44  func updateLocalEpoch(bc *core.BlockChain, block *neatTypes.Block) {
    45  	if block.NumberU64() == 0 {
    46  		return
    47  	}
    48  
    49  	ncExtra, _ := types.ExtractNeatConExtra(block.Header())
    50  	epochInBlock := ep.FromBytes(ncExtra.EpochBytes)
    51  
    52  	eng := bc.Engine().(consensus.NeatCon)
    53  	currentEpoch := eng.GetEpoch()
    54  
    55  	if epochInBlock != nil {
    56  		if epochInBlock.Number == currentEpoch.Number+1 {
    57  			if block.NumberU64() == currentEpoch.StartBlock+2 {
    58  				epochInBlock.Status = ep.EPOCH_VOTED_NOT_SAVED
    59  				epochInBlock.SetRewardScheme(currentEpoch.GetRewardScheme())
    60  				currentEpoch.SetNextEpoch(epochInBlock)
    61  			} else if block.NumberU64() == currentEpoch.EndBlock-1 {
    62  				nextEp := currentEpoch.GetNextEpoch()
    63  				nextEp.Validators = epochInBlock.Validators
    64  				nextEp.Status = ep.EPOCH_VOTED_NOT_SAVED
    65  			}
    66  			currentEpoch.Save()
    67  		} else if epochInBlock.Number == currentEpoch.Number {
    68  			currentEpoch.StartTime = epochInBlock.StartTime
    69  			currentEpoch.Save()
    70  
    71  			if currentEpoch.Number > 0 {
    72  				ep.UpdateEpochEndTime(currentEpoch.GetDB(), currentEpoch.Number-1, epochInBlock.StartTime)
    73  			}
    74  		}
    75  	}
    76  }
    77  
    78  func autoStartMining(bc *core.BlockChain, block *neatTypes.Block) {
    79  	eng := bc.Engine().(consensus.NeatCon)
    80  	currentEpoch := eng.GetEpoch()
    81  
    82  	if block.NumberU64() == currentEpoch.EndBlock-1 {
    83  		fmt.Printf("auto start mining first %v\n", block.Number())
    84  		nextEp := currentEpoch.GetNextEpoch()
    85  		state, _ := bc.State()
    86  		nextValidators := currentEpoch.Validators.Copy()
    87  		dryrunErr := ep.DryRunUpdateEpochValidatorSet(state, nextValidators, nextEp.GetEpochValidatorVoteSet())
    88  		if dryrunErr != nil {
    89  			panic("can not update the validator set base on the vote, error: " + dryrunErr.Error())
    90  		}
    91  		nextEp.Validators = nextValidators
    92  
    93  		if nextValidators.HasAddress(eng.PrivateValidator().Bytes()) && !eng.IsStarted() {
    94  			fmt.Printf("auto start mining first, post start mining event")
    95  			bc.PostChainEvents([]interface{}{core.StartMiningEvent{}}, nil)
    96  		}
    97  	}
    98  }