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.

427 lines
12 KiB

  1. package consensus
  2. import (
  3. "encoding/hex"
  4. "math"
  5. "testing"
  6. "time"
  7. "github.com/gogo/protobuf/proto"
  8. "github.com/stretchr/testify/assert"
  9. "github.com/stretchr/testify/require"
  10. "github.com/tendermint/tendermint/crypto/merkle"
  11. "github.com/tendermint/tendermint/libs/bits"
  12. tmrand "github.com/tendermint/tendermint/libs/rand"
  13. "github.com/tendermint/tendermint/p2p"
  14. tmcons "github.com/tendermint/tendermint/proto/tendermint/consensus"
  15. tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
  16. "github.com/tendermint/tendermint/types"
  17. )
  18. func TestMsgToProto(t *testing.T) {
  19. psh := types.PartSetHeader{
  20. Total: 1,
  21. Hash: tmrand.Bytes(32),
  22. }
  23. pbPsh := psh.ToProto()
  24. bi := types.BlockID{
  25. Hash: tmrand.Bytes(32),
  26. PartSetHeader: psh,
  27. }
  28. pbBi := bi.ToProto()
  29. bits := bits.NewBitArray(1)
  30. pbBits := bits.ToProto()
  31. parts := types.Part{
  32. Index: 1,
  33. Bytes: []byte("test"),
  34. Proof: merkle.Proof{
  35. Total: 1,
  36. Index: 1,
  37. LeafHash: tmrand.Bytes(32),
  38. Aunts: [][]byte{},
  39. },
  40. }
  41. pbParts, err := parts.ToProto()
  42. require.NoError(t, err)
  43. proposal := types.Proposal{
  44. Type: tmproto.ProposalType,
  45. Height: 1,
  46. Round: 1,
  47. POLRound: 1,
  48. BlockID: bi,
  49. Timestamp: time.Now(),
  50. Signature: tmrand.Bytes(20),
  51. }
  52. pbProposal := proposal.ToProto()
  53. pv := types.NewMockPV()
  54. pk, err := pv.GetPubKey()
  55. require.NoError(t, err)
  56. val := types.NewValidator(pk, 100)
  57. vote, err := types.MakeVote(
  58. 1, types.BlockID{}, &types.ValidatorSet{Proposer: val, Validators: []*types.Validator{val}},
  59. pv, "chainID", time.Now())
  60. require.NoError(t, err)
  61. pbVote := vote.ToProto()
  62. testsCases := []struct {
  63. testName string
  64. msg Message
  65. want *tmcons.Message
  66. wantErr bool
  67. }{
  68. {"successful NewRoundStepMessage", &NewRoundStepMessage{
  69. Height: 2,
  70. Round: 1,
  71. Step: 1,
  72. SecondsSinceStartTime: 1,
  73. LastCommitRound: 2,
  74. }, &tmcons.Message{
  75. Sum: &tmcons.Message_NewRoundStep{
  76. NewRoundStep: &tmcons.NewRoundStep{
  77. Height: 2,
  78. Round: 1,
  79. Step: 1,
  80. SecondsSinceStartTime: 1,
  81. LastCommitRound: 2,
  82. },
  83. },
  84. }, false},
  85. {"successful NewValidBlockMessage", &NewValidBlockMessage{
  86. Height: 1,
  87. Round: 1,
  88. BlockPartSetHeader: psh,
  89. BlockParts: bits,
  90. IsCommit: false,
  91. }, &tmcons.Message{
  92. Sum: &tmcons.Message_NewValidBlock{
  93. NewValidBlock: &tmcons.NewValidBlock{
  94. Height: 1,
  95. Round: 1,
  96. BlockPartSetHeader: pbPsh,
  97. BlockParts: pbBits,
  98. IsCommit: false,
  99. },
  100. },
  101. }, false},
  102. {"successful BlockPartMessage", &BlockPartMessage{
  103. Height: 100,
  104. Round: 1,
  105. Part: &parts,
  106. }, &tmcons.Message{
  107. Sum: &tmcons.Message_BlockPart{
  108. BlockPart: &tmcons.BlockPart{
  109. Height: 100,
  110. Round: 1,
  111. Part: *pbParts,
  112. },
  113. },
  114. }, false},
  115. {"successful ProposalPOLMessage", &ProposalPOLMessage{
  116. Height: 1,
  117. ProposalPOLRound: 1,
  118. ProposalPOL: bits,
  119. }, &tmcons.Message{
  120. Sum: &tmcons.Message_ProposalPol{
  121. ProposalPol: &tmcons.ProposalPOL{
  122. Height: 1,
  123. ProposalPolRound: 1,
  124. ProposalPol: *pbBits,
  125. },
  126. }}, false},
  127. {"successful ProposalMessage", &ProposalMessage{
  128. Proposal: &proposal,
  129. }, &tmcons.Message{
  130. Sum: &tmcons.Message_Proposal{
  131. Proposal: &tmcons.Proposal{
  132. Proposal: *pbProposal,
  133. },
  134. },
  135. }, false},
  136. {"successful VoteMessage", &VoteMessage{
  137. Vote: vote,
  138. }, &tmcons.Message{
  139. Sum: &tmcons.Message_Vote{
  140. Vote: &tmcons.Vote{
  141. Vote: pbVote,
  142. },
  143. },
  144. }, false},
  145. {"successful VoteSetMaj23", &VoteSetMaj23Message{
  146. Height: 1,
  147. Round: 1,
  148. Type: 1,
  149. BlockID: bi,
  150. }, &tmcons.Message{
  151. Sum: &tmcons.Message_VoteSetMaj23{
  152. VoteSetMaj23: &tmcons.VoteSetMaj23{
  153. Height: 1,
  154. Round: 1,
  155. Type: 1,
  156. BlockID: pbBi,
  157. },
  158. },
  159. }, false},
  160. {"successful VoteSetBits", &VoteSetBitsMessage{
  161. Height: 1,
  162. Round: 1,
  163. Type: 1,
  164. BlockID: bi,
  165. Votes: bits,
  166. }, &tmcons.Message{
  167. Sum: &tmcons.Message_VoteSetBits{
  168. VoteSetBits: &tmcons.VoteSetBits{
  169. Height: 1,
  170. Round: 1,
  171. Type: 1,
  172. BlockID: pbBi,
  173. Votes: *pbBits,
  174. },
  175. },
  176. }, false},
  177. {"failure", nil, &tmcons.Message{}, true},
  178. }
  179. for _, tt := range testsCases {
  180. tt := tt
  181. t.Run(tt.testName, func(t *testing.T) {
  182. pb, err := MsgToProto(tt.msg)
  183. if tt.wantErr == true {
  184. assert.Equal(t, err != nil, tt.wantErr)
  185. return
  186. }
  187. assert.EqualValues(t, tt.want, pb, tt.testName)
  188. msg, err := MsgFromProto(pb)
  189. if !tt.wantErr {
  190. require.NoError(t, err)
  191. bcm := assert.Equal(t, tt.msg, msg, tt.testName)
  192. assert.True(t, bcm, tt.testName)
  193. } else {
  194. require.Error(t, err, tt.testName)
  195. }
  196. })
  197. }
  198. }
  199. func TestWALMsgProto(t *testing.T) {
  200. parts := types.Part{
  201. Index: 1,
  202. Bytes: []byte("test"),
  203. Proof: merkle.Proof{
  204. Total: 1,
  205. Index: 1,
  206. LeafHash: tmrand.Bytes(32),
  207. Aunts: [][]byte{},
  208. },
  209. }
  210. pbParts, err := parts.ToProto()
  211. require.NoError(t, err)
  212. testsCases := []struct {
  213. testName string
  214. msg WALMessage
  215. want *tmcons.WALMessage
  216. wantErr bool
  217. }{
  218. {"successful EventDataRoundState", types.EventDataRoundState{
  219. Height: 2,
  220. Round: 1,
  221. Step: "ronies",
  222. }, &tmcons.WALMessage{
  223. Sum: &tmcons.WALMessage_EventDataRoundState{
  224. EventDataRoundState: &tmproto.EventDataRoundState{
  225. Height: 2,
  226. Round: 1,
  227. Step: "ronies",
  228. },
  229. },
  230. }, false},
  231. {"successful msgInfo", msgInfo{
  232. Msg: &BlockPartMessage{
  233. Height: 100,
  234. Round: 1,
  235. Part: &parts,
  236. },
  237. PeerID: p2p.NodeID("string"),
  238. }, &tmcons.WALMessage{
  239. Sum: &tmcons.WALMessage_MsgInfo{
  240. MsgInfo: &tmcons.MsgInfo{
  241. Msg: tmcons.Message{
  242. Sum: &tmcons.Message_BlockPart{
  243. BlockPart: &tmcons.BlockPart{
  244. Height: 100,
  245. Round: 1,
  246. Part: *pbParts,
  247. },
  248. },
  249. },
  250. PeerID: "string",
  251. },
  252. },
  253. }, false},
  254. {"successful timeoutInfo", timeoutInfo{
  255. Duration: time.Duration(100),
  256. Height: 1,
  257. Round: 1,
  258. Step: 1,
  259. }, &tmcons.WALMessage{
  260. Sum: &tmcons.WALMessage_TimeoutInfo{
  261. TimeoutInfo: &tmcons.TimeoutInfo{
  262. Duration: time.Duration(100),
  263. Height: 1,
  264. Round: 1,
  265. Step: 1,
  266. },
  267. },
  268. }, false},
  269. {"successful EndHeightMessage", EndHeightMessage{
  270. Height: 1,
  271. }, &tmcons.WALMessage{
  272. Sum: &tmcons.WALMessage_EndHeight{
  273. EndHeight: &tmcons.EndHeight{
  274. Height: 1,
  275. },
  276. },
  277. }, false},
  278. {"failure", nil, &tmcons.WALMessage{}, true},
  279. }
  280. for _, tt := range testsCases {
  281. tt := tt
  282. t.Run(tt.testName, func(t *testing.T) {
  283. pb, err := WALToProto(tt.msg)
  284. if tt.wantErr == true {
  285. assert.Equal(t, err != nil, tt.wantErr)
  286. return
  287. }
  288. assert.EqualValues(t, tt.want, pb, tt.testName)
  289. msg, err := WALFromProto(pb)
  290. if !tt.wantErr {
  291. require.NoError(t, err)
  292. assert.Equal(t, tt.msg, msg, tt.testName) // need the concrete type as WAL Message is a empty interface
  293. } else {
  294. require.Error(t, err, tt.testName)
  295. }
  296. })
  297. }
  298. }
  299. // nolint:lll //ignore line length for tests
  300. func TestConsMsgsVectors(t *testing.T) {
  301. date := time.Date(2018, 8, 30, 12, 0, 0, 0, time.UTC)
  302. psh := types.PartSetHeader{
  303. Total: 1,
  304. Hash: []byte("add_more_exclamation_marks_code-"),
  305. }
  306. pbPsh := psh.ToProto()
  307. bi := types.BlockID{
  308. Hash: []byte("add_more_exclamation_marks_code-"),
  309. PartSetHeader: psh,
  310. }
  311. pbBi := bi.ToProto()
  312. bits := bits.NewBitArray(1)
  313. pbBits := bits.ToProto()
  314. parts := types.Part{
  315. Index: 1,
  316. Bytes: []byte("test"),
  317. Proof: merkle.Proof{
  318. Total: 1,
  319. Index: 1,
  320. LeafHash: []byte("add_more_exclamation_marks_code-"),
  321. Aunts: [][]byte{},
  322. },
  323. }
  324. pbParts, err := parts.ToProto()
  325. require.NoError(t, err)
  326. proposal := types.Proposal{
  327. Type: tmproto.ProposalType,
  328. Height: 1,
  329. Round: 1,
  330. POLRound: 1,
  331. BlockID: bi,
  332. Timestamp: date,
  333. Signature: []byte("add_more_exclamation"),
  334. }
  335. pbProposal := proposal.ToProto()
  336. v := &types.Vote{
  337. ValidatorAddress: []byte("add_more_exclamation"),
  338. ValidatorIndex: 1,
  339. Height: 1,
  340. Round: 0,
  341. Timestamp: date,
  342. Type: tmproto.PrecommitType,
  343. BlockID: bi,
  344. }
  345. vpb := v.ToProto()
  346. testCases := []struct {
  347. testName string
  348. cMsg proto.Message
  349. expBytes string
  350. }{
  351. {"NewRoundStep", &tmcons.Message{Sum: &tmcons.Message_NewRoundStep{NewRoundStep: &tmcons.NewRoundStep{
  352. Height: 1,
  353. Round: 1,
  354. Step: 1,
  355. SecondsSinceStartTime: 1,
  356. LastCommitRound: 1,
  357. }}}, "0a0a08011001180120012801"},
  358. {"NewRoundStep Max", &tmcons.Message{Sum: &tmcons.Message_NewRoundStep{NewRoundStep: &tmcons.NewRoundStep{
  359. Height: math.MaxInt64,
  360. Round: math.MaxInt32,
  361. Step: math.MaxUint32,
  362. SecondsSinceStartTime: math.MaxInt64,
  363. LastCommitRound: math.MaxInt32,
  364. }}}, "0a2608ffffffffffffffff7f10ffffffff0718ffffffff0f20ffffffffffffffff7f28ffffffff07"},
  365. {"NewValidBlock", &tmcons.Message{Sum: &tmcons.Message_NewValidBlock{
  366. NewValidBlock: &tmcons.NewValidBlock{
  367. Height: 1, Round: 1, BlockPartSetHeader: pbPsh, BlockParts: pbBits, IsCommit: false}}},
  368. "1231080110011a24080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d22050801120100"},
  369. {"Proposal", &tmcons.Message{Sum: &tmcons.Message_Proposal{Proposal: &tmcons.Proposal{Proposal: *pbProposal}}},
  370. "1a720a7008201001180120012a480a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d1224080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d320608c0b89fdc053a146164645f6d6f72655f6578636c616d6174696f6e"},
  371. {"ProposalPol", &tmcons.Message{Sum: &tmcons.Message_ProposalPol{
  372. ProposalPol: &tmcons.ProposalPOL{Height: 1, ProposalPolRound: 1}}},
  373. "2206080110011a00"},
  374. {"BlockPart", &tmcons.Message{Sum: &tmcons.Message_BlockPart{
  375. BlockPart: &tmcons.BlockPart{Height: 1, Round: 1, Part: *pbParts}}},
  376. "2a36080110011a3008011204746573741a26080110011a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d"},
  377. {"Vote", &tmcons.Message{Sum: &tmcons.Message_Vote{
  378. Vote: &tmcons.Vote{Vote: vpb}}},
  379. "32700a6e0802100122480a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d1224080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d2a0608c0b89fdc0532146164645f6d6f72655f6578636c616d6174696f6e3801"},
  380. {"HasVote", &tmcons.Message{Sum: &tmcons.Message_HasVote{
  381. HasVote: &tmcons.HasVote{Height: 1, Round: 1, Type: tmproto.PrevoteType, Index: 1}}},
  382. "3a080801100118012001"},
  383. {"HasVote", &tmcons.Message{Sum: &tmcons.Message_HasVote{
  384. HasVote: &tmcons.HasVote{Height: math.MaxInt64, Round: math.MaxInt32,
  385. Type: tmproto.PrevoteType, Index: math.MaxInt32}}},
  386. "3a1808ffffffffffffffff7f10ffffffff07180120ffffffff07"},
  387. {"VoteSetMaj23", &tmcons.Message{Sum: &tmcons.Message_VoteSetMaj23{
  388. VoteSetMaj23: &tmcons.VoteSetMaj23{Height: 1, Round: 1, Type: tmproto.PrevoteType, BlockID: pbBi}}},
  389. "425008011001180122480a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d1224080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d"},
  390. {"VoteSetBits", &tmcons.Message{Sum: &tmcons.Message_VoteSetBits{
  391. VoteSetBits: &tmcons.VoteSetBits{Height: 1, Round: 1, Type: tmproto.PrevoteType, BlockID: pbBi, Votes: *pbBits}}},
  392. "4a5708011001180122480a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d1224080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d2a050801120100"},
  393. }
  394. for _, tc := range testCases {
  395. tc := tc
  396. t.Run(tc.testName, func(t *testing.T) {
  397. bz, err := proto.Marshal(tc.cMsg)
  398. require.NoError(t, err)
  399. require.Equal(t, tc.expBytes, hex.EncodeToString(bz))
  400. })
  401. }
  402. }