github.com/okex/exchain@v1.8.0/libs/tendermint/types/evidence_test.go (about) 1 package types 2 3 import ( 4 "math" 5 "testing" 6 "time" 7 8 "github.com/okex/exchain/libs/tendermint/crypto" 9 "github.com/okex/exchain/libs/tendermint/crypto/ed25519" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 14 "github.com/okex/exchain/libs/tendermint/crypto/secp256k1" 15 "github.com/okex/exchain/libs/tendermint/crypto/tmhash" 16 ) 17 18 type voteData struct { 19 vote1 *Vote 20 vote2 *Vote 21 valid bool 22 } 23 24 func makeVote( 25 t *testing.T, val PrivValidator, chainID string, valIndex int, height int64, round, step int, blockID BlockID, 26 ) *Vote { 27 pubKey, err := val.GetPubKey() 28 require.NoError(t, err) 29 v := &Vote{ 30 ValidatorAddress: pubKey.Address(), 31 ValidatorIndex: valIndex, 32 Height: height, 33 Round: round, 34 Type: SignedMsgType(step), 35 BlockID: blockID, 36 } 37 err = val.SignVote(chainID, v) 38 if err != nil { 39 panic(err) 40 } 41 return v 42 } 43 44 func TestEvidence(t *testing.T) { 45 val := NewMockPV() 46 val2 := NewMockPV() 47 48 blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash")) 49 blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash")) 50 blockID3 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash")) 51 blockID4 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash2")) 52 53 const chainID = "mychain" 54 55 vote1 := makeVote(t, val, chainID, 0, 10, 2, 1, blockID) 56 badVote := makeVote(t, val, chainID, 0, 10, 2, 1, blockID) 57 err := val2.SignVote(chainID, badVote) 58 assert.NoError(t, err) 59 60 cases := []voteData{ 61 {vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID2), true}, // different block ids 62 {vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID3), true}, 63 {vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID4), true}, 64 {vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID), false}, // wrong block id 65 {vote1, makeVote(t, val, "mychain2", 0, 10, 2, 1, blockID2), false}, // wrong chain id 66 {vote1, makeVote(t, val, chainID, 1, 10, 2, 1, blockID2), false}, // wrong val index 67 {vote1, makeVote(t, val, chainID, 0, 11, 2, 1, blockID2), false}, // wrong height 68 {vote1, makeVote(t, val, chainID, 0, 10, 3, 1, blockID2), false}, // wrong round 69 {vote1, makeVote(t, val, chainID, 0, 10, 2, 2, blockID2), false}, // wrong step 70 {vote1, makeVote(t, val2, chainID, 0, 10, 2, 1, blockID), false}, // wrong validator 71 {vote1, badVote, false}, // signed by wrong key 72 } 73 74 pubKey, err := val.GetPubKey() 75 require.NoError(t, err) 76 for _, c := range cases { 77 ev := &DuplicateVoteEvidence{ 78 VoteA: c.vote1, 79 VoteB: c.vote2, 80 } 81 if c.valid { 82 assert.Nil(t, ev.Verify(chainID, pubKey), "evidence should be valid") 83 } else { 84 assert.NotNil(t, ev.Verify(chainID, pubKey), "evidence should be invalid") 85 } 86 } 87 } 88 89 func TestDuplicatedVoteEvidence(t *testing.T) { 90 ev := randomDuplicatedVoteEvidence(t) 91 92 assert.True(t, ev.Equal(ev)) 93 assert.False(t, ev.Equal(&DuplicateVoteEvidence{})) 94 } 95 96 func TestEvidenceList(t *testing.T) { 97 ev := randomDuplicatedVoteEvidence(t) 98 evl := EvidenceList([]Evidence{ev}) 99 100 assert.NotNil(t, evl.Hash()) 101 assert.True(t, evl.Has(ev)) 102 assert.False(t, evl.Has(&DuplicateVoteEvidence{})) 103 } 104 105 func TestMaxEvidenceBytes(t *testing.T) { 106 val := NewMockPV() 107 blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) 108 blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) 109 const chainID = "mychain" 110 ev := &DuplicateVoteEvidence{ 111 PubKey: secp256k1.GenPrivKey().PubKey(), // use secp because it's pubkey is longer 112 VoteA: makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, math.MaxInt64, blockID), 113 VoteB: makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, math.MaxInt64, blockID2), 114 } 115 116 bz, err := cdc.MarshalBinaryLengthPrefixed(ev) 117 require.NoError(t, err) 118 119 assert.EqualValues(t, MaxEvidenceBytes, len(bz)) 120 } 121 122 func randomDuplicatedVoteEvidence(t *testing.T) *DuplicateVoteEvidence { 123 val := NewMockPV() 124 blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash")) 125 blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash")) 126 const chainID = "mychain" 127 return &DuplicateVoteEvidence{ 128 VoteA: makeVote(t, val, chainID, 0, 10, 2, 1, blockID), 129 VoteB: makeVote(t, val, chainID, 0, 10, 2, 1, blockID2), 130 } 131 } 132 133 func TestDuplicateVoteEvidenceValidation(t *testing.T) { 134 val := NewMockPV() 135 blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) 136 blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) 137 const chainID = "mychain" 138 139 testCases := []struct { 140 testName string 141 malleateEvidence func(*DuplicateVoteEvidence) 142 expectErr bool 143 }{ 144 {"Good DuplicateVoteEvidence", func(ev *DuplicateVoteEvidence) {}, false}, 145 {"Nil vote A", func(ev *DuplicateVoteEvidence) { ev.VoteA = nil }, true}, 146 {"Nil vote B", func(ev *DuplicateVoteEvidence) { ev.VoteB = nil }, true}, 147 {"Nil votes", func(ev *DuplicateVoteEvidence) { 148 ev.VoteA = nil 149 ev.VoteB = nil 150 }, true}, 151 {"Invalid vote type", func(ev *DuplicateVoteEvidence) { 152 ev.VoteA = makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0, blockID2) 153 }, true}, 154 {"Invalid vote order", func(ev *DuplicateVoteEvidence) { 155 swap := ev.VoteA.Copy() 156 ev.VoteA = ev.VoteB.Copy() 157 ev.VoteB = swap 158 }, true}, 159 } 160 for _, tc := range testCases { 161 tc := tc 162 t.Run(tc.testName, func(t *testing.T) { 163 pk := secp256k1.GenPrivKey().PubKey() 164 vote1 := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0x02, blockID) 165 vote2 := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0x02, blockID2) 166 ev := NewDuplicateVoteEvidence(pk, vote1, vote2) 167 tc.malleateEvidence(ev) 168 assert.Equal(t, tc.expectErr, ev.ValidateBasic() != nil, "Validate Basic had an unexpected result") 169 }) 170 } 171 } 172 173 func TestMockGoodEvidenceValidateBasic(t *testing.T) { 174 goodEvidence := NewMockEvidence(int64(1), time.Now(), 1, []byte{1}) 175 assert.Nil(t, goodEvidence.ValidateBasic()) 176 } 177 178 func TestMockBadEvidenceValidateBasic(t *testing.T) { 179 badEvidence := NewMockEvidence(int64(1), time.Now(), 1, []byte{1}) 180 assert.Nil(t, badEvidence.ValidateBasic()) 181 } 182 183 func TestEvidenceProto(t *testing.T) { 184 // -------- Votes -------- 185 val := NewMockPV() 186 blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) 187 blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) 188 const chainID = "mychain" 189 v := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, 1, 0x01, blockID) 190 v2 := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, 2, 0x01, blockID2) 191 192 tests := []struct { 193 testName string 194 evidence Evidence 195 wantErr bool 196 wantErr2 bool 197 }{ 198 {"&DuplicateVoteEvidence empty fail", &DuplicateVoteEvidence{}, true, true}, 199 {"&DuplicateVoteEvidence nil voteB", &DuplicateVoteEvidence{VoteA: v, VoteB: nil}, true, true}, 200 {"&DuplicateVoteEvidence nil voteA", &DuplicateVoteEvidence{VoteA: nil, VoteB: v}, true, true}, 201 {"&DuplicateVoteEvidence success", &DuplicateVoteEvidence{VoteA: v2, VoteB: v, 202 PubKey: val.PrivKey.PubKey()}, false, false}, 203 } 204 for _, tt := range tests { 205 tt := tt 206 t.Run(tt.testName, func(t *testing.T) { 207 pb, err := EvidenceToProto(tt.evidence) 208 if tt.wantErr { 209 assert.Error(t, err, tt.testName) 210 return 211 } 212 assert.NoError(t, err, tt.testName) 213 214 evi, err := EvidenceFromProto(pb) 215 if tt.wantErr2 { 216 assert.Error(t, err, tt.testName) 217 return 218 } 219 require.Equal(t, tt.evidence, evi, tt.testName) 220 }) 221 } 222 } 223 224 type emptyPubKey struct{} 225 226 func (emptyPubKey) Address() crypto.Address { 227 return []byte("empty") 228 } 229 230 func (emptyPubKey) Bytes() []byte { 231 return []byte("empty") 232 } 233 234 func (emptyPubKey) VerifyBytes(msg []byte, sig []byte) bool { 235 return false 236 } 237 238 func (emptyPubKey) Equals(crypto.PubKey) bool { 239 return false 240 } 241 242 var _ crypto.PubKey = emptyPubKey{} 243 244 func TestDuplicateVoteEvidenceAmino(t *testing.T) { 245 var duplicateVoteEvidenceTestCases = []DuplicateVoteEvidence{ 246 {}, 247 { 248 PubKey: secp256k1.GenPrivKey().PubKey(), 249 VoteA: makeVote(t, NewMockPV(), "mychain", 0, 10, 2, 1, makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))), 250 VoteB: makeVote(t, NewMockPV(), "mychain", 0, 10, 2, 1, makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))), 251 }, 252 { 253 PubKey: ed25519.GenPrivKey().PubKey(), 254 }, 255 { 256 PubKey: emptyPubKey{}, 257 VoteA: &Vote{}, 258 }, 259 } 260 cdc.RegisterConcrete(emptyPubKey{}, "emptyPubKey", nil) 261 262 for _, tc := range duplicateVoteEvidenceTestCases { 263 expectData, err := cdc.MarshalBinaryBare(tc) 264 require.NoError(t, err) 265 266 require.Equal(t, len(expectData), tc.AminoSize(cdc)+4) 267 268 var expectValue DuplicateVoteEvidence 269 err = cdc.UnmarshalBinaryBare(expectData, &expectValue) 270 require.NoError(t, err) 271 272 var actualValue DuplicateVoteEvidence 273 tmp, err := cdc.UnmarshalBinaryBareWithRegisteredUnmarshaller(expectData, &actualValue) 274 require.NoError(t, err) 275 _, ok := tmp.(DuplicateVoteEvidence) 276 require.False(t, ok) 277 _, ok = tmp.(*DuplicateVoteEvidence) 278 require.True(t, ok) 279 actualValue = *(tmp.(*DuplicateVoteEvidence)) 280 281 require.EqualValues(t, expectValue, actualValue) 282 } 283 } 284 285 func TestEvidenceAmino(t *testing.T) { 286 var evidenceTestCases = []Evidence{ 287 // nil, 288 &DuplicateVoteEvidence{}, 289 } 290 291 for _, evi := range evidenceTestCases { 292 expectData, err := cdc.MarshalBinaryBare(evi) 293 require.NoError(t, err) 294 295 var expectValue Evidence 296 err = cdc.UnmarshalBinaryBare(expectData, &expectValue) 297 require.NoError(t, err) 298 299 var actualValue Evidence 300 tmp, err := cdc.UnmarshalBinaryBareWithRegisteredUnmarshaller(expectData, &actualValue) 301 require.NoError(t, err) 302 _, ok := tmp.(Evidence) 303 require.True(t, ok) 304 actualValue = (tmp.(Evidence)) 305 306 require.EqualValues(t, expectValue, actualValue) 307 } 308 309 evidenceTestCases = []Evidence{ 310 &MockEvidence{}, 311 &MockRandomEvidence{}, 312 } 313 314 for _, evi := range evidenceTestCases { 315 expectData, err := cdc.MarshalBinaryBare(evi) 316 require.NoError(t, err) 317 318 var expectValue Evidence 319 err = cdc.UnmarshalBinaryBare(expectData, &expectValue) 320 require.NoError(t, err) 321 322 var actualValue Evidence 323 _, err = cdc.UnmarshalBinaryBareWithRegisteredUnmarshaller(expectData, &actualValue) 324 require.Error(t, err) 325 } 326 }