From 880d031124553560d7ab9ceccbc95d13e9f1ad91 Mon Sep 17 00:00:00 2001 From: Shoaib Ahmed Date: Tue, 2 Aug 2022 17:21:38 +0200 Subject: [PATCH] Object safe Protobuf (#2412) * Define protobuf error * Implement object safe Protobuf trait * Add test for object safety * Provide blanket impls for ToBoxed and TryFromIfSized * Add blanket impl test * Use more specific bounds * Seal Protobuf supertraits * Add mod erased * Rename erased traits * Doc comments for Protobuf * Update code to use ibc_proto::protobuf::Protobuf * Fix no_std check * Address review feedback * Rename Protobuf to Protobuf * Remove Sealed mod * Rename Into -> CloneInto and return T instead of Box --- Cargo.lock | 1 + modules/src/applications/transfer/error.rs | 2 +- .../applications/transfer/msgs/transfer.rs | 2 +- .../clients/ics07_tendermint/client_def.rs | 2 +- .../clients/ics07_tendermint/client_state.rs | 2 +- .../ics07_tendermint/consensus_state.rs | 5 +- .../src/clients/ics07_tendermint/header.rs | 2 +- .../clients/ics07_tendermint/misbehaviour.rs | 2 +- .../src/core/ics02_client/client_consensus.rs | 2 +- modules/src/core/ics02_client/client_state.rs | 2 +- modules/src/core/ics02_client/error.rs | 2 +- modules/src/core/ics02_client/header.rs | 2 +- modules/src/core/ics02_client/height.rs | 2 +- modules/src/core/ics02_client/misbehaviour.rs | 2 +- .../core/ics02_client/msgs/create_client.rs | 2 +- .../src/core/ics02_client/msgs/misbehavior.rs | 2 +- .../core/ics02_client/msgs/update_client.rs | 2 +- .../core/ics02_client/msgs/upgrade_client.rs | 2 +- .../src/core/ics02_client/trust_threshold.rs | 2 +- .../src/core/ics03_connection/connection.rs | 2 +- .../ics03_connection/msgs/conn_open_ack.rs | 2 +- .../msgs/conn_open_confirm.rs | 2 +- .../ics03_connection/msgs/conn_open_init.rs | 2 +- .../ics03_connection/msgs/conn_open_try.rs | 2 +- modules/src/core/ics03_connection/version.rs | 2 +- modules/src/core/ics04_channel/channel.rs | 2 +- modules/src/core/ics04_channel/error.rs | 2 +- .../ics04_channel/msgs/acknowledgement.rs | 2 +- .../ics04_channel/msgs/chan_close_confirm.rs | 2 +- .../ics04_channel/msgs/chan_close_init.rs | 2 +- .../core/ics04_channel/msgs/chan_open_ack.rs | 2 +- .../ics04_channel/msgs/chan_open_confirm.rs | 2 +- .../core/ics04_channel/msgs/chan_open_init.rs | 2 +- .../core/ics04_channel/msgs/chan_open_try.rs | 2 +- .../core/ics04_channel/msgs/recv_packet.rs | 2 +- .../src/core/ics04_channel/msgs/timeout.rs | 2 +- .../ics04_channel/msgs/timeout_on_close.rs | 2 +- modules/src/core/ics26_routing/error.rs | 2 +- modules/src/core/ics26_routing/msgs.rs | 2 +- modules/src/mock/client_state.rs | 2 +- modules/src/mock/header.rs | 2 +- modules/src/mock/misbehaviour.rs | 2 +- proto/Cargo.toml | 1 + proto/src/lib.rs | 1 + proto/src/protobuf/erased.rs | 30 +++ proto/src/protobuf/error.rs | 43 ++++ proto/src/protobuf/mod.rs | 215 ++++++++++++++++++ relayer/src/chain/cosmos.rs | 2 +- relayer/src/error.rs | 2 +- 49 files changed, 335 insertions(+), 45 deletions(-) create mode 100644 proto/src/protobuf/erased.rs create mode 100644 proto/src/protobuf/error.rs create mode 100644 proto/src/protobuf/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 935228e2e0..6aa3ed2865 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1458,6 +1458,7 @@ version = "0.19.1" dependencies = [ "base64", "bytes", + "flex-error", "prost", "prost-types", "schemars", diff --git a/modules/src/applications/transfer/error.rs b/modules/src/applications/transfer/error.rs index e5d0e794b9..c289eb29fd 100644 --- a/modules/src/applications/transfer/error.rs +++ b/modules/src/applications/transfer/error.rs @@ -1,8 +1,8 @@ use alloc::string::FromUtf8Error; use flex_error::{define_error, DisplayOnly, TraceError}; +use ibc_proto::protobuf::Error as TendermintProtoError; use subtle_encoding::Error as EncodingError; -use tendermint_proto::Error as TendermintProtoError; use uint::FromDecStrErr; use crate::core::ics04_channel::channel::Order; diff --git a/modules/src/applications/transfer/msgs/transfer.rs b/modules/src/applications/transfer/msgs/transfer.rs index 7d92972ce8..6a54cba9e2 100644 --- a/modules/src/applications/transfer/msgs/transfer.rs +++ b/modules/src/applications/transfer/msgs/transfer.rs @@ -5,7 +5,7 @@ use crate::prelude::*; use ibc_proto::cosmos::base::v1beta1::Coin; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::applications::transfer::v1::MsgTransfer as RawMsgTransfer; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use crate::applications::transfer::error::Error; use crate::core::ics04_channel::timeout::TimeoutHeight; diff --git a/modules/src/clients/ics07_tendermint/client_def.rs b/modules/src/clients/ics07_tendermint/client_def.rs index 34a6cabfbe..56a9b4e8f4 100644 --- a/modules/src/clients/ics07_tendermint/client_def.rs +++ b/modules/src/clients/ics07_tendermint/client_def.rs @@ -1,10 +1,10 @@ use core::convert::TryInto; use ibc_proto::ibc::core::commitment::v1::MerkleProof as RawMerkleProof; +use ibc_proto::protobuf::Protobuf; use prost::Message; use tendermint_light_client_verifier::types::{TrustedBlockState, UntrustedBlockState}; use tendermint_light_client_verifier::{ProdVerifier, Verdict, Verifier}; -use tendermint_proto::Protobuf; use crate::clients::ics07_tendermint::client_state::ClientState as TmClientState; use crate::clients::ics07_tendermint::consensus_state::ConsensusState as TmConsensusState; diff --git a/modules/src/clients/ics07_tendermint/client_state.rs b/modules/src/clients/ics07_tendermint/client_state.rs index 13c9e89a63..3b3baf5ac3 100644 --- a/modules/src/clients/ics07_tendermint/client_state.rs +++ b/modules/src/clients/ics07_tendermint/client_state.rs @@ -3,9 +3,9 @@ use crate::prelude::*; use core::convert::{TryFrom, TryInto}; use core::time::Duration; +use ibc_proto::protobuf::Protobuf; use serde::{Deserialize, Serialize}; use tendermint_light_client_verifier::options::Options; -use tendermint_proto::Protobuf; use ibc_proto::ibc::core::client::v1::Height as RawHeight; use ibc_proto::ibc::lightclients::tendermint::v1::ClientState as RawClientState; diff --git a/modules/src/clients/ics07_tendermint/consensus_state.rs b/modules/src/clients/ics07_tendermint/consensus_state.rs index b9e8d72299..2c52884288 100644 --- a/modules/src/clients/ics07_tendermint/consensus_state.rs +++ b/modules/src/clients/ics07_tendermint/consensus_state.rs @@ -1,11 +1,10 @@ use crate::prelude::*; +use ibc_proto::ibc::lightclients::tendermint::v1::ConsensusState as RawConsensusState; +use ibc_proto::protobuf::Protobuf; use serde::Serialize; use tendermint::{hash::Algorithm, time::Time, Hash}; use tendermint_proto::google::protobuf as tpb; -use tendermint_proto::Protobuf; - -use ibc_proto::ibc::lightclients::tendermint::v1::ConsensusState as RawConsensusState; use crate::clients::ics07_tendermint::error::Error; use crate::clients::ics07_tendermint::header::Header; diff --git a/modules/src/clients/ics07_tendermint/header.rs b/modules/src/clients/ics07_tendermint/header.rs index 8aa43b8329..330407c0e4 100644 --- a/modules/src/clients/ics07_tendermint/header.rs +++ b/modules/src/clients/ics07_tendermint/header.rs @@ -1,11 +1,11 @@ use core::cmp::Ordering; use bytes::Buf; +use ibc_proto::protobuf::Protobuf; use prost::Message; use serde_derive::{Deserialize, Serialize}; use tendermint::block::signed_header::SignedHeader; use tendermint::validator::Set as ValidatorSet; -use tendermint_proto::Protobuf; use crate::alloc::string::ToString; diff --git a/modules/src/clients/ics07_tendermint/misbehaviour.rs b/modules/src/clients/ics07_tendermint/misbehaviour.rs index 52ecb9178f..c96a35edd8 100644 --- a/modules/src/clients/ics07_tendermint/misbehaviour.rs +++ b/modules/src/clients/ics07_tendermint/misbehaviour.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use ibc_proto::ibc::lightclients::tendermint::v1::Misbehaviour as RawMisbehaviour; diff --git a/modules/src/core/ics02_client/client_consensus.rs b/modules/src/core/ics02_client/client_consensus.rs index e4555af440..4c072ce53e 100644 --- a/modules/src/core/ics02_client/client_consensus.rs +++ b/modules/src/core/ics02_client/client_consensus.rs @@ -5,8 +5,8 @@ use core::marker::{Send, Sync}; use ibc_proto::google::protobuf::Any as ProtoAny; use ibc_proto::ibc::core::client::v1::ConsensusStateWithHeight; +use ibc_proto::protobuf::Protobuf; use serde::Serialize; -use tendermint_proto::Protobuf; use crate::clients::ics07_tendermint::consensus_state::ConsensusState as TmConsensusState; use crate::core::ics02_client::client_type::ClientType; diff --git a/modules/src/core/ics02_client/client_state.rs b/modules/src/core/ics02_client/client_state.rs index ce34bc3720..7d7803ab0d 100644 --- a/modules/src/core/ics02_client/client_state.rs +++ b/modules/src/core/ics02_client/client_state.rs @@ -2,8 +2,8 @@ use core::marker::{Send, Sync}; use core::time::Duration; use ibc_proto::google::protobuf::Any; +use ibc_proto::protobuf::Protobuf; use serde::{Deserialize, Serialize}; -use tendermint_proto::Protobuf; use ibc_proto::ibc::core::client::v1::IdentifiedClientState; diff --git a/modules/src/core/ics02_client/error.rs b/modules/src/core/ics02_client/error.rs index 94582c03fc..2052f01e6b 100644 --- a/modules/src/core/ics02_client/error.rs +++ b/modules/src/core/ics02_client/error.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use flex_error::{define_error, TraceError}; -use tendermint_proto::Error as TendermintProtoError; +use ibc_proto::protobuf::Error as TendermintProtoError; use crate::core::ics02_client::client_type::ClientType; use crate::core::ics02_client::height::HeightError; diff --git a/modules/src/core/ics02_client/header.rs b/modules/src/core/ics02_client/header.rs index 06070ac267..0a11dfde81 100644 --- a/modules/src/core/ics02_client/header.rs +++ b/modules/src/core/ics02_client/header.rs @@ -1,9 +1,9 @@ use core::ops::Deref; use ibc_proto::google::protobuf::Any; +use ibc_proto::protobuf::Protobuf; use serde_derive::{Deserialize, Serialize}; use subtle_encoding::hex; -use tendermint_proto::Protobuf; use crate::clients::ics07_tendermint::header::{decode_header, Header as TendermintHeader}; use crate::core::ics02_client::client_type::ClientType; diff --git a/modules/src/core/ics02_client/height.rs b/modules/src/core/ics02_client/height.rs index dc84b3ffad..9dee17454c 100644 --- a/modules/src/core/ics02_client/height.rs +++ b/modules/src/core/ics02_client/height.rs @@ -5,8 +5,8 @@ use core::num::ParseIntError; use core::str::FromStr; use flex_error::{define_error, TraceError}; +use ibc_proto::protobuf::Protobuf; use serde_derive::{Deserialize, Serialize}; -use tendermint_proto::Protobuf; use ibc_proto::ibc::core::client::v1::Height as RawHeight; diff --git a/modules/src/core/ics02_client/misbehaviour.rs b/modules/src/core/ics02_client/misbehaviour.rs index a5ad57cbbd..adad475c32 100644 --- a/modules/src/core/ics02_client/misbehaviour.rs +++ b/modules/src/core/ics02_client/misbehaviour.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use ibc_proto::google::protobuf::Any; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use crate::clients::ics07_tendermint::misbehaviour::Misbehaviour as TmMisbehaviour; use crate::core::ics02_client::error::Error; diff --git a/modules/src/core/ics02_client/msgs/create_client.rs b/modules/src/core/ics02_client/msgs/create_client.rs index 26727e4bbd..1ffcbcce58 100644 --- a/modules/src/core/ics02_client/msgs/create_client.rs +++ b/modules/src/core/ics02_client/msgs/create_client.rs @@ -2,7 +2,7 @@ use crate::prelude::*; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use ibc_proto::ibc::core::client::v1::MsgCreateClient as RawMsgCreateClient; diff --git a/modules/src/core/ics02_client/msgs/misbehavior.rs b/modules/src/core/ics02_client/msgs/misbehavior.rs index 648aaf9d2f..93e8c912f3 100644 --- a/modules/src/core/ics02_client/msgs/misbehavior.rs +++ b/modules/src/core/ics02_client/msgs/misbehavior.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use ibc_proto::ibc::core::client::v1::MsgSubmitMisbehaviour as RawMsgSubmitMisbehaviour; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use crate::core::ics02_client::error::Error; use crate::core::ics02_client::misbehaviour::AnyMisbehaviour; diff --git a/modules/src/core/ics02_client/msgs/update_client.rs b/modules/src/core/ics02_client/msgs/update_client.rs index b7cdc4c53d..27fe4fe5cb 100644 --- a/modules/src/core/ics02_client/msgs/update_client.rs +++ b/modules/src/core/ics02_client/msgs/update_client.rs @@ -2,7 +2,7 @@ use crate::prelude::*; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use ibc_proto::ibc::core::client::v1::MsgUpdateClient as RawMsgUpdateClient; diff --git a/modules/src/core/ics02_client/msgs/upgrade_client.rs b/modules/src/core/ics02_client/msgs/upgrade_client.rs index 6f5b0626de..1861fef5ee 100644 --- a/modules/src/core/ics02_client/msgs/upgrade_client.rs +++ b/modules/src/core/ics02_client/msgs/upgrade_client.rs @@ -3,7 +3,7 @@ use crate::prelude::*; use core::str::FromStr; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use ibc_proto::ibc::core::client::v1::MsgUpgradeClient as RawMsgUpgradeClient; use ibc_proto::ibc::core::commitment::v1::MerkleProof as RawMerkleProof; diff --git a/modules/src/core/ics02_client/trust_threshold.rs b/modules/src/core/ics02_client/trust_threshold.rs index 4769a4f9ff..b37eeb397c 100644 --- a/modules/src/core/ics02_client/trust_threshold.rs +++ b/modules/src/core/ics02_client/trust_threshold.rs @@ -4,8 +4,8 @@ use core::{convert::TryFrom, fmt}; +use ibc_proto::protobuf::Protobuf; use serde::{Deserialize, Serialize}; -use tendermint_proto::Protobuf; use ibc_proto::ibc::lightclients::tendermint::v1::Fraction; use tendermint::trust_threshold::TrustThresholdFraction; diff --git a/modules/src/core/ics03_connection/connection.rs b/modules/src/core/ics03_connection/connection.rs index 793501f35b..2bbce2e8ba 100644 --- a/modules/src/core/ics03_connection/connection.rs +++ b/modules/src/core/ics03_connection/connection.rs @@ -4,8 +4,8 @@ use core::str::FromStr; use core::time::Duration; use core::{fmt, u64}; +use ibc_proto::protobuf::Protobuf; use serde::{Deserialize, Serialize}; -use tendermint_proto::Protobuf; use ibc_proto::ibc::core::connection::v1::{ ConnectionEnd as RawConnectionEnd, Counterparty as RawCounterparty, diff --git a/modules/src/core/ics03_connection/msgs/conn_open_ack.rs b/modules/src/core/ics03_connection/msgs/conn_open_ack.rs index 42cb51106a..72c30147a9 100644 --- a/modules/src/core/ics03_connection/msgs/conn_open_ack.rs +++ b/modules/src/core/ics03_connection/msgs/conn_open_ack.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenAck as RawMsgConnectionOpenAck; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use crate::core::ics02_client::client_state::AnyClientState; use crate::core::ics03_connection::error::Error; diff --git a/modules/src/core/ics03_connection/msgs/conn_open_confirm.rs b/modules/src/core/ics03_connection/msgs/conn_open_confirm.rs index 4c876d22e8..750b8ec168 100644 --- a/modules/src/core/ics03_connection/msgs/conn_open_confirm.rs +++ b/modules/src/core/ics03_connection/msgs/conn_open_confirm.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenConfirm as RawMsgConnectionOpenConfirm; diff --git a/modules/src/core/ics03_connection/msgs/conn_open_init.rs b/modules/src/core/ics03_connection/msgs/conn_open_init.rs index 196fbcf119..b48bf3f2ce 100644 --- a/modules/src/core/ics03_connection/msgs/conn_open_init.rs +++ b/modules/src/core/ics03_connection/msgs/conn_open_init.rs @@ -3,7 +3,7 @@ use crate::prelude::*; use core::time::Duration; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenInit as RawMsgConnectionOpenInit; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use crate::core::ics03_connection::connection::Counterparty; use crate::core::ics03_connection::error::Error; diff --git a/modules/src/core/ics03_connection/msgs/conn_open_try.rs b/modules/src/core/ics03_connection/msgs/conn_open_try.rs index ad315ae461..7cdad9c2e7 100644 --- a/modules/src/core/ics03_connection/msgs/conn_open_try.rs +++ b/modules/src/core/ics03_connection/msgs/conn_open_try.rs @@ -5,7 +5,7 @@ use core::{ time::Duration, }; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenTry as RawMsgConnectionOpenTry; diff --git a/modules/src/core/ics03_connection/version.rs b/modules/src/core/ics03_connection/version.rs index 652262d6ec..d5f24d83de 100644 --- a/modules/src/core/ics03_connection/version.rs +++ b/modules/src/core/ics03_connection/version.rs @@ -3,8 +3,8 @@ use core::fmt::Display; use crate::prelude::*; use ibc_proto::ibc::core::connection::v1::Version as RawVersion; +use ibc_proto::protobuf::Protobuf; use serde::{Deserialize, Serialize}; -use tendermint_proto::Protobuf; use crate::core::ics03_connection::error::Error; use crate::core::ics04_channel::channel::Order; diff --git a/modules/src/core/ics04_channel/channel.rs b/modules/src/core/ics04_channel/channel.rs index bfdd6f5497..14a6d8576e 100644 --- a/modules/src/core/ics04_channel/channel.rs +++ b/modules/src/core/ics04_channel/channel.rs @@ -3,8 +3,8 @@ use crate::prelude::*; use core::fmt; use core::str::FromStr; +use ibc_proto::protobuf::Protobuf; use serde::{Deserialize, Serialize}; -use tendermint_proto::Protobuf; use ibc_proto::ibc::core::channel::v1::{ Channel as RawChannel, Counterparty as RawCounterparty, diff --git a/modules/src/core/ics04_channel/error.rs b/modules/src/core/ics04_channel/error.rs index 67a465ca79..028ab3609b 100644 --- a/modules/src/core/ics04_channel/error.rs +++ b/modules/src/core/ics04_channel/error.rs @@ -13,7 +13,7 @@ use crate::timestamp::Timestamp; use crate::Height; use flex_error::{define_error, TraceError}; -use tendermint_proto::Error as TendermintError; +use ibc_proto::protobuf::Error as TendermintError; define_error! { #[derive(Debug, PartialEq, Eq)] diff --git a/modules/src/core/ics04_channel/msgs/acknowledgement.rs b/modules/src/core/ics04_channel/msgs/acknowledgement.rs index a41dd0d5d0..325b9ae402 100644 --- a/modules/src/core/ics04_channel/msgs/acknowledgement.rs +++ b/modules/src/core/ics04_channel/msgs/acknowledgement.rs @@ -2,7 +2,7 @@ use crate::prelude::*; use derive_more::{From, Into}; use ibc_proto::ibc::core::channel::v1::MsgAcknowledgement as RawMsgAcknowledgement; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use crate::core::ics04_channel::error::Error; use crate::core::ics04_channel::packet::Packet; diff --git a/modules/src/core/ics04_channel/msgs/chan_close_confirm.rs b/modules/src/core/ics04_channel/msgs/chan_close_confirm.rs index 48b641576a..23553743a2 100644 --- a/modules/src/core/ics04_channel/msgs/chan_close_confirm.rs +++ b/modules/src/core/ics04_channel/msgs/chan_close_confirm.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use ibc_proto::ibc::core::channel::v1::MsgChannelCloseConfirm as RawMsgChannelCloseConfirm; diff --git a/modules/src/core/ics04_channel/msgs/chan_close_init.rs b/modules/src/core/ics04_channel/msgs/chan_close_init.rs index 846d66e794..331ef85609 100644 --- a/modules/src/core/ics04_channel/msgs/chan_close_init.rs +++ b/modules/src/core/ics04_channel/msgs/chan_close_init.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use ibc_proto::ibc::core::channel::v1::MsgChannelCloseInit as RawMsgChannelCloseInit; diff --git a/modules/src/core/ics04_channel/msgs/chan_open_ack.rs b/modules/src/core/ics04_channel/msgs/chan_open_ack.rs index 8d6dfef831..c57dbd770f 100644 --- a/modules/src/core/ics04_channel/msgs/chan_open_ack.rs +++ b/modules/src/core/ics04_channel/msgs/chan_open_ack.rs @@ -7,7 +7,7 @@ use crate::signer::Signer; use crate::tx_msg::Msg; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenAck as RawMsgChannelOpenAck; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; pub const TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenAck"; diff --git a/modules/src/core/ics04_channel/msgs/chan_open_confirm.rs b/modules/src/core/ics04_channel/msgs/chan_open_confirm.rs index c7a547759e..90aaaa3025 100644 --- a/modules/src/core/ics04_channel/msgs/chan_open_confirm.rs +++ b/modules/src/core/ics04_channel/msgs/chan_open_confirm.rs @@ -6,7 +6,7 @@ use crate::signer::Signer; use crate::tx_msg::Msg; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenConfirm as RawMsgChannelOpenConfirm; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; pub const TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenConfirm"; diff --git a/modules/src/core/ics04_channel/msgs/chan_open_init.rs b/modules/src/core/ics04_channel/msgs/chan_open_init.rs index b5b4130a90..d86576f99e 100644 --- a/modules/src/core/ics04_channel/msgs/chan_open_init.rs +++ b/modules/src/core/ics04_channel/msgs/chan_open_init.rs @@ -6,7 +6,7 @@ use crate::signer::Signer; use crate::tx_msg::Msg; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenInit as RawMsgChannelOpenInit; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; pub const TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenInit"; diff --git a/modules/src/core/ics04_channel/msgs/chan_open_try.rs b/modules/src/core/ics04_channel/msgs/chan_open_try.rs index 6dfb2c874e..4d7e4113fc 100644 --- a/modules/src/core/ics04_channel/msgs/chan_open_try.rs +++ b/modules/src/core/ics04_channel/msgs/chan_open_try.rs @@ -9,7 +9,7 @@ use crate::signer::Signer; use crate::tx_msg::Msg; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenTry as RawMsgChannelOpenTry; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use core::str::FromStr; diff --git a/modules/src/core/ics04_channel/msgs/recv_packet.rs b/modules/src/core/ics04_channel/msgs/recv_packet.rs index 30b8522b3d..b38dab2318 100644 --- a/modules/src/core/ics04_channel/msgs/recv_packet.rs +++ b/modules/src/core/ics04_channel/msgs/recv_packet.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use ibc_proto::ibc::core::channel::v1::MsgRecvPacket as RawMsgRecvPacket; diff --git a/modules/src/core/ics04_channel/msgs/timeout.rs b/modules/src/core/ics04_channel/msgs/timeout.rs index 966fdd80a2..e33657b199 100644 --- a/modules/src/core/ics04_channel/msgs/timeout.rs +++ b/modules/src/core/ics04_channel/msgs/timeout.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use ibc_proto::ibc::core::channel::v1::MsgTimeout as RawMsgTimeout; diff --git a/modules/src/core/ics04_channel/msgs/timeout_on_close.rs b/modules/src/core/ics04_channel/msgs/timeout_on_close.rs index 029aeb623b..ac8f00a0f5 100644 --- a/modules/src/core/ics04_channel/msgs/timeout_on_close.rs +++ b/modules/src/core/ics04_channel/msgs/timeout_on_close.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use ibc_proto::ibc::core::channel::v1::MsgTimeoutOnClose as RawMsgTimeoutOnClose; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use crate::core::ics04_channel::error::Error; use crate::core::ics04_channel::packet::{Packet, Sequence}; diff --git a/modules/src/core/ics26_routing/error.rs b/modules/src/core/ics26_routing/error.rs index 260a688cdd..c0d3c69c6d 100644 --- a/modules/src/core/ics26_routing/error.rs +++ b/modules/src/core/ics26_routing/error.rs @@ -30,7 +30,7 @@ define_error! { | e | { format_args!("unknown type URL {0}", e.url) }, MalformedMessageBytes - [ TraceError ] + [ TraceError ] | _ | { "the message is malformed and cannot be decoded" }, } } diff --git a/modules/src/core/ics26_routing/msgs.rs b/modules/src/core/ics26_routing/msgs.rs index 3f2306e6e9..ff0e552b3c 100644 --- a/modules/src/core/ics26_routing/msgs.rs +++ b/modules/src/core/ics26_routing/msgs.rs @@ -11,7 +11,7 @@ use crate::core::ics04_channel::msgs::{ chan_open_init, chan_open_try, recv_packet, timeout, timeout_on_close, ChannelMsg, PacketMsg, }; use crate::core::ics26_routing::error::Error; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; /// Enumeration of all messages that the local ICS26 module is capable of routing. #[derive(Clone, Debug)] diff --git a/modules/src/mock/client_state.rs b/modules/src/mock/client_state.rs index e3847c438d..70c4999f6d 100644 --- a/modules/src/mock/client_state.rs +++ b/modules/src/mock/client_state.rs @@ -4,8 +4,8 @@ use alloc::collections::btree_map::BTreeMap as HashMap; use core::time::Duration; +use ibc_proto::protobuf::Protobuf; use serde::{Deserialize, Serialize}; -use tendermint_proto::Protobuf; use ibc_proto::ibc::mock::ClientState as RawMockClientState; use ibc_proto::ibc::mock::ConsensusState as RawMockConsensusState; diff --git a/modules/src/mock/header.rs b/modules/src/mock/header.rs index f30b1f3642..8a83c8bcbc 100644 --- a/modules/src/mock/header.rs +++ b/modules/src/mock/header.rs @@ -1,5 +1,5 @@ +use ibc_proto::protobuf::Protobuf; use serde_derive::{Deserialize, Serialize}; -use tendermint_proto::Protobuf; use ibc_proto::ibc::mock::Header as RawMockHeader; diff --git a/modules/src/mock/misbehaviour.rs b/modules/src/mock/misbehaviour.rs index b7aa35d59d..205b7e915f 100644 --- a/modules/src/mock/misbehaviour.rs +++ b/modules/src/mock/misbehaviour.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -use tendermint_proto::Protobuf; +use ibc_proto::protobuf::Protobuf; use ibc_proto::ibc::mock::Misbehaviour as RawMisbehaviour; diff --git a/proto/Cargo.toml b/proto/Cargo.toml index 4b95f6a558..dc736877be 100644 --- a/proto/Cargo.toml +++ b/proto/Cargo.toml @@ -30,6 +30,7 @@ tonic = { version = "0.7", optional = true, default-features = false } serde = { version = "1.0", default-features = false } schemars = { version = "0.8", optional = true } base64 = { version = "0.13", default-features = false, features = ["alloc"] } +flex-error = { version = "0.4.4", default-features = false } [dependencies.tendermint-proto] version = "=0.23.8" diff --git a/proto/src/lib.rs b/proto/src/lib.rs index febfd89d72..525232bcf2 100644 --- a/proto/src/lib.rs +++ b/proto/src/lib.rs @@ -11,6 +11,7 @@ #![doc(html_root_url = "https://docs.rs/ibc-proto/0.19.1")] pub mod google; +pub mod protobuf; extern crate alloc; diff --git a/proto/src/protobuf/erased.rs b/proto/src/protobuf/erased.rs new file mode 100644 index 0000000000..7aef34d413 --- /dev/null +++ b/proto/src/protobuf/erased.rs @@ -0,0 +1,30 @@ +use core::convert::{Into as CoreInto, TryFrom as CoreTryFrom}; + +pub trait CloneInto { + fn clone_into(&self) -> T; +} + +impl> CloneInto for U { + fn clone_into(&self) -> T { + self.clone().into() + } +} + +pub trait TryFrom { + type Error; + + fn try_from(t: T) -> Result + where + Self: Sized; +} + +impl> TryFrom for U { + type Error = >::Error; + + fn try_from(t: T) -> Result + where + Self: Sized, + { + >::try_from(t) + } +} diff --git a/proto/src/protobuf/error.rs b/proto/src/protobuf/error.rs new file mode 100644 index 0000000000..35fc944db7 --- /dev/null +++ b/proto/src/protobuf/error.rs @@ -0,0 +1,43 @@ +use alloc::format; +use alloc::string::String; +use core::fmt::Display; +use core::format_args; +use core::num::TryFromIntError; + +use flex_error::{define_error, DisplayOnly}; +use prost::{DecodeError, EncodeError}; + +use super::erased::TryFrom; + +define_error! { + Error { + TryFromProtobuf + { reason: String } + | e | { + format_args!("error converting message type into domain type: {}", + e.reason) + }, + + EncodeMessage + [ DisplayOnly ] + | _ | { "error encoding message into buffer" }, + + DecodeMessage + [ DisplayOnly ] + | _ | { "error decoding buffer into message" }, + + ParseLength + [ DisplayOnly ] + | _ | { "error parsing encoded length" }, + } +} + +impl Error { + pub fn try_from(e: E) -> Error + where + E: Display, + T: TryFrom, + { + Error::try_from_protobuf(format!("{}", e)) + } +} diff --git a/proto/src/protobuf/mod.rs b/proto/src/protobuf/mod.rs new file mode 100644 index 0000000000..2af79c0410 --- /dev/null +++ b/proto/src/protobuf/mod.rs @@ -0,0 +1,215 @@ +//! This module provides an object safe equivalent of the `tendermint_proto::Protobuf` trait, +//! thereby allowing for easy Google Protocol Buffers encoding and decoding of domain types with +//! validation. +//! +//! Domain types implementing the `Protobuf` trait are expected to implement `TryFrom` and +//! `Into` where `T` is the raw type. The equivalent object safe `erased` counterparts have +//! blanket implementations and are derived automatically. +//! +//! ## Examples +//! +//! ```rust +//! use core::convert::TryFrom; +//! +//! use prost::Message; +//! use ibc_proto::protobuf::Protobuf; +//! +//! // This struct would ordinarily be automatically generated by prost. +//! #[derive(Clone, PartialEq, Message)] +//! pub struct MyRawType { +//! #[prost(uint64, tag="1")] +//! pub a: u64, +//! #[prost(string, tag="2")] +//! pub b: String, +//! } +//! +//! #[derive(Clone)] +//! pub struct MyDomainType { +//! a: u64, +//! b: String, +//! } +//! +//! impl MyDomainType { +//! // Trivial constructor with basic validation logic. +//! pub fn new(a: u64, b: String) -> Result { +//! if a < 1 { +//! return Err("a must be greater than 0".to_owned()); +//! } +//! Ok(Self { a, b }) +//! } +//! } +//! +//! impl TryFrom for MyDomainType { +//! type Error = String; +//! +//! fn try_from(value: MyRawType) -> Result { +//! Self::new(value.a, value.b) +//! } +//! } +//! +//! impl From for MyRawType { +//! fn from(value: MyDomainType) -> Self { +//! Self { a: value.a, b: value.b } +//! } +//! } +//! +//! impl Protobuf for MyDomainType {} +//! ``` +mod erased; +mod error; + +use alloc::vec::Vec; +use core::fmt::Display; + +use bytes::Buf; +use prost::encoding::encoded_len_varint; +use prost::Message; + +pub use self::error::Error; + +/// Object safe equivalent of `tendermint_proto::Protobuf`. +pub trait Protobuf +where + Self: erased::TryFrom + erased::CloneInto, + >::Error: Display, +{ + /// Encode into a buffer in Protobuf format. + /// + /// Uses [`prost::Message::encode`] after converting into its counterpart + /// Protobuf data structure. + /// + /// [`prost::Message::encode`]: https://docs.rs/prost/*/prost/trait.Message.html#method.encode + fn encode(&self, buf: &mut Vec) -> Result<(), Error> { + self.clone_into().encode(buf).map_err(Error::encode_message) + } + + /// Encode with a length-delimiter to a buffer in Protobuf format. + /// + /// An error will be returned if the buffer does not have sufficient capacity. + /// + /// Uses [`prost::Message::encode_length_delimited`] after converting into + /// its counterpart Protobuf data structure. + /// + /// [`prost::Message::encode_length_delimited`]: https://docs.rs/prost/*/prost/trait.Message.html#method.encode_length_delimited + fn encode_length_delimited(&self, buf: &mut Vec) -> Result<(), Error> { + self.clone_into() + .encode_length_delimited(buf) + .map_err(Error::encode_message) + } + + /// Constructor that attempts to decode an instance from a buffer. + /// + /// The entire buffer will be consumed. + /// + /// Similar to [`prost::Message::decode`] but with additional validation + /// prior to constructing the destination type. + /// + /// [`prost::Message::decode`]: https://docs.rs/prost/*/prost/trait.Message.html#method.decode + fn decode(buf: B) -> Result + where + Self: Sized, + { + let raw = Raw::decode(buf).map_err(Error::decode_message)?; + + Self::try_from(raw).map_err(Error::try_from::) + } + + /// Constructor that attempts to decode a length-delimited instance from + /// the buffer. + /// + /// The entire buffer will be consumed. + /// + /// Similar to [`prost::Message::decode_length_delimited`] but with + /// additional validation prior to constructing the destination type. + /// + /// [`prost::Message::decode_length_delimited`]: https://docs.rs/prost/*/prost/trait.Message.html#method.decode_length_delimited + fn decode_length_delimited(buf: B) -> Result + where + Self: Sized, + { + let raw = Raw::decode_length_delimited(buf).map_err(Error::decode_message)?; + + Self::try_from(raw).map_err(Error::try_from::) + } + + /// Returns the encoded length of the message without a length delimiter. + /// + /// Uses [`prost::Message::encoded_len`] after converting to its + /// counterpart Protobuf data structure. + /// + /// [`prost::Message::encoded_len`]: https://docs.rs/prost/*/prost/trait.Message.html#method.encoded_len + fn encoded_len(&self) -> usize { + self.clone_into().encoded_len() + } + + /// Encodes into a Protobuf-encoded `Vec`. + fn encode_vec(&self) -> Result, Error> { + let mut wire = Vec::with_capacity(self.encoded_len()); + self.encode(&mut wire).map(|_| wire) + } + + /// Constructor that attempts to decode a Protobuf-encoded instance from a + /// `Vec` (or equivalent). + fn decode_vec(v: &[u8]) -> Result + where + Self: Sized, + { + Self::decode(v) + } + + /// Encode with a length-delimiter to a `Vec` Protobuf-encoded message. + fn encode_length_delimited_vec(&self) -> Result, Error> { + let len = self.encoded_len(); + let lenu64 = len.try_into().map_err(Error::parse_length)?; + let mut wire = Vec::with_capacity(len + encoded_len_varint(lenu64)); + self.encode_length_delimited(&mut wire).map(|_| wire) + } + + /// Constructor that attempts to decode a Protobuf-encoded instance with a + /// length-delimiter from a `Vec` or equivalent. + fn decode_length_delimited_vec(v: &[u8]) -> Result + where + Self: Sized, + { + Self::decode_length_delimited(v) + } +} + +#[cfg(test)] +mod test { + use core::convert::{From, TryFrom}; + + use super::*; + use crate::google::protobuf::Any; + + #[test] + fn test_protobuf_object_safety() { + let _test: Option>> = None; + } + + #[test] + fn test_protobuf_blanket_impls() { + trait Foo: Protobuf {} + + #[derive(Clone)] + struct Domain; + + impl Foo for Domain {} + + impl Protobuf for Domain {} + + impl TryFrom for Domain { + type Error = Error; + + fn try_from(_: Any) -> Result { + unimplemented!() + } + } + + impl From for Any { + fn from(_: Domain) -> Self { + unimplemented!() + } + } + } +} diff --git a/relayer/src/chain/cosmos.rs b/relayer/src/chain/cosmos.rs index c43513fff8..8f785b5061 100644 --- a/relayer/src/chain/cosmos.rs +++ b/relayer/src/chain/cosmos.rs @@ -10,13 +10,13 @@ use num_bigint::BigInt; use std::thread; use bitcoin::hashes::hex::ToHex; +use ibc_proto::protobuf::Protobuf; use tendermint::block::Height as TmHeight; use tendermint::{ abci::{Event, Path as TendermintABCIPath}, node::info::TxIndexStatus, }; use tendermint_light_client_verifier::types::LightBlock as TmLightBlock; -use tendermint_proto::Protobuf; use tendermint_rpc::{ endpoint::broadcast::tx_sync::Response, endpoint::status, Client, HttpClient, Order, }; diff --git a/relayer/src/error.rs b/relayer/src/error.rs index 4ca9948054..6386f6ef59 100644 --- a/relayer/src/error.rs +++ b/relayer/src/error.rs @@ -5,6 +5,7 @@ use core::time::Duration; use flex_error::{define_error, DisplayOnly, TraceClone, TraceError}; use http::uri::InvalidUri; use humantime::format_duration; +use ibc_proto::protobuf::Error as TendermintProtoError; use prost::{DecodeError, EncodeError}; use regex::Regex; use tendermint::Error as TendermintError; @@ -12,7 +13,6 @@ use tendermint_light_client::components::io::IoError as LightClientIoError; use tendermint_light_client::errors::{ Error as LightClientError, ErrorDetail as LightClientErrorDetail, }; -use tendermint_proto::Error as TendermintProtoError; use tendermint_rpc::endpoint::abci_query::AbciQuery; use tendermint_rpc::endpoint::broadcast::tx_commit::TxResult; use tendermint_rpc::Error as TendermintRpcError;