From 8d273d9762ab55a909e2581318b2cc8ddfcecf36 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Thu, 7 Sep 2023 19:06:31 +0100 Subject: [PATCH 1/4] feat(xcm): support json schema (for CosmWasm VM support) --- Cargo.lock | 36 ++++++++++++++++++++++++++++ polkadot/xcm/Cargo.toml | 2 ++ polkadot/xcm/src/v3/junction.rs | 4 ++++ polkadot/xcm/src/v3/junctions.rs | 1 + polkadot/xcm/src/v3/multiasset.rs | 8 +++++++ polkadot/xcm/src/v3/multilocation.rs | 1 + 6 files changed, 52 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index a95a7e2561d6e..f771dc6dbf0c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15956,6 +15956,30 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "schemars" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763f8cd0d4c71ed8389c90cb8100cba87e763bd01a8e614d4f0af97bcd50a161" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0f696e21e10fa546b7ffb1c9672c6de8fbc7a81acf59524386d8639bf12737" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + [[package]] name = "schnellru" version = "0.2.1" @@ -16211,6 +16235,17 @@ dependencies = [ "syn 2.0.31", ] +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "serde_fmt" version = "1.0.3" @@ -17890,6 +17925,7 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", + "schemars", "serde", "sp-io", "sp-weights", diff --git a/polkadot/xcm/Cargo.toml b/polkadot/xcm/Cargo.toml index f04f31c3ec103..35c6d84ac1d41 100644 --- a/polkadot/xcm/Cargo.toml +++ b/polkadot/xcm/Cargo.toml @@ -14,6 +14,7 @@ log = { version = "0.4.17", default-features = false } parity-scale-codec = { version = "3.6.1", default-features = false, features = [ "derive", "max-encoded-len" ] } scale-info = { version = "2.5.0", default-features = false, features = ["derive", "serde"] } sp-weights = { path = "../../substrate/primitives/weights", default-features = false, features = ["serde"] } +schemars = { version = "0.8.13", default-features = true, optional = true} serde = { version = "1.0.188", default-features = false, features = ["alloc", "derive"] } xcm-procedural = { path = "procedural" } environmental = { version = "1.1.4", default-features = false } @@ -25,6 +26,7 @@ hex-literal = "0.4.1" [features] default = [ "std" ] +schema = [ "schemars", "std" ] wasm-api = [] std = [ "bounded-collections/std", diff --git a/polkadot/xcm/src/v3/junction.rs b/polkadot/xcm/src/v3/junction.rs index b5dd5bc7c88fe..350fe669c681c 100644 --- a/polkadot/xcm/src/v3/junction.rs +++ b/polkadot/xcm/src/v3/junction.rs @@ -49,6 +49,7 @@ use serde::{Deserialize, Serialize}; Serialize, Deserialize, )] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum NetworkId { /// Network specified by the first 32 bytes of its genesis block. ByGenesis([u8; 32]), @@ -116,6 +117,7 @@ impl TryFrom for NetworkId { Serialize, Deserialize, )] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum BodyId { /// The only body in its context. Unit, @@ -186,6 +188,7 @@ impl TryFrom for BodyId { Serialize, Deserialize, )] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum BodyPart { /// The body's declaration, under whatever means it decides. Voice, @@ -261,6 +264,7 @@ impl TryFrom for BodyPart { Serialize, Deserialize, )] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum Junction { /// An indexed parachain belonging to and operated by the context. /// diff --git a/polkadot/xcm/src/v3/junctions.rs b/polkadot/xcm/src/v3/junctions.rs index f7624c91c8612..eced662b81465 100644 --- a/polkadot/xcm/src/v3/junctions.rs +++ b/polkadot/xcm/src/v3/junctions.rs @@ -44,6 +44,7 @@ pub(crate) const MAX_JUNCTIONS: usize = 8; serde::Serialize, serde::Deserialize, )] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum Junctions { /// The interpreting consensus system. Here, diff --git a/polkadot/xcm/src/v3/multiasset.rs b/polkadot/xcm/src/v3/multiasset.rs index 188555318c8c0..c2df5e3b0317e 100644 --- a/polkadot/xcm/src/v3/multiasset.rs +++ b/polkadot/xcm/src/v3/multiasset.rs @@ -47,6 +47,7 @@ use scale_info::TypeInfo; Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, TypeInfo, MaxEncodedLen, )] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum AssetInstance { /// Undefined - used if the non-fungible asset class has only one instance. Undefined, @@ -242,6 +243,7 @@ impl TryFrom for u128 { /// instance. #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum Fungibility { /// A fungible asset; we record a number of units, as a `u128` in the inner item. Fungible(#[codec(compact)] u128), @@ -311,6 +313,7 @@ impl TryFrom for Fungibility { Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, )] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum WildFungibility { /// The asset is fungible. Fungible, @@ -334,6 +337,7 @@ impl TryFrom for WildFungibility { Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, )] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum AssetId { /// A specific location identifying an asset. Concrete(MultiLocation), @@ -408,6 +412,7 @@ impl AssetId { /// Either an amount of a single fungible asset, or a single well-identified non-fungible asset. #[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct MultiAsset { /// The overall asset identity (aka *class*, in the case of a non-fungible). pub id: AssetId, @@ -505,6 +510,7 @@ impl TryFrom for MultiAsset { /// - The number of items should grow no larger than `MAX_ITEMS_IN_MULTIASSETS`. #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo, Default)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct MultiAssets(Vec); /// Maximum number of items in a single `MultiAssets` value that can be decoded. @@ -700,6 +706,7 @@ impl MultiAssets { /// A wildcard representing a set of assets. #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum WildMultiAsset { /// All assets in Holding. All, @@ -812,6 +819,7 @@ impl, B: Into> From<(A, B)> for WildMultiAsset /// `MultiAsset` collection, defined either by a number of `MultiAssets` or a single wildcard. #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum MultiAssetFilter { /// Specify the filter as being everything contained by the given `MultiAssets` inner. Definite(MultiAssets), diff --git a/polkadot/xcm/src/v3/multilocation.rs b/polkadot/xcm/src/v3/multilocation.rs index 8a1575d9bc950..6d466c89ab9ad 100644 --- a/polkadot/xcm/src/v3/multilocation.rs +++ b/polkadot/xcm/src/v3/multilocation.rs @@ -66,6 +66,7 @@ use scale_info::TypeInfo; serde::Serialize, serde::Deserialize, )] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct MultiLocation { /// The number of parent junctions at the beginning of this `MultiLocation`. pub parents: u8, From 725a19fc675a391c9b3ba734026a741dfe47c455 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Wed, 6 Dec 2023 14:27:38 +0000 Subject: [PATCH 2/4] xcm is fully sendable as part of CW msg --- Cargo.lock | 6 ++++-- polkadot/xcm/Cargo.toml | 4 ++-- polkadot/xcm/src/double_encoded.rs | 1 + polkadot/xcm/src/v2/mod.rs | 1 + polkadot/xcm/src/v3/mod.rs | 10 ++++++++++ polkadot/xcm/src/v3/traits.rs | 1 + substrate/primitives/weights/Cargo.toml | 5 +++++ substrate/primitives/weights/src/weight_v2.rs | 1 + 8 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e44f57b14d97a..3567fbabe69d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1521,13 +1521,14 @@ dependencies = [ [[package]] name = "bounded-collections" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b05133427c07c4776906f673ccf36c21b102c9829c641a5b56bd151d44fd6" +checksum = "ca548b6163b872067dc5eb82fd130c56881435e30367d2073594a3d9744120dd" dependencies = [ "log", "parity-scale-codec", "scale-info", + "schemars", "serde", ] @@ -18115,6 +18116,7 @@ dependencies = [ "bounded-collections", "parity-scale-codec", "scale-info", + "schemars", "serde", "smallvec", "sp-arithmetic", diff --git a/polkadot/xcm/Cargo.toml b/polkadot/xcm/Cargo.toml index 9cf00e651565a..3d05957a3febf 100644 --- a/polkadot/xcm/Cargo.toml +++ b/polkadot/xcm/Cargo.toml @@ -15,7 +15,7 @@ parity-scale-codec = { version = "3.6.1", default-features = false, features = [ scale-info = { version = "2.10.0", default-features = false, features = ["derive", "serde"] } sp-weights = { path = "../../substrate/primitives/weights", default-features = false, features = ["serde"] } serde = { version = "1.0.193", default-features = false, features = ["alloc", "derive"] } -schemars = { version = "0.8.13", default-features = true, optional = true} +schemars = { version = "0.8.13", default-features = true, optional = true } xcm-procedural = { path = "procedural" } environmental = { version = "1.1.4", default-features = false } @@ -36,4 +36,4 @@ std = [ "serde/std", "sp-weights/std", ] -json-schema = [ "dep:schemars", "bounded-collections/json-schema" ] \ No newline at end of file +json-schema = ["bounded-collections/json-schema", "dep:schemars", "sp-weights/json-schema"] diff --git a/polkadot/xcm/src/double_encoded.rs b/polkadot/xcm/src/double_encoded.rs index 875b811da3f71..45856f657d1a4 100644 --- a/polkadot/xcm/src/double_encoded.rs +++ b/polkadot/xcm/src/double_encoded.rs @@ -25,6 +25,7 @@ use parity_scale_codec::{Decode, DecodeLimit, Encode}; #[codec(decode_bound())] #[scale_info(bounds(), skip_type_params(T))] #[scale_info(replace_segment("staging_xcm", "xcm"))] +#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub struct DoubleEncoded { encoded: Vec, #[codec(skip)] diff --git a/polkadot/xcm/src/v2/mod.rs b/polkadot/xcm/src/v2/mod.rs index 7f654ebfd9e9b..188b7f0b5c938 100644 --- a/polkadot/xcm/src/v2/mod.rs +++ b/polkadot/xcm/src/v2/mod.rs @@ -82,6 +82,7 @@ pub use traits::{Error, ExecuteXcm, GetWeight, Outcome, Result, SendError, SendR /// Basically just the XCM (more general) version of `ParachainDispatchOrigin`. #[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] #[scale_info(replace_segment("staging_xcm", "xcm"))] +#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub enum OriginKind { /// Origin should just be the native dispatch origin representation for the sender in the /// local runtime framework. For Cumulus/Frame chains this is the `Parachain` or `Relay` origin diff --git a/polkadot/xcm/src/v3/mod.rs b/polkadot/xcm/src/v3/mod.rs index bbdd504ceb0ff..50b7a539122d6 100644 --- a/polkadot/xcm/src/v3/mod.rs +++ b/polkadot/xcm/src/v3/mod.rs @@ -69,6 +69,7 @@ pub type QueryId = u64; #[codec(encode_bound())] #[scale_info(bounds(), skip_type_params(Call))] #[scale_info(replace_segment("staging_xcm", "xcm"))] +#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub struct Xcm(pub Vec>); /// The maximal number of instructions in an XCM before decoding fails. @@ -232,15 +233,19 @@ pub mod prelude { } parameter_types! { + #[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub MaxPalletNameLen: u32 = 48; /// Maximum size of the encoded error code coming from a `Dispatch` result, used for /// `MaybeErrorCode`. This is not (yet) enforced, so it's just an indication of expectation. + #[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub MaxDispatchErrorLen: u32 = 128; + #[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub MaxPalletsInfo: u32 = 64; } #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] #[scale_info(replace_segment("staging_xcm", "xcm"))] +#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub struct PalletInfo { #[codec(compact)] pub index: u32, @@ -272,6 +277,7 @@ impl PalletInfo { #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] #[scale_info(replace_segment("staging_xcm", "xcm"))] +#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub enum MaybeErrorCode { Success, Error(BoundedVec), @@ -296,6 +302,7 @@ impl Default for MaybeErrorCode { /// Response data to a query. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] #[scale_info(replace_segment("staging_xcm", "xcm"))] +#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub enum Response { /// No response. Serves as a neutral default. Null, @@ -320,6 +327,7 @@ impl Default for Response { /// Information regarding the composition of a query response. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] #[scale_info(replace_segment("staging_xcm", "xcm"))] +#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub struct QueryResponseInfo { /// The destination to which the query response message should be send. pub destination: MultiLocation, @@ -333,6 +341,7 @@ pub struct QueryResponseInfo { /// An optional weight limit. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] #[scale_info(replace_segment("staging_xcm", "xcm"))] +#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub enum WeightLimit { /// No weight limit imposed. Unlimited, @@ -417,6 +426,7 @@ impl XcmContext { #[codec(decode_bound())] #[scale_info(bounds(), skip_type_params(Call))] #[scale_info(replace_segment("staging_xcm", "xcm"))] +#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub enum Instruction { /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into the Holding /// Register. diff --git a/polkadot/xcm/src/v3/traits.rs b/polkadot/xcm/src/v3/traits.rs index 6054bf1456a5d..29bd40a6a2d8d 100644 --- a/polkadot/xcm/src/v3/traits.rs +++ b/polkadot/xcm/src/v3/traits.rs @@ -30,6 +30,7 @@ use super::*; /// they will retain the same index over time. #[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] #[scale_info(replace_segment("staging_xcm", "xcm"))] +#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub enum Error { // Errors that happen due to instructions being executed. These alone are defined in the // XCM specification. diff --git a/substrate/primitives/weights/Cargo.toml b/substrate/primitives/weights/Cargo.toml index 163b241276cec..fb2e2ae8cb1a0 100644 --- a/substrate/primitives/weights/Cargo.toml +++ b/substrate/primitives/weights/Cargo.toml @@ -21,6 +21,7 @@ smallvec = "1.11.0" sp-arithmetic = { path = "../arithmetic", default-features = false } sp-debug-derive = { path = "../debug-derive", default-features = false } sp-std = { path = "../std", default-features = false } +schemars = { version = "0.8.3", default-features = false, optional = true } [features] default = ["std"] @@ -44,3 +45,7 @@ serde = [ "scale-info/serde", "sp-arithmetic/serde", ] + +json-schema = [ + "dep:schemars", +] diff --git a/substrate/primitives/weights/src/weight_v2.rs b/substrate/primitives/weights/src/weight_v2.rs index d692aaff8f5ab..3c10929f433b6 100644 --- a/substrate/primitives/weights/src/weight_v2.rs +++ b/substrate/primitives/weights/src/weight_v2.rs @@ -23,6 +23,7 @@ use super::*; #[derive(Encode, Decode, MaxEncodedLen, TypeInfo, Eq, PartialEq, Copy, Clone, Debug, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] pub struct Weight { #[codec(compact)] /// The weight of computational time used based on some reference hardware. From ef60be4255063591943b140e8da68b4d199e179a Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Wed, 6 Dec 2023 14:32:29 +0000 Subject: [PATCH 3/4] happy --- prdoc/pr_1454.prdoc | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 prdoc/pr_1454.prdoc diff --git a/prdoc/pr_1454.prdoc b/prdoc/pr_1454.prdoc new file mode 100644 index 0000000000000..7d1ee2860dcd7 --- /dev/null +++ b/prdoc/pr_1454.prdoc @@ -0,0 +1,10 @@ +title: Support XCM as part of Cosmos CosmWasm contract messages + +doc: + - audience: XCM Dev + description: | + Made XCM JSON schema behind flag, bumped bounded-collection so to ensure it has that flag too. + +crates: + - name: staging-xcm + - name: sp-weights From bc2e9f9435a3071a5e99d570fb13d46d8ef1ae52 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Wed, 6 Dec 2023 14:36:34 +0000 Subject: [PATCH 4/4] more happy --- prdoc/pr_1454.prdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prdoc/pr_1454.prdoc b/prdoc/pr_1454.prdoc index 7d1ee2860dcd7..c96bfcde6cfe8 100644 --- a/prdoc/pr_1454.prdoc +++ b/prdoc/pr_1454.prdoc @@ -1,7 +1,7 @@ title: Support XCM as part of Cosmos CosmWasm contract messages doc: - - audience: XCM Dev + - audience: Runtime Dev description: | Made XCM JSON schema behind flag, bumped bounded-collection so to ensure it has that flag too.