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.

571 lines
19 KiB

max-bytes PR follow-up (#2318) * ReapMaxTxs: return all txs if max is negative this mirrors ReapMaxBytes behavior See https://github.com/tendermint/tendermint/pull/2184#discussion_r214439950 * increase MaxAminoOverheadForBlock tested with: ``` func TestMaxAminoOverheadForBlock(t *testing.T) { maxChainID := "" for i := 0; i < MaxChainIDLen; i++ { maxChainID += "𠜎" } h := Header{ ChainID: maxChainID, Height: 10, Time: time.Now().UTC(), NumTxs: 100, TotalTxs: 200, LastBlockID: makeBlockID(make([]byte, 20), 300, make([]byte, 20)), LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), DataHash: tmhash.Sum([]byte("data_hash")), ValidatorsHash: tmhash.Sum([]byte("validators_hash")), NextValidatorsHash: tmhash.Sum([]byte("next_validators_hash")), ConsensusHash: tmhash.Sum([]byte("consensus_hash")), AppHash: tmhash.Sum([]byte("app_hash")), LastResultsHash: tmhash.Sum([]byte("last_results_hash")), EvidenceHash: tmhash.Sum([]byte("evidence_hash")), ProposerAddress: tmhash.Sum([]byte("proposer_address")), } b := Block{ Header: h, Data: Data{Txs: makeTxs(10000, 100)}, Evidence: EvidenceData{}, LastCommit: &Commit{}, } bz, err := cdc.MarshalBinary(b) require.NoError(t, err) assert.Equal(t, MaxHeaderBytes+MaxAminoOverheadForBlock-2, len(bz)-1000000-20000-1) } ``` * fix MaxYYY constants calculation by using math.MaxInt64 See https://github.com/tendermint/tendermint/pull/2184#discussion_r214444244 * pass mempool filter as an option See https://github.com/tendermint/tendermint/pull/2184#discussion_r214445869 * fixes after Dev's comments
6 years ago
max-bytes PR follow-up (#2318) * ReapMaxTxs: return all txs if max is negative this mirrors ReapMaxBytes behavior See https://github.com/tendermint/tendermint/pull/2184#discussion_r214439950 * increase MaxAminoOverheadForBlock tested with: ``` func TestMaxAminoOverheadForBlock(t *testing.T) { maxChainID := "" for i := 0; i < MaxChainIDLen; i++ { maxChainID += "𠜎" } h := Header{ ChainID: maxChainID, Height: 10, Time: time.Now().UTC(), NumTxs: 100, TotalTxs: 200, LastBlockID: makeBlockID(make([]byte, 20), 300, make([]byte, 20)), LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), DataHash: tmhash.Sum([]byte("data_hash")), ValidatorsHash: tmhash.Sum([]byte("validators_hash")), NextValidatorsHash: tmhash.Sum([]byte("next_validators_hash")), ConsensusHash: tmhash.Sum([]byte("consensus_hash")), AppHash: tmhash.Sum([]byte("app_hash")), LastResultsHash: tmhash.Sum([]byte("last_results_hash")), EvidenceHash: tmhash.Sum([]byte("evidence_hash")), ProposerAddress: tmhash.Sum([]byte("proposer_address")), } b := Block{ Header: h, Data: Data{Txs: makeTxs(10000, 100)}, Evidence: EvidenceData{}, LastCommit: &Commit{}, } bz, err := cdc.MarshalBinary(b) require.NoError(t, err) assert.Equal(t, MaxHeaderBytes+MaxAminoOverheadForBlock-2, len(bz)-1000000-20000-1) } ``` * fix MaxYYY constants calculation by using math.MaxInt64 See https://github.com/tendermint/tendermint/pull/2184#discussion_r214444244 * pass mempool filter as an option See https://github.com/tendermint/tendermint/pull/2184#discussion_r214445869 * fixes after Dev's comments
6 years ago
  1. package types
  2. import (
  3. "math"
  4. "testing"
  5. "time"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/stretchr/testify/require"
  8. "github.com/tendermint/tendermint/crypto"
  9. "github.com/tendermint/tendermint/crypto/ed25519"
  10. "github.com/tendermint/tendermint/crypto/tmhash"
  11. tmrand "github.com/tendermint/tendermint/libs/rand"
  12. )
  13. type voteData struct {
  14. vote1 *Vote
  15. vote2 *Vote
  16. valid bool
  17. }
  18. func makeVote(
  19. t *testing.T, val PrivValidator, chainID string, valIndex int, height int64, round, step int, blockID BlockID,
  20. ) *Vote {
  21. pubKey, err := val.GetPubKey()
  22. require.NoError(t, err)
  23. v := &Vote{
  24. ValidatorAddress: pubKey.Address(),
  25. ValidatorIndex: valIndex,
  26. Height: height,
  27. Round: round,
  28. Type: SignedMsgType(step),
  29. BlockID: blockID,
  30. }
  31. err = val.SignVote(chainID, v)
  32. if err != nil {
  33. panic(err)
  34. }
  35. return v
  36. }
  37. func TestEvidence(t *testing.T) {
  38. val := NewMockPV()
  39. val2 := NewMockPV()
  40. blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))
  41. blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash"))
  42. blockID3 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash"))
  43. blockID4 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash2"))
  44. const chainID = "mychain"
  45. vote1 := makeVote(t, val, chainID, 0, 10, 2, 1, blockID)
  46. badVote := makeVote(t, val, chainID, 0, 10, 2, 1, blockID)
  47. err := val2.SignVote(chainID, badVote)
  48. assert.NoError(t, err)
  49. cases := []voteData{
  50. {vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID2), true}, // different block ids
  51. {vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID3), true},
  52. {vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID4), true},
  53. {vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID), false}, // wrong block id
  54. {vote1, makeVote(t, val, "mychain2", 0, 10, 2, 1, blockID2), false}, // wrong chain id
  55. {vote1, makeVote(t, val, chainID, 1, 10, 2, 1, blockID2), false}, // wrong val index
  56. {vote1, makeVote(t, val, chainID, 0, 11, 2, 1, blockID2), false}, // wrong height
  57. {vote1, makeVote(t, val, chainID, 0, 10, 3, 1, blockID2), false}, // wrong round
  58. {vote1, makeVote(t, val, chainID, 0, 10, 2, 2, blockID2), false}, // wrong step
  59. {vote1, makeVote(t, val2, chainID, 0, 10, 2, 1, blockID), false}, // wrong validator
  60. {vote1, badVote, false}, // signed by wrong key
  61. }
  62. pubKey, err := val.GetPubKey()
  63. require.NoError(t, err)
  64. for _, c := range cases {
  65. ev := &DuplicateVoteEvidence{
  66. VoteA: c.vote1,
  67. VoteB: c.vote2,
  68. }
  69. if c.valid {
  70. assert.Nil(t, ev.Verify(chainID, pubKey), "evidence should be valid")
  71. } else {
  72. assert.NotNil(t, ev.Verify(chainID, pubKey), "evidence should be invalid")
  73. }
  74. }
  75. }
  76. func TestDuplicatedVoteEvidence(t *testing.T) {
  77. ev := randomDuplicatedVoteEvidence(t)
  78. assert.True(t, ev.Equal(ev))
  79. assert.False(t, ev.Equal(&DuplicateVoteEvidence{}))
  80. }
  81. func TestEvidenceList(t *testing.T) {
  82. ev := randomDuplicatedVoteEvidence(t)
  83. evl := EvidenceList([]Evidence{ev})
  84. assert.NotNil(t, evl.Hash())
  85. assert.True(t, evl.Has(ev))
  86. assert.False(t, evl.Has(&DuplicateVoteEvidence{}))
  87. }
  88. func TestMaxEvidenceBytes(t *testing.T) {
  89. val := NewMockPV()
  90. blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  91. blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  92. const chainID = "mychain"
  93. ev := &DuplicateVoteEvidence{
  94. VoteA: makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, math.MaxInt64, blockID),
  95. VoteB: makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, math.MaxInt64, blockID2),
  96. }
  97. //TODO: Add other types of evidence to test and set MaxEvidenceBytes accordingly
  98. // evl := &LunaticValidatorEvidence{
  99. // Header: makeHeaderRandom(),
  100. // Vote: makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, math.MaxInt64, blockID2),
  101. // InvalidHeaderField: "",
  102. // }
  103. // evp := &PhantomValidatorEvidence{
  104. // Header: makeHeaderRandom(),
  105. // Vote: makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, math.MaxInt64, blockID2),
  106. // LastHeightValidatorWasInSet: math.MaxInt64,
  107. // }
  108. // signedHeader := SignedHeader{Header: makeHeaderRandom(), Commit: randCommit(time.Now())}
  109. // evc := &ConflictingHeadersEvidence{
  110. // H1: &signedHeader,
  111. // H2: &signedHeader,
  112. // }
  113. testCases := []struct {
  114. testName string
  115. evidence Evidence
  116. }{
  117. {"DuplicateVote", ev},
  118. // {"LunaticValidatorEvidence", evl},
  119. // {"PhantomValidatorEvidence", evp},
  120. // {"ConflictingHeadersEvidence", evc},
  121. }
  122. for _, tt := range testCases {
  123. bz, err := cdc.MarshalBinaryLengthPrefixed(tt.evidence)
  124. require.NoError(t, err, tt.testName)
  125. assert.LessOrEqual(t, MaxEvidenceBytes, int64(len(bz)), tt.testName)
  126. }
  127. }
  128. func randomDuplicatedVoteEvidence(t *testing.T) *DuplicateVoteEvidence {
  129. val := NewMockPV()
  130. blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))
  131. blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash"))
  132. const chainID = "mychain"
  133. return &DuplicateVoteEvidence{
  134. VoteA: makeVote(t, val, chainID, 0, 10, 2, 1, blockID),
  135. VoteB: makeVote(t, val, chainID, 0, 10, 2, 1, blockID2),
  136. }
  137. }
  138. func TestDuplicateVoteEvidenceValidation(t *testing.T) {
  139. val := NewMockPV()
  140. blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  141. blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  142. const chainID = "mychain"
  143. testCases := []struct {
  144. testName string
  145. malleateEvidence func(*DuplicateVoteEvidence)
  146. expectErr bool
  147. }{
  148. {"Good DuplicateVoteEvidence", func(ev *DuplicateVoteEvidence) {}, false},
  149. {"Nil vote A", func(ev *DuplicateVoteEvidence) { ev.VoteA = nil }, true},
  150. {"Nil vote B", func(ev *DuplicateVoteEvidence) { ev.VoteB = nil }, true},
  151. {"Nil votes", func(ev *DuplicateVoteEvidence) {
  152. ev.VoteA = nil
  153. ev.VoteB = nil
  154. }, true},
  155. {"Invalid vote type", func(ev *DuplicateVoteEvidence) {
  156. ev.VoteA = makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0, blockID2)
  157. }, true},
  158. {"Invalid vote order", func(ev *DuplicateVoteEvidence) {
  159. swap := ev.VoteA.Copy()
  160. ev.VoteA = ev.VoteB.Copy()
  161. ev.VoteB = swap
  162. }, true},
  163. }
  164. for _, tc := range testCases {
  165. tc := tc
  166. t.Run(tc.testName, func(t *testing.T) {
  167. vote1 := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0x02, blockID)
  168. vote2 := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0x02, blockID2)
  169. ev := NewDuplicateVoteEvidence(vote1, vote2)
  170. tc.malleateEvidence(ev)
  171. assert.Equal(t, tc.expectErr, ev.ValidateBasic() != nil, "Validate Basic had an unexpected result")
  172. })
  173. }
  174. }
  175. func TestMockGoodEvidenceValidateBasic(t *testing.T) {
  176. goodEvidence := NewMockEvidence(int64(1), time.Now(), []byte{1})
  177. assert.Nil(t, goodEvidence.ValidateBasic())
  178. }
  179. func TestMockBadEvidenceValidateBasic(t *testing.T) {
  180. badEvidence := NewMockEvidence(int64(1), time.Now(), []byte{1})
  181. assert.Nil(t, badEvidence.ValidateBasic())
  182. }
  183. func TestLunaticValidatorEvidence(t *testing.T) {
  184. var (
  185. blockID = makeBlockIDRandom()
  186. header = makeHeaderRandom()
  187. bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
  188. val = NewMockPV()
  189. vote = makeVote(t, val, header.ChainID, 0, header.Height, 0, 2, blockID)
  190. )
  191. header.Time = bTime
  192. ev := &LunaticValidatorEvidence{
  193. Header: header,
  194. Vote: vote,
  195. InvalidHeaderField: "AppHash",
  196. }
  197. assert.Equal(t, header.Height, ev.Height())
  198. assert.Equal(t, bTime, ev.Time())
  199. assert.EqualValues(t, vote.ValidatorAddress, ev.Address())
  200. assert.NotEmpty(t, ev.Hash())
  201. assert.NotEmpty(t, ev.Bytes())
  202. pubKey, err := val.GetPubKey()
  203. require.NoError(t, err)
  204. assert.NoError(t, ev.Verify(header.ChainID, pubKey))
  205. assert.Error(t, ev.Verify("other", pubKey))
  206. privKey2 := ed25519.GenPrivKey()
  207. pubKey2 := privKey2.PubKey()
  208. assert.Error(t, ev.Verify("other", pubKey2))
  209. assert.True(t, ev.Equal(ev))
  210. assert.NoError(t, ev.ValidateBasic())
  211. assert.NotEmpty(t, ev.String())
  212. }
  213. func TestPhantomValidatorEvidence(t *testing.T) {
  214. var (
  215. blockID = makeBlockIDRandom()
  216. header = makeHeaderRandom()
  217. bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
  218. val = NewMockPV()
  219. vote = makeVote(t, val, header.ChainID, 0, header.Height, 0, 2, blockID)
  220. )
  221. header.Time = bTime
  222. ev := &PhantomValidatorEvidence{
  223. Header: header,
  224. Vote: vote,
  225. LastHeightValidatorWasInSet: header.Height - 1,
  226. }
  227. assert.Equal(t, header.Height, ev.Height())
  228. assert.Equal(t, bTime, ev.Time())
  229. assert.EqualValues(t, vote.ValidatorAddress, ev.Address())
  230. assert.NotEmpty(t, ev.Hash())
  231. assert.NotEmpty(t, ev.Bytes())
  232. pubKey, err := val.GetPubKey()
  233. require.NoError(t, err)
  234. assert.NoError(t, ev.Verify(header.ChainID, pubKey))
  235. assert.Error(t, ev.Verify("other", pubKey))
  236. privKey2 := ed25519.GenPrivKey()
  237. pubKey2 := privKey2.PubKey()
  238. assert.Error(t, ev.Verify("other", pubKey2))
  239. assert.True(t, ev.Equal(ev))
  240. assert.NoError(t, ev.ValidateBasic())
  241. assert.NotEmpty(t, ev.String())
  242. }
  243. func TestConflictingHeadersEvidence(t *testing.T) {
  244. const (
  245. chainID = "TestConflictingHeadersEvidence"
  246. height int64 = 37
  247. )
  248. var (
  249. blockID = makeBlockIDRandom()
  250. header1 = makeHeaderRandom()
  251. header2 = makeHeaderRandom()
  252. )
  253. header1.Height = height
  254. header1.LastBlockID = blockID
  255. header1.ChainID = chainID
  256. header2.Height = height
  257. header2.LastBlockID = blockID
  258. header2.ChainID = chainID
  259. voteSet1, valSet, vals := randVoteSet(height, 1, PrecommitType, 10, 1)
  260. voteSet2 := NewVoteSet(chainID, height, 1, PrecommitType, valSet)
  261. commit1, err := MakeCommit(BlockID{
  262. Hash: header1.Hash(),
  263. PartsHeader: PartSetHeader{
  264. Total: 100,
  265. Hash: crypto.CRandBytes(tmhash.Size),
  266. },
  267. }, height, 1, voteSet1, vals, time.Now())
  268. require.NoError(t, err)
  269. commit2, err := MakeCommit(BlockID{
  270. Hash: header2.Hash(),
  271. PartsHeader: PartSetHeader{
  272. Total: 100,
  273. Hash: crypto.CRandBytes(tmhash.Size),
  274. },
  275. }, height, 1, voteSet2, vals, time.Now())
  276. require.NoError(t, err)
  277. ev := &ConflictingHeadersEvidence{
  278. H1: &SignedHeader{
  279. Header: header1,
  280. Commit: commit1,
  281. },
  282. H2: &SignedHeader{
  283. Header: header2,
  284. Commit: commit2,
  285. },
  286. }
  287. assert.Panics(t, func() {
  288. ev.Address()
  289. })
  290. assert.Panics(t, func() {
  291. pubKey, _ := vals[0].GetPubKey()
  292. ev.Verify(chainID, pubKey)
  293. })
  294. assert.Equal(t, height, ev.Height())
  295. // assert.Equal(t, bTime, ev.Time())
  296. assert.NotEmpty(t, ev.Hash())
  297. assert.NotEmpty(t, ev.Bytes())
  298. assert.NoError(t, ev.VerifyComposite(header1, valSet))
  299. assert.True(t, ev.Equal(ev))
  300. assert.NoError(t, ev.ValidateBasic())
  301. assert.NotEmpty(t, ev.String())
  302. }
  303. func TestPotentialAmnesiaEvidence(t *testing.T) {
  304. const (
  305. chainID = "TestPotentialAmnesiaEvidence"
  306. height int64 = 37
  307. )
  308. var (
  309. val = NewMockPV()
  310. blockID = makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  311. blockID2 = makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  312. vote1 = makeVote(t, val, chainID, 0, height, 0, 2, blockID)
  313. vote2 = makeVote(t, val, chainID, 0, height, 1, 2, blockID2)
  314. )
  315. ev := &PotentialAmnesiaEvidence{
  316. VoteA: vote2,
  317. VoteB: vote1,
  318. }
  319. assert.Equal(t, height, ev.Height())
  320. // assert.Equal(t, bTime, ev.Time())
  321. assert.EqualValues(t, vote1.ValidatorAddress, ev.Address())
  322. assert.NotEmpty(t, ev.Hash())
  323. assert.NotEmpty(t, ev.Bytes())
  324. pubKey, err := val.GetPubKey()
  325. require.NoError(t, err)
  326. assert.NoError(t, ev.Verify(chainID, pubKey))
  327. assert.Error(t, ev.Verify("other", pubKey))
  328. privKey2 := ed25519.GenPrivKey()
  329. pubKey2 := privKey2.PubKey()
  330. assert.Error(t, ev.Verify("other", pubKey2))
  331. assert.True(t, ev.Equal(ev))
  332. assert.NoError(t, ev.ValidateBasic())
  333. assert.NotEmpty(t, ev.String())
  334. }
  335. func TestProofOfLockChange(t *testing.T) {
  336. const (
  337. chainID = "TestProofOfLockChange"
  338. height int64 = 37
  339. )
  340. // 1: valid POLC - nothing should fail
  341. voteSet, valSet, privValidators, blockID := buildVoteSet(height, 1, 3, 7, 0, PrecommitType)
  342. pubKey, err := privValidators[7].GetPubKey()
  343. require.NoError(t, err)
  344. polc := makePOLCFromVoteSet(voteSet, pubKey, blockID)
  345. assert.Equal(t, height, polc.Height())
  346. assert.NoError(t, polc.ValidateBasic())
  347. assert.True(t, polc.MajorityOfVotes(valSet))
  348. assert.NotEmpty(t, polc.String())
  349. // test validate basic on a set of bad cases
  350. var badPOLCs []ProofOfLockChange
  351. // 2: node has already voted in next round
  352. pubKey, err = privValidators[0].GetPubKey()
  353. require.NoError(t, err)
  354. polc2 := makePOLCFromVoteSet(voteSet, pubKey, blockID)
  355. badPOLCs = append(badPOLCs, polc2)
  356. // 3: one vote was from a different round
  357. voteSet, _, privValidators, blockID = buildVoteSet(height, 1, 3, 7, 0, PrecommitType)
  358. pubKey, err = privValidators[7].GetPubKey()
  359. require.NoError(t, err)
  360. polc = makePOLCFromVoteSet(voteSet, pubKey, blockID)
  361. badVote := makeVote(t, privValidators[8], chainID, 8, height, 2, 2, blockID)
  362. polc.Votes = append(polc.Votes, *badVote)
  363. badPOLCs = append(badPOLCs, polc)
  364. // 4: one vote was from a different height
  365. polc = makePOLCFromVoteSet(voteSet, pubKey, blockID)
  366. badVote = makeVote(t, privValidators[8], chainID, 8, height+1, 1, 2, blockID)
  367. polc.Votes = append(polc.Votes, *badVote)
  368. badPOLCs = append(badPOLCs, polc)
  369. // 5: one vote was from a different vote type
  370. polc = makePOLCFromVoteSet(voteSet, pubKey, blockID)
  371. badVote = makeVote(t, privValidators[8], chainID, 8, height, 1, 1, blockID)
  372. polc.Votes = append(polc.Votes, *badVote)
  373. badPOLCs = append(badPOLCs, polc)
  374. // 5: one of the votes was for a nil block
  375. polc = makePOLCFromVoteSet(voteSet, pubKey, blockID)
  376. badVote = makeVote(t, privValidators[8], chainID, 8, height, 1, 2, BlockID{})
  377. polc.Votes = append(polc.Votes, *badVote)
  378. badPOLCs = append(badPOLCs, polc)
  379. for idx, polc := range badPOLCs {
  380. err := polc.ValidateBasic()
  381. assert.Error(t, err)
  382. if err == nil {
  383. t.Errorf("test no. %d failed", idx+2)
  384. }
  385. }
  386. }
  387. func makeHeaderRandom() *Header {
  388. return &Header{
  389. ChainID: tmrand.Str(12),
  390. Height: int64(tmrand.Uint16()) + 1,
  391. Time: time.Now(),
  392. LastBlockID: makeBlockIDRandom(),
  393. LastCommitHash: crypto.CRandBytes(tmhash.Size),
  394. DataHash: crypto.CRandBytes(tmhash.Size),
  395. ValidatorsHash: crypto.CRandBytes(tmhash.Size),
  396. NextValidatorsHash: crypto.CRandBytes(tmhash.Size),
  397. ConsensusHash: crypto.CRandBytes(tmhash.Size),
  398. AppHash: crypto.CRandBytes(tmhash.Size),
  399. LastResultsHash: crypto.CRandBytes(tmhash.Size),
  400. EvidenceHash: crypto.CRandBytes(tmhash.Size),
  401. ProposerAddress: crypto.CRandBytes(crypto.AddressSize),
  402. }
  403. }
  404. func TestEvidenceProto(t *testing.T) {
  405. // -------- Votes --------
  406. val := NewMockPV()
  407. blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  408. blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  409. const chainID = "mychain"
  410. v := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, 1, 0x01, blockID)
  411. v2 := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, 2, 0x01, blockID2)
  412. // -------- SignedHeaders --------
  413. const height int64 = 37
  414. var (
  415. header1 = makeHeaderRandom()
  416. header2 = makeHeaderRandom()
  417. )
  418. header1.Height = height
  419. header1.LastBlockID = blockID
  420. header1.ChainID = chainID
  421. header2.Height = height
  422. header2.LastBlockID = blockID
  423. header2.ChainID = chainID
  424. voteSet1, valSet, vals := randVoteSet(height, 1, PrecommitType, 10, 1)
  425. voteSet2 := NewVoteSet(chainID, height, 1, PrecommitType, valSet)
  426. commit1, err := MakeCommit(BlockID{
  427. Hash: header1.Hash(),
  428. PartsHeader: PartSetHeader{
  429. Total: 100,
  430. Hash: crypto.CRandBytes(tmhash.Size),
  431. },
  432. }, height, 1, voteSet1, vals, time.Now())
  433. require.NoError(t, err)
  434. commit2, err := MakeCommit(BlockID{
  435. Hash: header2.Hash(),
  436. PartsHeader: PartSetHeader{
  437. Total: 100,
  438. Hash: crypto.CRandBytes(tmhash.Size),
  439. },
  440. }, height, 1, voteSet2, vals, time.Now())
  441. require.NoError(t, err)
  442. h1 := &SignedHeader{
  443. Header: header1,
  444. Commit: commit1,
  445. }
  446. h2 := &SignedHeader{
  447. Header: header2,
  448. Commit: commit2,
  449. }
  450. tests := []struct {
  451. testName string
  452. evidence Evidence
  453. wantErr bool
  454. wantErr2 bool
  455. }{
  456. {"&DuplicateVoteEvidence empty fail", &DuplicateVoteEvidence{}, false, true},
  457. {"&DuplicateVoteEvidence nil voteB", &DuplicateVoteEvidence{VoteA: v, VoteB: nil}, false, true},
  458. {"&DuplicateVoteEvidence nil voteA", &DuplicateVoteEvidence{VoteA: nil, VoteB: v}, false, true},
  459. {"&DuplicateVoteEvidence success", &DuplicateVoteEvidence{VoteA: v2, VoteB: v}, false, false},
  460. {"&ConflictingHeadersEvidence empty fail", &ConflictingHeadersEvidence{}, false, true},
  461. {"&ConflictingHeadersEvidence nil H2", &ConflictingHeadersEvidence{H1: h1, H2: nil}, false, true},
  462. {"&ConflictingHeadersEvidence nil H1", &ConflictingHeadersEvidence{H1: nil, H2: h2}, false, true},
  463. {"ConflictingHeadersEvidence empty fail", ConflictingHeadersEvidence{}, false, true},
  464. {"ConflictingHeadersEvidence nil H2", ConflictingHeadersEvidence{H1: h1, H2: nil}, false, true},
  465. {"ConflictingHeadersEvidence nil H1", ConflictingHeadersEvidence{H1: nil, H2: h2}, false, true},
  466. {"ConflictingHeadersEvidence success", ConflictingHeadersEvidence{H1: h1, H2: h2}, false, false},
  467. {"LunaticValidatorEvidence empty fail", LunaticValidatorEvidence{}, false, true},
  468. {"LunaticValidatorEvidence only header fail", LunaticValidatorEvidence{Header: header1}, false, true},
  469. {"LunaticValidatorEvidence only vote fail", LunaticValidatorEvidence{Vote: v}, false, true},
  470. {"LunaticValidatorEvidence header & vote fail", LunaticValidatorEvidence{Header: header1, Vote: v}, false, true},
  471. {"LunaticValidatorEvidence success", LunaticValidatorEvidence{Header: header1,
  472. Vote: v, InvalidHeaderField: "ValidatorsHash"}, false, true},
  473. {"&LunaticValidatorEvidence empty fail", &LunaticValidatorEvidence{}, false, true},
  474. {"LunaticValidatorEvidence only header fail", &LunaticValidatorEvidence{Header: header1}, false, true},
  475. {"LunaticValidatorEvidence only vote fail", &LunaticValidatorEvidence{Vote: v}, false, true},
  476. {"LunaticValidatorEvidence header & vote fail", &LunaticValidatorEvidence{Header: header1, Vote: v}, false, true},
  477. {"&LunaticValidatorEvidence empty fail", &LunaticValidatorEvidence{}, false, true},
  478. {"PotentialAmnesiaEvidence empty fail", PotentialAmnesiaEvidence{}, false, true},
  479. {"PotentialAmnesiaEvidence nil VoteB", PotentialAmnesiaEvidence{VoteA: v, VoteB: nil}, false, true},
  480. {"PotentialAmnesiaEvidence nil VoteA", PotentialAmnesiaEvidence{VoteA: nil, VoteB: v2}, false, true},
  481. {"&PotentialAmnesiaEvidence empty fail", &PotentialAmnesiaEvidence{}, false, true},
  482. {"&PotentialAmnesiaEvidence nil VoteB", &PotentialAmnesiaEvidence{VoteA: v, VoteB: nil}, false, true},
  483. {"&PotentialAmnesiaEvidence nil VoteA", &PotentialAmnesiaEvidence{VoteA: nil, VoteB: v2}, false, true},
  484. {"&PotentialAmnesiaEvidence success", &PotentialAmnesiaEvidence{VoteA: v2, VoteB: v}, false, false},
  485. }
  486. for _, tt := range tests {
  487. tt := tt
  488. t.Run(tt.testName, func(t *testing.T) {
  489. pb, err := EvidenceToProto(tt.evidence)
  490. if tt.wantErr {
  491. assert.Error(t, err, tt.testName)
  492. return
  493. }
  494. assert.NoError(t, err, tt.testName)
  495. evi, err := EvidenceFromProto(pb)
  496. if tt.wantErr2 {
  497. assert.Error(t, err, tt.testName)
  498. return
  499. }
  500. require.Equal(t, tt.evidence, evi, tt.testName)
  501. })
  502. }
  503. }