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 }