github.com/Finschia/ostracon@v1.1.5/consensus/msgs_test.go (about) 1 package consensus 2 3 import ( 4 "encoding/hex" 5 "math" 6 "testing" 7 "time" 8 9 "github.com/gogo/protobuf/proto" 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 13 tmcons "github.com/tendermint/tendermint/proto/tendermint/consensus" 14 tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 15 16 "github.com/Finschia/ostracon/crypto/merkle" 17 "github.com/Finschia/ostracon/libs/bits" 18 tmrand "github.com/Finschia/ostracon/libs/rand" 19 "github.com/Finschia/ostracon/p2p" 20 "github.com/Finschia/ostracon/types" 21 ) 22 23 func TestMsgToProto(t *testing.T) { 24 psh := types.PartSetHeader{ 25 Total: 1, 26 Hash: tmrand.Bytes(32), 27 } 28 pbPsh := psh.ToProto() 29 bi := types.BlockID{ 30 Hash: tmrand.Bytes(32), 31 PartSetHeader: psh, 32 } 33 pbBi := bi.ToProto() 34 bits := bits.NewBitArray(1) 35 pbBits := bits.ToProto() 36 37 parts := types.Part{ 38 Index: 1, 39 Bytes: []byte("test"), 40 Proof: merkle.Proof{ 41 Total: 1, 42 Index: 1, 43 LeafHash: tmrand.Bytes(32), 44 Aunts: [][]byte{}, 45 }, 46 } 47 pbParts, err := parts.ToProto() 48 require.NoError(t, err) 49 50 proposal := types.Proposal{ 51 Type: tmproto.ProposalType, 52 Height: 1, 53 Round: 1, 54 POLRound: 1, 55 BlockID: bi, 56 Timestamp: time.Now(), 57 Signature: tmrand.Bytes(20), 58 } 59 pbProposal := proposal.ToProto() 60 61 pv := types.NewMockPV() 62 pk, err := pv.GetPubKey() 63 require.NoError(t, err) 64 val := types.NewValidator(pk, 100) 65 66 vote, err := types.MakeVote( 67 1, types.BlockID{}, &types.ValidatorSet{Validators: []*types.Validator{val}}, 68 pv, "chainID", time.Now()) 69 require.NoError(t, err) 70 pbVote := vote.ToProto() 71 72 testsCases := []struct { 73 testName string 74 msg Message 75 want *tmcons.Message 76 wantErr bool 77 }{ 78 {"successful NewRoundStepMessage", &NewRoundStepMessage{ 79 Height: 2, 80 Round: 1, 81 Step: 1, 82 SecondsSinceStartTime: 1, 83 LastCommitRound: 2, 84 }, (&tmcons.NewRoundStep{ 85 Height: 2, 86 Round: 1, 87 Step: 1, 88 SecondsSinceStartTime: 1, 89 LastCommitRound: 2, 90 }).Wrap().(*tmcons.Message), 91 92 false}, 93 94 {"successful NewValidBlockMessage", &NewValidBlockMessage{ 95 Height: 1, 96 Round: 1, 97 BlockPartSetHeader: psh, 98 BlockParts: bits, 99 IsCommit: false, 100 }, (&tmcons.NewValidBlock{ 101 Height: 1, 102 Round: 1, 103 BlockPartSetHeader: pbPsh, 104 BlockParts: pbBits, 105 IsCommit: false, 106 }).Wrap().(*tmcons.Message), 107 108 false}, 109 {"successful BlockPartMessage", &BlockPartMessage{ 110 Height: 100, 111 Round: 1, 112 Part: &parts, 113 }, (&tmcons.BlockPart{ 114 Height: 100, 115 Round: 1, 116 Part: *pbParts, 117 }).Wrap().(*tmcons.Message), 118 119 false}, 120 {"successful ProposalPOLMessage", &ProposalPOLMessage{ 121 Height: 1, 122 ProposalPOLRound: 1, 123 ProposalPOL: bits, 124 }, (&tmcons.ProposalPOL{ 125 Height: 1, 126 ProposalPolRound: 1, 127 ProposalPol: *pbBits, 128 }).Wrap().(*tmcons.Message), 129 false}, 130 {"successful ProposalMessage", &ProposalMessage{ 131 Proposal: &proposal, 132 }, (&tmcons.Proposal{ 133 Proposal: *pbProposal, 134 }).Wrap().(*tmcons.Message), 135 136 false}, 137 {"successful VoteMessage", &VoteMessage{ 138 Vote: vote, 139 }, (&tmcons.Vote{ 140 Vote: pbVote, 141 }).Wrap().(*tmcons.Message), 142 143 false}, 144 {"successful VoteSetMaj23", &VoteSetMaj23Message{ 145 Height: 1, 146 Round: 1, 147 Type: 1, 148 BlockID: bi, 149 }, (&tmcons.VoteSetMaj23{ 150 Height: 1, 151 Round: 1, 152 Type: 1, 153 BlockID: pbBi, 154 }).Wrap().(*tmcons.Message), 155 156 false}, 157 {"successful VoteSetBits", &VoteSetBitsMessage{ 158 Height: 1, 159 Round: 1, 160 Type: 1, 161 BlockID: bi, 162 Votes: bits, 163 }, (&tmcons.VoteSetBits{ 164 Height: 1, 165 Round: 1, 166 Type: 1, 167 BlockID: pbBi, 168 Votes: *pbBits, 169 }).Wrap().(*tmcons.Message), 170 171 false}, 172 {"failure", nil, &tmcons.Message{}, true}, 173 } 174 for _, tt := range testsCases { 175 tt := tt 176 t.Run(tt.testName, func(t *testing.T) { 177 pb, err := MsgToProto(tt.msg) 178 if tt.wantErr == true { 179 assert.Equal(t, err != nil, tt.wantErr) 180 return 181 } 182 assert.EqualValues(t, tt.want, pb, tt.testName) 183 184 msg, err := MsgFromProto(pb) 185 186 if !tt.wantErr { 187 require.NoError(t, err) 188 bcm := assert.Equal(t, tt.msg, msg, tt.testName) 189 assert.True(t, bcm, tt.testName) 190 } else { 191 require.Error(t, err, tt.testName) 192 } 193 }) 194 } 195 } 196 197 func TestWALMsgProto(t *testing.T) { 198 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 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.ID("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 290 msg, err := WALFromProto(pb) 291 292 if !tt.wantErr { 293 require.NoError(t, err) 294 assert.Equal(t, tt.msg, msg, tt.testName) // need the concrete type as WAL Message is a empty interface 295 } else { 296 require.Error(t, err, tt.testName) 297 } 298 }) 299 } 300 } 301 302 // nolint:lll //ignore line length for tests 303 func TestConsMsgsVectors(t *testing.T) { 304 date := time.Date(2018, 8, 30, 12, 0, 0, 0, time.UTC) 305 psh := types.PartSetHeader{ 306 Total: 1, 307 Hash: []byte("add_more_exclamation_marks_code-"), 308 } 309 pbPsh := psh.ToProto() 310 311 bi := types.BlockID{ 312 Hash: []byte("add_more_exclamation_marks_code-"), 313 PartSetHeader: psh, 314 } 315 pbBi := bi.ToProto() 316 bits := bits.NewBitArray(1) 317 pbBits := bits.ToProto() 318 319 parts := types.Part{ 320 Index: 1, 321 Bytes: []byte("test"), 322 Proof: merkle.Proof{ 323 Total: 1, 324 Index: 1, 325 LeafHash: []byte("add_more_exclamation_marks_code-"), 326 Aunts: [][]byte{}, 327 }, 328 } 329 pbParts, err := parts.ToProto() 330 require.NoError(t, err) 331 332 proposal := types.Proposal{ 333 Type: tmproto.ProposalType, 334 Height: 1, 335 Round: 1, 336 POLRound: 1, 337 BlockID: bi, 338 Timestamp: date, 339 Signature: []byte("add_more_exclamation"), 340 } 341 pbProposal := proposal.ToProto() 342 343 v := &types.Vote{ 344 ValidatorAddress: []byte("add_more_exclamation"), 345 ValidatorIndex: 1, 346 Height: 1, 347 Round: 0, 348 Timestamp: date, 349 Type: tmproto.PrecommitType, 350 BlockID: bi, 351 } 352 vpb := v.ToProto() 353 354 testCases := []struct { 355 testName string 356 cMsg proto.Message 357 expBytes string 358 }{ 359 {"NewRoundStep", &tmcons.Message{Sum: &tmcons.Message_NewRoundStep{NewRoundStep: &tmcons.NewRoundStep{ 360 Height: 1, 361 Round: 1, 362 Step: 1, 363 SecondsSinceStartTime: 1, 364 LastCommitRound: 1, 365 }}}, "0a0a08011001180120012801"}, 366 {"NewRoundStep Max", &tmcons.Message{Sum: &tmcons.Message_NewRoundStep{NewRoundStep: &tmcons.NewRoundStep{ 367 Height: math.MaxInt64, 368 Round: math.MaxInt32, 369 Step: math.MaxUint32, 370 SecondsSinceStartTime: math.MaxInt64, 371 LastCommitRound: math.MaxInt32, 372 }}}, "0a2608ffffffffffffffff7f10ffffffff0718ffffffff0f20ffffffffffffffff7f28ffffffff07"}, 373 {"NewValidBlock", &tmcons.Message{Sum: &tmcons.Message_NewValidBlock{ 374 NewValidBlock: &tmcons.NewValidBlock{ 375 Height: 1, Round: 1, BlockPartSetHeader: pbPsh, BlockParts: pbBits, IsCommit: false}}}, 376 "1231080110011a24080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d22050801120100"}, 377 {"Proposal", &tmcons.Message{Sum: &tmcons.Message_Proposal{Proposal: &tmcons.Proposal{Proposal: *pbProposal}}}, 378 "1a720a7008201001180120012a480a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d1224080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d320608c0b89fdc053a146164645f6d6f72655f6578636c616d6174696f6e"}, 379 {"ProposalPol", &tmcons.Message{Sum: &tmcons.Message_ProposalPol{ 380 ProposalPol: &tmcons.ProposalPOL{Height: 1, ProposalPolRound: 1}}}, 381 "2206080110011a00"}, 382 {"BlockPart", &tmcons.Message{Sum: &tmcons.Message_BlockPart{ 383 BlockPart: &tmcons.BlockPart{Height: 1, Round: 1, Part: *pbParts}}}, 384 "2a36080110011a3008011204746573741a26080110011a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d"}, 385 {"Vote", &tmcons.Message{Sum: &tmcons.Message_Vote{ 386 Vote: &tmcons.Vote{Vote: vpb}}}, 387 "32700a6e0802100122480a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d1224080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d2a0608c0b89fdc0532146164645f6d6f72655f6578636c616d6174696f6e3801"}, 388 {"HasVote", &tmcons.Message{Sum: &tmcons.Message_HasVote{ 389 HasVote: &tmcons.HasVote{Height: 1, Round: 1, Type: tmproto.PrevoteType, Index: 1}}}, 390 "3a080801100118012001"}, 391 {"HasVote", &tmcons.Message{Sum: &tmcons.Message_HasVote{ 392 HasVote: &tmcons.HasVote{Height: math.MaxInt64, Round: math.MaxInt32, 393 Type: tmproto.PrevoteType, Index: math.MaxInt32}}}, 394 "3a1808ffffffffffffffff7f10ffffffff07180120ffffffff07"}, 395 {"VoteSetMaj23", &tmcons.Message{Sum: &tmcons.Message_VoteSetMaj23{ 396 VoteSetMaj23: &tmcons.VoteSetMaj23{Height: 1, Round: 1, Type: tmproto.PrevoteType, BlockID: pbBi}}}, 397 "425008011001180122480a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d1224080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d"}, 398 {"VoteSetBits", &tmcons.Message{Sum: &tmcons.Message_VoteSetBits{ 399 VoteSetBits: &tmcons.VoteSetBits{Height: 1, Round: 1, Type: tmproto.PrevoteType, BlockID: pbBi, Votes: *pbBits}}}, 400 "4a5708011001180122480a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d1224080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d2a050801120100"}, 401 } 402 403 for _, tc := range testCases { 404 tc := tc 405 t.Run(tc.testName, func(t *testing.T) { 406 bz, err := proto.Marshal(tc.cMsg) 407 require.NoError(t, err) 408 409 require.Equal(t, tc.expBytes, hex.EncodeToString(bz)) 410 }) 411 } 412 }