github.com/okex/exchain@v1.8.0/libs/tendermint/consensus/consensus_new_round.go (about) 1 package consensus 2 3 import ( 4 "fmt" 5 cstypes "github.com/okex/exchain/libs/tendermint/consensus/types" 6 "github.com/okex/exchain/libs/tendermint/types" 7 tmtime "github.com/okex/exchain/libs/tendermint/types/time" 8 ) 9 10 //----------------------------------------------------------------------------- 11 // State functions 12 // Used internally by handleTimeout and handleMsg to make state transitions 13 14 // Enter: `timeoutNewHeight` by startTime (R0PrevoteTime+timeoutCommit), 15 // 16 // or, if SkipTimeoutCommit==true, after receiving all precommits from (height,round-1) 17 // 18 // Enter: `timeoutPrecommits` after any +2/3 precommits from (height,round-1) 19 // Enter: +2/3 precommits for nil at (height,round-1) 20 // Enter: +2/3 prevotes any or +2/3 precommits for block or any from (height, round) 21 // NOTE: cs.StartTime was already set for height. 22 func (cs *State) enterNewRound(height int64, round int) { 23 logger := cs.Logger.With("height", height, "round", round) 24 if cs.Height != height || round < cs.Round || (cs.Round == round && cs.Step != cstypes.RoundStepNewHeight) { 25 logger.Debug(fmt.Sprintf( 26 "enterNewRound(%v/%v): Invalid args. Current step: %v/%v/%v", 27 height, 28 round, 29 cs.Height, 30 cs.Round, 31 cs.Step)) 32 return 33 } 34 35 cs.doNewRound(height, round, false, nil) 36 } 37 38 func (cs *State) doNewRound(height int64, round int, avc bool, val *types.Validator) { 39 logger := cs.Logger.With("height", height, "round", round) 40 cs.initNewHeight() 41 if !avc { 42 if now := tmtime.Now(); cs.StartTime.After(now) { 43 logger.Info("Need to set a buffer and log message here for sanity.", "startTime", cs.StartTime, "now", now) 44 } 45 logger.Info(fmt.Sprintf("enterNewRound(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) 46 47 // Increment validators if necessary 48 validators := cs.Validators 49 if cs.Round < round { 50 validators = validators.Copy() 51 validators.IncrementProposerPriority(round - cs.Round) 52 } 53 cs.Validators = validators 54 cs.Votes.SetRound(round + 1) // also track next round (round+1) to allow round-skipping 55 } else { 56 cs.trc.Pin("NewRoundVC-%d", round) 57 logger.Info(fmt.Sprintf("enterNewRoundAVC(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) 58 59 cs.Validators.Proposer = val 60 if cs.Votes.Round() == 0 { 61 cs.Votes.SetRound(1) // also track next round (round+1) to allow round-skipping 62 } 63 } 64 65 // Setup new round 66 // we don't fire newStep for this step, 67 // but we fire an event, so update the round step first 68 cs.updateRoundStep(round, cstypes.RoundStepNewRound) 69 cs.HasVC = avc 70 if round == 0 { 71 // We've already reset these upon new height, 72 // and meanwhile we might have received a proposal 73 // for round 0. 74 } else { 75 logger.Info("Resetting Proposal info") 76 cs.Proposal = nil 77 cs.ProposalBlock = nil 78 cs.ProposalBlockParts = nil 79 } 80 81 cs.TriggeredTimeoutPrecommit = false 82 cs.eventBus.PublishEventNewRound(cs.NewRoundEvent()) 83 cs.metrics.Rounds.Set(float64(round)) 84 85 // Wait for txs to be available in the mempool 86 // before we enterPropose in round 0. If the last block changed the app hash, 87 // we may need an empty "proof" block, and enterPropose immediately. 88 waitForTxs := cs.config.WaitForTxs() && round == 0 && !cs.needProofBlock(height) 89 if waitForTxs { 90 if cs.config.CreateEmptyBlocksInterval > 0 { 91 cs.scheduleTimeout(cs.config.CreateEmptyBlocksInterval, height, round, 92 cstypes.RoundStepNewRound) 93 } 94 } else { 95 cs.enterPropose(height, round) 96 } 97 } 98 99 func (cs *State) enterNewRoundAVC(height int64, round int, val *types.Validator) { 100 logger := cs.Logger.With("height", height, "round", round) 101 if round != 0 || cs.Round != 0 || cs.Height != height { 102 logger.Debug(fmt.Sprintf( 103 "enterNewRoundAVC(%v/%v): Invalid args. Current step: %v/%v/%v", 104 height, 105 round, 106 cs.Height, 107 cs.Round, 108 cs.Step)) 109 return 110 } 111 112 cs.doNewRound(height, round, true, val) 113 } 114 115 // Enter: `timeoutNewHeight` by startTime (after timeoutCommit), 116 func (cs *State) enterNewHeight(height int64) { 117 cs.Logger.Info("enterNewHeight", "vcMsg", cs.vcMsg, "proposer", cs.Validators.Proposer.Address) 118 if GetActiveVC() && cs.vcMsg != nil && cs.vcMsg.Validate(height, cs.Validators.Proposer.Address) { 119 _, val := cs.Validators.GetByAddress(cs.vcMsg.NewProposer) 120 cs.enterNewRoundAVC(height, 0, val) 121 } else { 122 cs.enterNewRound(height, 0) 123 } 124 }