diff --git a/frame-metadata/Cargo.toml b/frame-metadata/Cargo.toml index a4c1f5d..394986c 100644 --- a/frame-metadata/Cargo.toml +++ b/frame-metadata/Cargo.toml @@ -25,5 +25,6 @@ v13 = ["scale-info"] std = [ "codec/std", "scale-info/std", + "scale-info/serde", "serde", ] diff --git a/frame-metadata/src/lib.rs b/frame-metadata/src/lib.rs index 65fe1c5..4aec005 100644 --- a/frame-metadata/src/lib.rs +++ b/frame-metadata/src/lib.rs @@ -22,7 +22,10 @@ cfg_if::cfg_if! { if #[cfg(feature = "std")] { use codec::{Decode, Error, Input}; - use serde::Serialize; + use serde::{ + Deserialize, + Serialize, + }; } else { extern crate alloc; use alloc::vec::Vec; @@ -37,14 +40,29 @@ pub mod v12; #[cfg(feature = "v13")] pub mod v13; +cfg_if::cfg_if! { + if #[cfg(not(feature = "v13"))] { + /// Dummy trait in place of `scale_info::form::FormString`. + /// Since the `scale-info` crate is only imported for the `v13` feature. + pub trait FormString {} + + impl FormString for &'static str {} + #[cfg(feature = "std")] + impl FormString for String {} + } else { + pub(crate) use scale_info::form::FormString; + } +} + /// The metadata of a runtime. /// The version ID encoded/decoded through /// the enum nature of `RuntimeMetadata`. #[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub enum RuntimeMetadata { +#[cfg_attr(feature = "std", serde(bound(serialize = "S: Serialize")))] +pub enum RuntimeMetadata { /// Unused; enum filler. - V0(RuntimeMetadataDeprecated), + V0(core::marker::PhantomData), /// Version 1 for runtime metadata. No longer used. V1(RuntimeMetadataDeprecated), /// Version 2 for runtime metadata. No longer used. @@ -69,13 +87,13 @@ pub enum RuntimeMetadata { V11(RuntimeMetadataDeprecated), /// Version 12 for runtime metadata #[cfg(feature = "v12")] - V12(v12::RuntimeMetadataV12), + V12(v12::RuntimeMetadataV12), /// Version 12 for runtime metadata, as raw encoded bytes. #[cfg(not(feature = "v12"))] V12(OpaqueMetadata), /// Version 13 for runtime metadata. #[cfg(feature = "v13")] - V13(v13::RuntimeMetadataV13), + V13(v13::RuntimeMetadataV13), /// Version 13 for runtime metadata, as raw encoded bytes. #[cfg(not(feature = "v13"))] V13(OpaqueMetadata), @@ -83,12 +101,12 @@ pub enum RuntimeMetadata { /// Stores the encoded `RuntimeMetadata` as raw bytes. #[derive(Encode, Eq, PartialEq)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Deserialize, Debug))] pub struct OpaqueMetadata(pub Vec); /// Enum that should fail. #[derive(Eq, PartialEq)] -#[cfg_attr(feature = "std", derive(Serialize, Debug))] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] pub enum RuntimeMetadataDeprecated {} impl Encode for RuntimeMetadataDeprecated { diff --git a/frame-metadata/src/v12.rs b/frame-metadata/src/v12.rs index 99562de..4b6e0ec 100644 --- a/frame-metadata/src/v12.rs +++ b/frame-metadata/src/v12.rs @@ -35,6 +35,9 @@ cfg_if::cfg_if! { } } +use super::FormString; +use core::marker::PhantomData; + /// Current prefix of metadata pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness @@ -347,7 +350,10 @@ pub struct StorageMetadata { /// Metadata prefixed by a u32 for reserved usage #[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub struct RuntimeMetadataPrefixed(pub u32, pub super::RuntimeMetadata); +pub struct RuntimeMetadataPrefixed( + pub u32, + pub super::RuntimeMetadata, +); /// Metadata of the extrinsic used by the runtime. #[derive(Eq, Encode, PartialEq)] @@ -362,11 +368,14 @@ pub struct ExtrinsicMetadata { /// The metadata of a runtime. #[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub struct RuntimeMetadataV12 { +#[cfg_attr(feature = "std", serde(bound(serialize = "S: Serialize")))] +pub struct RuntimeMetadataV12 { /// Metadata of all the modules. pub modules: DecodeDifferentArray, /// Metadata of the extrinsic. pub extrinsic: ExtrinsicMetadata, + /// Marker for dummy type parameter required by v13 but not used here. + pub marker: PhantomData, } /// The latest version of the metadata. diff --git a/frame-metadata/src/v13.rs b/frame-metadata/src/v13.rs index b5b744e..f09b6b2 100644 --- a/frame-metadata/src/v13.rs +++ b/frame-metadata/src/v13.rs @@ -17,7 +17,7 @@ cfg_if::cfg_if! { if #[cfg(feature = "std")] { - use codec::{Decode, Error, Input}; + use codec::Decode; use serde::Serialize; } } @@ -38,7 +38,11 @@ pub type ByteGetter = Vec; /// Metadata prefixed by a u32 for reserved usage #[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub struct RuntimeMetadataPrefixed(pub u32, pub super::RuntimeMetadata); +#[cfg_attr(feature = "std", serde(bound(serialize = "S: Serialize")))] +pub struct RuntimeMetadataPrefixed( + pub u32, + pub super::RuntimeMetadata, +); pub type RuntimeMetadataLastVersion = RuntimeMetadataV13; @@ -52,12 +56,13 @@ impl From for RuntimeMetadataPrefixed { // todo: [AJ] add back clone derive if required (requires PortableRegistry to implement clone) #[derive(PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr(feature = "std", serde(bound(serialize = "S: Serialize")))] pub struct RuntimeMetadataV13 { pub types: PortableRegistry, /// Metadata of all the modules. - pub modules: Vec>, + pub modules: Vec>>, /// Metadata of the extrinsic. - pub extrinsic: ExtrinsicMetadata, + pub extrinsic: ExtrinsicMetadata>, } impl RuntimeMetadataV13 { @@ -74,13 +79,19 @@ impl RuntimeMetadataV13 { } /// Metadata of the extrinsic used by the runtime. -#[derive(Clone, PartialEq, Eq, Encode, Debug)] -#[cfg_attr(feature = "std", derive(Decode))] +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] pub struct ExtrinsicMetadata { + /// The type of the extrinsic. + pub ty: T::Type, /// Extrinsic version. pub version: u8, /// The signed extensions in the order they appear in the extrinsic. - pub signed_extensions: Vec, + pub signed_extensions: Vec>, } impl IntoPortable for ExtrinsicMetadata { @@ -88,8 +99,34 @@ impl IntoPortable for ExtrinsicMetadata { fn into_portable(self, registry: &mut Registry) -> Self::Output { ExtrinsicMetadata { + ty: registry.register_type(&self.ty), version: self.version, - signed_extensions: registry.register_types(self.signed_extensions), + signed_extensions: registry.map_into_portable(self.signed_extensions), + } + } +} + +/// Metadata of an extrinsic's signed extension. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] +pub struct SignedExtensionMetadata { + /// The unique signed extension identifier, which may be different from the type name. + pub identifier: T::String, + /// The signed extensions in the order they appear in the extrinsic. + pub ty: T::Type, +} + +impl IntoPortable for SignedExtensionMetadata { + type Output = SignedExtensionMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + SignedExtensionMetadata { + identifier: self.identifier.into_portable(registry), + ty: registry.register_type(&self.ty), } } } @@ -97,13 +134,20 @@ impl IntoPortable for ExtrinsicMetadata { /// All metadata about an runtime module. #[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] pub struct ModuleMetadata { pub name: T::String, pub storage: Option>>, pub calls: Option>>, pub event: Option>>, - // pub constants: DFnA, + pub constants: Option>>, pub errors: Vec>, + /// Define the index of the module, this index will be used for the encoding of module event, + /// call and origin variants. + pub index: u8, } impl IntoPortable for ModuleMetadata { @@ -117,7 +161,11 @@ impl IntoPortable for ModuleMetadata { .map(|storage| registry.map_into_portable(storage)), calls: self.calls.map(|calls| registry.map_into_portable(calls)), event: self.event.map(|event| registry.map_into_portable(event)), + constants: self + .constants + .map(|constant| registry.map_into_portable(constant)), errors: registry.map_into_portable(self.errors), + index: self.index, } } } @@ -125,6 +173,10 @@ impl IntoPortable for ModuleMetadata { /// All metadata of the storage. #[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] pub struct StorageMetadata { /// The common prefix used by all storage entries. pub prefix: T::String, @@ -145,6 +197,10 @@ impl IntoPortable for StorageMetadata { /// All the metadata about one storage entry. #[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] pub struct StorageEntryMetadata { pub name: T::String, pub modifier: StorageEntryModifier, @@ -191,6 +247,10 @@ pub enum StorageHasher { /// A storage entry type. #[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] pub enum StorageEntryType { Plain(T::String), Map { @@ -244,8 +304,12 @@ impl IntoPortable for StorageEntryType { } /// All the metadata about a function. -#[derive(Clone, PartialEq, Eq, Encode, Debug)] -#[cfg_attr(feature = "std", derive(Decode))] +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] pub struct FunctionMetadata { pub name: T::String, pub arguments: Vec>, @@ -265,8 +329,12 @@ impl IntoPortable for FunctionMetadata { } /// All the metadata about a function argument. -#[derive(Clone, PartialEq, Eq, Encode, Debug)] -#[cfg_attr(feature = "std", derive(Decode))] +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] pub struct FunctionArgumentMetadata { pub name: T::String, pub ty: T::Type, @@ -286,8 +354,12 @@ impl IntoPortable for FunctionArgumentMetadata { } /// All the metadata about an outer event. -#[derive(Clone, PartialEq, Eq, Encode, Debug)] -#[cfg_attr(feature = "std", derive(Decode))] +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] pub struct OuterEventMetadata { pub name: T::String, pub events: Vec>, @@ -305,8 +377,12 @@ impl IntoPortable for OuterEventMetadata { } /// Metadata about a module event. -#[derive(Clone, PartialEq, Eq, Encode, Debug)] -#[cfg_attr(feature = "std", derive(Decode))] +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] pub struct ModuleEventMetadata { pub name: T::String, pub events: Vec>, @@ -324,8 +400,12 @@ impl IntoPortable for ModuleEventMetadata { } /// All the metadata about an event. -#[derive(Clone, PartialEq, Eq, Encode, Debug)] -#[cfg_attr(feature = "std", derive(Decode))] +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] pub struct EventMetadata { pub name: T::String, pub arguments: Vec>, @@ -344,9 +424,40 @@ impl IntoPortable for EventMetadata { } } +/// All the metadata about one module constant. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] +pub struct ModuleConstantMetadata { + pub name: T::String, + pub ty: T::Type, + pub value: ByteGetter, + pub documentation: Vec, +} + +impl IntoPortable for ModuleConstantMetadata { + type Output = ModuleConstantMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + ModuleConstantMetadata { + name: self.name.into_portable(registry), + ty: registry.register_type(&self.ty), + value: self.value, + documentation: registry.map_into_portable(self.documentation), + } + } +} + /// All the metadata about a module error. #[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] pub struct ErrorMetadata { pub name: T::String, pub documentation: Vec, @@ -380,8 +491,12 @@ impl IntoPortable for ErrorMetadata { /// `pred`'s display name is `Predicate` and the display name of /// the return type is simply `bool`. Note that `Predicate` could /// simply be a type alias to `fn(i32, i32) -> Ordering`. -#[derive(Clone, PartialEq, Eq, Encode, Debug)] -#[cfg_attr(feature = "std", derive(Decode))] +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +#[cfg_attr( + feature = "std", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] pub struct TypeSpec { /// The actual type. pub ty: T::Type,