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.

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