-
Notifications
You must be signed in to change notification settings - Fork 123
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
When trying to define an `osmosis-proto` crate (#239), we ran into the problem that it needed to import `cosmrs` to be able to impl the `MsgProto` trait. We couldn't follow the same pattern as `cosmrs` defining the type URLs for `cosmos-sdk-proto`, which it could only do because it defined the `MsgProto` trait as well. Knowledge of the type URLs is necessary to convert to/from `Any`, which Cosmos SDK uses all over the place. So far there isn't a good upstream solution to this problem in `prost` or AFAICT in `tendermint-proto` either. There's an upstream tracking issue for `prost` here: tokio-rs/prost#299 The ideal solution to this problem seems to be adding a `TYPE_URL` to `prost::Message`, and automatically populating them with `prost-build`. Failing that, this commit introduces a `TypeUrl` trait with an associated `TYPE_URL` const (previously provided by the `MsgProto` trait). The `from_any` and `to_any` methods have been moved to `MessageExt`.
- Loading branch information
1 parent
9eb479e
commit 5d3bed0
Showing
15 changed files
with
269 additions
and
214 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
//! Support traits for Cosmos SDK protobufs. | ||
pub use prost::Message; | ||
|
||
use crate::Any; | ||
use prost::{DecodeError, EncodeError}; | ||
use std::str::FromStr; | ||
|
||
/// Associate a type URL with a given proto. | ||
pub trait TypeUrl: Message { | ||
/// Type URL value | ||
const TYPE_URL: &'static str; | ||
} | ||
|
||
/// Extension trait for [`Message`]. | ||
pub trait MessageExt: Message { | ||
/// Parse this message proto from [`Any`]. | ||
fn from_any(any: &Any) -> Result<Self, DecodeError> | ||
where | ||
Self: Default + Sized + TypeUrl, | ||
{ | ||
if any.type_url == Self::TYPE_URL { | ||
Ok(Self::decode(&*any.value)?) | ||
} else { | ||
let mut err = DecodeError::new(format!( | ||
"expected type URL: \"{}\" (got: \"{}\")", | ||
Self::TYPE_URL, | ||
&any.type_url | ||
)); | ||
err.push("unexpected type URL", "type_url"); | ||
Err(err) | ||
} | ||
} | ||
|
||
/// Serialize this message proto as [`Any`]. | ||
fn to_any(&self) -> Result<Any, EncodeError> | ||
where | ||
Self: TypeUrl, | ||
{ | ||
self.to_bytes().map(|bytes| Any { | ||
type_url: Self::TYPE_URL.to_owned(), | ||
value: bytes, | ||
}) | ||
} | ||
|
||
/// Serialize this protobuf message as a byte vector. | ||
fn to_bytes(&self) -> Result<Vec<u8>, EncodeError>; | ||
} | ||
|
||
impl<M> MessageExt for M | ||
where | ||
M: prost::Message, | ||
{ | ||
fn to_bytes(&self) -> Result<Vec<u8>, EncodeError> { | ||
let mut bytes = Vec::new(); | ||
Message::encode(self, &mut bytes)?; | ||
Ok(bytes) | ||
} | ||
} | ||
|
||
/// Extension traits for optionally parsing non-empty strings. | ||
/// | ||
/// This is a common pattern in Cosmos SDK protobufs. | ||
pub trait ParseOptional: AsRef<str> { | ||
/// Parse optional field. | ||
fn parse_optional<T: FromStr>(&self) -> Result<Option<T>, T::Err> { | ||
if self.as_ref().is_empty() { | ||
Ok(None) | ||
} else { | ||
Ok(Some(self.as_ref().parse()?)) | ||
} | ||
} | ||
} | ||
|
||
impl ParseOptional for str {} | ||
impl ParseOptional for String {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
//! Registry of type URLs associated with various protobuf types defined in | ||
//! this crate. | ||
// TODO(tarcieri): leverage first-class support for type URLs in prost? | ||
// See: https://github.com/tokio-rs/prost/issues/299 | ||
|
||
use crate::{cosmos, traits::TypeUrl}; | ||
|
||
#[cfg(feature = "cosmwasm")] | ||
use crate::cosmwasm; | ||
|
||
impl TypeUrl for cosmos::bank::v1beta1::MsgSend { | ||
const TYPE_URL: &'static str = "/cosmos.bank.v1beta1.MsgSend"; | ||
} | ||
|
||
impl TypeUrl for cosmos::bank::v1beta1::MsgMultiSend { | ||
const TYPE_URL: &'static str = "/cosmos.bank.v1beta1.MsgMultiSend"; | ||
} | ||
|
||
impl TypeUrl for cosmos::distribution::v1beta1::MsgSetWithdrawAddress { | ||
const TYPE_URL: &'static str = "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress"; | ||
} | ||
|
||
impl TypeUrl for cosmos::distribution::v1beta1::MsgWithdrawDelegatorReward { | ||
const TYPE_URL: &'static str = "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"; | ||
} | ||
|
||
impl TypeUrl for cosmos::distribution::v1beta1::MsgWithdrawValidatorCommission { | ||
const TYPE_URL: &'static str = "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission"; | ||
} | ||
|
||
impl TypeUrl for cosmos::distribution::v1beta1::MsgFundCommunityPool { | ||
const TYPE_URL: &'static str = "/cosmos.distribution.v1beta1.MsgFundCommunityPool"; | ||
} | ||
|
||
impl TypeUrl for cosmos::feegrant::v1beta1::MsgGrantAllowance { | ||
const TYPE_URL: &'static str = "/cosmos.feegrant.v1beta1.MsgGrantAllowance"; | ||
} | ||
|
||
impl TypeUrl for cosmos::feegrant::v1beta1::MsgRevokeAllowance { | ||
const TYPE_URL: &'static str = "/cosmos.feegrant.v1beta1.MsgRevokeAllowance"; | ||
} | ||
|
||
impl TypeUrl for cosmos::feegrant::v1beta1::BasicAllowance { | ||
const TYPE_URL: &'static str = "/cosmos.feegrant.v1beta1.BasicAllowance"; | ||
} | ||
|
||
impl TypeUrl for cosmos::feegrant::v1beta1::PeriodicAllowance { | ||
const TYPE_URL: &'static str = "/cosmos.feegrant.v1beta1.PeriodicAllowance"; | ||
} | ||
|
||
impl TypeUrl for cosmos::feegrant::v1beta1::AllowedMsgAllowance { | ||
const TYPE_URL: &'static str = "/cosmos.feegrant.v1beta1.AllowedMsgAllowance"; | ||
} | ||
|
||
impl TypeUrl for cosmos::staking::v1beta1::MsgDelegate { | ||
const TYPE_URL: &'static str = "/cosmos.staking.v1beta1.MsgDelegate"; | ||
} | ||
|
||
impl TypeUrl for cosmos::staking::v1beta1::MsgUndelegate { | ||
const TYPE_URL: &'static str = "/cosmos.staking.v1beta1.MsgUndelegate"; | ||
} | ||
|
||
impl TypeUrl for cosmos::staking::v1beta1::MsgBeginRedelegate { | ||
const TYPE_URL: &'static str = "/cosmos.staking.v1beta1.MsgBeginRedelegate"; | ||
} | ||
|
||
impl TypeUrl for cosmos::base::abci::v1beta1::MsgData { | ||
const TYPE_URL: &'static str = "/cosmos.base.v1beta1.abci.MsgData"; | ||
} | ||
|
||
impl TypeUrl for cosmos::base::abci::v1beta1::TxMsgData { | ||
const TYPE_URL: &'static str = "/cosmos.base.v1beta1.abci.TxMsgData"; | ||
} | ||
|
||
#[cfg(feature = "cosmwasm")] | ||
impl TypeUrl for cosmwasm::wasm::v1::MsgStoreCode { | ||
const TYPE_URL: &'static str = "/cosmwasm.wasm.v1.MsgStoreCode"; | ||
} | ||
|
||
#[cfg(feature = "cosmwasm")] | ||
impl TypeUrl for cosmwasm::wasm::v1::MsgInstantiateContract { | ||
const TYPE_URL: &'static str = "/cosmwasm.wasm.v1.MsgInstantiateContract"; | ||
} | ||
|
||
#[cfg(feature = "cosmwasm")] | ||
impl TypeUrl for cosmwasm::wasm::v1::MsgExecuteContract { | ||
const TYPE_URL: &'static str = "/cosmwasm.wasm.v1.MsgExecuteContract"; | ||
} | ||
|
||
#[cfg(feature = "cosmwasm")] | ||
impl TypeUrl for cosmwasm::wasm::v1::MsgMigrateContract { | ||
const TYPE_URL: &'static str = "/cosmwasm.wasm.v1.MsgMigrateContract"; | ||
} | ||
|
||
#[cfg(feature = "cosmwasm")] | ||
impl TypeUrl for cosmwasm::wasm::v1::MsgUpdateAdmin { | ||
const TYPE_URL: &'static str = "/cosmwasm.wasm.v1.MsgUpdateAdmin"; | ||
} | ||
|
||
#[cfg(feature = "cosmwasm")] | ||
impl TypeUrl for cosmwasm::wasm::v1::MsgClearAdmin { | ||
const TYPE_URL: &'static str = "/cosmwasm.wasm.v1.MsgClearAdmin"; | ||
} | ||
|
||
#[cfg(feature = "cosmwasm")] | ||
impl TypeUrl for cosmwasm::wasm::v1::MsgStoreCodeResponse { | ||
const TYPE_URL: &'static str = "/cosmwasm.wasm.v1.MsgStoreCodeResponse"; | ||
} | ||
|
||
#[cfg(feature = "cosmwasm")] | ||
impl TypeUrl for cosmwasm::wasm::v1::MsgInstantiateContractResponse { | ||
const TYPE_URL: &'static str = "/cosmwasm.wasm.v1.MsgInstantiateContractResponse"; | ||
} | ||
|
||
#[cfg(feature = "cosmwasm")] | ||
impl TypeUrl for cosmwasm::wasm::v1::MsgExecuteContractResponse { | ||
const TYPE_URL: &'static str = "/cosmwasm.wasm.v1.MsgExecuteContractResponse"; | ||
} | ||
|
||
#[cfg(feature = "cosmwasm")] | ||
impl TypeUrl for cosmwasm::wasm::v1::MsgMigrateContractResponse { | ||
const TYPE_URL: &'static str = "/cosmwasm.wasm.v1.MsgMigrateContractResponse"; | ||
} | ||
|
||
#[cfg(feature = "cosmwasm")] | ||
impl TypeUrl for cosmwasm::wasm::v1::MsgUpdateAdminResponse { | ||
const TYPE_URL: &'static str = "/cosmwasm.wasm.v1.MsgUpdateAdminResponse"; | ||
} | ||
|
||
#[cfg(feature = "cosmwasm")] | ||
impl TypeUrl for cosmwasm::wasm::v1::MsgClearAdminResponse { | ||
const TYPE_URL: &'static str = "/cosmwasm.wasm.v1.MsgClearAdminResponse"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,7 +45,6 @@ pub mod dev; | |
|
||
mod base; | ||
mod error; | ||
mod prost_ext; | ||
|
||
pub use crate::{ | ||
base::{AccountId, Coin, Denom}, | ||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.