package consensus
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/tendermint/tendermint/libs/log"
|
|
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
|
"github.com/tendermint/tendermint/types"
|
|
)
|
|
|
|
func peerStateSetup(h, r, v int) *PeerState {
|
|
ps := NewPeerState(log.TestingLogger(), "testPeerState")
|
|
ps.PRS.Height = int64(h)
|
|
ps.PRS.Round = int32(r)
|
|
ps.ensureVoteBitArrays(int64(h), v)
|
|
return ps
|
|
}
|
|
|
|
func TestSetHasVote(t *testing.T) {
|
|
ps := peerStateSetup(1, 1, 1)
|
|
pva := ps.PRS.Prevotes.Copy()
|
|
|
|
// nil vote should return ErrPeerStateNilVote
|
|
err := ps.SetHasVote(nil)
|
|
require.Equal(t, ErrPeerStateSetNilVote, err)
|
|
|
|
// the peer giving an invalid index should returns ErrPeerStateInvalidVoteIndex
|
|
v0 := &types.Vote{
|
|
Height: 1,
|
|
ValidatorIndex: -1,
|
|
Round: 1,
|
|
Type: tmproto.PrevoteType,
|
|
}
|
|
|
|
err = ps.SetHasVote(v0)
|
|
require.Equal(t, ErrPeerStateInvalidVoteIndex, err)
|
|
|
|
// the peer giving an invalid index should returns ErrPeerStateInvalidVoteIndex
|
|
v1 := &types.Vote{
|
|
Height: 1,
|
|
ValidatorIndex: 1,
|
|
Round: 1,
|
|
Type: tmproto.PrevoteType,
|
|
}
|
|
|
|
err = ps.SetHasVote(v1)
|
|
require.Equal(t, ErrPeerStateInvalidVoteIndex, err)
|
|
|
|
// the peer giving a correct index should return nil (vote has been set)
|
|
v2 := &types.Vote{
|
|
Height: 1,
|
|
ValidatorIndex: 0,
|
|
Round: 1,
|
|
Type: tmproto.PrevoteType,
|
|
}
|
|
require.Nil(t, ps.SetHasVote(v2))
|
|
|
|
// verify vote
|
|
pva.SetIndex(0, true)
|
|
require.Equal(t, pva, ps.getVoteBitArray(1, 1, tmproto.PrevoteType))
|
|
|
|
// the vote is not in the correct height/round/voteType should return nil (ignore the vote)
|
|
v3 := &types.Vote{
|
|
Height: 2,
|
|
ValidatorIndex: 0,
|
|
Round: 1,
|
|
Type: tmproto.PrevoteType,
|
|
}
|
|
require.Nil(t, ps.SetHasVote(v3))
|
|
// prevote bitarray has no update
|
|
require.Equal(t, pva, ps.getVoteBitArray(1, 1, tmproto.PrevoteType))
|
|
}
|
|
|
|
func TestApplyHasVoteMessage(t *testing.T) {
|
|
ps := peerStateSetup(1, 1, 1)
|
|
pva := ps.PRS.Prevotes.Copy()
|
|
|
|
// ignore the message with an invalid height
|
|
msg := &HasVoteMessage{
|
|
Height: 2,
|
|
}
|
|
require.Nil(t, ps.ApplyHasVoteMessage(msg))
|
|
|
|
// apply a message like v2 in TestSetHasVote
|
|
msg2 := &HasVoteMessage{
|
|
Height: 1,
|
|
Index: 0,
|
|
Round: 1,
|
|
Type: tmproto.PrevoteType,
|
|
}
|
|
|
|
require.Nil(t, ps.ApplyHasVoteMessage(msg2))
|
|
|
|
// verify vote
|
|
pva.SetIndex(0, true)
|
|
require.Equal(t, pva, ps.getVoteBitArray(1, 1, tmproto.PrevoteType))
|
|
|
|
// skip test cases like v & v3 in TestSetHasVote due to the same path
|
|
}
|