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