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  }