diff --git a/proto/tendermint/blocksync/message.go b/proto/tendermint/blocksync/message.go new file mode 100644 index 000000000..1840c4e61 --- /dev/null +++ b/proto/tendermint/blocksync/message.go @@ -0,0 +1,107 @@ +package blocksync + +import ( + "errors" + "fmt" + + "github.com/gogo/protobuf/proto" +) + +const ( + BlockResponseMessagePrefixSize = 4 + BlockResponseMessageFieldKeySize = 1 +) + +// Wrap implements the p2p Wrapper interface and wraps a blockchain message. +func (m *Message) Wrap(pb proto.Message) error { + switch msg := pb.(type) { + case *BlockRequest: + m.Sum = &Message_BlockRequest{BlockRequest: msg} + + case *BlockResponse: + m.Sum = &Message_BlockResponse{BlockResponse: msg} + + case *NoBlockResponse: + m.Sum = &Message_NoBlockResponse{NoBlockResponse: msg} + + case *StatusRequest: + m.Sum = &Message_StatusRequest{StatusRequest: msg} + + case *StatusResponse: + m.Sum = &Message_StatusResponse{StatusResponse: msg} + + default: + return fmt.Errorf("unknown message: %T", msg) + } + + return nil +} + +// Unwrap implements the p2p Wrapper interface and unwraps a wrapped blockchain +// message. +func (m *Message) Unwrap() (proto.Message, error) { + switch msg := m.Sum.(type) { + case *Message_BlockRequest: + return m.GetBlockRequest(), nil + + case *Message_BlockResponse: + return m.GetBlockResponse(), nil + + case *Message_NoBlockResponse: + return m.GetNoBlockResponse(), nil + + case *Message_StatusRequest: + return m.GetStatusRequest(), nil + + case *Message_StatusResponse: + return m.GetStatusResponse(), nil + + default: + return nil, fmt.Errorf("unknown message: %T", msg) + } +} + +// Validate validates the message returning an error upon failure. +func (m *Message) Validate() error { + if m == nil { + return errors.New("message cannot be nil") + } + + switch msg := m.Sum.(type) { + case *Message_BlockRequest: + if m.GetBlockRequest().Height < 0 { + return errors.New("negative Height") + } + + case *Message_BlockResponse: + // validate basic is called later when converting from proto + return nil + + case *Message_NoBlockResponse: + if m.GetNoBlockResponse().Height < 0 { + return errors.New("negative Height") + } + + case *Message_StatusResponse: + if m.GetStatusResponse().Base < 0 { + return errors.New("negative Base") + } + if m.GetStatusResponse().Height < 0 { + return errors.New("negative Height") + } + if m.GetStatusResponse().Base > m.GetStatusResponse().Height { + return fmt.Errorf( + "base %v cannot be greater than height %v", + m.GetStatusResponse().Base, m.GetStatusResponse().Height, + ) + } + + case *Message_StatusRequest: + return nil + + default: + return fmt.Errorf("unknown message type: %T", msg) + } + + return nil +} diff --git a/proto/tendermint/consensus/message.go b/proto/tendermint/consensus/message.go new file mode 100644 index 000000000..bcdab629a --- /dev/null +++ b/proto/tendermint/consensus/message.go @@ -0,0 +1,80 @@ +package consensus + +import ( + "fmt" + + "github.com/gogo/protobuf/proto" +) + +// Wrap implements the p2p Wrapper interface and wraps a consensus proto message. +func (m *Message) Wrap(pb proto.Message) error { + switch msg := pb.(type) { + case *NewRoundStep: + m.Sum = &Message_NewRoundStep{NewRoundStep: msg} + + case *NewValidBlock: + m.Sum = &Message_NewValidBlock{NewValidBlock: msg} + + case *Proposal: + m.Sum = &Message_Proposal{Proposal: msg} + + case *ProposalPOL: + m.Sum = &Message_ProposalPol{ProposalPol: msg} + + case *BlockPart: + m.Sum = &Message_BlockPart{BlockPart: msg} + + case *Vote: + m.Sum = &Message_Vote{Vote: msg} + + case *HasVote: + m.Sum = &Message_HasVote{HasVote: msg} + + case *VoteSetMaj23: + m.Sum = &Message_VoteSetMaj23{VoteSetMaj23: msg} + + case *VoteSetBits: + m.Sum = &Message_VoteSetBits{VoteSetBits: msg} + + default: + return fmt.Errorf("unknown message: %T", msg) + } + + return nil +} + +// Unwrap implements the p2p Wrapper interface and unwraps a wrapped consensus +// proto message. +func (m *Message) Unwrap() (proto.Message, error) { + switch msg := m.Sum.(type) { + case *Message_NewRoundStep: + return m.GetNewRoundStep(), nil + + case *Message_NewValidBlock: + return m.GetNewValidBlock(), nil + + case *Message_Proposal: + return m.GetProposal(), nil + + case *Message_ProposalPol: + return m.GetProposalPol(), nil + + case *Message_BlockPart: + return m.GetBlockPart(), nil + + case *Message_Vote: + return m.GetVote(), nil + + case *Message_HasVote: + return m.GetHasVote(), nil + + case *Message_VoteSetMaj23: + return m.GetVoteSetMaj23(), nil + + case *Message_VoteSetBits: + return m.GetVoteSetBits(), nil + + default: + return nil, fmt.Errorf("unknown message: %T", msg) + } +} diff --git a/proto/tendermint/mempool/message.go b/proto/tendermint/mempool/message.go new file mode 100644 index 000000000..a3e249f99 --- /dev/null +++ b/proto/tendermint/mempool/message.go @@ -0,0 +1,32 @@ +package mempool + +import ( + "fmt" + + "github.com/gogo/protobuf/proto" +) + +// Wrap implements the p2p Wrapper interface and wraps a mempool message. +func (m *Message) Wrap(pb proto.Message) error { + switch msg := pb.(type) { + case *Txs: + m.Sum = &Message_Txs{Txs: msg} + + default: + return fmt.Errorf("unknown message: %T", msg) + } + + return nil +} + +// Unwrap implements the p2p Wrapper interface and unwraps a wrapped mempool +// message. +func (m *Message) Unwrap() (proto.Message, error) { + switch msg := m.Sum.(type) { + case *Message_Txs: + return m.GetTxs(), nil + + default: + return nil, fmt.Errorf("unknown message: %T", msg) + } +} diff --git a/proto/tendermint/p2p/pex.go b/proto/tendermint/p2p/pex.go new file mode 100644 index 000000000..61036142f --- /dev/null +++ b/proto/tendermint/p2p/pex.go @@ -0,0 +1,33 @@ +package p2p + +import ( + "fmt" + + "github.com/gogo/protobuf/proto" +) + +// Wrap implements the p2p Wrapper interface and wraps a PEX message. +func (m *PexMessage) Wrap(pb proto.Message) error { + switch msg := pb.(type) { + case *PexRequest: + m.Sum = &PexMessage_PexRequest{PexRequest: msg} + case *PexResponse: + m.Sum = &PexMessage_PexResponse{PexResponse: msg} + default: + return fmt.Errorf("unknown pex message: %T", msg) + } + return nil +} + +// Unwrap implements the p2p Wrapper interface and unwraps a wrapped PEX +// message. +func (m *PexMessage) Unwrap() (proto.Message, error) { + switch msg := m.Sum.(type) { + case *PexMessage_PexRequest: + return msg.PexRequest, nil + case *PexMessage_PexResponse: + return msg.PexResponse, nil + default: + return nil, fmt.Errorf("unknown pex message: %T", msg) + } +} diff --git a/proto/tendermint/statesync/message.go b/proto/tendermint/statesync/message.go new file mode 100644 index 000000000..92d3764fd --- /dev/null +++ b/proto/tendermint/statesync/message.go @@ -0,0 +1,137 @@ +package statesync + +import ( + "errors" + "fmt" + + "github.com/gogo/protobuf/proto" +) + +// Wrap implements the p2p Wrapper interface and wraps a state sync proto message. +func (m *Message) Wrap(pb proto.Message) error { + switch msg := pb.(type) { + case *ChunkRequest: + m.Sum = &Message_ChunkRequest{ChunkRequest: msg} + + case *ChunkResponse: + m.Sum = &Message_ChunkResponse{ChunkResponse: msg} + + case *SnapshotsRequest: + m.Sum = &Message_SnapshotsRequest{SnapshotsRequest: msg} + + case *SnapshotsResponse: + m.Sum = &Message_SnapshotsResponse{SnapshotsResponse: msg} + + case *LightBlockRequest: + m.Sum = &Message_LightBlockRequest{LightBlockRequest: msg} + + case *LightBlockResponse: + m.Sum = &Message_LightBlockResponse{LightBlockResponse: msg} + + case *ParamsRequest: + m.Sum = &Message_ParamsRequest{ParamsRequest: msg} + + case *ParamsResponse: + m.Sum = &Message_ParamsResponse{ParamsResponse: msg} + + default: + return fmt.Errorf("unknown message: %T", msg) + } + + return nil +} + +// Unwrap implements the p2p Wrapper interface and unwraps a wrapped state sync +// proto message. +func (m *Message) Unwrap() (proto.Message, error) { + switch msg := m.Sum.(type) { + case *Message_ChunkRequest: + return m.GetChunkRequest(), nil + + case *Message_ChunkResponse: + return m.GetChunkResponse(), nil + + case *Message_SnapshotsRequest: + return m.GetSnapshotsRequest(), nil + + case *Message_SnapshotsResponse: + return m.GetSnapshotsResponse(), nil + + case *Message_LightBlockRequest: + return m.GetLightBlockRequest(), nil + + case *Message_LightBlockResponse: + return m.GetLightBlockResponse(), nil + + case *Message_ParamsRequest: + return m.GetParamsRequest(), nil + + case *Message_ParamsResponse: + return m.GetParamsResponse(), nil + + default: + return nil, fmt.Errorf("unknown message: %T", msg) + } +} + +// Validate validates the message returning an error upon failure. +func (m *Message) Validate() error { + if m == nil { + return errors.New("message cannot be nil") + } + + switch msg := m.Sum.(type) { + case *Message_ChunkRequest: + if m.GetChunkRequest().Height == 0 { + return errors.New("height cannot be 0") + } + + case *Message_ChunkResponse: + if m.GetChunkResponse().Height == 0 { + return errors.New("height cannot be 0") + } + if m.GetChunkResponse().Missing && len(m.GetChunkResponse().Chunk) > 0 { + return errors.New("missing chunk cannot have contents") + } + if !m.GetChunkResponse().Missing && m.GetChunkResponse().Chunk == nil { + return errors.New("chunk cannot be nil") + } + + case *Message_SnapshotsRequest: + + case *Message_SnapshotsResponse: + if m.GetSnapshotsResponse().Height == 0 { + return errors.New("height cannot be 0") + } + if len(m.GetSnapshotsResponse().Hash) == 0 { + return errors.New("snapshot has no hash") + } + if m.GetSnapshotsResponse().Chunks == 0 { + return errors.New("snapshot has no chunks") + } + + case *Message_LightBlockRequest: + if m.GetLightBlockRequest().Height == 0 { + return errors.New("height cannot be 0") + } + + // light block validation handled by the backfill process + case *Message_LightBlockResponse: + + case *Message_ParamsRequest: + if m.GetParamsRequest().Height == 0 { + return errors.New("height cannot be 0") + } + + case *Message_ParamsResponse: + resp := m.GetParamsResponse() + if resp.Height == 0 { + return errors.New("height cannot be 0") + } + + default: + return fmt.Errorf("unknown message type: %T", msg) + } + + return nil +}