You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.8 KiB

  1. package types
  2. import (
  3. "testing"
  4. "github.com/stretchr/testify/assert"
  5. "github.com/stretchr/testify/require"
  6. "github.com/tendermint/tendermint/crypto/secp256k1"
  7. "github.com/tendermint/tendermint/crypto/tmhash"
  8. )
  9. type voteData struct {
  10. vote1 *Vote
  11. vote2 *Vote
  12. valid bool
  13. }
  14. func makeVote(val PrivValidator, chainID string, valIndex int, height int64, round, step int, blockID BlockID) *Vote {
  15. v := &Vote{
  16. ValidatorAddress: val.GetAddress(),
  17. ValidatorIndex: valIndex,
  18. Height: height,
  19. Round: round,
  20. Type: byte(step),
  21. BlockID: blockID,
  22. }
  23. err := val.SignVote(chainID, v)
  24. if err != nil {
  25. panic(err)
  26. }
  27. return v
  28. }
  29. func TestEvidence(t *testing.T) {
  30. val := NewMockPV()
  31. val2 := NewMockPV()
  32. blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))
  33. blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash"))
  34. blockID3 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash"))
  35. blockID4 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash2"))
  36. const chainID = "mychain"
  37. vote1 := makeVote(val, chainID, 0, 10, 2, 1, blockID)
  38. badVote := makeVote(val, chainID, 0, 10, 2, 1, blockID)
  39. err := val2.SignVote(chainID, badVote)
  40. if err != nil {
  41. panic(err)
  42. }
  43. cases := []voteData{
  44. {vote1, makeVote(val, chainID, 0, 10, 2, 1, blockID2), true}, // different block ids
  45. {vote1, makeVote(val, chainID, 0, 10, 2, 1, blockID3), true},
  46. {vote1, makeVote(val, chainID, 0, 10, 2, 1, blockID4), true},
  47. {vote1, makeVote(val, chainID, 0, 10, 2, 1, blockID), false}, // wrong block id
  48. {vote1, makeVote(val, "mychain2", 0, 10, 2, 1, blockID2), false}, // wrong chain id
  49. {vote1, makeVote(val, chainID, 1, 10, 2, 1, blockID2), false}, // wrong val index
  50. {vote1, makeVote(val, chainID, 0, 11, 2, 1, blockID2), false}, // wrong height
  51. {vote1, makeVote(val, chainID, 0, 10, 3, 1, blockID2), false}, // wrong round
  52. {vote1, makeVote(val, chainID, 0, 10, 2, 2, blockID2), false}, // wrong step
  53. {vote1, makeVote(val2, chainID, 0, 10, 2, 1, blockID), false}, // wrong validator
  54. {vote1, badVote, false}, // signed by wrong key
  55. }
  56. pubKey := val.GetPubKey()
  57. for _, c := range cases {
  58. ev := &DuplicateVoteEvidence{
  59. VoteA: c.vote1,
  60. VoteB: c.vote2,
  61. }
  62. if c.valid {
  63. assert.Nil(t, ev.Verify(chainID, pubKey), "evidence should be valid")
  64. } else {
  65. assert.NotNil(t, ev.Verify(chainID, pubKey), "evidence should be invalid")
  66. }
  67. }
  68. }
  69. func TestDuplicatedVoteEvidence(t *testing.T) {
  70. ev := randomDuplicatedVoteEvidence()
  71. assert.True(t, ev.Equal(ev))
  72. assert.False(t, ev.Equal(&DuplicateVoteEvidence{}))
  73. }
  74. func TestEvidenceList(t *testing.T) {
  75. ev := randomDuplicatedVoteEvidence()
  76. evl := EvidenceList([]Evidence{ev})
  77. assert.NotNil(t, evl.Hash())
  78. assert.True(t, evl.Has(ev))
  79. assert.False(t, evl.Has(&DuplicateVoteEvidence{}))
  80. }
  81. func TestMaxEvidenceBytes(t *testing.T) {
  82. val := NewMockPV()
  83. blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), 1000, tmhash.Sum([]byte("partshash")))
  84. blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), 1000, tmhash.Sum([]byte("partshash")))
  85. const chainID = "mychain"
  86. ev := &DuplicateVoteEvidence{
  87. PubKey: secp256k1.GenPrivKey().PubKey(), // use secp because it's pubkey is longer
  88. VoteA: makeVote(val, chainID, 0, 10, 2, 1, blockID),
  89. VoteB: makeVote(val, chainID, 0, 10, 2, 1, blockID2),
  90. }
  91. bz, err := cdc.MarshalBinary(ev)
  92. require.NoError(t, err)
  93. assert.Equal(t, MaxEvidenceBytes, len(bz))
  94. }
  95. func randomDuplicatedVoteEvidence() *DuplicateVoteEvidence {
  96. val := NewMockPV()
  97. blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))
  98. blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash"))
  99. const chainID = "mychain"
  100. return &DuplicateVoteEvidence{
  101. VoteA: makeVote(val, chainID, 0, 10, 2, 1, blockID),
  102. VoteB: makeVote(val, chainID, 0, 10, 2, 1, blockID2),
  103. }
  104. }