Browse Source

Merge pull request #1142 from tendermint/add_valid_value_mechanism

Add support for ValidBlock mechanism for the simplest case
pull/1213/merge
Ethan Buchman 7 years ago
committed by GitHub
parent
commit
9cdba04fe9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 1 deletions
  1. +19
    -1
      consensus/state.go
  2. +7
    -0
      consensus/types/state.go

+ 19
- 1
consensus/state.go View File

@ -477,6 +477,9 @@ func (cs *ConsensusState) updateToState(state sm.State) {
cs.LockedRound = 0 cs.LockedRound = 0
cs.LockedBlock = nil cs.LockedBlock = nil
cs.LockedBlockParts = nil cs.LockedBlockParts = nil
cs.ValidRound = 0
cs.ValidBlock = nil
cs.ValidBlockParts = nil
cs.Votes = cstypes.NewHeightVoteSet(state.ChainID, height, validators) cs.Votes = cstypes.NewHeightVoteSet(state.ChainID, height, validators)
cs.CommitRound = -1 cs.CommitRound = -1
cs.LastCommit = lastPrecommits cs.LastCommit = lastPrecommits
@ -798,6 +801,9 @@ func (cs *ConsensusState) defaultDecideProposal(height int64, round int) {
if cs.LockedBlock != nil { if cs.LockedBlock != nil {
// If we're locked onto a block, just choose that. // If we're locked onto a block, just choose that.
block, blockParts = cs.LockedBlock, cs.LockedBlockParts block, blockParts = cs.LockedBlock, cs.LockedBlockParts
} else if cs.ValidBlock != nil {
// If there is valid block, choose that.
block, blockParts = cs.ValidBlock, cs.ValidBlockParts
} else { } else {
// Create a new proposal block from state/txs from the mempool. // Create a new proposal block from state/txs from the mempool.
block, blockParts = cs.createProposalBlock() block, blockParts = cs.createProposalBlock()
@ -1375,13 +1381,13 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerID p2p.ID) (added bool,
case types.VoteTypePrevote: case types.VoteTypePrevote:
prevotes := cs.Votes.Prevotes(vote.Round) prevotes := cs.Votes.Prevotes(vote.Round)
cs.Logger.Info("Added to prevote", "vote", vote, "prevotes", prevotes.StringShort()) cs.Logger.Info("Added to prevote", "vote", vote, "prevotes", prevotes.StringShort())
blockID, ok := prevotes.TwoThirdsMajority()
// First, unlock if prevotes is a valid POL. // First, unlock if prevotes is a valid POL.
// >> lockRound < POLRound <= unlockOrChangeLockRound (see spec) // >> lockRound < POLRound <= unlockOrChangeLockRound (see spec)
// NOTE: If (lockRound < POLRound) but !(POLRound <= unlockOrChangeLockRound), // NOTE: If (lockRound < POLRound) but !(POLRound <= unlockOrChangeLockRound),
// we'll still enterNewRound(H,vote.R) and enterPrecommit(H,vote.R) to process it // we'll still enterNewRound(H,vote.R) and enterPrecommit(H,vote.R) to process it
// there. // there.
if (cs.LockedBlock != nil) && (cs.LockedRound < vote.Round) && (vote.Round <= cs.Round) { if (cs.LockedBlock != nil) && (cs.LockedRound < vote.Round) && (vote.Round <= cs.Round) {
blockID, ok := prevotes.TwoThirdsMajority()
if ok && !cs.LockedBlock.HashesTo(blockID.Hash) { if ok && !cs.LockedBlock.HashesTo(blockID.Hash) {
cs.Logger.Info("Unlocking because of POL.", "lockedRound", cs.LockedRound, "POLRound", vote.Round) cs.Logger.Info("Unlocking because of POL.", "lockedRound", cs.LockedRound, "POLRound", vote.Round)
cs.LockedRound = 0 cs.LockedRound = 0
@ -1390,6 +1396,18 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerID p2p.ID) (added bool,
cs.eventBus.PublishEventUnlock(cs.RoundStateEvent()) cs.eventBus.PublishEventUnlock(cs.RoundStateEvent())
} }
} }
// Update ValidBlock
if ok && !blockID.IsZero() && !cs.ValidBlock.HashesTo(blockID.Hash) && vote.Round > cs.ValidRound {
// update valid value
if cs.ProposalBlock.HashesTo(blockID.Hash) {
cs.ValidRound = vote.Round
cs.ValidBlock = cs.ProposalBlock
cs.ValidBlockParts = cs.ProposalBlockParts
}
//TODO: We might want to update ValidBlock also in case we don't have that block yet,
// and obtain the required block using gossiping
}
if cs.Round <= vote.Round && prevotes.HasTwoThirdsAny() { if cs.Round <= vote.Round && prevotes.HasTwoThirdsAny() {
// Round-skip over to PrevoteWait or goto Precommit. // Round-skip over to PrevoteWait or goto Precommit.
cs.enterNewRound(height, vote.Round) // if the vote is ahead of us cs.enterNewRound(height, vote.Round) // if the vote is ahead of us


+ 7
- 0
consensus/types/state.go View File

@ -70,6 +70,9 @@ type RoundState struct {
LockedRound int LockedRound int
LockedBlock *types.Block LockedBlock *types.Block
LockedBlockParts *types.PartSet LockedBlockParts *types.PartSet
ValidRound int
ValidBlock *types.Block
ValidBlockParts *types.PartSet
Votes *HeightVoteSet Votes *HeightVoteSet
CommitRound int // CommitRound int //
LastCommit *types.VoteSet // Last precommits at Height-1 LastCommit *types.VoteSet // Last precommits at Height-1
@ -106,6 +109,8 @@ func (rs *RoundState) StringIndented(indent string) string {
%s ProposalBlock: %v %v %s ProposalBlock: %v %v
%s LockedRound: %v %s LockedRound: %v
%s LockedBlock: %v %v %s LockedBlock: %v %v
%s ValidRound: %v
%s ValidBlock: %v %v
%s Votes: %v %s Votes: %v
%s LastCommit: %v %s LastCommit: %v
%s LastValidators:%v %s LastValidators:%v
@ -118,6 +123,8 @@ func (rs *RoundState) StringIndented(indent string) string {
indent, rs.ProposalBlockParts.StringShort(), rs.ProposalBlock.StringShort(), indent, rs.ProposalBlockParts.StringShort(), rs.ProposalBlock.StringShort(),
indent, rs.LockedRound, indent, rs.LockedRound,
indent, rs.LockedBlockParts.StringShort(), rs.LockedBlock.StringShort(), indent, rs.LockedBlockParts.StringShort(), rs.LockedBlock.StringShort(),
indent, rs.ValidRound,
indent, rs.ValidBlockParts.StringShort(), rs.ValidBlock.StringShort(),
indent, rs.Votes.StringIndented(indent+" "), indent, rs.Votes.StringIndented(indent+" "),
indent, rs.LastCommit.StringShort(), indent, rs.LastCommit.StringShort(),
indent, rs.LastValidators.StringIndented(indent+" "), indent, rs.LastValidators.StringIndented(indent+" "),


Loading…
Cancel
Save