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.

280 lines
9.1 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
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. )
  12. func examplePrevote() *Vote {
  13. return exampleVote(byte(PrevoteType))
  14. }
  15. func examplePrecommit() *Vote {
  16. return exampleVote(byte(PrecommitType))
  17. }
  18. func exampleVote(t byte) *Vote {
  19. var stamp, err = time.Parse(TimeFormat, "2017-12-25T03:00:01.234Z")
  20. if err != nil {
  21. panic(err)
  22. }
  23. return &Vote{
  24. Type: SignedMsgType(t),
  25. Height: 12345,
  26. Round: 2,
  27. Timestamp: stamp,
  28. BlockID: BlockID{
  29. Hash: tmhash.Sum([]byte("blockID_hash")),
  30. PartsHeader: PartSetHeader{
  31. Total: 1000000,
  32. Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")),
  33. },
  34. },
  35. ValidatorAddress: crypto.AddressHash([]byte("validator_address")),
  36. ValidatorIndex: 56789,
  37. }
  38. }
  39. func TestVoteSignable(t *testing.T) {
  40. vote := examplePrecommit()
  41. signBytes := vote.SignBytes("test_chain_id")
  42. expected, err := cdc.MarshalBinaryLengthPrefixed(CanonicalizeVote("test_chain_id", vote))
  43. require.NoError(t, err)
  44. require.Equal(t, expected, signBytes, "Got unexpected sign bytes for Vote.")
  45. }
  46. func TestVoteSignableTestVectors(t *testing.T) {
  47. vote := CanonicalizeVote("", &Vote{Height: 1, Round: 1})
  48. tests := []struct {
  49. canonicalVote CanonicalVote
  50. want []byte
  51. }{
  52. {
  53. CanonicalizeVote("", &Vote{}),
  54. // NOTE: Height and Round are skipped here. This case needs to be considered while parsing.
  55. // []byte{0x22, 0x9, 0x9, 0x0, 0x9, 0x6e, 0x88, 0xf1, 0xff, 0xff, 0xff},
  56. []byte{0x22, 0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
  57. },
  58. // with proper (fixed size) height and round (PreCommit):
  59. {
  60. CanonicalizeVote("", &Vote{Height: 1, Round: 1, Type: PrecommitType}),
  61. []byte{
  62. 0x8, // (field_number << 3) | wire_type
  63. 0x2, // PrecommitType
  64. 0x11, // (field_number << 3) | wire_type
  65. 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height
  66. 0x19, // (field_number << 3) | wire_type
  67. 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round
  68. 0x22, // (field_number << 3) | wire_type
  69. // remaining fields (timestamp):
  70. 0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
  71. },
  72. // with proper (fixed size) height and round (PreVote):
  73. {
  74. CanonicalizeVote("", &Vote{Height: 1, Round: 1, Type: PrevoteType}),
  75. []byte{
  76. 0x8, // (field_number << 3) | wire_type
  77. 0x1, // PrevoteType
  78. 0x11, // (field_number << 3) | wire_type
  79. 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height
  80. 0x19, // (field_number << 3) | wire_type
  81. 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round
  82. 0x22, // (field_number << 3) | wire_type
  83. // remaining fields (timestamp):
  84. 0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
  85. },
  86. {
  87. vote,
  88. []byte{
  89. 0x11, // (field_number << 3) | wire_type
  90. 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height
  91. 0x19, // (field_number << 3) | wire_type
  92. 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round
  93. // remaining fields (timestamp):
  94. 0x22,
  95. 0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
  96. },
  97. // containing non-empty chain_id:
  98. {
  99. CanonicalizeVote("test_chain_id", &Vote{Height: 1, Round: 1}),
  100. []byte{
  101. 0x11, // (field_number << 3) | wire_type
  102. 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height
  103. 0x19, // (field_number << 3) | wire_type
  104. 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round
  105. // remaining fields:
  106. 0x22, // (field_number << 3) | wire_type
  107. 0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1, // timestamp
  108. 0x32, // (field_number << 3) | wire_type
  109. 0xd, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64}, // chainID
  110. },
  111. }
  112. for i, tc := range tests {
  113. got, err := cdc.MarshalBinaryBare(tc.canonicalVote)
  114. require.NoError(t, err)
  115. require.Equal(t, tc.want, got, "test case #%v: got unexpected sign bytes for Vote.", i)
  116. }
  117. }
  118. func TestVoteProposalNotEq(t *testing.T) {
  119. cv := CanonicalizeVote("", &Vote{Height: 1, Round: 1})
  120. p := CanonicalizeProposal("", &Proposal{Height: 1, Round: 1})
  121. vb, err := cdc.MarshalBinaryLengthPrefixed(cv)
  122. require.NoError(t, err)
  123. pb, err := cdc.MarshalBinaryLengthPrefixed(p)
  124. require.NoError(t, err)
  125. require.NotEqual(t, vb, pb)
  126. }
  127. func TestVoteVerifySignature(t *testing.T) {
  128. privVal := NewMockPV()
  129. pubkey := privVal.GetPubKey()
  130. vote := examplePrecommit()
  131. signBytes := vote.SignBytes("test_chain_id")
  132. // sign it
  133. err := privVal.SignVote("test_chain_id", vote)
  134. require.NoError(t, err)
  135. // verify the same vote
  136. valid := pubkey.VerifyBytes(vote.SignBytes("test_chain_id"), vote.Signature)
  137. require.True(t, valid)
  138. // serialize, deserialize and verify again....
  139. precommit := new(Vote)
  140. bs, err := cdc.MarshalBinaryLengthPrefixed(vote)
  141. require.NoError(t, err)
  142. err = cdc.UnmarshalBinaryLengthPrefixed(bs, &precommit)
  143. require.NoError(t, err)
  144. // verify the transmitted vote
  145. newSignBytes := precommit.SignBytes("test_chain_id")
  146. require.Equal(t, string(signBytes), string(newSignBytes))
  147. valid = pubkey.VerifyBytes(newSignBytes, precommit.Signature)
  148. require.True(t, valid)
  149. }
  150. func TestIsVoteTypeValid(t *testing.T) {
  151. tc := []struct {
  152. name string
  153. in SignedMsgType
  154. out bool
  155. }{
  156. {"Prevote", PrevoteType, true},
  157. {"Precommit", PrecommitType, true},
  158. {"InvalidType", SignedMsgType(0x3), false},
  159. }
  160. for _, tt := range tc {
  161. tt := tt
  162. t.Run(tt.name, func(st *testing.T) {
  163. if rs := IsVoteTypeValid(tt.in); rs != tt.out {
  164. t.Errorf("Got unexpected Vote type. Expected:\n%v\nGot:\n%v", rs, tt.out)
  165. }
  166. })
  167. }
  168. }
  169. func TestVoteVerify(t *testing.T) {
  170. privVal := NewMockPV()
  171. pubkey := privVal.GetPubKey()
  172. vote := examplePrevote()
  173. vote.ValidatorAddress = pubkey.Address()
  174. err := vote.Verify("test_chain_id", ed25519.GenPrivKey().PubKey())
  175. if assert.Error(t, err) {
  176. assert.Equal(t, ErrVoteInvalidValidatorAddress, err)
  177. }
  178. err = vote.Verify("test_chain_id", pubkey)
  179. if assert.Error(t, err) {
  180. assert.Equal(t, ErrVoteInvalidSignature, err)
  181. }
  182. }
  183. func TestMaxVoteBytes(t *testing.T) {
  184. // time is varint encoded so need to pick the max.
  185. // year int, month Month, day, hour, min, sec, nsec int, loc *Location
  186. timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC)
  187. vote := &Vote{
  188. ValidatorAddress: crypto.AddressHash([]byte("validator_address")),
  189. ValidatorIndex: math.MaxInt64,
  190. Height: math.MaxInt64,
  191. Round: math.MaxInt64,
  192. Timestamp: timestamp,
  193. Type: PrevoteType,
  194. BlockID: BlockID{
  195. Hash: tmhash.Sum([]byte("blockID_hash")),
  196. PartsHeader: PartSetHeader{
  197. Total: math.MaxInt64,
  198. Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")),
  199. },
  200. },
  201. }
  202. privVal := NewMockPV()
  203. err := privVal.SignVote("test_chain_id", vote)
  204. require.NoError(t, err)
  205. bz, err := cdc.MarshalBinaryLengthPrefixed(vote)
  206. require.NoError(t, err)
  207. assert.EqualValues(t, MaxVoteBytes, len(bz))
  208. }
  209. func TestVoteString(t *testing.T) {
  210. str := examplePrecommit().String()
  211. expected := `Vote{56789:6AF1F4111082 12345/02/2(Precommit) 8B01023386C3 000000000000 @ 2017-12-25T03:00:01.234Z}`
  212. if str != expected {
  213. t.Errorf("Got unexpected string for Vote. Expected:\n%v\nGot:\n%v", expected, str)
  214. }
  215. str2 := examplePrevote().String()
  216. expected = `Vote{56789:6AF1F4111082 12345/02/1(Prevote) 8B01023386C3 000000000000 @ 2017-12-25T03:00:01.234Z}`
  217. if str2 != expected {
  218. t.Errorf("Got unexpected string for Vote. Expected:\n%v\nGot:\n%v", expected, str2)
  219. }
  220. }
  221. func TestVoteValidateBasic(t *testing.T) {
  222. privVal := NewMockPV()
  223. testCases := []struct {
  224. testName string
  225. malleateVote func(*Vote)
  226. expectErr bool
  227. }{
  228. {"Good Vote", func(v *Vote) {}, false},
  229. {"Negative Height", func(v *Vote) { v.Height = -1 }, true},
  230. {"Negative Round", func(v *Vote) { v.Round = -1 }, true},
  231. {"Invalid BlockID", func(v *Vote) { v.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}} }, true},
  232. {"Invalid Address", func(v *Vote) { v.ValidatorAddress = make([]byte, 1) }, true},
  233. {"Invalid ValidatorIndex", func(v *Vote) { v.ValidatorIndex = -1 }, true},
  234. {"Invalid Signature", func(v *Vote) { v.Signature = nil }, true},
  235. {"Too big Signature", func(v *Vote) { v.Signature = make([]byte, MaxSignatureSize+1) }, true},
  236. }
  237. for _, tc := range testCases {
  238. t.Run(tc.testName, func(t *testing.T) {
  239. vote := examplePrecommit()
  240. err := privVal.SignVote("test_chain_id", vote)
  241. require.NoError(t, err)
  242. tc.malleateVote(vote)
  243. assert.Equal(t, tc.expectErr, vote.ValidateBasic() != nil, "Validate Basic had an unexpected result")
  244. })
  245. }
  246. }