tendermint/consensus/vote_set_test.go

321 lines
11 KiB
Go
Raw Normal View History

2014-10-14 13:11:54 -07:00
package consensus
import (
2014-10-31 18:35:38 -07:00
"bytes"
2014-12-17 01:37:13 -08:00
. "github.com/tendermint/tendermint/block"
2014-10-15 23:55:52 -07:00
. "github.com/tendermint/tendermint/common"
2014-10-31 18:35:38 -07:00
. "github.com/tendermint/tendermint/common/test"
2014-10-14 13:11:54 -07:00
"testing"
)
2014-10-17 16:48:27 -07:00
// NOTE: see consensus/test.go for common test methods.
2014-10-15 20:15:38 -07:00
2014-10-14 13:11:54 -07:00
func TestAddVote(t *testing.T) {
2014-12-17 01:37:13 -08:00
height, round := uint(1), uint(0)
voteSet, _, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1)
val0 := privValidators[0]
2014-10-15 20:15:38 -07:00
2014-10-15 23:55:52 -07:00
// t.Logf(">> %v", voteSet)
2014-10-15 20:15:38 -07:00
2014-12-17 01:37:13 -08:00
if voteSet.GetByAddress(val0.Address) != nil {
t.Errorf("Expected GetByAddress(val0.Address) to be nil")
2014-10-15 23:55:52 -07:00
}
if voteSet.BitArray().GetIndex(0) {
t.Errorf("Expected BitArray.GetIndex(0) to be false")
}
2014-10-30 03:32:09 -07:00
hash, header, ok := voteSet.TwoThirdsMajority()
if hash != nil || !header.IsZero() || ok {
2014-10-15 23:55:52 -07:00
t.Errorf("There should be no 2/3 majority")
}
2014-10-31 18:35:38 -07:00
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
2014-12-17 01:37:13 -08:00
vote.Signature = val0.SignVoteUnsafe(vote)
voteSet.Add(val0.Address, vote)
2014-10-15 20:15:38 -07:00
2014-12-17 01:37:13 -08:00
if voteSet.GetByAddress(val0.Address) == nil {
t.Errorf("Expected GetByAddress(val0.Address) to be present")
2014-10-15 23:55:52 -07:00
}
if !voteSet.BitArray().GetIndex(0) {
t.Errorf("Expected BitArray.GetIndex(0) to be true")
}
2014-10-30 03:32:09 -07:00
hash, header, ok = voteSet.TwoThirdsMajority()
if hash != nil || !header.IsZero() || ok {
2014-10-15 23:55:52 -07:00
t.Errorf("There should be no 2/3 majority")
}
2014-10-14 13:11:54 -07:00
}
func Test2_3Majority(t *testing.T) {
2014-12-17 01:37:13 -08:00
height, round := uint(1), uint(0)
voteSet, _, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1)
2014-10-15 23:55:52 -07:00
// 6 out of 10 voted for nil.
2014-10-31 18:35:38 -07:00
voteProto := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
2014-10-15 23:55:52 -07:00
for i := 0; i < 6; i++ {
2014-10-31 18:35:38 -07:00
vote := voteProto.Copy()
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[i].SignVoteUnsafe(vote)
voteSet.Add(privValidators[i].Address, vote)
2014-10-15 23:55:52 -07:00
}
2014-10-30 03:32:09 -07:00
hash, header, ok := voteSet.TwoThirdsMajority()
if hash != nil || !header.IsZero() || ok {
2014-10-15 23:55:52 -07:00
t.Errorf("There should be no 2/3 majority")
}
// 7th validator voted for some blockhash
2014-10-31 18:35:38 -07:00
{
vote := voteProto.Copy()
vote.BlockHash = CRandBytes(32)
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[6].SignVoteUnsafe(vote)
voteSet.Add(privValidators[6].Address, vote)
2014-10-31 18:35:38 -07:00
hash, header, ok = voteSet.TwoThirdsMajority()
if hash != nil || !header.IsZero() || ok {
t.Errorf("There should be no 2/3 majority")
}
}
// 8th validator voted for nil.
{
vote := voteProto.Copy()
vote.BlockHash = nil
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[7].SignVoteUnsafe(vote)
voteSet.Add(privValidators[7].Address, vote)
2014-10-31 18:35:38 -07:00
hash, header, ok = voteSet.TwoThirdsMajority()
if hash != nil || !header.IsZero() || !ok {
t.Errorf("There should be 2/3 majority for nil")
}
}
}
func Test2_3MajorityRedux(t *testing.T) {
2014-12-17 01:37:13 -08:00
height, round := uint(1), uint(0)
voteSet, _, privValidators := makeVoteSet(height, round, VoteTypePrevote, 100, 1)
2014-10-31 18:35:38 -07:00
blockHash := CRandBytes(32)
2014-12-17 01:37:13 -08:00
blockPartsTotal := uint(123)
2014-10-31 18:35:38 -07:00
blockParts := PartSetHeader{blockPartsTotal, CRandBytes(32)}
// 66 out of 100 voted for nil.
voteProto := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: blockParts}
for i := 0; i < 66; i++ {
vote := voteProto.Copy()
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[i].SignVoteUnsafe(vote)
voteSet.Add(privValidators[i].Address, vote)
2014-10-31 18:35:38 -07:00
}
hash, header, ok := voteSet.TwoThirdsMajority()
2014-10-30 03:32:09 -07:00
if hash != nil || !header.IsZero() || ok {
2014-10-15 23:55:52 -07:00
t.Errorf("There should be no 2/3 majority")
}
2014-10-31 18:35:38 -07:00
// 67th validator voted for nil
{
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil, BlockParts: PartSetHeader{}}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[66].SignVoteUnsafe(vote)
voteSet.Add(privValidators[66].Address, vote)
2014-10-31 18:35:38 -07:00
hash, header, ok = voteSet.TwoThirdsMajority()
if hash != nil || !header.IsZero() || ok {
t.Errorf("There should be no 2/3 majority: last vote added was nil")
}
}
// 68th validator voted for a different BlockParts PartSetHeader
{
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: PartSetHeader{blockPartsTotal, CRandBytes(32)}}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[67].SignVoteUnsafe(vote)
voteSet.Add(privValidators[67].Address, vote)
2014-10-31 18:35:38 -07:00
hash, header, ok = voteSet.TwoThirdsMajority()
if hash != nil || !header.IsZero() || ok {
t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Hash")
}
2014-10-15 23:55:52 -07:00
}
2014-10-31 18:35:38 -07:00
// 69th validator voted for different BlockParts Total
{
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: PartSetHeader{blockPartsTotal + 1, blockParts.Hash}}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[68].SignVoteUnsafe(vote)
voteSet.Add(privValidators[68].Address, vote)
2014-10-31 18:35:38 -07:00
hash, header, ok = voteSet.TwoThirdsMajority()
if hash != nil || !header.IsZero() || ok {
t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Total")
}
}
// 70th validator voted for different BlockHash
{
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: CRandBytes(32), BlockParts: blockParts}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[69].SignVoteUnsafe(vote)
voteSet.Add(privValidators[69].Address, vote)
2014-10-31 18:35:38 -07:00
hash, header, ok = voteSet.TwoThirdsMajority()
if hash != nil || !header.IsZero() || ok {
t.Errorf("There should be no 2/3 majority: last vote added had different BlockHash")
}
}
// 71st validator voted for the right BlockHash & BlockParts
{
vote := voteProto.Copy()
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[70].SignVoteUnsafe(vote)
voteSet.Add(privValidators[70].Address, vote)
2014-10-31 18:35:38 -07:00
hash, header, ok = voteSet.TwoThirdsMajority()
if !bytes.Equal(hash, blockHash) || !header.Equals(blockParts) || !ok {
t.Errorf("There should be 2/3 majority")
}
}
2014-10-15 23:55:52 -07:00
}
func TestBadVotes(t *testing.T) {
2014-12-17 01:37:13 -08:00
height, round := uint(1), uint(0)
voteSet, _, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1)
2014-10-15 23:55:52 -07:00
// val0 votes for nil.
2014-10-31 18:35:38 -07:00
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[0].SignVoteUnsafe(vote)
added, _, err := voteSet.Add(privValidators[0].Address, vote)
2014-10-15 23:55:52 -07:00
if !added || err != nil {
2014-12-17 01:37:13 -08:00
t.Errorf("Expected Add() to succeed")
2014-10-15 23:55:52 -07:00
}
// val0 votes again for some block.
2014-10-31 18:35:38 -07:00
vote = &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: CRandBytes(32)}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[0].SignVoteUnsafe(vote)
added, _, err = voteSet.Add(privValidators[0].Address, vote)
2014-10-15 23:55:52 -07:00
if added || err == nil {
2014-12-17 01:37:13 -08:00
t.Errorf("Expected Add() to fail, dupeout.")
2014-10-15 23:55:52 -07:00
}
// val1 votes on another height
2014-10-31 18:35:38 -07:00
vote = &Vote{Height: height + 1, Round: round, Type: VoteTypePrevote, BlockHash: nil}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[1].SignVoteUnsafe(vote)
added, _, err = voteSet.Add(privValidators[1].Address, vote)
2014-10-15 23:55:52 -07:00
if added {
2014-12-17 01:37:13 -08:00
t.Errorf("Expected Add() to fail, wrong height")
2014-10-15 23:55:52 -07:00
}
// val2 votes on another round
2014-10-31 18:35:38 -07:00
vote = &Vote{Height: height, Round: round + 1, Type: VoteTypePrevote, BlockHash: nil}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[2].SignVoteUnsafe(vote)
added, _, err = voteSet.Add(privValidators[2].Address, vote)
2014-10-15 23:55:52 -07:00
if added {
2014-12-17 01:37:13 -08:00
t.Errorf("Expected Add() to fail, wrong round")
2014-10-15 23:55:52 -07:00
}
// val3 votes of another type.
2014-10-31 18:35:38 -07:00
vote = &Vote{Height: height, Round: round, Type: VoteTypePrecommit, BlockHash: nil}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[3].SignVoteUnsafe(vote)
added, _, err = voteSet.Add(privValidators[3].Address, vote)
2014-10-15 23:55:52 -07:00
if added {
2014-12-17 01:37:13 -08:00
t.Errorf("Expected Add() to fail, wrong type")
2014-10-15 23:55:52 -07:00
}
}
func TestAddCommitsToPrevoteVotes(t *testing.T) {
2014-12-17 01:37:13 -08:00
height, round := uint(2), uint(5)
voteSet, _, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1)
2014-10-15 23:55:52 -07:00
// val0, val1, val2, val3, val4, val5 vote for nil.
2014-10-31 18:35:38 -07:00
voteProto := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
2014-10-15 23:55:52 -07:00
for i := 0; i < 6; i++ {
2014-10-31 18:35:38 -07:00
vote := voteProto.Copy()
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[i].SignVoteUnsafe(vote)
voteSet.Add(privValidators[i].Address, vote)
2014-10-15 23:55:52 -07:00
}
2014-10-30 03:32:09 -07:00
hash, header, ok := voteSet.TwoThirdsMajority()
if hash != nil || !header.IsZero() || ok {
2014-10-15 23:55:52 -07:00
t.Errorf("There should be no 2/3 majority")
}
// Attempt to add a commit from val6 at a previous height
2014-10-31 18:35:38 -07:00
vote := &Vote{Height: height - 1, Round: round, Type: VoteTypeCommit, BlockHash: nil}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[6].SignVoteUnsafe(vote)
added, _, _ := voteSet.Add(privValidators[6].Address, vote)
2014-10-15 23:55:52 -07:00
if added {
2014-12-17 01:37:13 -08:00
t.Errorf("Expected Add() to fail, wrong height.")
2014-10-15 23:55:52 -07:00
}
// Attempt to add a commit from val6 at a later round
2014-10-31 18:35:38 -07:00
vote = &Vote{Height: height, Round: round + 1, Type: VoteTypeCommit, BlockHash: nil}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[6].SignVoteUnsafe(vote)
added, _, _ = voteSet.Add(privValidators[6].Address, vote)
2014-10-15 23:55:52 -07:00
if added {
2014-12-17 01:37:13 -08:00
t.Errorf("Expected Add() to fail, cannot add future round vote.")
2014-10-15 23:55:52 -07:00
}
// Attempt to add a commit from val6 for currrent height/round.
2014-10-31 18:35:38 -07:00
vote = &Vote{Height: height, Round: round, Type: VoteTypeCommit, BlockHash: nil}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[6].SignVoteUnsafe(vote)
added, _, err := voteSet.Add(privValidators[6].Address, vote)
2014-10-15 23:55:52 -07:00
if added || err == nil {
2014-12-17 01:37:13 -08:00
t.Errorf("Expected Add() to fail, only prior round commits can be added.")
2014-10-15 23:55:52 -07:00
}
// Add commit from val6 at a previous round
2014-10-31 18:35:38 -07:00
vote = &Vote{Height: height, Round: round - 1, Type: VoteTypeCommit, BlockHash: nil}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[6].SignVoteUnsafe(vote)
added, _, err = voteSet.Add(privValidators[6].Address, vote)
2014-10-15 23:55:52 -07:00
if !added || err != nil {
2014-12-17 01:37:13 -08:00
t.Errorf("Expected Add() to succeed, commit for prior rounds are relevant.")
2014-10-15 23:55:52 -07:00
}
// Also add commit from val7 for previous round.
2014-10-31 18:35:38 -07:00
vote = &Vote{Height: height, Round: round - 2, Type: VoteTypeCommit, BlockHash: nil}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[7].SignVoteUnsafe(vote)
added, _, err = voteSet.Add(privValidators[7].Address, vote)
2014-10-15 23:55:52 -07:00
if !added || err != nil {
2014-12-17 01:37:13 -08:00
t.Errorf("Expected Add() to succeed. err: %v", err)
2014-10-15 23:55:52 -07:00
}
// We should have 2/3 majority
2014-10-30 03:32:09 -07:00
hash, header, ok = voteSet.TwoThirdsMajority()
if hash != nil || !header.IsZero() || !ok {
2014-10-15 23:55:52 -07:00
t.Errorf("There should be 2/3 majority for nil")
}
2014-10-14 13:11:54 -07:00
}
2014-10-31 18:35:38 -07:00
func TestMakeValidation(t *testing.T) {
2014-12-17 01:37:13 -08:00
height, round := uint(1), uint(0)
voteSet, _, privValidators := makeVoteSet(height, round, VoteTypeCommit, 10, 1)
2014-10-31 18:35:38 -07:00
blockHash, blockParts := CRandBytes(32), PartSetHeader{123, CRandBytes(32)}
// 6 out of 10 voted for some block.
voteProto := &Vote{Height: height, Round: round, Type: VoteTypeCommit,
BlockHash: blockHash, BlockParts: blockParts}
for i := 0; i < 6; i++ {
vote := voteProto.Copy()
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[i].SignVoteUnsafe(vote)
voteSet.Add(privValidators[i].Address, vote)
2014-10-31 18:35:38 -07:00
}
// MakeValidation should fail.
AssertPanics(t, "Doesn't have +2/3 majority", func() { voteSet.MakeValidation() })
// 7th voted for some other block.
{
vote := &Vote{Height: height, Round: round, Type: VoteTypeCommit,
BlockHash: CRandBytes(32),
BlockParts: PartSetHeader{123, CRandBytes(32)}}
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[6].SignVoteUnsafe(vote)
voteSet.Add(privValidators[6].Address, vote)
2014-10-31 18:35:38 -07:00
}
// The 8th voted like everyone else.
{
vote := voteProto.Copy()
2014-12-17 01:37:13 -08:00
vote.Signature = privValidators[7].SignVoteUnsafe(vote)
voteSet.Add(privValidators[7].Address, vote)
2014-10-31 18:35:38 -07:00
}
validation := voteSet.MakeValidation()
// Validation should have 10 elements
if len(validation.Commits) != 10 {
t.Errorf("Validation Commits should have the same number of commits as validators")
}
// Ensure that Validation commits are ordered.
2014-12-17 01:37:13 -08:00
if err := validation.ValidateBasic(); err != nil {
t.Errorf("Error in Validation.ValidateBasic(): %v", err)
2014-10-31 18:35:38 -07:00
}
2014-12-17 01:37:13 -08:00
2014-10-31 18:35:38 -07:00
}