Fix HeightVoteSet bug where first catchup vote doesn't get added

This commit is contained in:
Jae Kwon 2015-12-31 15:02:38 -08:00
parent 0e7b069cd8
commit 9247b0fbd2
6 changed files with 89 additions and 32 deletions

View File

@ -95,15 +95,16 @@ func (hvs *HeightVoteSet) AddByIndex(valIndex int, vote *types.Vote, peerKey str
if voteSet == nil {
if _, ok := hvs.peerCatchupRounds[peerKey]; !ok {
hvs.addRound(vote.Round)
voteSet = hvs.getVoteSet(vote.Round, vote.Type)
hvs.peerCatchupRounds[peerKey] = vote.Round
} else {
// Peer has sent a vote that does not match our round,
// for more than one round. Bad peer!
// TODO punish peer.
log.Warn("Deal with peer giving votes from unwanted rounds")
}
return
}
}
added, address, err = voteSet.AddByIndex(valIndex, vote)
return
}

View File

@ -0,0 +1,48 @@
package consensus
import (
_ "github.com/tendermint/tendermint/config/tendermint_test"
"github.com/tendermint/tendermint/types"
"testing"
)
func TestPeerCatchupRounds(t *testing.T) {
valSet, privVals := types.RandValidatorSet(10, 1)
hvs := NewHeightVoteSet(1, valSet)
vote999_0 := makeVoteHR(t, 1, 999, privVals[0])
added, _, err := hvs.AddByIndex(0, vote999_0, "peer1")
if !added || err != nil {
t.Error("Expected to successfully add vote from peer", added, err)
}
vote1000_0 := makeVoteHR(t, 1, 1000, privVals[0])
added, _, err = hvs.AddByIndex(0, vote1000_0, "peer1")
if added {
t.Error("Expected to *not* add vote from peer, too many catchup rounds.")
}
added, _, err = hvs.AddByIndex(0, vote1000_0, "peer2")
if !added || err != nil {
t.Error("Expected to successfully add vote from another peer")
}
}
func makeVoteHR(t *testing.T, height, round int, privVal *types.PrivValidator) *types.Vote {
vote := &types.Vote{
Height: height,
Round: round,
Type: types.VoteTypePrecommit,
BlockHash: []byte("fakehash"),
}
chainID := config.GetString("chain_id")
err := privVal.SignVote(chainID, vote)
if err != nil {
t.Fatalf("Error signing vote: %v", err)
return nil
}
return vote
}

View File

@ -83,3 +83,24 @@ func (vc validatorCodec) Compare(o1 interface{}, o2 interface{}) int {
PanicSanity("ValidatorCodec.Compare not implemented")
return 0
}
//--------------------------------------------------------------------------------
// For testing...
func RandValidator(randPower bool, minPower int64) (*Validator, *PrivValidator) {
privVal := GenPrivValidator()
_, tempFilePath := Tempfile("priv_validator_")
privVal.SetFile(tempFilePath)
votePower := minPower
if randPower {
votePower += int64(RandUint32())
}
val := &Validator{
Address: privVal.Address,
PubKey: privVal.PubKey,
LastCommitHeight: 0,
VotingPower: votePower,
Accum: 0,
}
return val, privVal
}

View File

@ -309,3 +309,19 @@ type accumComparable int64
func (ac accumComparable) Less(o interface{}) bool {
return int64(ac) > int64(o.(accumComparable))
}
//----------------------------------------
// For testing
func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []*PrivValidator) {
vals := make([]*Validator, numValidators)
privValidators := make([]*PrivValidator, numValidators)
for i := 0; i < numValidators; i++ {
val, privValidator := RandValidator(false, votingPower)
vals[i] = val
privValidators[i] = privValidator
}
valSet := NewValidatorSet(vals)
sort.Sort(PrivValidatorsByAddress(privValidators))
return valSet, privValidators
}

View File

@ -300,24 +300,3 @@ func (voteSet *VoteSet) MakeValidation() *Validation {
Precommits: precommits,
}
}
//--------------------------------------------------------------------------------
// For testing...
func RandValidator(randPower bool, minPower int64) (*Validator, *PrivValidator) {
privVal := GenPrivValidator()
_, tempFilePath := Tempfile("priv_validator_")
privVal.SetFile(tempFilePath)
votePower := minPower
if randPower {
votePower += int64(RandUint32())
}
val := &Validator{
Address: privVal.Address,
PubKey: privVal.PubKey,
LastCommitHeight: 0,
VotingPower: votePower,
Accum: 0,
}
return val, privVal
}

View File

@ -2,7 +2,6 @@ package types
import (
"bytes"
"sort"
. "github.com/tendermint/go-common"
. "github.com/tendermint/go-common/test"
@ -11,16 +10,9 @@ import (
"testing"
)
// Move it out?
func randVoteSet(height int, round int, type_ byte, numValidators int, votingPower int64) (*VoteSet, *ValidatorSet, []*PrivValidator) {
vals := make([]*Validator, numValidators)
privValidators := make([]*PrivValidator, numValidators)
for i := 0; i < numValidators; i++ {
val, privValidator := RandValidator(false, votingPower)
vals[i] = val
privValidators[i] = privValidator
}
valSet := NewValidatorSet(vals)
sort.Sort(PrivValidatorsByAddress(privValidators))
valSet, privValidators := RandValidatorSet(numValidators, votingPower)
return NewVoteSet(height, round, type_, valSet), valSet, privValidators
}