|
|
@ -6,12 +6,54 @@ import ( |
|
|
|
. "github.com/tendermint/tendermint/block" |
|
|
|
. "github.com/tendermint/tendermint/common" |
|
|
|
. "github.com/tendermint/tendermint/common/test" |
|
|
|
"github.com/tendermint/tendermint/state" |
|
|
|
|
|
|
|
"testing" |
|
|
|
) |
|
|
|
|
|
|
|
// NOTE: see consensus/test.go for common test methods.
|
|
|
|
|
|
|
|
// Convenience: Return new vote with different height
|
|
|
|
func withHeight(vote *Vote, height uint) *Vote { |
|
|
|
vote = vote.Copy() |
|
|
|
vote.Height = height |
|
|
|
return vote |
|
|
|
} |
|
|
|
|
|
|
|
// Convenience: Return new vote with different round
|
|
|
|
func withRound(vote *Vote, round uint) *Vote { |
|
|
|
vote = vote.Copy() |
|
|
|
vote.Round = round |
|
|
|
return vote |
|
|
|
} |
|
|
|
|
|
|
|
// Convenience: Return new vote with different type
|
|
|
|
func withType(vote *Vote, type_ byte) *Vote { |
|
|
|
vote = vote.Copy() |
|
|
|
vote.Type = type_ |
|
|
|
return vote |
|
|
|
} |
|
|
|
|
|
|
|
// Convenience: Return new vote with different blockHash
|
|
|
|
func withBlockHash(vote *Vote, blockHash []byte) *Vote { |
|
|
|
vote = vote.Copy() |
|
|
|
vote.BlockHash = blockHash |
|
|
|
return vote |
|
|
|
} |
|
|
|
|
|
|
|
// Convenience: Return new vote with different blockParts
|
|
|
|
func withBlockParts(vote *Vote, blockParts PartSetHeader) *Vote { |
|
|
|
vote = vote.Copy() |
|
|
|
vote.BlockParts = blockParts |
|
|
|
return vote |
|
|
|
} |
|
|
|
|
|
|
|
func signAddVote(privVal *state.PrivValidator, vote *Vote, voteSet *VoteSet) (bool, error) { |
|
|
|
vote.Signature = privVal.SignVoteUnsafe(vote) |
|
|
|
added, _, err := voteSet.Add(privVal.Address, vote) |
|
|
|
return added, err |
|
|
|
} |
|
|
|
|
|
|
|
func TestAddVote(t *testing.T) { |
|
|
|
height, round := uint(1), uint(0) |
|
|
|
voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) |
|
|
@ -31,8 +73,7 @@ func TestAddVote(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} |
|
|
|
vote.Signature = val0.SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(val0.Address, vote) |
|
|
|
signAddVote(val0, vote, voteSet) |
|
|
|
|
|
|
|
if voteSet.GetByAddress(val0.Address) == nil { |
|
|
|
t.Errorf("Expected GetByAddress(val0.Address) to be present") |
|
|
@ -50,12 +91,11 @@ func Test2_3Majority(t *testing.T) { |
|
|
|
height, round := uint(1), uint(0) |
|
|
|
voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) |
|
|
|
|
|
|
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} |
|
|
|
|
|
|
|
// 6 out of 10 voted for nil.
|
|
|
|
voteProto := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} |
|
|
|
for i := 0; i < 6; i++ { |
|
|
|
vote := voteProto.Copy() |
|
|
|
vote.Signature = privValidators[i].SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(privValidators[i].Address, vote) |
|
|
|
signAddVote(privValidators[i], vote, voteSet) |
|
|
|
} |
|
|
|
hash, header, ok := voteSet.TwoThirdsMajority() |
|
|
|
if hash != nil || !header.IsZero() || ok { |
|
|
@ -64,10 +104,7 @@ func Test2_3Majority(t *testing.T) { |
|
|
|
|
|
|
|
// 7th validator voted for some blockhash
|
|
|
|
{ |
|
|
|
vote := voteProto.Copy() |
|
|
|
vote.BlockHash = CRandBytes(32) |
|
|
|
vote.Signature = privValidators[6].SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(privValidators[6].Address, vote) |
|
|
|
signAddVote(privValidators[6], withBlockHash(vote, RandBytes(32)), voteSet) |
|
|
|
hash, header, ok = voteSet.TwoThirdsMajority() |
|
|
|
if hash != nil || !header.IsZero() || ok { |
|
|
|
t.Errorf("There should be no 2/3 majority") |
|
|
@ -76,10 +113,7 @@ func Test2_3Majority(t *testing.T) { |
|
|
|
|
|
|
|
// 8th validator voted for nil.
|
|
|
|
{ |
|
|
|
vote := voteProto.Copy() |
|
|
|
vote.BlockHash = nil |
|
|
|
vote.Signature = privValidators[7].SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(privValidators[7].Address, vote) |
|
|
|
signAddVote(privValidators[7], vote, voteSet) |
|
|
|
hash, header, ok = voteSet.TwoThirdsMajority() |
|
|
|
if hash != nil || !header.IsZero() || !ok { |
|
|
|
t.Errorf("There should be 2/3 majority for nil") |
|
|
@ -95,12 +129,11 @@ func Test2_3MajorityRedux(t *testing.T) { |
|
|
|
blockPartsTotal := uint(123) |
|
|
|
blockParts := PartSetHeader{blockPartsTotal, CRandBytes(32)} |
|
|
|
|
|
|
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: blockParts} |
|
|
|
|
|
|
|
// 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() |
|
|
|
vote.Signature = privValidators[i].SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(privValidators[i].Address, vote) |
|
|
|
signAddVote(privValidators[i], vote, voteSet) |
|
|
|
} |
|
|
|
hash, header, ok := voteSet.TwoThirdsMajority() |
|
|
|
if hash != nil || !header.IsZero() || ok { |
|
|
@ -109,9 +142,7 @@ func Test2_3MajorityRedux(t *testing.T) { |
|
|
|
|
|
|
|
// 67th validator voted for nil
|
|
|
|
{ |
|
|
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil, BlockParts: PartSetHeader{}} |
|
|
|
vote.Signature = privValidators[66].SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(privValidators[66].Address, vote) |
|
|
|
signAddVote(privValidators[66], withBlockHash(vote, nil), voteSet) |
|
|
|
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") |
|
|
@ -120,9 +151,8 @@ func Test2_3MajorityRedux(t *testing.T) { |
|
|
|
|
|
|
|
// 68th validator voted for a different BlockParts PartSetHeader
|
|
|
|
{ |
|
|
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: PartSetHeader{blockPartsTotal, CRandBytes(32)}} |
|
|
|
vote.Signature = privValidators[67].SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(privValidators[67].Address, vote) |
|
|
|
blockParts := PartSetHeader{blockPartsTotal, CRandBytes(32)} |
|
|
|
signAddVote(privValidators[67], withBlockParts(vote, blockParts), voteSet) |
|
|
|
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") |
|
|
@ -131,9 +161,8 @@ func Test2_3MajorityRedux(t *testing.T) { |
|
|
|
|
|
|
|
// 69th validator voted for different BlockParts Total
|
|
|
|
{ |
|
|
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: PartSetHeader{blockPartsTotal + 1, blockParts.Hash}} |
|
|
|
vote.Signature = privValidators[68].SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(privValidators[68].Address, vote) |
|
|
|
blockParts := PartSetHeader{blockPartsTotal + 1, blockParts.Hash} |
|
|
|
signAddVote(privValidators[68], withBlockParts(vote, blockParts), voteSet) |
|
|
|
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") |
|
|
@ -142,9 +171,7 @@ func Test2_3MajorityRedux(t *testing.T) { |
|
|
|
|
|
|
|
// 70th validator voted for different BlockHash
|
|
|
|
{ |
|
|
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: CRandBytes(32), BlockParts: blockParts} |
|
|
|
vote.Signature = privValidators[69].SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(privValidators[69].Address, vote) |
|
|
|
signAddVote(privValidators[69], withBlockHash(vote, RandBytes(32)), voteSet) |
|
|
|
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") |
|
|
@ -153,9 +180,7 @@ func Test2_3MajorityRedux(t *testing.T) { |
|
|
|
|
|
|
|
// 71st validator voted for the right BlockHash & BlockParts
|
|
|
|
{ |
|
|
|
vote := voteProto.Copy() |
|
|
|
vote.Signature = privValidators[70].SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(privValidators[70].Address, vote) |
|
|
|
signAddVote(privValidators[70], vote, voteSet) |
|
|
|
hash, header, ok = voteSet.TwoThirdsMajority() |
|
|
|
if !bytes.Equal(hash, blockHash) || !header.Equals(blockParts) || !ok { |
|
|
|
t.Errorf("There should be 2/3 majority") |
|
|
@ -169,40 +194,31 @@ func TestBadVotes(t *testing.T) { |
|
|
|
|
|
|
|
// val0 votes for nil.
|
|
|
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} |
|
|
|
vote.Signature = privValidators[0].SignVoteUnsafe(vote) |
|
|
|
added, _, err := voteSet.Add(privValidators[0].Address, vote) |
|
|
|
added, err := signAddVote(privValidators[0], vote, voteSet) |
|
|
|
if !added || err != nil { |
|
|
|
t.Errorf("Expected Add() to succeed") |
|
|
|
} |
|
|
|
|
|
|
|
// val0 votes again for some block.
|
|
|
|
vote = &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: CRandBytes(32)} |
|
|
|
vote.Signature = privValidators[0].SignVoteUnsafe(vote) |
|
|
|
added, _, err = voteSet.Add(privValidators[0].Address, vote) |
|
|
|
added, err = signAddVote(privValidators[0], withBlockHash(vote, RandBytes(32)), voteSet) |
|
|
|
if added || err == nil { |
|
|
|
t.Errorf("Expected Add() to fail, dupeout.") |
|
|
|
} |
|
|
|
|
|
|
|
// val1 votes on another height
|
|
|
|
vote = &Vote{Height: height + 1, Round: round, Type: VoteTypePrevote, BlockHash: nil} |
|
|
|
vote.Signature = privValidators[1].SignVoteUnsafe(vote) |
|
|
|
added, _, err = voteSet.Add(privValidators[1].Address, vote) |
|
|
|
added, err = signAddVote(privValidators[1], withHeight(vote, height+1), voteSet) |
|
|
|
if added { |
|
|
|
t.Errorf("Expected Add() to fail, wrong height") |
|
|
|
} |
|
|
|
|
|
|
|
// val2 votes on another round
|
|
|
|
vote = &Vote{Height: height, Round: round + 1, Type: VoteTypePrevote, BlockHash: nil} |
|
|
|
vote.Signature = privValidators[2].SignVoteUnsafe(vote) |
|
|
|
added, _, err = voteSet.Add(privValidators[2].Address, vote) |
|
|
|
added, err = signAddVote(privValidators[2], withRound(vote, round+1), voteSet) |
|
|
|
if added { |
|
|
|
t.Errorf("Expected Add() to fail, wrong round") |
|
|
|
} |
|
|
|
|
|
|
|
// val3 votes of another type.
|
|
|
|
vote = &Vote{Height: height, Round: round, Type: VoteTypePrecommit, BlockHash: nil} |
|
|
|
vote.Signature = privValidators[3].SignVoteUnsafe(vote) |
|
|
|
added, _, err = voteSet.Add(privValidators[3].Address, vote) |
|
|
|
added, err = signAddVote(privValidators[3], withType(vote, VoteTypePrecommit), voteSet) |
|
|
|
if added { |
|
|
|
t.Errorf("Expected Add() to fail, wrong type") |
|
|
|
} |
|
|
@ -213,11 +229,9 @@ func TestAddCommitsToPrevoteVotes(t *testing.T) { |
|
|
|
voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) |
|
|
|
|
|
|
|
// val0, val1, val2, val3, val4, val5 vote for nil.
|
|
|
|
voteProto := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} |
|
|
|
vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} |
|
|
|
for i := 0; i < 6; i++ { |
|
|
|
vote := voteProto.Copy() |
|
|
|
vote.Signature = privValidators[i].SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(privValidators[i].Address, vote) |
|
|
|
signAddVote(privValidators[i], vote, voteSet) |
|
|
|
} |
|
|
|
hash, header, ok := voteSet.TwoThirdsMajority() |
|
|
|
if hash != nil || !header.IsZero() || ok { |
|
|
@ -225,41 +239,36 @@ func TestAddCommitsToPrevoteVotes(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
// Attempt to add a commit from val6 at a previous height
|
|
|
|
vote := &Vote{Height: height - 1, Round: round, Type: VoteTypeCommit, BlockHash: nil} |
|
|
|
vote.Signature = privValidators[6].SignVoteUnsafe(vote) |
|
|
|
added, _, _ := voteSet.Add(privValidators[6].Address, vote) |
|
|
|
vote = &Vote{Height: height - 1, Round: round, Type: VoteTypeCommit, BlockHash: nil} |
|
|
|
added, _ := signAddVote(privValidators[6], vote, voteSet) |
|
|
|
if added { |
|
|
|
t.Errorf("Expected Add() to fail, wrong height.") |
|
|
|
} |
|
|
|
|
|
|
|
// Attempt to add a commit from val6 at a later round
|
|
|
|
vote = &Vote{Height: height, Round: round + 1, Type: VoteTypeCommit, BlockHash: nil} |
|
|
|
vote.Signature = privValidators[6].SignVoteUnsafe(vote) |
|
|
|
added, _, _ = voteSet.Add(privValidators[6].Address, vote) |
|
|
|
added, _ = signAddVote(privValidators[6], vote, voteSet) |
|
|
|
if added { |
|
|
|
t.Errorf("Expected Add() to fail, cannot add future round vote.") |
|
|
|
} |
|
|
|
|
|
|
|
// Attempt to add a commit from val6 for currrent height/round.
|
|
|
|
vote = &Vote{Height: height, Round: round, Type: VoteTypeCommit, BlockHash: nil} |
|
|
|
vote.Signature = privValidators[6].SignVoteUnsafe(vote) |
|
|
|
added, _, err := voteSet.Add(privValidators[6].Address, vote) |
|
|
|
added, err := signAddVote(privValidators[6], vote, voteSet) |
|
|
|
if added || err == nil { |
|
|
|
t.Errorf("Expected Add() to fail, only prior round commits can be added.") |
|
|
|
} |
|
|
|
|
|
|
|
// Add commit from val6 at a previous round
|
|
|
|
vote = &Vote{Height: height, Round: round - 1, Type: VoteTypeCommit, BlockHash: nil} |
|
|
|
vote.Signature = privValidators[6].SignVoteUnsafe(vote) |
|
|
|
added, _, err = voteSet.Add(privValidators[6].Address, vote) |
|
|
|
added, err = signAddVote(privValidators[6], vote, voteSet) |
|
|
|
if !added || err != nil { |
|
|
|
t.Errorf("Expected Add() to succeed, commit for prior rounds are relevant.") |
|
|
|
} |
|
|
|
|
|
|
|
// Also add commit from val7 for previous round.
|
|
|
|
vote = &Vote{Height: height, Round: round - 2, Type: VoteTypeCommit, BlockHash: nil} |
|
|
|
vote.Signature = privValidators[7].SignVoteUnsafe(vote) |
|
|
|
added, _, err = voteSet.Add(privValidators[7].Address, vote) |
|
|
|
added, err = signAddVote(privValidators[7], vote, voteSet) |
|
|
|
if !added || err != nil { |
|
|
|
t.Errorf("Expected Add() to succeed. err: %v", err) |
|
|
|
} |
|
|
@ -277,13 +286,12 @@ func TestMakeValidation(t *testing.T) { |
|
|
|
voteSet, _, privValidators := randVoteSet(height, round, VoteTypeCommit, 10, 1) |
|
|
|
blockHash, blockParts := CRandBytes(32), PartSetHeader{123, CRandBytes(32)} |
|
|
|
|
|
|
|
// 6 out of 10 voted for some block.
|
|
|
|
voteProto := &Vote{Height: height, Round: round, Type: VoteTypeCommit, |
|
|
|
vote := &Vote{Height: height, Round: round, Type: VoteTypeCommit, |
|
|
|
BlockHash: blockHash, BlockParts: blockParts} |
|
|
|
|
|
|
|
// 6 out of 10 voted for some block.
|
|
|
|
for i := 0; i < 6; i++ { |
|
|
|
vote := voteProto.Copy() |
|
|
|
vote.Signature = privValidators[i].SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(privValidators[i].Address, vote) |
|
|
|
signAddVote(privValidators[i], vote, voteSet) |
|
|
|
} |
|
|
|
|
|
|
|
// MakeValidation should fail.
|
|
|
@ -291,18 +299,14 @@ func TestMakeValidation(t *testing.T) { |
|
|
|
|
|
|
|
// 7th voted for some other block.
|
|
|
|
{ |
|
|
|
vote := &Vote{Height: height, Round: round, Type: VoteTypeCommit, |
|
|
|
BlockHash: CRandBytes(32), |
|
|
|
BlockParts: PartSetHeader{123, CRandBytes(32)}} |
|
|
|
vote.Signature = privValidators[6].SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(privValidators[6].Address, vote) |
|
|
|
vote := withBlockHash(vote, RandBytes(32)) |
|
|
|
vote = withBlockParts(vote, PartSetHeader{123, RandBytes(32)}) |
|
|
|
signAddVote(privValidators[6], vote, voteSet) |
|
|
|
} |
|
|
|
|
|
|
|
// The 8th voted like everyone else.
|
|
|
|
{ |
|
|
|
vote := voteProto.Copy() |
|
|
|
vote.Signature = privValidators[7].SignVoteUnsafe(vote) |
|
|
|
voteSet.Add(privValidators[7].Address, vote) |
|
|
|
signAddVote(privValidators[7], vote, voteSet) |
|
|
|
} |
|
|
|
|
|
|
|
validation := voteSet.MakeValidation() |
|
|
|