diff --git a/.changelog/unreleased/features/1390-derive-arbitrary.md b/.changelog/unreleased/features/1390-derive-arbitrary.md new file mode 100644 index 000000000..21b269f31 --- /dev/null +++ b/.changelog/unreleased/features/1390-derive-arbitrary.md @@ -0,0 +1,2 @@ +- Added arbitrary trait implementation behind "arbitrary" feature flag. + ([\#1390](https://github.com/cosmos/ibc-rs/pull/1390)) \ No newline at end of file diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index a7cf8c9e2..71293dbed 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -125,7 +125,7 @@ jobs: - name: Install cargo-msrv env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: cargo binstall --no-confirm cargo-msrv + run: cargo binstall --no-confirm cargo-msrv --force - name: Verify and Test Rust version run: | diff --git a/Cargo.toml b/Cargo.toml index 99e92f7ad..162989143 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,7 @@ authors = [ "Informal Systems " ] [workspace.dependencies] # external dependencies +arbitrary = { version = "1.4", features = [ "derive" ] } base64 = { version = "0.22", default-features = false } borsh = { version = "1", default-features = false, features = [ "derive" ] } displaydoc = { version = "0.2.5", default-features = false } diff --git a/ibc-apps/Cargo.toml b/ibc-apps/Cargo.toml index 6ef3c6ac6..1d49ce1d5 100644 --- a/ibc-apps/Cargo.toml +++ b/ibc-apps/Cargo.toml @@ -44,3 +44,4 @@ parity-scale-codec = [ nft-transfer = [ "ibc-app-nft-transfer", ] +arbitrary = [ "ibc-app-transfer/arbitrary", "ibc-app-nft-transfer/arbitrary" ] diff --git a/ibc-apps/ics20-transfer/Cargo.toml b/ibc-apps/ics20-transfer/Cargo.toml index 0f36a3700..70e99d951 100644 --- a/ibc-apps/ics20-transfer/Cargo.toml +++ b/ibc-apps/ics20-transfer/Cargo.toml @@ -55,3 +55,4 @@ parity-scale-codec = [ "ibc-app-transfer-types/parity-scale-codec", "ibc-core/parity-scale-codec", ] +arbitrary = [ "ibc-app-transfer-types/arbitrary", "ibc-core/arbitrary" ] diff --git a/ibc-apps/ics20-transfer/types/Cargo.toml b/ibc-apps/ics20-transfer/types/Cargo.toml index 30e477f28..9d6a9270c 100644 --- a/ibc-apps/ics20-transfer/types/Cargo.toml +++ b/ibc-apps/ics20-transfer/types/Cargo.toml @@ -20,6 +20,7 @@ all-features = true [dependencies] # external dependencies +arbitrary = { workspace = true, optional = true } borsh = { workspace = true, optional = true } derive_more = { workspace = true } displaydoc = { workspace = true } @@ -74,3 +75,4 @@ parity-scale-codec = [ "ibc-core/parity-scale-codec", "ibc-proto/parity-scale-codec", ] +arbitrary = [ "dep:arbitrary", "ibc-core/arbitrary", "std" ] diff --git a/ibc-apps/ics20-transfer/types/src/amount.rs b/ibc-apps/ics20-transfer/types/src/amount.rs index 8f1b2c81f..df81f5960 100644 --- a/ibc-apps/ics20-transfer/types/src/amount.rs +++ b/ibc-apps/ics20-transfer/types/src/amount.rs @@ -10,10 +10,12 @@ use ibc_core::primitives::serializers; use primitive_types::U256; /// A type for representing token transfer amounts. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Display, From, Into)] pub struct Amount( + #[cfg_attr(feature = "arbitrary", arbitrary(with = arb_u256))] #[cfg_attr(feature = "schema", schemars(with = "String"))] #[cfg_attr(feature = "serde", serde(serialize_with = "serializers::serialize"))] #[cfg_attr(feature = "serde", serde(deserialize_with = "deserialize"))] @@ -129,6 +131,12 @@ where .map_err(serde::de::Error::custom) } +#[cfg(feature = "arbitrary")] +fn arb_u256(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { + let parts: [u8; 32] = arbitrary::Arbitrary::arbitrary(u)?; + Ok(U256::from_big_endian(&parts)) +} + #[cfg(test)] mod tests { use super::Amount; diff --git a/ibc-apps/ics20-transfer/types/src/coin.rs b/ibc-apps/ics20-transfer/types/src/coin.rs index db95bcc9f..0447c4b5c 100644 --- a/ibc-apps/ics20-transfer/types/src/coin.rs +++ b/ibc-apps/ics20-transfer/types/src/coin.rs @@ -21,6 +21,7 @@ pub type RawCoin = Coin; const VALID_DENOM_CHARACTERS: &str = "/:._-"; /// Coin defines a token with a denomination and an amount. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[cfg_attr( @@ -165,12 +166,12 @@ mod tests { "115792089237316195423570985008687907853269984665640564039457584007913129639936stake" )] #[case::invalid_char_in_denom("0x!")] - #[case::blackslash_in_denom("0x1/:.\\_-")] + #[case::backslash_in_denom("0x1/:.\\_-")] #[should_panic] fn test_failed_parse_raw_coin(#[case] _raw: RawCoin) {} #[rstest] - #[case::nomal("123stake,1a1,999den0m", &[(123, "stake"), (1, "a1"), (999, "den0m")])] + #[case::normal("123stake,1a1,999den0m", &[(123, "stake"), (1, "a1"), (999, "den0m")])] #[case::tricky("123stake,1a1-999den0m", &[(123, "stake"), (1, "a1-999den0m")])] #[case::colon_delimiter("123stake:1a1:999den0m", &[(123, "stake:1a1:999den0m")])] #[case::dash_delimiter("123stake-1a1-999den0m", &[(123, "stake-1a1-999den0m")])] diff --git a/ibc-apps/ics20-transfer/types/src/denom.rs b/ibc-apps/ics20-transfer/types/src/denom.rs index 44cd4e210..630ef7479 100644 --- a/ibc-apps/ics20-transfer/types/src/denom.rs +++ b/ibc-apps/ics20-transfer/types/src/denom.rs @@ -14,6 +14,7 @@ use ibc_proto::ibc::applications::transfer::v1::DenomTrace as RawDenomTrace; /// /// For example, given the token `my_port-1/my_channel-1/my_port-2/my_channel-2/base_denom`, /// `base_denom` is the "base" of the denomination +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(transparent))] #[cfg_attr( @@ -55,6 +56,7 @@ impl FromStr for BaseDenom { /// For example, given the token `my_port-1/my_channel-1/my_port-2/my_channel-2/base_denom`, /// `my_port-1/my_channel-1` is a trace prefix, and `my_port-2/my_channel-2` is another one. /// See [TracePath] which stitches trace prefixes together. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( @@ -122,6 +124,7 @@ impl Display for TracePrefix { /// Internally, the `TracePath` is modelled as a `Vec` but with the order reversed, i.e. /// "transfer/channel-0/transfer/channel-1/uatom" => `["transfer/channel-1", "transfer/channel-0"]` /// This is done for ease of addition/removal of prefixes. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( @@ -236,6 +239,7 @@ impl Display for TracePath { } /// A type that contains the base denomination for ICS20 and the source tracing information path. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[cfg_attr( diff --git a/ibc-apps/ics20-transfer/types/src/memo.rs b/ibc-apps/ics20-transfer/types/src/memo.rs index a49c40beb..dfe98ed6c 100644 --- a/ibc-apps/ics20-transfer/types/src/memo.rs +++ b/ibc-apps/ics20-transfer/types/src/memo.rs @@ -10,6 +10,7 @@ use core::str::FromStr; use ibc_core::primitives::prelude::*; /// Represents the token transfer memo +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-apps/ics20-transfer/types/src/msgs/transfer.rs b/ibc-apps/ics20-transfer/types/src/msgs/transfer.rs index 4f822b5a6..5b3e41257 100644 --- a/ibc-apps/ics20-transfer/types/src/msgs/transfer.rs +++ b/ibc-apps/ics20-transfer/types/src/msgs/transfer.rs @@ -20,6 +20,7 @@ pub(crate) const TYPE_URL: &str = "/ibc.applications.transfer.v1.MsgTransfer"; /// have to specify the information related to the transfer of the token, and /// let the library figure out how to build the packet properly. #[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr( feature = "parity-scale-codec", diff --git a/ibc-apps/ics20-transfer/types/src/packet.rs b/ibc-apps/ics20-transfer/types/src/packet.rs index 8d4d5192c..f757a25df 100644 --- a/ibc-apps/ics20-transfer/types/src/packet.rs +++ b/ibc-apps/ics20-transfer/types/src/packet.rs @@ -10,6 +10,7 @@ use ibc_proto::ibc::applications::transfer::v2::FungibleTokenPacketData as RawPa use super::{Amount, Memo, PrefixedCoin, PrefixedDenom}; /// Defines the structure of token transfers' packet bytes +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr( feature = "serde", diff --git a/ibc-apps/ics721-nft-transfer/Cargo.toml b/ibc-apps/ics721-nft-transfer/Cargo.toml index 2b3149f99..e7625cfd1 100644 --- a/ibc-apps/ics721-nft-transfer/Cargo.toml +++ b/ibc-apps/ics721-nft-transfer/Cargo.toml @@ -52,3 +52,4 @@ parity-scale-codec = [ "ibc-app-nft-transfer-types/parity-scale-codec", "ibc-core/parity-scale-codec", ] +arbitrary = [ "ibc-app-nft-transfer-types/arbitrary", "ibc-core/arbitrary" ] diff --git a/ibc-apps/ics721-nft-transfer/types/Cargo.toml b/ibc-apps/ics721-nft-transfer/types/Cargo.toml index bf9c36e2c..944349284 100644 --- a/ibc-apps/ics721-nft-transfer/types/Cargo.toml +++ b/ibc-apps/ics721-nft-transfer/types/Cargo.toml @@ -20,6 +20,7 @@ all-features = true [dependencies] # external dependencies +arbitrary = { workspace = true, optional = true } borsh = { workspace = true, optional = true } base64 = { workspace = true, features = [ "alloc" ] } derive_more = { workspace = true } @@ -81,3 +82,9 @@ parity-scale-codec = [ "ibc-proto/parity-scale-codec", "ibc-app-transfer-types/parity-scale-codec", ] +arbitrary = [ + "dep:arbitrary", + "ibc-core/arbitrary", + "ibc-app-transfer-types/arbitrary", + "std", +] diff --git a/ibc-apps/ics721-nft-transfer/types/src/class.rs b/ibc-apps/ics721-nft-transfer/types/src/class.rs index d554be89b..f223243ca 100644 --- a/ibc-apps/ics721-nft-transfer/types/src/class.rs +++ b/ibc-apps/ics721-nft-transfer/types/src/class.rs @@ -14,6 +14,7 @@ use ibc_proto::ibc::applications::nft_transfer::v1::ClassTrace as RawClassTrace; use crate::data::Data; /// Class ID for an NFT +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( @@ -56,6 +57,7 @@ impl FromStr for ClassId { } /// Prefixed class to trace sources like ICS-20 PrefixedDenom +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[cfg_attr( @@ -180,10 +182,12 @@ impl Display for PrefixedClassId { } /// Class URI for an NFT +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct ClassUri( + #[cfg_attr(feature = "arbitrary", arbitrary(with = crate::arb_uri))] #[cfg_attr(feature = "serde", serde(with = "serializers"))] #[cfg_attr(feature = "schema", schemars(with = "String"))] Uri, @@ -253,6 +257,7 @@ impl FromStr for ClassUri { } /// Class data for an NFT +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-apps/ics721-nft-transfer/types/src/data.rs b/ibc-apps/ics721-nft-transfer/types/src/data.rs index 5151203f3..a7f4858b7 100644 --- a/ibc-apps/ics721-nft-transfer/types/src/data.rs +++ b/ibc-apps/ics721-nft-transfer/types/src/data.rs @@ -10,6 +10,7 @@ use ibc_core::host::types::error::DecodingError; use ibc_core::primitives::prelude::*; use mime::Mime; +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-apps/ics721-nft-transfer/types/src/lib.rs b/ibc-apps/ics721-nft-transfer/types/src/lib.rs index 6992c98f0..68818015a 100644 --- a/ibc-apps/ics721-nft-transfer/types/src/lib.rs +++ b/ibc-apps/ics721-nft-transfer/types/src/lib.rs @@ -55,3 +55,9 @@ use ibc_core::channel::types::acknowledgement::StatusValue; pub fn ack_success_b64() -> StatusValue { StatusValue::new(ACK_SUCCESS_B64).expect("ack status value is never supposed to be empty") } + +#[cfg(feature = "arbitrary")] +fn arb_uri(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { + let raw: std::string::String = arbitrary::Arbitrary::arbitrary(u)?; + http::Uri::try_from(&raw).map_err(|_| arbitrary::Error::IncorrectFormat) +} diff --git a/ibc-apps/ics721-nft-transfer/types/src/memo.rs b/ibc-apps/ics721-nft-transfer/types/src/memo.rs index b18f2027d..996373d95 100644 --- a/ibc-apps/ics721-nft-transfer/types/src/memo.rs +++ b/ibc-apps/ics721-nft-transfer/types/src/memo.rs @@ -10,6 +10,7 @@ use core::str::FromStr; use ibc_core::primitives::prelude::*; /// Represents the token transfer memo +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-apps/ics721-nft-transfer/types/src/msgs/transfer.rs b/ibc-apps/ics721-nft-transfer/types/src/msgs/transfer.rs index 0ced7dbac..a3f8569a1 100644 --- a/ibc-apps/ics721-nft-transfer/types/src/msgs/transfer.rs +++ b/ibc-apps/ics721-nft-transfer/types/src/msgs/transfer.rs @@ -20,6 +20,7 @@ pub(crate) const TYPE_URL: &str = "/ibc.applications.nft_transfer.v1.MsgTransfer /// have to specify the information related to the transfer of the token, and /// let the library figure out how to build the packet properly. #[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr( feature = "parity-scale-codec", diff --git a/ibc-apps/ics721-nft-transfer/types/src/packet.rs b/ibc-apps/ics721-nft-transfer/types/src/packet.rs index afa773bfc..5ccf429f3 100644 --- a/ibc-apps/ics721-nft-transfer/types/src/packet.rs +++ b/ibc-apps/ics721-nft-transfer/types/src/packet.rs @@ -15,6 +15,7 @@ use crate::memo::Memo; use crate::token::{TokenData, TokenIds, TokenUri}; /// Defines the structure of token transfers' packet bytes +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] diff --git a/ibc-apps/ics721-nft-transfer/types/src/token.rs b/ibc-apps/ics721-nft-transfer/types/src/token.rs index b865ed126..910714d04 100644 --- a/ibc-apps/ics721-nft-transfer/types/src/token.rs +++ b/ibc-apps/ics721-nft-transfer/types/src/token.rs @@ -11,6 +11,7 @@ use ibc_core::primitives::serializers; use crate::data::Data; /// Token ID for an NFT +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( @@ -52,6 +53,7 @@ impl FromStr for TokenId { } } +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( @@ -116,10 +118,12 @@ impl TryFrom> for TokenIds { } /// Token URI for an NFT +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct TokenUri( + #[cfg_attr(feature = "arbitrary", arbitrary(with = crate::arb_uri))] #[cfg_attr(feature = "serde", serde(with = "serializers"))] #[cfg_attr(feature = "schema", schemars(with = "String"))] Uri, @@ -187,6 +191,7 @@ impl FromStr for TokenUri { } /// Token data for an NFT +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/Cargo.toml b/ibc-core/Cargo.toml index eebb12318..73785201d 100644 --- a/ibc-core/Cargo.toml +++ b/ibc-core/Cargo.toml @@ -82,3 +82,13 @@ parity-scale-codec = [ "ibc-core-handler/parity-scale-codec", "ibc-primitives/parity-scale-codec", ] +arbitrary = [ + "ibc-core-client/arbitrary", + "ibc-core-connection/arbitrary", + "ibc-core-channel/arbitrary", + "ibc-core-commitment-types/arbitrary", + "ibc-core-host/arbitrary", + "ibc-core-handler/arbitrary", + "ibc-primitives/arbitrary", + "std", +] diff --git a/ibc-core/ics02-client/Cargo.toml b/ibc-core/ics02-client/Cargo.toml index 7502b6a25..aec647ccb 100644 --- a/ibc-core/ics02-client/Cargo.toml +++ b/ibc-core/ics02-client/Cargo.toml @@ -69,3 +69,10 @@ parity-scale-codec = [ "ibc-core-handler-types/parity-scale-codec", "ibc-primitives/parity-scale-codec", ] +arbitrary = [ + "ibc-core-client-types/arbitrary", + "ibc-core-commitment-types/arbitrary", + "ibc-core-host/arbitrary", + "ibc-core-handler-types/arbitrary", + "ibc-primitives/arbitrary", +] diff --git a/ibc-core/ics02-client/types/Cargo.toml b/ibc-core/ics02-client/types/Cargo.toml index abc812cd4..8e8451371 100644 --- a/ibc-core/ics02-client/types/Cargo.toml +++ b/ibc-core/ics02-client/types/Cargo.toml @@ -20,6 +20,7 @@ all-features = true [dependencies] # external dependencies +arbitrary = { workspace = true, optional = true } borsh = { workspace = true, optional = true } derive_more = { workspace = true } displaydoc = { workspace = true } @@ -86,3 +87,10 @@ parity-scale-codec = [ "ibc-primitives/parity-scale-codec", "ibc-proto/parity-scale-codec", ] +arbitrary = [ + "dep:arbitrary", + "ibc-primitives/arbitrary", + "ibc-core-commitment-types/arbitrary", + "ibc-core-host-types/arbitrary", + "std", +] diff --git a/ibc-core/ics02-client/types/src/height.rs b/ibc-core/ics02-client/types/src/height.rs index 612351863..1ae788add 100644 --- a/ibc-core/ics02-client/types/src/height.rs +++ b/ibc-core/ics02-client/types/src/height.rs @@ -13,6 +13,7 @@ use crate::error::ClientError; /// The core IBC height type, which represents the height of a chain, /// which typically is the number of blocks since genesis /// (or more generally, since the last revision/hard upgrade). +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics02-client/types/src/msgs/create_client.rs b/ibc-core/ics02-client/types/src/msgs/create_client.rs index 1891a143e..d898e44da 100644 --- a/ibc-core/ics02-client/types/src/msgs/create_client.rs +++ b/ibc-core/ics02-client/types/src/msgs/create_client.rs @@ -10,6 +10,7 @@ use ibc_proto::Protobuf; pub const CREATE_CLIENT_TYPE_URL: &str = "/ibc.core.client.v1.MsgCreateClient"; /// A type of message that triggers the creation of a new on-chain (IBC) client. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) @@ -17,7 +18,9 @@ pub const CREATE_CLIENT_TYPE_URL: &str = "/ibc.core.client.v1.MsgCreateClient"; #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct MsgCreateClient { + #[cfg_attr(feature = "arbitrary", arbitrary(with = ibc_primitives::arb_protobuf_any))] pub client_state: Any, + #[cfg_attr(feature = "arbitrary", arbitrary(with = ibc_primitives::arb_protobuf_any))] pub consensus_state: Any, pub signer: Signer, } diff --git a/ibc-core/ics02-client/types/src/msgs/misbehaviour.rs b/ibc-core/ics02-client/types/src/msgs/misbehaviour.rs index 1e495393b..22737778a 100644 --- a/ibc-core/ics02-client/types/src/msgs/misbehaviour.rs +++ b/ibc-core/ics02-client/types/src/msgs/misbehaviour.rs @@ -14,6 +14,7 @@ pub const SUBMIT_MISBEHAVIOUR_TYPE_URL: &str = "/ibc.core.client.v1.MsgSubmitMis /// /// Deprecated since v0.51.0. Misbehaviour reports should be submitted via the `MsgUpdateClient` /// type through its `client_message` field. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[deprecated( since = "0.51.0", note = "Misbehaviour reports should be submitted via `MsgUpdateClient` through its `client_message` field" @@ -28,6 +29,7 @@ pub struct MsgSubmitMisbehaviour { /// client unique identifier pub client_id: ClientId, /// misbehaviour, used for freezing the light client + #[cfg_attr(feature = "arbitrary", arbitrary(with = ibc_primitives::arb_protobuf_any))] pub misbehaviour: ProtoAny, /// signer address pub signer: Signer, diff --git a/ibc-core/ics02-client/types/src/msgs/mod.rs b/ibc-core/ics02-client/types/src/msgs/mod.rs index fbb76a821..6e8887891 100644 --- a/ibc-core/ics02-client/types/src/msgs/mod.rs +++ b/ibc-core/ics02-client/types/src/msgs/mod.rs @@ -21,6 +21,7 @@ pub use upgrade_client::*; /// Encodes all the different client messages #[allow(dead_code)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics02-client/types/src/msgs/recover_client.rs b/ibc-core/ics02-client/types/src/msgs/recover_client.rs index 5ef857cba..91fcb1006 100644 --- a/ibc-core/ics02-client/types/src/msgs/recover_client.rs +++ b/ibc-core/ics02-client/types/src/msgs/recover_client.rs @@ -17,6 +17,7 @@ pub const RECOVER_CLIENT_TYPE_URL: &str = "/ibc.core.client.v1.MsgRecoverClient" /// client recovery functionality is not part of ibc-rs's public API. The /// intended usage of this message type is to be integrated with hosts' /// governance modules, not to be called directly via `dispatch`. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics02-client/types/src/msgs/update_client.rs b/ibc-core/ics02-client/types/src/msgs/update_client.rs index 16a5d250d..8e9e901c2 100644 --- a/ibc-core/ics02-client/types/src/msgs/update_client.rs +++ b/ibc-core/ics02-client/types/src/msgs/update_client.rs @@ -14,6 +14,7 @@ pub const UPDATE_CLIENT_TYPE_URL: &str = "/ibc.core.client.v1.MsgUpdateClient"; /// either with new headers, or evidence of misbehaviour. /// Note that some types of misbehaviour can be detected when the headers /// are updated (`UpdateKind::UpdateClient`). +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) @@ -22,6 +23,7 @@ pub const UPDATE_CLIENT_TYPE_URL: &str = "/ibc.core.client.v1.MsgUpdateClient"; #[derive(Clone, Debug, PartialEq, Eq)] pub struct MsgUpdateClient { pub client_id: ClientId, + #[cfg_attr(feature = "arbitrary", arbitrary(with = ibc_primitives::arb_protobuf_any))] pub client_message: Any, pub signer: Signer, } diff --git a/ibc-core/ics02-client/types/src/msgs/upgrade_client.rs b/ibc-core/ics02-client/types/src/msgs/upgrade_client.rs index d581f8e1b..ba66c391d 100644 --- a/ibc-core/ics02-client/types/src/msgs/upgrade_client.rs +++ b/ibc-core/ics02-client/types/src/msgs/upgrade_client.rs @@ -14,6 +14,7 @@ use ibc_proto::Protobuf; pub const UPGRADE_CLIENT_TYPE_URL: &str = "/ibc.core.client.v1.MsgUpgradeClient"; /// A type of message that triggers the upgrade of an on-chain (IBC) client. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) @@ -24,9 +25,11 @@ pub struct MsgUpgradeClient { // client unique identifier pub client_id: ClientId, // Upgraded client state + #[cfg_attr(feature = "arbitrary", arbitrary(with = ibc_primitives::arb_protobuf_any))] pub upgraded_client_state: Any, // Upgraded consensus state, only contains enough information // to serve as a basis of trust in update logic + #[cfg_attr(feature = "arbitrary", arbitrary(with = ibc_primitives::arb_protobuf_any))] pub upgraded_consensus_state: Any, // proof that old chain committed to new client pub proof_upgrade_client: CommitmentProofBytes, diff --git a/ibc-core/ics03-connection/Cargo.toml b/ibc-core/ics03-connection/Cargo.toml index a6b19b7ab..aad4efcdf 100644 --- a/ibc-core/ics03-connection/Cargo.toml +++ b/ibc-core/ics03-connection/Cargo.toml @@ -71,3 +71,10 @@ wasm-client = [ "dep:ibc-client-wasm-types", "dep:prost", ] +arbitrary = [ + "ibc-core-client/arbitrary", + "ibc-core-connection-types/arbitrary", + "ibc-core-host/arbitrary", + "ibc-core-handler-types/arbitrary", + "ibc-primitives/arbitrary", +] diff --git a/ibc-core/ics03-connection/types/Cargo.toml b/ibc-core/ics03-connection/types/Cargo.toml index 39ecc8485..016c2bf76 100644 --- a/ibc-core/ics03-connection/types/Cargo.toml +++ b/ibc-core/ics03-connection/types/Cargo.toml @@ -20,6 +20,7 @@ all-features = true [dependencies] # external dependencies +arbitrary = { workspace = true, optional = true } borsh = { workspace = true, optional = true } derive_more = { workspace = true } displaydoc = { workspace = true } @@ -89,3 +90,11 @@ parity-scale-codec = [ "ibc-primitives/parity-scale-codec", "ibc-proto/parity-scale-codec", ] +arbitrary = [ + "dep:arbitrary", + "ibc-core-client-types/arbitrary", + "ibc-core-commitment-types/arbitrary", + "ibc-core-host-types/arbitrary", + "ibc-primitives/arbitrary", + "std", +] diff --git a/ibc-core/ics03-connection/types/src/connection.rs b/ibc-core/ics03-connection/types/src/connection.rs index f518f86a5..4657d00fe 100644 --- a/ibc-core/ics03-connection/types/src/connection.rs +++ b/ibc-core/ics03-connection/types/src/connection.rs @@ -339,6 +339,7 @@ impl ConnectionEnd { } } +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics03-connection/types/src/msgs/conn_open_ack.rs b/ibc-core/ics03-connection/types/src/msgs/conn_open_ack.rs index 9379c25e3..73147c9e5 100644 --- a/ibc-core/ics03-connection/types/src/msgs/conn_open_ack.rs +++ b/ibc-core/ics03-connection/types/src/msgs/conn_open_ack.rs @@ -14,6 +14,7 @@ pub const CONN_OPEN_ACK_TYPE_URL: &str = "/ibc.core.connection.v1.MsgConnectionO /// Per our convention, this message is sent to chain A. /// The handler will check proofs of chain B. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) @@ -26,6 +27,7 @@ pub struct MsgConnectionOpenAck { /// ConnectionId that chain B has chosen for its ConnectionEnd pub conn_id_on_b: ConnectionId, /// ClientState of client tracking chain A on chain B + #[cfg_attr(feature = "arbitrary", arbitrary(with = ibc_primitives::arb_protobuf_any))] pub client_state_of_a_on_b: Any, /// proof of ConnectionEnd stored on Chain B during ConnOpenTry pub proof_conn_end_on_b: CommitmentProofBytes, diff --git a/ibc-core/ics03-connection/types/src/msgs/conn_open_confirm.rs b/ibc-core/ics03-connection/types/src/msgs/conn_open_confirm.rs index 24a58b87e..d7791c110 100644 --- a/ibc-core/ics03-connection/types/src/msgs/conn_open_confirm.rs +++ b/ibc-core/ics03-connection/types/src/msgs/conn_open_confirm.rs @@ -11,6 +11,7 @@ pub const CONN_OPEN_CONFIRM_TYPE_URL: &str = "/ibc.core.connection.v1.MsgConnect /// Per our convention, this message is sent to chain B. /// The handler will check proofs of chain A. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics03-connection/types/src/msgs/conn_open_init.rs b/ibc-core/ics03-connection/types/src/msgs/conn_open_init.rs index 57790a387..8f63d83ff 100644 --- a/ibc-core/ics03-connection/types/src/msgs/conn_open_init.rs +++ b/ibc-core/ics03-connection/types/src/msgs/conn_open_init.rs @@ -14,6 +14,7 @@ pub const CONN_OPEN_INIT_TYPE_URL: &str = "/ibc.core.connection.v1.MsgConnection /// Per our convention, this message is sent to chain A. /// The handler will check proofs of chain B. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct MsgConnectionOpenInit { diff --git a/ibc-core/ics03-connection/types/src/msgs/conn_open_try.rs b/ibc-core/ics03-connection/types/src/msgs/conn_open_try.rs index ea5f22f03..9db757470 100644 --- a/ibc-core/ics03-connection/types/src/msgs/conn_open_try.rs +++ b/ibc-core/ics03-connection/types/src/msgs/conn_open_try.rs @@ -17,12 +17,14 @@ pub const CONN_OPEN_TRY_TYPE_URL: &str = "/ibc.core.connection.v1.MsgConnectionO /// Per our convention, this message is sent to chain B. /// The handler will check proofs of chain A. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct MsgConnectionOpenTry { /// ClientId on B that the connection is being opened for pub client_id_on_b: ClientId, /// ClientState of client tracking chain B on chain A + #[cfg_attr(feature = "arbitrary", arbitrary(with = ibc_primitives::arb_protobuf_any))] pub client_state_of_b_on_a: Any, /// ClientId, ConnectionId and prefix of chain A pub counterparty: Counterparty, diff --git a/ibc-core/ics03-connection/types/src/msgs/mod.rs b/ibc-core/ics03-connection/types/src/msgs/mod.rs index d3be3dcf6..3e374e001 100644 --- a/ibc-core/ics03-connection/types/src/msgs/mod.rs +++ b/ibc-core/ics03-connection/types/src/msgs/mod.rs @@ -25,6 +25,7 @@ pub use conn_open_init::*; pub use conn_open_try::*; /// Enumeration of all possible messages that the ICS3 protocol processes. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics03-connection/types/src/version.rs b/ibc-core/ics03-connection/types/src/version.rs index 89f577cc0..d51641d50 100644 --- a/ibc-core/ics03-connection/types/src/version.rs +++ b/ibc-core/ics03-connection/types/src/version.rs @@ -11,6 +11,7 @@ use ibc_proto::Protobuf; use crate::error::ConnectionError; /// Stores the identifier and the features supported by a version +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics04-channel/Cargo.toml b/ibc-core/ics04-channel/Cargo.toml index 1ad973cc1..9ad505d41 100644 --- a/ibc-core/ics04-channel/Cargo.toml +++ b/ibc-core/ics04-channel/Cargo.toml @@ -81,3 +81,12 @@ parity-scale-codec = [ "ibc-core-router/parity-scale-codec", "ibc-primitives/parity-scale-codec", ] +arbitrary = [ + "ibc-core-client/arbitrary", + "ibc-core-connection/arbitrary", + "ibc-core-channel-types/arbitrary", + "ibc-core-commitment-types/arbitrary", + "ibc-core-host/arbitrary", + "ibc-core-handler-types/arbitrary", + "ibc-primitives/arbitrary", +] diff --git a/ibc-core/ics04-channel/types/Cargo.toml b/ibc-core/ics04-channel/types/Cargo.toml index 5cff829ce..89e2d4b29 100644 --- a/ibc-core/ics04-channel/types/Cargo.toml +++ b/ibc-core/ics04-channel/types/Cargo.toml @@ -20,6 +20,7 @@ all-features = true [dependencies] # external dependencies +arbitrary = { workspace = true, optional = true } borsh = { workspace = true, optional = true } derive_more = { workspace = true } displaydoc = { workspace = true } @@ -101,3 +102,12 @@ parity-scale-codec = [ "ibc-primitives/parity-scale-codec", "ibc-proto/parity-scale-codec", ] +arbitrary = [ + "dep:arbitrary", + "ibc-core-client-types/arbitrary", + "ibc-core-connection-types/arbitrary", + "ibc-core-host-types/arbitrary", + "ibc-core-commitment-types/arbitrary", + "ibc-primitives/arbitrary", + "std", +] diff --git a/ibc-core/ics04-channel/types/src/acknowledgement.rs b/ibc-core/ics04-channel/types/src/acknowledgement.rs index efbbe28ce..1ca867387 100644 --- a/ibc-core/ics04-channel/types/src/acknowledgement.rs +++ b/ibc-core/ics04-channel/types/src/acknowledgement.rs @@ -11,6 +11,7 @@ use crate::error::ChannelError; /// A generic Acknowledgement type that modules may interpret as they like. /// /// NOTE: An acknowledgement cannot be empty. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics04-channel/types/src/channel.rs b/ibc-core/ics04-channel/types/src/channel.rs index 38140cb35..ba03f9da3 100644 --- a/ibc-core/ics04-channel/types/src/channel.rs +++ b/ibc-core/ics04-channel/types/src/channel.rs @@ -430,6 +430,7 @@ impl From for RawCounterparty { } /// Represents the channel ordering +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics04-channel/types/src/msgs/acknowledgement.rs b/ibc-core/ics04-channel/types/src/msgs/acknowledgement.rs index 10839e91d..3f531279b 100644 --- a/ibc-core/ics04-channel/types/src/msgs/acknowledgement.rs +++ b/ibc-core/ics04-channel/types/src/msgs/acknowledgement.rs @@ -14,6 +14,7 @@ pub const ACKNOWLEDGEMENT_TYPE_URL: &str = "/ibc.core.channel.v1.MsgAcknowledgem /// /// Message definition for packet acknowledgements. /// +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics04-channel/types/src/msgs/chan_close_confirm.rs b/ibc-core/ics04-channel/types/src/msgs/chan_close_confirm.rs index f3cbf1171..112aae137 100644 --- a/ibc-core/ics04-channel/types/src/msgs/chan_close_confirm.rs +++ b/ibc-core/ics04-channel/types/src/msgs/chan_close_confirm.rs @@ -14,6 +14,7 @@ pub const CHAN_CLOSE_CONFIRM_TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelCl /// datagram). /// Per our convention, this message is sent to chain B. /// +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics04-channel/types/src/msgs/chan_close_init.rs b/ibc-core/ics04-channel/types/src/msgs/chan_close_init.rs index 3d852e5fa..9aa8a11bc 100644 --- a/ibc-core/ics04-channel/types/src/msgs/chan_close_init.rs +++ b/ibc-core/ics04-channel/types/src/msgs/chan_close_init.rs @@ -11,6 +11,7 @@ pub const CHAN_CLOSE_INIT_TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelClose /// Message definition for the first step in the channel close handshake (`ChanCloseInit` datagram). /// Per our convention, this message is sent to chain A. /// +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics04-channel/types/src/msgs/chan_open_ack.rs b/ibc-core/ics04-channel/types/src/msgs/chan_open_ack.rs index 4d1151ff6..6a54373a8 100644 --- a/ibc-core/ics04-channel/types/src/msgs/chan_open_ack.rs +++ b/ibc-core/ics04-channel/types/src/msgs/chan_open_ack.rs @@ -14,6 +14,7 @@ pub const CHAN_OPEN_ACK_TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenAck /// Message definition for the third step in the channel open handshake (`ChanOpenAck` datagram). /// /// Per our convention, this message is sent to chain A. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics04-channel/types/src/msgs/chan_open_confirm.rs b/ibc-core/ics04-channel/types/src/msgs/chan_open_confirm.rs index d28fe2a6e..259c5a198 100644 --- a/ibc-core/ics04-channel/types/src/msgs/chan_open_confirm.rs +++ b/ibc-core/ics04-channel/types/src/msgs/chan_open_confirm.rs @@ -14,6 +14,7 @@ pub const CHAN_OPEN_CONFIRM_TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpe /// datagram). /// Per our convention, this message is sent to chain B. /// +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics04-channel/types/src/msgs/chan_open_init.rs b/ibc-core/ics04-channel/types/src/msgs/chan_open_init.rs index 2299802d4..a86a22a16 100644 --- a/ibc-core/ics04-channel/types/src/msgs/chan_open_init.rs +++ b/ibc-core/ics04-channel/types/src/msgs/chan_open_init.rs @@ -15,6 +15,7 @@ pub const CHAN_OPEN_INIT_TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenIn /// Message definition for the first step in the channel open handshake (`ChanOpenInit` datagram). /// Per our convention, this message is sent to chain A. /// +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics04-channel/types/src/msgs/chan_open_try.rs b/ibc-core/ics04-channel/types/src/msgs/chan_open_try.rs index 042f2c07a..6a25dcf60 100644 --- a/ibc-core/ics04-channel/types/src/msgs/chan_open_try.rs +++ b/ibc-core/ics04-channel/types/src/msgs/chan_open_try.rs @@ -17,6 +17,7 @@ pub const CHAN_OPEN_TRY_TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenTry /// Message definition for the second step in the channel open handshake (`ChanOpenTry` datagram). /// Per our convention, this message is sent to chain B. /// +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics04-channel/types/src/msgs/mod.rs b/ibc-core/ics04-channel/types/src/msgs/mod.rs index 8e518591c..705d764e0 100644 --- a/ibc-core/ics04-channel/types/src/msgs/mod.rs +++ b/ibc-core/ics04-channel/types/src/msgs/mod.rs @@ -29,6 +29,7 @@ pub use timeout::*; pub use timeout_on_close::*; /// All channel messages +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) @@ -45,6 +46,7 @@ pub enum ChannelMsg { } /// All packet messages +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics04-channel/types/src/msgs/recv_packet.rs b/ibc-core/ics04-channel/types/src/msgs/recv_packet.rs index c2b14ab41..bd596ae59 100644 --- a/ibc-core/ics04-channel/types/src/msgs/recv_packet.rs +++ b/ibc-core/ics04-channel/types/src/msgs/recv_packet.rs @@ -13,6 +13,7 @@ pub const RECV_PACKET_TYPE_URL: &str = "/ibc.core.channel.v1.MsgRecvPacket"; /// /// Message definition for the "packet receiving" datagram. /// +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics04-channel/types/src/msgs/timeout.rs b/ibc-core/ics04-channel/types/src/msgs/timeout.rs index 5fc255896..9d3c7bbd9 100644 --- a/ibc-core/ics04-channel/types/src/msgs/timeout.rs +++ b/ibc-core/ics04-channel/types/src/msgs/timeout.rs @@ -15,6 +15,7 @@ pub const TIMEOUT_TYPE_URL: &str = "/ibc.core.channel.v1.MsgTimeout"; /// Message definition for packet timeout domain type, /// which is sent on chain A and needs to prove that a previously sent packet was not received on chain B /// +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics04-channel/types/src/msgs/timeout_on_close.rs b/ibc-core/ics04-channel/types/src/msgs/timeout_on_close.rs index 34394b856..dfc3ad062 100644 --- a/ibc-core/ics04-channel/types/src/msgs/timeout_on_close.rs +++ b/ibc-core/ics04-channel/types/src/msgs/timeout_on_close.rs @@ -14,6 +14,7 @@ pub const TIMEOUT_ON_CLOSE_TYPE_URL: &str = "/ibc.core.channel.v1.MsgTimeoutOnCl /// /// Message definition for packet timeout domain type. /// +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-core/ics04-channel/types/src/packet.rs b/ibc-core/ics04-channel/types/src/packet.rs index 82b28a1fd..7dd73c0ba 100644 --- a/ibc-core/ics04-channel/types/src/packet.rs +++ b/ibc-core/ics04-channel/types/src/packet.rs @@ -68,6 +68,7 @@ impl core::fmt::Display for PacketMsgType { /// The packet type; this is what applications send to one another. /// /// Each application defines the structure of the `data` field. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics04-channel/types/src/timeout/height.rs b/ibc-core/ics04-channel/types/src/timeout/height.rs index 46d6ab49a..8ca967037 100644 --- a/ibc-core/ics04-channel/types/src/timeout/height.rs +++ b/ibc-core/ics04-channel/types/src/timeout/height.rs @@ -17,6 +17,7 @@ use ibc_proto::ibc::core::client::v1::Height as RawHeight; /// is legal and meaningful, even though the Tendermint spec rejects this height /// as invalid. Thus, it must be parsed specially, where this special case means /// "no timeout". +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics04-channel/types/src/timeout/timestamp.rs b/ibc-core/ics04-channel/types/src/timeout/timestamp.rs index 8cd45b712..dd11089cd 100644 --- a/ibc-core/ics04-channel/types/src/timeout/timestamp.rs +++ b/ibc-core/ics04-channel/types/src/timeout/timestamp.rs @@ -14,6 +14,7 @@ use crate::error::ChannelError; /// nanoseconds. A protocol value of 0 indicates that the timestamp is not set. /// In this case, we use the explicit `Never` variant to distinguish the absence /// of a timeout when converting from a zero protobuf value. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics04-channel/types/src/version.rs b/ibc-core/ics04-channel/types/src/version.rs index 1cf5c894a..a441a17b9 100644 --- a/ibc-core/ics04-channel/types/src/version.rs +++ b/ibc-core/ics04-channel/types/src/version.rs @@ -15,6 +15,7 @@ use super::error::ChannelError; /// This field is opaque to the core IBC protocol. /// No explicit validation is necessary, and the /// spec (v1) currently allows empty strings. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics23-commitment/types/Cargo.toml b/ibc-core/ics23-commitment/types/Cargo.toml index b627642fd..fc68f2d3d 100644 --- a/ibc-core/ics23-commitment/types/Cargo.toml +++ b/ibc-core/ics23-commitment/types/Cargo.toml @@ -20,6 +20,7 @@ all-features = true [dependencies] # external dependencies +arbitrary = { workspace = true, optional = true } borsh = { workspace = true, optional = true } derive_more = { workspace = true, features = [ "as_ref" ] } displaydoc = { workspace = true } @@ -79,3 +80,9 @@ parity-scale-codec = [ "ibc-core-host-types/parity-scale-codec", "ibc-proto/parity-scale-codec", ] +arbitrary = [ + "dep:arbitrary", + "ibc-core-host-types/arbitrary", + "ibc-primitives/arbitrary", + "std", +] diff --git a/ibc-core/ics23-commitment/types/src/commitment.rs b/ibc-core/ics23-commitment/types/src/commitment.rs index af1f30153..a15278a43 100644 --- a/ibc-core/ics23-commitment/types/src/commitment.rs +++ b/ibc-core/ics23-commitment/types/src/commitment.rs @@ -63,6 +63,7 @@ impl From> for CommitmentRoot { /// /// For example, in the case of a proof of membership in a Merkle tree, /// this encodes a Merkle proof. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) @@ -128,6 +129,7 @@ impl<'a> TryFrom<&'a CommitmentProofBytes> for MerkleProof { /// Defines a store prefix of the commitment proof. /// /// See [spec](https://github.com/cosmos/ibc/blob/main/spec/core/ics-023-vector-commitments/README.md#prefix). +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics24-host/Cargo.toml b/ibc-core/ics24-host/Cargo.toml index c97fb7324..55af891af 100644 --- a/ibc-core/ics24-host/Cargo.toml +++ b/ibc-core/ics24-host/Cargo.toml @@ -92,3 +92,12 @@ parity-scale-codec = [ "ibc-core-handler-types/parity-scale-codec", "ibc-primitives/parity-scale-codec", ] +arbitrary = [ + "ibc-core-client-types/arbitrary", + "ibc-core-connection-types/arbitrary", + "ibc-core-channel-types/arbitrary", + "ibc-core-commitment-types/arbitrary", + "ibc-core-host-types/arbitrary", + "ibc-core-handler-types/arbitrary", + "ibc-primitives/arbitrary", +] diff --git a/ibc-core/ics24-host/cosmos/Cargo.toml b/ibc-core/ics24-host/cosmos/Cargo.toml index 50e06f273..c8d4fed29 100644 --- a/ibc-core/ics24-host/cosmos/Cargo.toml +++ b/ibc-core/ics24-host/cosmos/Cargo.toml @@ -110,3 +110,11 @@ parity-scale-codec = [ "ibc-primitives/parity-scale-codec", "ibc-proto/parity-scale-codec", ] +arbitrary = [ + "ibc-core-client-types/arbitrary", + "ibc-core-connection-types/arbitrary", + "ibc-core-commitment-types/arbitrary", + "ibc-core-host-types/arbitrary", + "ibc-core-handler-types/arbitrary", + "ibc-primitives/arbitrary", +] diff --git a/ibc-core/ics24-host/types/Cargo.toml b/ibc-core/ics24-host/types/Cargo.toml index e4953c720..4aadb3687 100644 --- a/ibc-core/ics24-host/types/Cargo.toml +++ b/ibc-core/ics24-host/types/Cargo.toml @@ -20,6 +20,7 @@ all-features = true [dependencies] # external dependencies +arbitrary = { workspace = true, optional = true } base64 = { workspace = true } borsh = { workspace = true, optional = true } derive_more = { workspace = true } @@ -64,3 +65,4 @@ parity-scale-codec = [ "dep:scale-info", "ibc-primitives/parity-scale-codec", ] +arbitrary = [ "dep:arbitrary", "ibc-primitives/arbitrary", "std" ] diff --git a/ibc-core/ics24-host/types/src/identifiers/channel_id.rs b/ibc-core/ics24-host/types/src/identifiers/channel_id.rs index c8f9e30d7..2223778bd 100644 --- a/ibc-core/ics24-host/types/src/identifiers/channel_id.rs +++ b/ibc-core/ics24-host/types/src/identifiers/channel_id.rs @@ -9,6 +9,7 @@ use crate::validate::validate_channel_identifier; const CHANNEL_ID_PREFIX: &str = "channel"; +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics24-host/types/src/identifiers/client_id.rs b/ibc-core/ics24-host/types/src/identifiers/client_id.rs index d0128336b..76f157c19 100644 --- a/ibc-core/ics24-host/types/src/identifiers/client_id.rs +++ b/ibc-core/ics24-host/types/src/identifiers/client_id.rs @@ -6,6 +6,7 @@ use ibc_primitives::prelude::*; use crate::error::IdentifierError; use crate::validate::{validate_client_identifier, validate_client_type}; +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics24-host/types/src/identifiers/connection_id.rs b/ibc-core/ics24-host/types/src/identifiers/connection_id.rs index 9fe9657cc..92fe20260 100644 --- a/ibc-core/ics24-host/types/src/identifiers/connection_id.rs +++ b/ibc-core/ics24-host/types/src/identifiers/connection_id.rs @@ -9,6 +9,7 @@ use crate::validate::validate_connection_identifier; const CONNECTION_ID_PREFIX: &str = "connection"; +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics24-host/types/src/identifiers/port_id.rs b/ibc-core/ics24-host/types/src/identifiers/port_id.rs index e1a0e062d..2f28b4a41 100644 --- a/ibc-core/ics24-host/types/src/identifiers/port_id.rs +++ b/ibc-core/ics24-host/types/src/identifiers/port_id.rs @@ -9,6 +9,7 @@ use crate::validate::validate_port_identifier; const TRANSFER_PORT_ID: &str = "transfer"; +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics24-host/types/src/identifiers/sequence.rs b/ibc-core/ics24-host/types/src/identifiers/sequence.rs index 0ab91f24c..c150f2e8a 100644 --- a/ibc-core/ics24-host/types/src/identifiers/sequence.rs +++ b/ibc-core/ics24-host/types/src/identifiers/sequence.rs @@ -2,6 +2,7 @@ use ibc_primitives::prelude::*; use crate::error::IdentifierError; +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-core/ics25-handler/Cargo.toml b/ibc-core/ics25-handler/Cargo.toml index 43dcf44ed..f296f1c4d 100644 --- a/ibc-core/ics25-handler/Cargo.toml +++ b/ibc-core/ics25-handler/Cargo.toml @@ -81,3 +81,12 @@ parity-scale-codec = [ "ibc-core-handler-types/parity-scale-codec", "ibc-primitives/parity-scale-codec", ] +arbitrary = [ + "ibc-core-client/arbitrary", + "ibc-core-connection/arbitrary", + "ibc-core-channel/arbitrary", + "ibc-core-commitment-types/arbitrary", + "ibc-core-host/arbitrary", + "ibc-core-handler-types/arbitrary", + "ibc-primitives/arbitrary", +] diff --git a/ibc-core/ics25-handler/types/Cargo.toml b/ibc-core/ics25-handler/types/Cargo.toml index 8e5154493..714b17f32 100644 --- a/ibc-core/ics25-handler/types/Cargo.toml +++ b/ibc-core/ics25-handler/types/Cargo.toml @@ -20,6 +20,7 @@ all-features = true [dependencies] # external dependencies +arbitrary = { workspace = true, optional = true } borsh = { workspace = true, optional = true } derive_more = { workspace = true } displaydoc = { workspace = true } @@ -107,3 +108,13 @@ parity-scale-codec = [ "ibc-primitives/parity-scale-codec", "ibc-proto/parity-scale-codec", ] +arbitrary = [ + "dep:arbitrary", + "ibc-core-client-types/arbitrary", + "ibc-core-connection-types/arbitrary", + "ibc-core-channel-types/arbitrary", + "ibc-core-commitment-types/arbitrary", + "ibc-core-host-types/arbitrary", + "ibc-primitives/arbitrary", + "std", +] diff --git a/ibc-core/ics25-handler/types/src/msgs.rs b/ibc-core/ics25-handler/types/src/msgs.rs index a47a9b702..9156f8815 100644 --- a/ibc-core/ics25-handler/types/src/msgs.rs +++ b/ibc-core/ics25-handler/types/src/msgs.rs @@ -23,6 +23,7 @@ use ibc_proto::google::protobuf::Any; use ibc_proto::Protobuf; /// Enumeration of all messages that the local ICS26 module is capable of routing. +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) diff --git a/ibc-primitives/Cargo.toml b/ibc-primitives/Cargo.toml index 7f8432e7d..cdbe77b9a 100644 --- a/ibc-primitives/Cargo.toml +++ b/ibc-primitives/Cargo.toml @@ -20,6 +20,7 @@ all-features = true [dependencies] # external dependencies +arbitrary = { workspace = true, optional = true } borsh = { workspace = true, optional = true } derive_more = { workspace = true } displaydoc = { workspace = true } @@ -67,3 +68,4 @@ parity-scale-codec = [ "dep:scale-info", "ibc-proto/parity-scale-codec", ] +arbitrary = [ "dep:arbitrary", "std" ] diff --git a/ibc-primitives/src/lib.rs b/ibc-primitives/src/lib.rs index 277c794cd..c2f7aa81a 100644 --- a/ibc-primitives/src/lib.rs +++ b/ibc-primitives/src/lib.rs @@ -34,3 +34,12 @@ pub mod proto { pub use ibc_proto::google::protobuf::{Any, Duration, Timestamp}; pub use ibc_proto::{Error, Protobuf}; } + +#[cfg(feature = "arbitrary")] +pub fn arb_protobuf_any( + u: &mut arbitrary::Unstructured<'_>, +) -> arbitrary::Result { + let type_url: std::string::String = arbitrary::Arbitrary::arbitrary(u)?; + let value: std::vec::Vec = arbitrary::Arbitrary::arbitrary(u)?; + Ok(ibc_proto::google::protobuf::Any { type_url, value }) +} diff --git a/ibc-primitives/src/types/signer.rs b/ibc-primitives/src/types/signer.rs index a00cd498e..0eeacef6f 100644 --- a/ibc-primitives/src/types/signer.rs +++ b/ibc-primitives/src/types/signer.rs @@ -3,6 +3,7 @@ use derive_more::Display; use crate::prelude::*; /// Represents the address of the signer of the current transaction +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( feature = "parity-scale-codec", derive( diff --git a/ibc-primitives/src/types/timestamp.rs b/ibc-primitives/src/types/timestamp.rs index 33fca85d6..eafa8608c 100644 --- a/ibc-primitives/src/types/timestamp.rs +++ b/ibc-primitives/src/types/timestamp.rs @@ -34,6 +34,14 @@ pub struct Timestamp { time: PrimitiveDateTime, } +#[cfg(feature = "arbitrary")] +impl<'a> arbitrary::Arbitrary<'a> for Timestamp { + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { + let nanos: u64 = arbitrary::Arbitrary::arbitrary(u)?; + Ok(Timestamp::from_nanoseconds(nanos)) + } +} + impl Timestamp { pub fn from_nanoseconds(nanoseconds: u64) -> Self { // As the `u64` can only represent times up to about year 2554, there is diff --git a/ibc/Cargo.toml b/ibc/Cargo.toml index 1005db2a0..1a1eb6f56 100644 --- a/ibc/Cargo.toml +++ b/ibc/Cargo.toml @@ -67,3 +67,9 @@ parity-scale-codec = [ "ibc-core-host-cosmos/parity-scale-codec", "ibc-primitives/parity-scale-codec", ] +arbitrary = [ + "ibc-apps/arbitrary", + "ibc-core/arbitrary", + "ibc-core-host-cosmos/arbitrary", + "ibc-primitives/arbitrary", +]