mirror of
https://github.com/tendermint/tendermint.git
synced 2026-08-28 03:46:33 +00:00
Fix consensus:
* Use LastValidators when a Vote is received for the last height. * Fix Validation.Height/Round to use FirstPrecommit.
This commit is contained in:
@@ -177,18 +177,20 @@ func (conR *ConsensusReactor) Receive(chId byte, peer *p2p.Peer, msgBytes []byte
|
||||
switch msg := msg_.(type) {
|
||||
case *VoteMessage:
|
||||
vote := msg.Vote
|
||||
var validators *ValidatorSet
|
||||
var validators *sm.ValidatorSet
|
||||
if rs.Height == vote.Height {
|
||||
validators = rs.Validators
|
||||
} else if rs.Height == vote.Height+1 {
|
||||
validators = rs.LastBondedValidators
|
||||
if !(rs.Step == RoundStepNewHeight && vote.Type == types.VoteTypePrecommit) {
|
||||
return // Wrong height, not a LastCommit straggler commit.
|
||||
}
|
||||
validators = rs.LastValidators
|
||||
} else {
|
||||
return // Wrong height. Not necessarily a bad peer.
|
||||
}
|
||||
VOTE_PASS:
|
||||
|
||||
// We have vote/validators. Height may not be rs.Height
|
||||
|
||||
address, _ := validators.GetByIndex(msg.ValidatorIndex)
|
||||
added, index, err := conR.conS.AddVote(address, vote, peer.Key)
|
||||
if err != nil {
|
||||
|
||||
@@ -215,6 +215,7 @@ type RoundState struct {
|
||||
LockedBlockParts *types.PartSet
|
||||
Votes *HeightVoteSet
|
||||
LastCommit *VoteSet // Last precommits at Height-1
|
||||
LastValidators *sm.ValidatorSet
|
||||
}
|
||||
|
||||
func (rs *RoundState) String() string {
|
||||
@@ -233,6 +234,7 @@ func (rs *RoundState) StringIndented(indent string) string {
|
||||
%s LockedBlock: %v %v
|
||||
%s Votes: %v
|
||||
%s LastCommit: %v
|
||||
%s LastValidators: %v
|
||||
%s}`,
|
||||
indent, rs.Height, rs.Round, rs.Step,
|
||||
indent, rs.StartTime,
|
||||
@@ -244,6 +246,7 @@ func (rs *RoundState) StringIndented(indent string) string {
|
||||
indent, rs.LockedBlockParts.StringShort(), rs.LockedBlock.StringShort(),
|
||||
indent, rs.Votes.StringIndented(indent+" "),
|
||||
indent, rs.LastCommit.StringShort(),
|
||||
indent, rs.LastValidators.StringIndented(indent+" "),
|
||||
indent)
|
||||
}
|
||||
|
||||
@@ -406,6 +409,7 @@ func (cs *ConsensusState) updateToState(state *sm.State, contiguous bool) {
|
||||
cs.LockedBlockParts = nil
|
||||
cs.Votes = NewHeightVoteSet(height, validators)
|
||||
cs.LastCommit = lastPrecommits
|
||||
cs.LastValidators = state.LastBondedValidators
|
||||
|
||||
cs.state = state
|
||||
cs.stagedBlock = nil
|
||||
|
||||
+21
-4
@@ -184,22 +184,39 @@ type Validation struct {
|
||||
Precommits []*Vote `json:"precommits"`
|
||||
|
||||
// Volatile
|
||||
hash []byte
|
||||
bitArray *BitArray
|
||||
firstPrecommit *Vote
|
||||
hash []byte
|
||||
bitArray *BitArray
|
||||
}
|
||||
|
||||
func (v *Validation) FirstPrecommit() *Vote {
|
||||
if len(v.Precommits) == 0 {
|
||||
return nil
|
||||
}
|
||||
if v.firstPrecommit != nil {
|
||||
return v.firstPrecommit
|
||||
}
|
||||
for _, precommit := range v.Precommits {
|
||||
if precommit != nil {
|
||||
v.firstPrecommit = precommit
|
||||
return precommit
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Validation) Height() int {
|
||||
if len(v.Precommits) == 0 {
|
||||
return 0
|
||||
}
|
||||
return v.Precommits[0].Height
|
||||
return v.FirstPrecommit().Height
|
||||
}
|
||||
|
||||
func (v *Validation) Round() int {
|
||||
if len(v.Precommits) == 0 {
|
||||
return 0
|
||||
}
|
||||
return v.Precommits[0].Round
|
||||
return v.FirstPrecommit().Round
|
||||
}
|
||||
|
||||
func (v *Validation) ValidateBasic() error {
|
||||
|
||||
Reference in New Issue
Block a user