Skip to content

Commit

Permalink
feat(xcm): support json schema (for CosmWasm VM support) (#1454)
Browse files Browse the repository at this point in the history
# Description

- What does this PR do? Allows to generate JSON schema for subset of XCM
in std builds
- Why are these changes needed? To support XCM messages in CosmWasm
contracts which require Schemars to generate contract clients
- How were these changes implemented and what do they affect? We will
use schema feature flag to build XCM pallet with JSON schema enabled

# Checklist

- [x] My PR includes a detailed description as outlined in the
"Description" section above
- [x] My PR follows the [labeling requirements](CONTRIBUTING.md#Process)
of this project (at minimum one label for `T`
  required)
- [x] I have made corresponding changes to the documentation (if
applicable)
- [x] I have added tests that prove my fix is effective or that my
feature works (if applicable)
- [x] If this PR alters any external APIs or interfaces used by
Polkadot, the corresponding Polkadot PR is ready as well
  as the corresponding Cumulus PR (optional)
  • Loading branch information
dzmitry-lahoda committed Dec 7, 2023
1 parent 1a4ab64 commit 95c3ee1
Show file tree
Hide file tree
Showing 13 changed files with 86 additions and 3 deletions.
42 changes: 40 additions & 2 deletions Cargo.lock

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

4 changes: 3 additions & 1 deletion polkadot/xcm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ edition.workspace = true
license.workspace = true

[dependencies]
bounded-collections = { version = "0.1.8", default-features = false, features = ["serde"] }
bounded-collections = { version = "0.1.9", default-features = false, features = ["serde"] }
derivative = { version = "2.2.0", default-features = false, features = ["use_core"] }
impl-trait-for-tuples = "0.2.2"
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.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 }
xcm-procedural = { path = "procedural" }
environmental = { version = "1.1.4", default-features = false }

Expand All @@ -35,3 +36,4 @@ std = [
"serde/std",
"sp-weights/std",
]
json-schema = ["bounded-collections/json-schema", "dep:schemars", "sp-weights/json-schema"]
1 change: 1 addition & 0 deletions polkadot/xcm/src/double_encoded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> {
encoded: Vec<u8>,
#[codec(skip)]
Expand Down
1 change: 1 addition & 0 deletions polkadot/xcm/src/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions polkadot/xcm/src/v3/junction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ use serde::{Deserialize, Serialize};
Serialize,
Deserialize,
)]
#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
#[scale_info(replace_segment("staging_xcm", "xcm"))]
pub enum NetworkId {
/// Network specified by the first 32 bytes of its genesis block.
Expand Down Expand Up @@ -119,6 +120,7 @@ impl TryFrom<OldNetworkId> for NetworkId {
Serialize,
Deserialize,
)]
#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
#[scale_info(replace_segment("staging_xcm", "xcm"))]
pub enum BodyId {
/// The only body in its context.
Expand Down Expand Up @@ -190,6 +192,7 @@ impl TryFrom<OldBodyId> for BodyId {
Serialize,
Deserialize,
)]
#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
#[scale_info(replace_segment("staging_xcm", "xcm"))]
pub enum BodyPart {
/// The body's declaration, under whatever means it decides.
Expand Down Expand Up @@ -266,6 +269,7 @@ impl TryFrom<OldBodyPart> for BodyPart {
Serialize,
Deserialize,
)]
#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
#[scale_info(replace_segment("staging_xcm", "xcm"))]
pub enum Junction {
/// An indexed parachain belonging to and operated by the context.
Expand Down
1 change: 1 addition & 0 deletions polkadot/xcm/src/v3/junctions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub(crate) const MAX_JUNCTIONS: usize = 8;
serde::Serialize,
serde::Deserialize,
)]
#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
#[scale_info(replace_segment("staging_xcm", "xcm"))]
pub enum Junctions {
/// The interpreting consensus system.
Expand Down
10 changes: 10 additions & 0 deletions polkadot/xcm/src/v3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Call>(pub Vec<Instruction<Call>>);

/// The maximal number of instructions in an XCM before decoding fails.
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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<u8, MaxDispatchErrorLen>),
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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<Call> {
/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into the Holding
/// Register.
Expand Down
8 changes: 8 additions & 0 deletions polkadot/xcm/src/v3/multiasset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "json-schema", derive(schemars::JsonSchema))]
#[scale_info(replace_segment("staging_xcm", "xcm"))]
pub enum AssetInstance {
/// Undefined - used if the non-fungible asset class has only one instance.
Expand Down Expand Up @@ -243,6 +244,7 @@ impl TryFrom<AssetInstance> 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 = "json-schema", derive(schemars::JsonSchema))]
#[scale_info(replace_segment("staging_xcm", "xcm"))]
pub enum Fungibility {
/// A fungible asset; we record a number of units, as a `u128` in the inner item.
Expand Down Expand Up @@ -313,6 +315,7 @@ impl TryFrom<OldFungibility> 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 = "json-schema", derive(schemars::JsonSchema))]
#[scale_info(replace_segment("staging_xcm", "xcm"))]
pub enum WildFungibility {
/// The asset is fungible.
Expand All @@ -337,6 +340,7 @@ impl TryFrom<OldWildFungibility> 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 = "json-schema", derive(schemars::JsonSchema))]
#[scale_info(replace_segment("staging_xcm", "xcm"))]
pub enum AssetId {
/// A specific location identifying an asset.
Expand Down Expand Up @@ -412,6 +416,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 = "json-schema", derive(schemars::JsonSchema))]
#[scale_info(replace_segment("staging_xcm", "xcm"))]
pub struct MultiAsset {
/// The overall asset identity (aka *class*, in the case of a non-fungible).
Expand Down Expand Up @@ -510,6 +515,7 @@ impl TryFrom<OldMultiAsset> 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 = "json-schema", derive(schemars::JsonSchema))]
#[scale_info(replace_segment("staging_xcm", "xcm"))]
pub struct MultiAssets(Vec<MultiAsset>);

Expand Down Expand Up @@ -710,6 +716,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 = "json-schema", derive(schemars::JsonSchema))]
#[scale_info(replace_segment("staging_xcm", "xcm"))]
pub enum WildMultiAsset {
/// All assets in Holding.
Expand Down Expand Up @@ -823,6 +830,7 @@ impl<A: Into<AssetId>, B: Into<WildFungibility>> 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 = "json-schema", derive(schemars::JsonSchema))]
#[scale_info(replace_segment("staging_xcm", "xcm"))]
pub enum MultiAssetFilter {
/// Specify the filter as being everything contained by the given `MultiAssets` inner.
Expand Down
1 change: 1 addition & 0 deletions polkadot/xcm/src/v3/multilocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ use scale_info::TypeInfo;
serde::Serialize,
serde::Deserialize,
)]
#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
pub struct MultiLocation {
/// The number of parent junctions at the beginning of this `MultiLocation`.
pub parents: u8,
Expand Down
1 change: 1 addition & 0 deletions polkadot/xcm/src/v3/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
10 changes: 10 additions & 0 deletions prdoc/pr_1454.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
title: Support XCM as part of Cosmos CosmWasm contract messages

doc:
- audience: Runtime 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
5 changes: 5 additions & 0 deletions substrate/primitives/weights/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand All @@ -44,3 +45,7 @@ serde = [
"scale-info/serde",
"sp-arithmetic/serde",
]

json-schema = [
"dep:schemars",
]
1 change: 1 addition & 0 deletions substrate/primitives/weights/src/weight_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 95c3ee1

Please sign in to comment.