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.

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