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.

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