Skip to content

Commit

Permalink
fix(proto): Fixed types encoding (#38)
Browse files Browse the repository at this point in the history
There was an assumption that serde was correlated with proto encoding.
The tests passed since they verified that serde serialization worked
which was true. This new update adds proto encoding testing along with
two major changes.

1. All types in `abstract-any` were moved from being just `T` to
`Any<T>`. The reason for this is that proto has to support for adding
custom generic encoding/decoding techniques, making generating this very
hard to do. This could be reserved for a future update, but for current
requirements its not needed.
2. Added `GenericData` type. When dealing with a response that may have
an array of different types, for example
`QueryAccountsResponse<BaseAccount<_>>` inside the `Auth` module doesn't
work because it can also contain `ModuleAccount<_>` and `IcaAccount<_>`,
replacing this with `QueryAccountsResponse<GenericData>` and validating
each `Any::type_url` to determine what to decode into.
  • Loading branch information
FloppyDisck authored Nov 7, 2024
2 parents 41d73c4 + ba5003b commit 02e20a7
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 544 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

7 changes: 6 additions & 1 deletion packages/bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
#![doc = include_str!("../README.md")]
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/86496504?s=100")]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![allow(rustdoc::bare_urls, clippy::derive_partial_eq_without_eq)]
#![allow(
rustdoc::bare_urls,
clippy::derive_partial_eq_without_eq,
clippy::doc_lazy_continuation,
clippy::too_long_first_doc_paragraph
)]
#![forbid(unsafe_code)]
#![warn(trivial_casts, trivial_numeric_casts, unused_import_braces)]

Expand Down
2 changes: 1 addition & 1 deletion packages/proto/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "archway-proto"
version = "0.2.0"
version = "0.3.0"
edition = "2021"
description = "Rust build of Archway's ProtoBuf definitions"
authors.workspace = true
Expand Down
22 changes: 17 additions & 5 deletions packages/proto/src/any.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use prost::bytes::{Buf, BufMut};
use prost::{Message, Name};
use serde::{ser, Deserialize, Deserializer, Serialize, Serializer};

pub type GenericData = Vec<u8>;

// An improved any type that allows you to implement typing directly into it
#[derive(Clone, PartialEq, Serialize, Deserialize, Message)]
pub struct Any<T: Message + PartialEq + Default> {
Expand All @@ -13,10 +16,18 @@ pub struct Any<T: Message + PartialEq + Default> {
impl<T: Message + Name + PartialEq + Default> Any<T> {
pub fn new(value: T) -> Self {
Self {
type_url: T::full_name(),
// The RPC endpoint fails we dont prepend a '/'
type_url: format!("/{}", T::full_name()),
value,
}
}

pub fn generic(value: T) -> Any<GenericData> {
Any {
type_url: T::full_name(),
value: value.encode_to_vec(),
}
}
}

// Deserialize data shown inside Any<T> and return T
Expand Down Expand Up @@ -146,14 +157,15 @@ pub mod vec {

#[cfg(test)]
mod test {
use crate::any::{Any, GenericData};
use prost::{Message, Name};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use serde_test::{assert_tokens, Token};

#[derive(:: serde :: Serialize, :: serde :: Deserialize)]
#[derive(::serde::Serialize, ::serde::Deserialize)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, :: prost :: Message)]
#[derive(Clone, PartialEq, ::prost::Message)]
struct ExternalStructTest<
A: Default + Message + Name + Send + Sync + Serialize + DeserializeOwned + PartialEq + Clone,
> {
Expand Down Expand Up @@ -185,9 +197,9 @@ mod test {
}
}

#[derive(:: serde :: Serialize, :: serde :: Deserialize)]
#[derive(::serde::Serialize, ::serde::Deserialize)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, :: prost :: Message)]
#[derive(Clone, PartialEq, ::prost::Message)]
struct BuildTest<
A: Default + Message + Name + Send + Sync + Serialize + DeserializeOwned + PartialEq + Clone,
C: Default + Message + Name + Send + Sync + Serialize + DeserializeOwned + PartialEq + Clone,
Expand Down
55 changes: 4 additions & 51 deletions packages/proto/src/gen/archway.cwica.v1.abstract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,6 @@ impl ::prost::Name for Params {
pub struct GenesisState {
#[doc = " params defines all the parameters of the module."]
#[prost(message, optional, tag = "1")]
#[serde(
serialize_with = "crate::any::option::generic_serialize",
deserialize_with = "crate::any::option::generic_deserialize"
)]
pub params: ::core::option::Option<Params>,
}
impl ::prost::Name for GenesisState {
Expand Down Expand Up @@ -98,10 +94,6 @@ impl ::prost::Name for QueryParamsRequest {
pub struct QueryParamsResponse {
#[doc = " params defines the parameters for the module"]
#[prost(message, optional, tag = "1")]
#[serde(
serialize_with = "crate::any::option::generic_serialize",
deserialize_with = "crate::any::option::generic_deserialize"
)]
pub params: ::core::option::Option<Params>,
}
impl ::prost::Name for QueryParamsResponse {
Expand All @@ -119,10 +111,6 @@ impl ::prost::Name for QueryParamsResponse {
pub struct SudoPayload {
#[doc = " ICA is the message which carries the success responses"]
#[prost(message, optional, tag = "1")]
#[serde(
serialize_with = "crate::any::option::generic_serialize",
deserialize_with = "crate::any::option::generic_deserialize"
)]
pub ica: ::core::option::Option<IcaSuccess>,
}
impl ::prost::Name for SudoPayload {
Expand All @@ -140,18 +128,10 @@ pub struct IcaSuccess {
#[doc = " account_registered is the message which carries the success response after"]
#[doc = " the ica account has been registered"]
#[prost(message, optional, tag = "1")]
#[serde(
serialize_with = "crate::any::option::generic_serialize",
deserialize_with = "crate::any::option::generic_deserialize"
)]
pub account_registered: ::core::option::Option<AccountRegistered>,
#[doc = " tx_executed is the message which carries the success response after the ica"]
#[doc = " tx has been executed"]
#[prost(message, optional, tag = "2")]
#[serde(
serialize_with = "crate::any::option::generic_serialize",
deserialize_with = "crate::any::option::generic_deserialize"
)]
pub tx_executed: ::core::option::Option<TxExecuted>,
}
impl ::prost::Name for IcaSuccess {
Expand Down Expand Up @@ -236,17 +216,7 @@ impl ::prost::Name for MsgRegisterInterchainAccountResponse {
#[derive(:: serde :: Serialize, :: serde :: Deserialize)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, :: prost :: Message)]
pub struct MsgSendTx<
A: Clone
+ PartialEq
+ Default
+ Send
+ Sync
+ prost::Message
+ serde::Serialize
+ serde::de::DeserializeOwned
+ prost::Name,
> {
pub struct MsgSendTx<A: Clone + PartialEq + Default + Send + Sync + prost::Message + prost::Name> {
#[doc = " contract_address is the address of the who wants to submit a transaction to"]
#[doc = " the counterparty chain"]
#[prost(string, tag = "1")]
Expand All @@ -256,29 +226,16 @@ pub struct MsgSendTx<
pub connection_id: ::prost::alloc::string::String,
#[doc = " msgs are the messages to be submitted to the counterparty chain"]
#[prost(message, repeated, tag = "3")]
#[serde(
serialize_with = "crate::any::vec::serialize",
deserialize_with = "crate::any::vec::deserialize"
)]
pub msgs: ::prost::alloc::vec::Vec<A>,
pub msgs: ::prost::alloc::vec::Vec<crate::any::Any<A>>,
#[doc = " memo is the memo to be included in the packet"]
#[prost(string, tag = "4")]
pub memo: ::prost::alloc::string::String,
#[doc = " timeout in seconds after which the packet times out"]
#[prost(uint64, tag = "5")]
pub timeout: u64,
}
impl<
A: Clone
+ PartialEq
+ Default
+ Send
+ Sync
+ prost::Message
+ serde::Serialize
+ serde::de::DeserializeOwned
+ prost::Name,
> ::prost::Name for MsgSendTx<A>
impl<A: Clone + PartialEq + Default + Send + Sync + prost::Message + prost::Name> ::prost::Name
for MsgSendTx<A>
{
const NAME: &'static str = "MsgSendTx";
const PACKAGE: &'static str = "archway.cwica.v1";
Expand Down Expand Up @@ -318,10 +275,6 @@ pub struct MsgUpdateParams {
#[doc = " params deines the module parmeters to update"]
#[doc = " NOTE: All parameters must be supplied."]
#[prost(message, optional, tag = "2")]
#[serde(
serialize_with = "crate::any::option::generic_serialize",
deserialize_with = "crate::any::option::generic_deserialize"
)]
pub params: ::core::option::Option<Params>,
}
impl ::prost::Name for MsgUpdateParams {
Expand Down
32 changes: 5 additions & 27 deletions packages/proto/src/gen/archway.genmsg.v1.abstract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,13 @@
#[derive(:: serde :: Serialize, :: serde :: Deserialize)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, :: prost :: Message)]
pub struct GenesisState<
A: Clone
+ PartialEq
+ Default
+ Send
+ Sync
+ prost::Message
+ serde::Serialize
+ serde::de::DeserializeOwned
+ prost::Name,
> {
pub struct GenesisState<A: Clone + PartialEq + Default + Send + Sync + prost::Message + prost::Name>
{
#[prost(message, repeated, tag = "1")]
#[serde(
serialize_with = "crate::any::vec::serialize",
deserialize_with = "crate::any::vec::deserialize"
)]
pub messages: ::prost::alloc::vec::Vec<A>,
pub messages: ::prost::alloc::vec::Vec<crate::any::Any<A>>,
}
impl<
A: Clone
+ PartialEq
+ Default
+ Send
+ Sync
+ prost::Message
+ serde::Serialize
+ serde::de::DeserializeOwned
+ prost::Name,
> ::prost::Name for GenesisState<A>
impl<A: Clone + PartialEq + Default + Send + Sync + prost::Message + prost::Name> ::prost::Name
for GenesisState<A>
{
const NAME: &'static str = "GenesisState";
const PACKAGE: &'static str = "archway.genmsg.v1";
Expand Down
Loading

0 comments on commit 02e20a7

Please sign in to comment.