새로운 합의 round 시작
timeout 시간에 맞춰 들어오거나, 이전 라운드의 2/3 (어떤 precommit이든) 이후 진입하거나,
동일 round의 2/3 이상 prevote or precommit에 의해 들어오거나
dir : consensus/state.go
proposer priority update (각 validator의 priority 업데이트)
validators := cs.Validators
if cs.Round < round {
validators = validators.Copy()
validators.IncrementProposerPriority(tmmath.SafeSubInt32(round, cs.Round))
}
set up new round
round, step의 숫자값을 맞춰주고, validator 정보를 업데이트
cs.updateRoundStep(round, cstpyes.roundStepNewRound)
cs.Validators = validators
// round가 변경된 경우 State(cs)의 proposal 관련 attribute 초기화
if round == 0 {
// do nothing in round 0
} else {
cs.Proposal = nil
cs.ProposalBlock = nil
cs.ProposalBlockParts = nil
}
voteset의 round를 추가한다.
voteset은 vote 인스턴스를 모아두는 인스턴스로, vote들 이외에도 height, round등이 있음.
(바꿔 말하면 각 round마다 대응하는 voteset 인스턴스를 가진다.)
cs.Votes.SetRound(tmmath.SafeAddInt32(round, 1))
cs.TriggeredTimeoutPrecommit = false
이 시점에서 tx가 하나도 없을 경우 사용자의 노드 설정에 따라 상황이 달라진다.
proof Block (부정 행위의 증거를 담는), emptyBlock (tx가 없는 빈 블록)에 따라 달라지는데,
노드가 tx를 기다리지 않도록 (빈 블록을 허용) 설정했고, proofBlock을 설정했을 경우
mempool에 tx가 없더라고 block을 생성해 증거를 담아야 하므로 Propose 단계로 진입.
waitForTxs := cs.config.WaitForTxs() && round == 0 && !cs.needProofBlock(height)
if waitForTxs {
if cs.config.CreateEmptyBlocksInterval > 0 {
// 타임 아웃을 다시 설정
cs.scheduleTimeout(...)
}
} else {
cs.enterPropose(height, round)
}