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  }