diff --git a/evidence/reactor_test.go b/evidence/reactor_test.go index ea9657d23..69dcdec57 100644 --- a/evidence/reactor_test.go +++ b/evidence/reactor_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" cfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/crypto/secp256k1" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/p2p" @@ -178,3 +179,30 @@ func TestReactorSelectiveBroadcast(t *testing.T) { peers := reactors[1].Switch.Peers().List() assert.Equal(t, 1, len(peers)) } +func TestEvidenceListMessageValidationBasic(t *testing.T) { + + testCases := []struct { + testName string + malleateEvListMsg func(*EvidenceListMessage) + expectErr bool + }{ + {"Good EvidenceListMessage", func(evList *EvidenceListMessage) {}, false}, + {"Invalid EvidenceListMessage", func(evList *EvidenceListMessage) { + evList.Evidence = append(evList.Evidence, + &types.DuplicateVoteEvidence{PubKey: secp256k1.GenPrivKey().PubKey()}) + }, true}, + } + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + evListMsg := &EvidenceListMessage{} + n := 3 + valAddr := []byte("myval") + evListMsg.Evidence = make([]types.Evidence, n) + for i := 0; i < n; i++ { + evListMsg.Evidence[i] = types.NewMockGoodEvidence(int64(i+1), 0, valAddr) + } + tc.malleateEvListMsg(evListMsg) + assert.Equal(t, tc.expectErr, evListMsg.ValidateBasic() != nil, "Validate Basic had an unexpected result") + }) + } +} diff --git a/types/evidence_test.go b/types/evidence_test.go index 033b51e5d..a96b63a9e 100644 --- a/types/evidence_test.go +++ b/types/evidence_test.go @@ -61,7 +61,7 @@ func TestEvidence(t *testing.T) { {vote1, makeVote(val, chainID, 0, 10, 3, 1, blockID2), false}, // wrong round {vote1, makeVote(val, chainID, 0, 10, 2, 2, blockID2), false}, // wrong step {vote1, makeVote(val2, chainID, 0, 10, 2, 1, blockID), false}, // wrong validator - {vote1, badVote, false}, // signed by wrong key + {vote1, badVote, false}, // signed by wrong key } pubKey := val.GetPubKey() @@ -121,3 +121,38 @@ func randomDuplicatedVoteEvidence() *DuplicateVoteEvidence { VoteB: makeVote(val, chainID, 0, 10, 2, 1, blockID2), } } + +func TestDuplicateVoteEvidenceValidation(t *testing.T) { + val := NewMockPV() + blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) + blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) + const chainID = "mychain" + + testCases := []struct { + testName string + malleateEvidence func(*DuplicateVoteEvidence) + expectErr bool + }{ + {"Good DuplicateVoteEvidence", func(ev *DuplicateVoteEvidence) {}, false}, + {"Nil vote A", func(ev *DuplicateVoteEvidence) { ev.VoteA = nil }, true}, + {"Nil vote B", func(ev *DuplicateVoteEvidence) { ev.VoteB = nil }, true}, + {"Nil votes", func(ev *DuplicateVoteEvidence) { + ev.VoteA = nil + ev.VoteB = nil + }, true}, + {"Invalid vote type", func(ev *DuplicateVoteEvidence) { + ev.VoteA = makeVote(val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0, blockID2) + }, true}, + } + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + ev := &DuplicateVoteEvidence{ + PubKey: secp256k1.GenPrivKey().PubKey(), + VoteA: makeVote(val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0x02, blockID), + VoteB: makeVote(val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0x02, blockID2), + } + tc.malleateEvidence(ev) + assert.Equal(t, tc.expectErr, ev.ValidateBasic() != nil, "Validate Basic had an unexpected result") + }) + } +} diff --git a/types/heartbeat_test.go b/types/heartbeat_test.go index e1ffdd6f1..0951c7b9d 100644 --- a/types/heartbeat_test.go +++ b/types/heartbeat_test.go @@ -3,8 +3,10 @@ package types import ( "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/secp256k1" ) func TestHeartbeatCopy(t *testing.T) { @@ -58,3 +60,45 @@ func TestHeartbeatWriteSignBytes(t *testing.T) { require.Equal(t, string(signBytes), "null") }) } + +func TestHeartbeatValidateBasic(t *testing.T) { + testCases := []struct { + testName string + malleateHeartBeat func(*Heartbeat) + expectErr bool + }{ + {"Good HeartBeat", func(hb *Heartbeat) {}, false}, + {"Invalid address size", func(hb *Heartbeat) { + hb.ValidatorAddress = nil + }, true}, + {"Negative validator index", func(hb *Heartbeat) { + hb.ValidatorIndex = -1 + }, true}, + {"Negative height", func(hb *Heartbeat) { + hb.Height = -1 + }, true}, + {"Negative round", func(hb *Heartbeat) { + hb.Round = -1 + }, true}, + {"Negative sequence", func(hb *Heartbeat) { + hb.Sequence = -1 + }, true}, + {"Missing signature", func(hb *Heartbeat) { + hb.Signature = nil + }, true}, + {"Signature too big", func(hb *Heartbeat) { + hb.Signature = make([]byte, MaxSignatureSize+1) + }, true}, + } + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + hb := &Heartbeat{ + ValidatorAddress: secp256k1.GenPrivKey().PubKey().Address(), + Signature: make([]byte, 4), + ValidatorIndex: 1, Height: 10, Round: 1} + + tc.malleateHeartBeat(hb) + assert.Equal(t, tc.expectErr, hb.ValidateBasic() != nil, "Validate Basic had an unexpected result") + }) + } +} diff --git a/types/part_set_test.go b/types/part_set_test.go index 3576e747e..e597088c6 100644 --- a/types/part_set_test.go +++ b/types/part_set_test.go @@ -83,3 +83,48 @@ func TestWrongProof(t *testing.T) { t.Errorf("Expected to fail adding a part with bad bytes.") } } + +func TestPartSetHeaderSetValidateBasic(t *testing.T) { + + testCases := []struct { + testName string + malleatePartSetHeader func(*PartSetHeader) + expectErr bool + }{ + {"Good PartSet", func(psHeader *PartSetHeader) {}, false}, + {"Negative Total", func(psHeader *PartSetHeader) { psHeader.Total = -2 }, true}, + {"Invalid Hash", func(psHeader *PartSetHeader) { psHeader.Hash = make([]byte, 1) }, true}, + } + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + data := cmn.RandBytes(testPartSize * 100) + ps := NewPartSetFromData(data, testPartSize) + psHeader := ps.Header() + tc.malleatePartSetHeader(&psHeader) + assert.Equal(t, tc.expectErr, psHeader.ValidateBasic() != nil, "Validate Basic had an unexpected result") + }) + } +} + +func TestPartValidateBasic(t *testing.T) { + + testCases := []struct { + testName string + malleatePart func(*Part) + expectErr bool + }{ + {"Good Part", func(pt *Part) {}, false}, + {"Negative index", func(pt *Part) { pt.Index = -1 }, true}, + {"Too big part", func(pt *Part) { pt.Bytes = make([]byte, BlockPartSizeBytes+1) }, true}, + } + + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + data := cmn.RandBytes(testPartSize * 100) + ps := NewPartSetFromData(data, testPartSize) + part := ps.GetPart(0) + tc.malleatePart(part) + assert.Equal(t, tc.expectErr, part.ValidateBasic() != nil, "Validate Basic had an unexpected result") + }) + } +} diff --git a/types/proposal_test.go b/types/proposal_test.go index 9738db2d2..f1c048e1d 100644 --- a/types/proposal_test.go +++ b/types/proposal_test.go @@ -1,10 +1,13 @@ package types import ( + "math" "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/tmhash" ) var testProposal *Proposal @@ -97,3 +100,41 @@ func BenchmarkProposalVerifySignature(b *testing.B) { pubKey.VerifyBytes(testProposal.SignBytes("test_chain_id"), testProposal.Signature) } } + +func TestProposalValidateBasic(t *testing.T) { + + privVal := NewMockPV() + testCases := []struct { + testName string + malleateProposal func(*Proposal) + expectErr bool + }{ + {"Good Proposal", func(p *Proposal) {}, false}, + {"Invalid Type", func(p *Proposal) { p.Type = PrecommitType }, true}, + {"Invalid Height", func(p *Proposal) { p.Height = -1 }, true}, + {"Invalid Round", func(p *Proposal) { p.Round = -1 }, true}, + {"Invalid POLRound", func(p *Proposal) { p.POLRound = -2 }, true}, + {"Invalid BlockId", func(p *Proposal) { + p.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}} + }, true}, + {"Invalid Signature", func(p *Proposal) { + p.Signature = make([]byte, 0) + }, true}, + {"Too big Signature", func(p *Proposal) { + p.Signature = make([]byte, MaxSignatureSize+1) + }, true}, + } + blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) + + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + prop := NewProposal( + 4, 2, 2, + blockID) + err := privVal.SignProposal("test_chain_id", prop) + require.NoError(t, err) + tc.malleateProposal(prop) + assert.Equal(t, tc.expectErr, prop.ValidateBasic() != nil, "Validate Basic had an unexpected result") + }) + } +} diff --git a/types/vote_test.go b/types/vote_test.go index cda54f898..942f2d6b9 100644 --- a/types/vote_test.go +++ b/types/vote_test.go @@ -250,3 +250,31 @@ func TestVoteString(t *testing.T) { t.Errorf("Got unexpected string for Vote. Expected:\n%v\nGot:\n%v", expected, str2) } } + +func TestVoteValidateBasic(t *testing.T) { + privVal := NewMockPV() + + testCases := []struct { + testName string + malleateVote func(*Vote) + expectErr bool + }{ + {"Good Vote", func(v *Vote) {}, false}, + {"Negative Height", func(v *Vote) { v.Height = -1 }, true}, + {"Negative Round", func(v *Vote) { v.Round = -1 }, true}, + {"Invalid BlockID", func(v *Vote) { v.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}} }, true}, + {"Invalid Address", func(v *Vote) { v.ValidatorAddress = make([]byte, 1) }, true}, + {"Invalid ValidatorIndex", func(v *Vote) { v.ValidatorIndex = -1 }, true}, + {"Invalid Signature", func(v *Vote) { v.Signature = nil }, true}, + {"Too big Signature", func(v *Vote) { v.Signature = make([]byte, MaxSignatureSize+1) }, true}, + } + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + vote := examplePrecommit() + err := privVal.SignVote("test_chain_id", vote) + require.NoError(t, err) + tc.malleateVote(vote) + assert.Equal(t, tc.expectErr, vote.ValidateBasic() != nil, "Validate Basic had an unexpected result") + }) + } +}