Skip to content

Commit

Permalink
rpc: add support for protobuf-encoded messages
Browse files Browse the repository at this point in the history
Adds initial support for the Protobuf-based RPC protocol used by
Tendermint v0.34.
  • Loading branch information
tony-iqlusion committed Oct 29, 2020
1 parent 2231381 commit d46647a
Show file tree
Hide file tree
Showing 10 changed files with 543 additions and 114 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ ledger = { version = "0.2", optional = true }
merlin = "2"
once_cell = "1.4"
prost = "0.6"
prost-derive = "0.6"
prost-amino = "0.6"
prost-amino-derive = "0.6"
prost-derive = "0.6"
prost-types = "0.6"
rand_core = { version = "0.5", features = ["std"] }
rpassword = { version = "5", optional = true }
serde = { version = "1", features = ["serde_derive"] }
Expand Down
6 changes: 4 additions & 2 deletions src/connection/secret_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
mod amino_types;
mod kdf;
mod nonce;
mod proto_types;
pub(crate) mod proto_types;
mod protocol;
mod public_key;

Expand Down Expand Up @@ -36,9 +36,11 @@ use zeroize::Zeroizing;
/// Size of the MAC tag
pub const TAG_SIZE: usize = 16;

/// Maximum size of a message
pub const DATA_MAX_SIZE: usize = 1024;

/// 4 + 1024 == 1028 total frame size
const DATA_LEN_SIZE: usize = 4;
const DATA_MAX_SIZE: usize = 1024;
const TOTAL_FRAME_SIZE: usize = DATA_MAX_SIZE + DATA_LEN_SIZE;

/// Generate a Secret Connection key at the given path
Expand Down
2 changes: 1 addition & 1 deletion src/connection/secret_connection/proto_types.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Secret Connection Protobuf Types
//! Secret Connection Protobuf Types (tendermint.p2p.conn)
//!
//! Generated from:
//! <https://github.com/tendermint/tendermint/blob/730e165/proto/tendermint/p2p/conn.proto>
Expand Down
17 changes: 7 additions & 10 deletions src/connection/secret_connection/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,20 @@ pub enum Version {

impl Version {
/// Does this version of Secret Connection use a transcript hash
pub(super) fn has_transcript(self) -> bool {
pub fn has_transcript(self) -> bool {
self != Version::Legacy
}

/// Are messages encoded using Protocol Buffers?
pub(super) fn is_protobuf(self) -> bool {
pub fn is_protobuf(self) -> bool {
match self {
Version::V0_34 => true,
Version::V0_33 | Version::Legacy => false,
}
}

/// Encode the initial handshake message (i.e. first one sent by both peers)
pub(super) fn encode_initial_handshake(self, eph_pubkey: &EphemeralPublic) -> Vec<u8> {
pub fn encode_initial_handshake(self, eph_pubkey: &EphemeralPublic) -> Vec<u8> {
if self.is_protobuf() {
// Equivalent Go implementation:
// https://github.com/tendermint/tendermint/blob/9e98c74/p2p/conn/secret_connection.go#L307-L312
Expand All @@ -72,7 +72,7 @@ impl Version {
}

/// Decode the initial handshake message
pub(super) fn decode_initial_handshake(self, bytes: &[u8]) -> Result<EphemeralPublic, Error> {
pub fn decode_initial_handshake(self, bytes: &[u8]) -> Result<EphemeralPublic, Error> {
let eph_pubkey = if self.is_protobuf() {
// Equivalent Go implementation:
// https://github.com/tendermint/tendermint/blob/9e98c74/p2p/conn/secret_connection.go#L315-L323
Expand Down Expand Up @@ -111,7 +111,7 @@ impl Version {
}

/// Encode signature which authenticates the handshake
pub(super) fn encode_auth_signature(
pub fn encode_auth_signature(
self,
pub_key: &ed25519::PublicKey,
signature: &ed25519::Signature,
Expand Down Expand Up @@ -149,7 +149,7 @@ impl Version {
}

/// Get the length of the auth message response for this protocol version
pub(super) fn auth_sig_msg_response_len(self) -> usize {
pub fn auth_sig_msg_response_len(self) -> usize {
if self.is_protobuf() {
// 32 + 64 + (proto overhead = 1 prefix + 2 fields + 2 lengths + total length)
103
Expand All @@ -160,10 +160,7 @@ impl Version {
}

/// Decode signature message which authenticates the handshake
pub(super) fn decode_auth_signature(
self,
bytes: &[u8],
) -> Result<proto_types::AuthSigMessage, Error> {
pub fn decode_auth_signature(self, bytes: &[u8]) -> Result<proto_types::AuthSigMessage, Error> {
if self.is_protobuf() {
// Parse Protobuf-encoded `AuthSigMessage`
proto_types::AuthSigMessage::decode_length_delimited(bytes).map_err(|e| {
Expand Down
12 changes: 12 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,18 @@ impl std::error::Error for Error {
}
}

impl From<prost::DecodeError> for Error {
fn from(other: prost::DecodeError) -> Self {
ErrorKind::ProtocolError.context(other).into()
}
}

impl From<prost::EncodeError> for Error {
fn from(other: prost::EncodeError) -> Self {
ErrorKind::ProtocolError.context(other).into()
}
}

impl From<prost_amino::DecodeError> for Error {
fn from(other: prost_amino::DecodeError) -> Self {
ErrorKind::ProtocolError.context(other).into()
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub mod error;
pub mod key_utils;
pub mod keyring;
pub mod prelude;
pub mod proto_types;
pub mod rpc;
pub mod session;

Expand Down
Loading

0 comments on commit d46647a

Please sign in to comment.