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