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