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.

457 lines
14 KiB

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