Fix HeightVoteSet bug where first catchup vote doesn't get added
This commit is contained in:
parent
0e7b069cd8
commit
9247b0fbd2
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue