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.

373 lines
12 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/secp256k1"
  11. "github.com/tendermint/tendermint/crypto/tmhash"
  12. tmrand "github.com/tendermint/tendermint/libs/rand"
  13. )
  14. type voteData struct {
  15. vote1 *Vote
  16. vote2 *Vote
  17. valid bool
  18. }
  19. func makeVote(
  20. t *testing.T, val PrivValidator, chainID string, valIndex int, height int64, round, step int, blockID BlockID,
  21. ) *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. BlockID: blockID,
  31. }
  32. err = val.SignVote(chainID, v)
  33. if err != nil {
  34. panic(err)
  35. }
  36. return v
  37. }
  38. func TestEvidence(t *testing.T) {
  39. val := NewMockPV()
  40. val2 := NewMockPV()
  41. blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))
  42. blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash"))
  43. blockID3 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash"))
  44. blockID4 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash2"))
  45. const chainID = "mychain"
  46. vote1 := makeVote(t, val, chainID, 0, 10, 2, 1, blockID)
  47. badVote := makeVote(t, val, chainID, 0, 10, 2, 1, blockID)
  48. err := val2.SignVote(chainID, badVote)
  49. assert.NoError(t, err)
  50. cases := []voteData{
  51. {vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID2), true}, // different block ids
  52. {vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID3), true},
  53. {vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID4), true},
  54. {vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID), false}, // wrong block id
  55. {vote1, makeVote(t, val, "mychain2", 0, 10, 2, 1, blockID2), false}, // wrong chain id
  56. {vote1, makeVote(t, val, chainID, 1, 10, 2, 1, blockID2), false}, // wrong val index
  57. {vote1, makeVote(t, val, chainID, 0, 11, 2, 1, blockID2), false}, // wrong height
  58. {vote1, makeVote(t, val, chainID, 0, 10, 3, 1, blockID2), false}, // wrong round
  59. {vote1, makeVote(t, val, chainID, 0, 10, 2, 2, blockID2), false}, // wrong step
  60. {vote1, makeVote(t, val2, chainID, 0, 10, 2, 1, blockID), false}, // wrong validator
  61. {vote1, badVote, false}, // signed by wrong key
  62. }
  63. pubKey, err := val.GetPubKey()
  64. require.NoError(t, err)
  65. for _, c := range cases {
  66. ev := &DuplicateVoteEvidence{
  67. VoteA: c.vote1,
  68. VoteB: c.vote2,
  69. }
  70. if c.valid {
  71. assert.Nil(t, ev.Verify(chainID, pubKey), "evidence should be valid")
  72. } else {
  73. assert.NotNil(t, ev.Verify(chainID, pubKey), "evidence should be invalid")
  74. }
  75. }
  76. }
  77. func TestDuplicatedVoteEvidence(t *testing.T) {
  78. ev := randomDuplicatedVoteEvidence(t)
  79. assert.True(t, ev.Equal(ev))
  80. assert.False(t, ev.Equal(&DuplicateVoteEvidence{}))
  81. }
  82. func TestEvidenceList(t *testing.T) {
  83. ev := randomDuplicatedVoteEvidence(t)
  84. evl := EvidenceList([]Evidence{ev})
  85. assert.NotNil(t, evl.Hash())
  86. assert.True(t, evl.Has(ev))
  87. assert.False(t, evl.Has(&DuplicateVoteEvidence{}))
  88. }
  89. func TestMaxEvidenceBytes(t *testing.T) {
  90. val := NewMockPV()
  91. blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  92. blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  93. const chainID = "mychain"
  94. ev := &DuplicateVoteEvidence{
  95. PubKey: secp256k1.GenPrivKey().PubKey(), // use secp because it's pubkey is longer
  96. VoteA: makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, math.MaxInt64, blockID),
  97. VoteB: makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, math.MaxInt64, blockID2),
  98. }
  99. bz, err := cdc.MarshalBinaryLengthPrefixed(ev)
  100. require.NoError(t, err)
  101. assert.EqualValues(t, MaxEvidenceBytes, len(bz))
  102. }
  103. func randomDuplicatedVoteEvidence(t *testing.T) *DuplicateVoteEvidence {
  104. val := NewMockPV()
  105. blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))
  106. blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash"))
  107. const chainID = "mychain"
  108. return &DuplicateVoteEvidence{
  109. VoteA: makeVote(t, val, chainID, 0, 10, 2, 1, blockID),
  110. VoteB: makeVote(t, val, chainID, 0, 10, 2, 1, blockID2),
  111. }
  112. }
  113. func TestDuplicateVoteEvidenceValidation(t *testing.T) {
  114. val := NewMockPV()
  115. blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  116. blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  117. const chainID = "mychain"
  118. testCases := []struct {
  119. testName string
  120. malleateEvidence func(*DuplicateVoteEvidence)
  121. expectErr bool
  122. }{
  123. {"Good DuplicateVoteEvidence", func(ev *DuplicateVoteEvidence) {}, false},
  124. {"Nil vote A", func(ev *DuplicateVoteEvidence) { ev.VoteA = nil }, true},
  125. {"Nil vote B", func(ev *DuplicateVoteEvidence) { ev.VoteB = nil }, true},
  126. {"Nil votes", func(ev *DuplicateVoteEvidence) {
  127. ev.VoteA = nil
  128. ev.VoteB = nil
  129. }, true},
  130. {"Invalid vote type", func(ev *DuplicateVoteEvidence) {
  131. ev.VoteA = makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0, blockID2)
  132. }, true},
  133. {"Invalid vote order", func(ev *DuplicateVoteEvidence) {
  134. swap := ev.VoteA.Copy()
  135. ev.VoteA = ev.VoteB.Copy()
  136. ev.VoteB = swap
  137. }, true},
  138. }
  139. for _, tc := range testCases {
  140. tc := tc
  141. t.Run(tc.testName, func(t *testing.T) {
  142. pk := secp256k1.GenPrivKey().PubKey()
  143. vote1 := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0x02, blockID)
  144. vote2 := makeVote(t, val, chainID, math.MaxInt64, math.MaxInt64, math.MaxInt64, 0x02, blockID2)
  145. ev := NewDuplicateVoteEvidence(pk, vote1, vote2)
  146. tc.malleateEvidence(ev)
  147. assert.Equal(t, tc.expectErr, ev.ValidateBasic() != nil, "Validate Basic had an unexpected result")
  148. })
  149. }
  150. }
  151. func TestMockGoodEvidenceValidateBasic(t *testing.T) {
  152. goodEvidence := NewMockEvidence(int64(1), time.Now(), []byte{1})
  153. assert.Nil(t, goodEvidence.ValidateBasic())
  154. }
  155. func TestMockBadEvidenceValidateBasic(t *testing.T) {
  156. badEvidence := NewMockEvidence(int64(1), time.Now(), []byte{1})
  157. assert.Nil(t, badEvidence.ValidateBasic())
  158. }
  159. func TestLunaticValidatorEvidence(t *testing.T) {
  160. var (
  161. blockID = makeBlockIDRandom()
  162. header = makeHeaderRandom()
  163. bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
  164. val = NewMockPV()
  165. vote = makeVote(t, val, header.ChainID, 0, header.Height, 0, 2, blockID)
  166. )
  167. header.Time = bTime
  168. ev := &LunaticValidatorEvidence{
  169. Header: header,
  170. Vote: vote,
  171. InvalidHeaderField: "AppHash",
  172. }
  173. assert.Equal(t, header.Height, ev.Height())
  174. assert.Equal(t, bTime, ev.Time())
  175. assert.EqualValues(t, vote.ValidatorAddress, ev.Address())
  176. assert.NotEmpty(t, ev.Hash())
  177. assert.NotEmpty(t, ev.Bytes())
  178. pubKey, err := val.GetPubKey()
  179. require.NoError(t, err)
  180. assert.NoError(t, ev.Verify(header.ChainID, pubKey))
  181. assert.Error(t, ev.Verify("other", pubKey))
  182. privKey2 := ed25519.GenPrivKey()
  183. pubKey2 := privKey2.PubKey()
  184. assert.Error(t, ev.Verify("other", pubKey2))
  185. assert.True(t, ev.Equal(ev))
  186. assert.NoError(t, ev.ValidateBasic())
  187. assert.NotEmpty(t, ev.String())
  188. }
  189. func TestPhantomValidatorEvidence(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)
  196. )
  197. header.Time = bTime
  198. ev := &PhantomValidatorEvidence{
  199. Header: header,
  200. Vote: vote,
  201. LastHeightValidatorWasInSet: header.Height - 1,
  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 TestConflictingHeadersEvidence(t *testing.T) {
  220. const (
  221. chainID = "TestConflictingHeadersEvidence"
  222. height int64 = 37
  223. )
  224. var (
  225. blockID = makeBlockIDRandom()
  226. header1 = makeHeaderRandom()
  227. header2 = makeHeaderRandom()
  228. )
  229. header1.Height = height
  230. header1.LastBlockID = blockID
  231. header1.ChainID = chainID
  232. header2.Height = height
  233. header2.LastBlockID = blockID
  234. header2.ChainID = chainID
  235. voteSet1, valSet, vals := randVoteSet(height, 1, PrecommitType, 10, 1)
  236. voteSet2 := NewVoteSet(chainID, height, 1, PrecommitType, valSet)
  237. commit1, err := MakeCommit(BlockID{
  238. Hash: header1.Hash(),
  239. PartsHeader: PartSetHeader{
  240. Total: 100,
  241. Hash: crypto.CRandBytes(tmhash.Size),
  242. },
  243. }, height, 1, voteSet1, vals, time.Now())
  244. require.NoError(t, err)
  245. commit2, err := MakeCommit(BlockID{
  246. Hash: header2.Hash(),
  247. PartsHeader: PartSetHeader{
  248. Total: 100,
  249. Hash: crypto.CRandBytes(tmhash.Size),
  250. },
  251. }, height, 1, voteSet2, vals, time.Now())
  252. require.NoError(t, err)
  253. ev := &ConflictingHeadersEvidence{
  254. H1: &SignedHeader{
  255. Header: header1,
  256. Commit: commit1,
  257. },
  258. H2: &SignedHeader{
  259. Header: header2,
  260. Commit: commit2,
  261. },
  262. }
  263. assert.Panics(t, func() {
  264. ev.Address()
  265. })
  266. assert.Panics(t, func() {
  267. pubKey, _ := vals[0].GetPubKey()
  268. ev.Verify(chainID, pubKey)
  269. })
  270. assert.Equal(t, height, ev.Height())
  271. // assert.Equal(t, bTime, ev.Time())
  272. assert.NotEmpty(t, ev.Hash())
  273. assert.NotEmpty(t, ev.Bytes())
  274. assert.NoError(t, ev.VerifyComposite(header1, valSet))
  275. assert.True(t, ev.Equal(ev))
  276. assert.NoError(t, ev.ValidateBasic())
  277. assert.NotEmpty(t, ev.String())
  278. }
  279. func TestPotentialAmnesiaEvidence(t *testing.T) {
  280. const (
  281. chainID = "TestPotentialAmnesiaEvidence"
  282. height int64 = 37
  283. )
  284. var (
  285. val = NewMockPV()
  286. blockID = makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  287. blockID2 = makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt64, tmhash.Sum([]byte("partshash")))
  288. vote1 = makeVote(t, val, chainID, 0, height, 0, 2, blockID)
  289. vote2 = makeVote(t, val, chainID, 0, height, 1, 2, blockID2)
  290. )
  291. ev := &PotentialAmnesiaEvidence{
  292. VoteA: vote2,
  293. VoteB: vote1,
  294. }
  295. assert.Equal(t, height, ev.Height())
  296. // assert.Equal(t, bTime, ev.Time())
  297. assert.EqualValues(t, vote1.ValidatorAddress, ev.Address())
  298. assert.NotEmpty(t, ev.Hash())
  299. assert.NotEmpty(t, ev.Bytes())
  300. pubKey, err := val.GetPubKey()
  301. require.NoError(t, err)
  302. assert.NoError(t, ev.Verify(chainID, pubKey))
  303. assert.Error(t, ev.Verify("other", pubKey))
  304. privKey2 := ed25519.GenPrivKey()
  305. pubKey2 := privKey2.PubKey()
  306. assert.Error(t, ev.Verify("other", pubKey2))
  307. assert.True(t, ev.Equal(ev))
  308. assert.NoError(t, ev.ValidateBasic())
  309. assert.NotEmpty(t, ev.String())
  310. }
  311. func makeHeaderRandom() *Header {
  312. return &Header{
  313. ChainID: tmrand.Str(12),
  314. Height: int64(tmrand.Uint16()) + 1,
  315. Time: time.Now(),
  316. LastBlockID: makeBlockIDRandom(),
  317. LastCommitHash: crypto.CRandBytes(tmhash.Size),
  318. DataHash: crypto.CRandBytes(tmhash.Size),
  319. ValidatorsHash: crypto.CRandBytes(tmhash.Size),
  320. NextValidatorsHash: crypto.CRandBytes(tmhash.Size),
  321. ConsensusHash: crypto.CRandBytes(tmhash.Size),
  322. AppHash: crypto.CRandBytes(tmhash.Size),
  323. LastResultsHash: crypto.CRandBytes(tmhash.Size),
  324. EvidenceHash: crypto.CRandBytes(tmhash.Size),
  325. ProposerAddress: crypto.CRandBytes(crypto.AddressSize),
  326. }
  327. }