You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

457 lines
14 KiB

package consensus
import (
"math"
"testing"
"time"
"github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/merkle"
"github.com/tendermint/tendermint/libs/bits"
tmrand "github.com/tendermint/tendermint/libs/rand"
"github.com/tendermint/tendermint/p2p"
tmcons "github.com/tendermint/tendermint/proto/tendermint/consensus"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/tendermint/tendermint/types"
)
func TestMsgToProto(t *testing.T) {
psh := types.PartSetHeader{
Total: 1,
Hash: tmrand.Bytes(32),
}
pbPsh := psh.ToProto()
bi := types.BlockID{
Hash: tmrand.Bytes(32),
PartSetHeader: psh,
}
pbBi := bi.ToProto()
bits := bits.NewBitArray(1)
pbBits := bits.ToProto()
parts := types.Part{
Index: 1,
Bytes: []byte("test"),
Proof: merkle.Proof{
Total: 1,
Index: 1,
LeafHash: tmrand.Bytes(32),
Aunts: [][]byte{},
},
}
pbParts, err := parts.ToProto()
require.NoError(t, err)
proposal := types.Proposal{
Type: tmproto.ProposalType,
Height: 1,
Round: 1,
POLRound: 1,
BlockID: bi,
Timestamp: time.Now(),
Signature: tmrand.Bytes(20),
}
pbProposal := proposal.ToProto()
pv := types.NewMockPV()
pk, err := pv.GetPubKey()
require.NoError(t, err)
val := types.NewValidator(pk, 100)
vote, err := types.MakeVote(
1, types.BlockID{}, &types.ValidatorSet{Proposer: val, Validators: []*types.Validator{val}},
pv, "chainID", time.Now())
require.NoError(t, err)
pbVote := vote.ToProto()
testsCases := []struct {
testName string
msg Message
want *tmcons.Message
wantErr bool
}{
{"successful NewRoundStepMessage", &NewRoundStepMessage{
Height: 2,
Round: 1,
Step: 1,
SecondsSinceStartTime: 1,
LastCommitRound: 2,
}, &tmcons.Message{
Sum: &tmcons.Message_NewRoundStep{
NewRoundStep: &tmcons.NewRoundStep{
Height: 2,
Round: 1,
Step: 1,
SecondsSinceStartTime: 1,
LastCommitRound: 2,
},
},
}, false},
{"successful NewValidBlockMessage", &NewValidBlockMessage{
Height: 1,
Round: 1,
BlockPartSetHeader: psh,
BlockParts: bits,
IsCommit: false,
}, &tmcons.Message{
Sum: &tmcons.Message_NewValidBlock{
NewValidBlock: &tmcons.NewValidBlock{
Height: 1,
Round: 1,
BlockPartSetHeader: pbPsh,
BlockParts: pbBits,
IsCommit: false,
},
},
}, false},
{"successful BlockPartMessage", &BlockPartMessage{
Height: 100,
Round: 1,
Part: &parts,
}, &tmcons.Message{
Sum: &tmcons.Message_BlockPart{
BlockPart: &tmcons.BlockPart{
Height: 100,
Round: 1,
Part: *pbParts,
},
},
}, false},
{"successful ProposalPOLMessage", &ProposalPOLMessage{
Height: 1,
ProposalPOLRound: 1,
ProposalPOL: bits,
}, &tmcons.Message{
Sum: &tmcons.Message_ProposalPol{
ProposalPol: &tmcons.ProposalPOL{
Height: 1,
ProposalPolRound: 1,
ProposalPol: *pbBits,
},
}}, false},
{"successful ProposalMessage", &ProposalMessage{
Proposal: &proposal,
}, &tmcons.Message{
Sum: &tmcons.Message_Proposal{
Proposal: &tmcons.Proposal{
Proposal: *pbProposal,
},
},
}, false},
{"successful VoteMessage", &VoteMessage{
Vote: vote,
}, &tmcons.Message{
Sum: &tmcons.Message_Vote{
Vote: &tmcons.Vote{
Vote: pbVote,
},
},
}, false},
{"successful VoteSetMaj23", &VoteSetMaj23Message{
Height: 1,
Round: 1,
Type: 1,
BlockID: bi,
}, &tmcons.Message{
Sum: &tmcons.Message_VoteSetMaj23{
VoteSetMaj23: &tmcons.VoteSetMaj23{
Height: 1,
Round: 1,
Type: 1,
BlockID: pbBi,
},
},
}, false},
{"successful VoteSetBits", &VoteSetBitsMessage{
Height: 1,
Round: 1,
Type: 1,
BlockID: bi,
Votes: bits,
}, &tmcons.Message{
Sum: &tmcons.Message_VoteSetBits{
VoteSetBits: &tmcons.VoteSetBits{
Height: 1,
Round: 1,
Type: 1,
BlockID: pbBi,
Votes: *pbBits,
},
},
}, false},
{"failure", nil, &tmcons.Message{}, true},
}
for _, tt := range testsCases {
tt := tt
t.Run(tt.testName, func(t *testing.T) {
pb, err := MsgToProto(tt.msg)
if tt.wantErr == true {
assert.Equal(t, err != nil, tt.wantErr)
return
}
assert.EqualValues(t, tt.want, pb, tt.testName)
msg, err := MsgFromProto(pb)
if !tt.wantErr {
require.NoError(t, err)
bcm := assert.Equal(t, tt.msg, msg, tt.testName)
assert.True(t, bcm, tt.testName)
} else {
require.Error(t, err, tt.testName)
}
})
}
}
func TestWALMsgProto(t *testing.T) {
parts := types.Part{
Index: 1,
Bytes: []byte("test"),
Proof: merkle.Proof{
Total: 1,
Index: 1,
LeafHash: tmrand.Bytes(32),
Aunts: [][]byte{},
},
}
pbParts, err := parts.ToProto()
require.NoError(t, err)
testsCases := []struct {
testName string
msg WALMessage
want *tmcons.WALMessage
wantErr bool
}{
{"successful EventDataRoundState", types.EventDataRoundState{
Height: 2,
Round: 1,
Step: "ronies",
}, &tmcons.WALMessage{
Sum: &tmcons.WALMessage_EventDataRoundState{
EventDataRoundState: &tmproto.EventDataRoundState{
Height: 2,
Round: 1,
Step: "ronies",
},
},
}, false},
{"successful msgInfo", msgInfo{
Msg: &BlockPartMessage{
Height: 100,
Round: 1,
Part: &parts,
},
PeerID: p2p.ID("string"),
}, &tmcons.WALMessage{
Sum: &tmcons.WALMessage_MsgInfo{
MsgInfo: &tmcons.MsgInfo{
Msg: tmcons.Message{
Sum: &tmcons.Message_BlockPart{
BlockPart: &tmcons.BlockPart{
Height: 100,
Round: 1,
Part: *pbParts,
},
},
},
PeerID: "string",
},
},
}, false},
{"successful timeoutInfo", timeoutInfo{
Duration: time.Duration(100),
Height: 1,
Round: 1,
Step: 1,
}, &tmcons.WALMessage{
Sum: &tmcons.WALMessage_TimeoutInfo{
TimeoutInfo: &tmcons.TimeoutInfo{
Duration: time.Duration(100),
Height: 1,
Round: 1,
Step: 1,
},
},
}, false},
{"successful EndHeightMessage", EndHeightMessage{
Height: 1,
}, &tmcons.WALMessage{
Sum: &tmcons.WALMessage_EndHeight{
EndHeight: &tmcons.EndHeight{
Height: 1,
},
},
}, false},
{"failure", nil, &tmcons.WALMessage{}, true},
}
for _, tt := range testsCases {
tt := tt
t.Run(tt.testName, func(t *testing.T) {
pb, err := WALToProto(tt.msg)
if tt.wantErr == true {
assert.Equal(t, err != nil, tt.wantErr)
return
}
assert.EqualValues(t, tt.want, pb, tt.testName)
msg, err := WALFromProto(pb)
if !tt.wantErr {
require.NoError(t, err)
assert.Equal(t, tt.msg, msg, tt.testName) // need the concrete type as WAL Message is a empty interface
} else {
require.Error(t, err, tt.testName)
}
})
}
}
func TestConsMsgsVectors(t *testing.T) {
date := time.Date(2018, 8, 30, 12, 0, 0, 0, time.UTC)
psh := types.PartSetHeader{
Total: 1,
Hash: []byte("add_more_exclamation_marks_code-"),
}
pbPsh := psh.ToProto()
bi := types.BlockID{
Hash: []byte("add_more_exclamation_marks_code-"),
PartSetHeader: psh,
}
pbBi := bi.ToProto()
bits := bits.NewBitArray(1)
pbBits := bits.ToProto()
parts := types.Part{
Index: 1,
Bytes: []byte("test"),
Proof: merkle.Proof{
Total: 1,
Index: 1,
LeafHash: []byte("add_more_exclamation_marks_code-"),
Aunts: [][]byte{},
},
}
pbParts, err := parts.ToProto()
require.NoError(t, err)
proposal := types.Proposal{
Type: tmproto.ProposalType,
Height: 1,
Round: 1,
POLRound: 1,
BlockID: bi,
Timestamp: date,
Signature: []byte("add_more_exclamation"),
}
pbProposal := proposal.ToProto()
v := &types.Vote{
ValidatorAddress: []byte("add_more_exclamation"),
ValidatorIndex: 1,
Height: 1,
Round: 0,
Timestamp: date,
Type: tmproto.PrecommitType,
BlockID: bi,
}
vpb := v.ToProto()
testCases := []struct {
testName string
cMsg proto.Message
expBytes []byte
}{
{"NewRoundStep", &tmcons.Message{Sum: &tmcons.Message_NewRoundStep{NewRoundStep: &tmcons.NewRoundStep{
Height: 1,
Round: 1,
Step: 1,
SecondsSinceStartTime: 1,
LastCommitRound: 1,
}}}, []byte{0xa, 0xa, 0x8, 0x1, 0x10, 0x1, 0x18, 0x1, 0x20, 0x1, 0x28, 0x1}},
{"NewRoundStep Max", &tmcons.Message{Sum: &tmcons.Message_NewRoundStep{NewRoundStep: &tmcons.NewRoundStep{
Height: math.MaxInt64,
Round: math.MaxInt32,
Step: math.MaxUint32,
SecondsSinceStartTime: math.MaxInt64,
LastCommitRound: math.MaxInt32,
}}}, []byte{0xa, 0x26, 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x10, 0xff,
0xff, 0xff, 0xff, 0x7, 0x18, 0xff, 0xff, 0xff, 0xff, 0xf, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x7f, 0x28, 0xff, 0xff, 0xff, 0xff, 0x7}},
{"NewValidBlock", &tmcons.Message{Sum: &tmcons.Message_NewValidBlock{
NewValidBlock: &tmcons.NewValidBlock{
Height: 1, Round: 1, BlockPartSetHeader: pbPsh, BlockParts: pbBits, IsCommit: false}}},
[]byte{0x12, 0x31, 0x8, 0x1, 0x10, 0x1, 0x1a, 0x24, 0x8, 0x1, 0x12, 0x20, 0x61, 0x64, 0x64, 0x5f, 0x6d,
0x6f, 0x72, 0x65, 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x61, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d,
0x61, 0x72, 0x6b, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2d, 0x22, 0x5, 0x8, 0x1, 0x12, 0x1, 0x0}},
{"Proposal", &tmcons.Message{Sum: &tmcons.Message_Proposal{Proposal: &tmcons.Proposal{Proposal: *pbProposal}}},
[]byte{0x1a, 0x72, 0xa, 0x70, 0x8, 0x20, 0x10, 0x1, 0x18, 0x1, 0x20, 0x1, 0x2a, 0x48, 0xa, 0x20, 0x61,
0x64, 0x64, 0x5f, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x61, 0x6d, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2d, 0x12, 0x24, 0x8,
0x1, 0x12, 0x20, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x61,
0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65,
0x2d, 0x32, 0x6, 0x8, 0xc0, 0xb8, 0x9f, 0xdc, 0x5, 0x3a, 0x14, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x6f, 0x72,
0x65, 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x61, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e}},
{"ProposalPol", &tmcons.Message{Sum: &tmcons.Message_ProposalPol{
ProposalPol: &tmcons.ProposalPOL{Height: 1, ProposalPolRound: 1}}},
[]byte{0x22, 0x6, 0x8, 0x1, 0x10, 0x1, 0x1a, 0x0}},
{"BlockPart", &tmcons.Message{Sum: &tmcons.Message_BlockPart{
BlockPart: &tmcons.BlockPart{Height: 1, Round: 1, Part: *pbParts}}},
[]byte{0x2a, 0x36, 0x8, 0x1, 0x10, 0x1, 0x1a, 0x30, 0x8, 0x1, 0x12, 0x4,
0x74, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x8, 0x1, 0x10, 0x1, 0x1a, 0x20, 0x61,
0x64, 0x64, 0x5f, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x61,
0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x5f, 0x63,
0x6f, 0x64, 0x65, 0x2d}},
{"Vote", &tmcons.Message{Sum: &tmcons.Message_Vote{
Vote: &tmcons.Vote{Vote: vpb}}},
[]byte{0x32, 0x70, 0xa, 0x6e, 0x8, 0x2, 0x10, 0x1, 0x22, 0x48, 0xa, 0x20, 0x61, 0x64, 0x64,
0x5f, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x61, 0x6d, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2d, 0x12,
0x24, 0x8, 0x1, 0x12, 0x20, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x78,
0x63, 0x6c, 0x61, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x5f,
0x63, 0x6f, 0x64, 0x65, 0x2d, 0x2a, 0x6, 0x8, 0xc0, 0xb8, 0x9f, 0xdc, 0x5, 0x32, 0x14, 0x61, 0x64,
0x64, 0x5f, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x61, 0x6d, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x38, 0x1}},
{"HasVote", &tmcons.Message{Sum: &tmcons.Message_HasVote{
HasVote: &tmcons.HasVote{Height: 1, Round: 1, Type: tmproto.PrevoteType, Index: 1}}},
[]byte{0x3a, 0x8, 0x8, 0x1, 0x10, 0x1, 0x18, 0x1, 0x20, 0x1}},
{"HasVote", &tmcons.Message{Sum: &tmcons.Message_HasVote{
HasVote: &tmcons.HasVote{Height: math.MaxInt64, Round: math.MaxInt32,
Type: tmproto.PrevoteType, Index: math.MaxInt32}}},
[]byte{0x3a, 0x18, 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x7f, 0x10, 0xff, 0xff, 0xff, 0xff, 0x7, 0x18, 0x1, 0x20, 0xff, 0xff, 0xff, 0xff, 0x7}},
{"VoteSetMaj23", &tmcons.Message{Sum: &tmcons.Message_VoteSetMaj23{
VoteSetMaj23: &tmcons.VoteSetMaj23{Height: 1, Round: 1, Type: tmproto.PrevoteType, BlockID: pbBi}}},
[]byte{0x42, 0x50, 0x8, 0x1, 0x10, 0x1, 0x18, 0x1, 0x22, 0x48, 0xa, 0x20, 0x61, 0x64, 0x64, 0x5f,
0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x61, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2d, 0x12, 0x24, 0x8, 0x1,
0x12, 0x20, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x61,
0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x5f, 0x63, 0x6f, 0x64,
0x65, 0x2d}},
{"VoteSetBits", &tmcons.Message{Sum: &tmcons.Message_VoteSetBits{
VoteSetBits: &tmcons.VoteSetBits{Height: 1, Round: 1, Type: tmproto.PrevoteType, BlockID: pbBi, Votes: *pbBits}}},
[]byte{0x4a, 0x57, 0x8, 0x1, 0x10, 0x1, 0x18, 0x1, 0x22, 0x48, 0xa, 0x20, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x6f, 0x72,
0x65, 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x61, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x73,
0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2d, 0x12, 0x24, 0x8, 0x1, 0x12, 0x20, 0x61, 0x64, 0x64, 0x5f, 0x6d, 0x6f, 0x72,
0x65, 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x61, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x73,
0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2d, 0x2a, 0x5, 0x8, 0x1, 0x12, 0x1, 0x0}},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.testName, func(t *testing.T) {
bz, err := proto.Marshal(tc.cMsg)
require.NoError(t, err)
require.Equal(t, tc.expBytes, bz)
})
}
}