Browse Source

Fix consensus:

* Use LastValidators when a Vote is received for the last height.
* Fix Validation.Height/Round to use FirstPrecommit.
pull/96/head
Jae Kwon 10 years ago
parent
commit
26c192b047
3 changed files with 30 additions and 7 deletions
  1. +5
    -3
      consensus/reactor.go
  2. +4
    -0
      consensus/state.go
  3. +21
    -4
      types/block.go

+ 5
- 3
consensus/reactor.go View File

@ -177,18 +177,20 @@ func (conR *ConsensusReactor) Receive(chId byte, peer *p2p.Peer, msgBytes []byte
switch msg := msg_.(type) { switch msg := msg_.(type) {
case *VoteMessage: case *VoteMessage:
vote := msg.Vote vote := msg.Vote
var validators *ValidatorSet
var validators *sm.ValidatorSet
if rs.Height == vote.Height { if rs.Height == vote.Height {
validators = rs.Validators validators = rs.Validators
} else if rs.Height == vote.Height+1 { } else if rs.Height == vote.Height+1 {
validators = rs.LastBondedValidators
if !(rs.Step == RoundStepNewHeight && vote.Type == types.VoteTypePrecommit) { if !(rs.Step == RoundStepNewHeight && vote.Type == types.VoteTypePrecommit) {
return // Wrong height, not a LastCommit straggler commit. return // Wrong height, not a LastCommit straggler commit.
} }
validators = rs.LastValidators
} else { } else {
return // Wrong height. Not necessarily a bad peer. 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) address, _ := validators.GetByIndex(msg.ValidatorIndex)
added, index, err := conR.conS.AddVote(address, vote, peer.Key) added, index, err := conR.conS.AddVote(address, vote, peer.Key)
if err != nil { if err != nil {


+ 4
- 0
consensus/state.go View File

@ -215,6 +215,7 @@ type RoundState struct {
LockedBlockParts *types.PartSet LockedBlockParts *types.PartSet
Votes *HeightVoteSet Votes *HeightVoteSet
LastCommit *VoteSet // Last precommits at Height-1 LastCommit *VoteSet // Last precommits at Height-1
LastValidators *sm.ValidatorSet
} }
func (rs *RoundState) String() string { func (rs *RoundState) String() string {
@ -233,6 +234,7 @@ func (rs *RoundState) StringIndented(indent string) string {
%s LockedBlock: %v %v %s LockedBlock: %v %v
%s Votes: %v %s Votes: %v
%s LastCommit: %v %s LastCommit: %v
%s LastValidators: %v
%s}`, %s}`,
indent, rs.Height, rs.Round, rs.Step, indent, rs.Height, rs.Round, rs.Step,
indent, rs.StartTime, indent, rs.StartTime,
@ -244,6 +246,7 @@ func (rs *RoundState) StringIndented(indent string) string {
indent, rs.LockedBlockParts.StringShort(), rs.LockedBlock.StringShort(), indent, rs.LockedBlockParts.StringShort(), rs.LockedBlock.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) indent)
} }
@ -406,6 +409,7 @@ func (cs *ConsensusState) updateToState(state *sm.State, contiguous bool) {
cs.LockedBlockParts = nil cs.LockedBlockParts = nil
cs.Votes = NewHeightVoteSet(height, validators) cs.Votes = NewHeightVoteSet(height, validators)
cs.LastCommit = lastPrecommits cs.LastCommit = lastPrecommits
cs.LastValidators = state.LastBondedValidators
cs.state = state cs.state = state
cs.stagedBlock = nil cs.stagedBlock = nil


+ 21
- 4
types/block.go View File

@ -184,22 +184,39 @@ type Validation struct {
Precommits []*Vote `json:"precommits"` Precommits []*Vote `json:"precommits"`
// Volatile // 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 { func (v *Validation) Height() int {
if len(v.Precommits) == 0 { if len(v.Precommits) == 0 {
return 0 return 0
} }
return v.Precommits[0].Height
return v.FirstPrecommit().Height
} }
func (v *Validation) Round() int { func (v *Validation) Round() int {
if len(v.Precommits) == 0 { if len(v.Precommits) == 0 {
return 0 return 0
} }
return v.Precommits[0].Round
return v.FirstPrecommit().Round
} }
func (v *Validation) ValidateBasic() error { func (v *Validation) ValidateBasic() error {


Loading…
Cancel
Save