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  }