diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 6936ea6..9664663 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -74,7 +74,7 @@ jobs: with: command: check toolchain: stable - args: --manifest-path ./frame-metadata/Cargo.toml --target wasm32-unknown-unknown --no-default-features + args: --manifest-path ./frame-metadata/Cargo.toml --target wasm32-unknown-unknown --no-default-features check-features: name: Check Features @@ -104,3 +104,16 @@ jobs: command: check toolchain: stable args: --manifest-path ./frame-metadata/Cargo.toml --no-default-features --features v12 + - name: Checking v13 + uses: actions-rs/cargo@master + with: + command: check + toolchain: stable + args: --manifest-path ./frame-metadata/Cargo.toml --no-default-features --features v13 + - name: Checking all versions + uses: actions-rs/cargo@master + with: + command: check + toolchain: stable + args: --manifest-path ./frame-metadata/Cargo.toml --no-default-features --features v12,v13 + diff --git a/frame-metadata/Cargo.toml b/frame-metadata/Cargo.toml index d6aa14b..a4c1f5d 100644 --- a/frame-metadata/Cargo.toml +++ b/frame-metadata/Cargo.toml @@ -14,12 +14,16 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +cfg-if = "1.0.0" +scale-info = { git = "https://github.com/paritytech/scale-info", default-features = false, optional = true, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } [features] default = ["std", "v12"] v12 = [] +v13 = ["scale-info"] std = [ "codec/std", + "scale-info/std", "serde", ] diff --git a/frame-metadata/src/lib.rs b/frame-metadata/src/lib.rs index b3667fe..65fe1c5 100644 --- a/frame-metadata/src/lib.rs +++ b/frame-metadata/src/lib.rs @@ -19,348 +19,23 @@ #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(feature = "std")] -use codec::{Decode, Error, Input}; -use codec::{Encode, Output}; -#[cfg(feature = "std")] -use serde::Serialize; - -#[cfg(not(feature = "std"))] -extern crate alloc; -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - -#[cfg(feature = "std")] -type StringBuf = String; - -/// Current prefix of metadata -pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness - -/// On `no_std` we do not support `Decode` and thus `StringBuf` is just `&'static str`. -/// So, if someone tries to decode this stuff on `no_std`, they will get a compilation error. -#[cfg(not(feature = "std"))] -type StringBuf = &'static str; - -/// A type that decodes to a different type than it encodes. -/// The user needs to make sure that both types use the same encoding. -/// -/// For example a `&'static [ &'static str ]` can be decoded to a `Vec`. -#[derive(Clone)] -pub enum DecodeDifferent -where - B: 'static, - O: 'static, -{ - Encode(B), - Decoded(O), -} - -impl Encode for DecodeDifferent -where - B: Encode + 'static, - O: Encode + 'static, -{ - fn encode_to(&self, dest: &mut W) { - match self { - DecodeDifferent::Encode(b) => b.encode_to(dest), - DecodeDifferent::Decoded(o) => o.encode_to(dest), - } - } -} - -impl codec::EncodeLike for DecodeDifferent -where - B: Encode + 'static, - O: Encode + 'static, -{ -} - -#[cfg(feature = "std")] -impl Decode for DecodeDifferent -where - B: 'static, - O: Decode + 'static, -{ - fn decode(input: &mut I) -> Result { - ::decode(input).map(|val| DecodeDifferent::Decoded(val)) - } -} - -impl PartialEq for DecodeDifferent -where - B: Encode + Eq + PartialEq + 'static, - O: Encode + Eq + PartialEq + 'static, -{ - fn eq(&self, other: &Self) -> bool { - self.encode() == other.encode() - } -} - -impl Eq for DecodeDifferent -where - B: Encode + Eq + PartialEq + 'static, - O: Encode + Eq + PartialEq + 'static, -{ -} - -impl core::fmt::Debug for DecodeDifferent -where - B: core::fmt::Debug + Eq + 'static, - O: core::fmt::Debug + Eq + 'static, -{ - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - match self { - DecodeDifferent::Encode(b) => b.fmt(f), - DecodeDifferent::Decoded(o) => o.fmt(f), - } - } -} - -#[cfg(feature = "std")] -impl serde::Serialize for DecodeDifferent -where - B: serde::Serialize + 'static, - O: serde::Serialize + 'static, -{ - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - match self { - DecodeDifferent::Encode(b) => b.serialize(serializer), - DecodeDifferent::Decoded(o) => o.serialize(serializer), - } - } -} - -pub type DecodeDifferentArray = DecodeDifferent<&'static [B], Vec>; - -type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; - -/// All the metadata about a function. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub struct FunctionMetadata { - pub name: DecodeDifferentStr, - pub arguments: DecodeDifferentArray, - pub documentation: DecodeDifferentArray<&'static str, StringBuf>, -} - -/// All the metadata about a function argument. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub struct FunctionArgumentMetadata { - pub name: DecodeDifferentStr, - pub ty: DecodeDifferentStr, -} - -/// Newtype wrapper for support encoding functions (actual the result of the function). -#[derive(Clone, Eq)] -pub struct FnEncode(pub fn() -> E) -where - E: Encode + 'static; - -impl Encode for FnEncode { - fn encode_to(&self, dest: &mut W) { - self.0().encode_to(dest); - } -} - -impl codec::EncodeLike for FnEncode {} - -impl PartialEq for FnEncode { - fn eq(&self, other: &Self) -> bool { - self.0().eq(&other.0()) - } -} - -impl core::fmt::Debug for FnEncode { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - self.0().fmt(f) - } -} - -#[cfg(feature = "std")] -impl serde::Serialize for FnEncode { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - self.0().serialize(serializer) - } -} - -/// All the metadata about an outer event. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub struct OuterEventMetadata { - pub name: DecodeDifferentStr, - pub events: DecodeDifferentArray< - (&'static str, FnEncode<&'static [EventMetadata]>), - (StringBuf, Vec), - >, -} - -/// All the metadata about an event. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub struct EventMetadata { - pub name: DecodeDifferentStr, - pub arguments: DecodeDifferentArray<&'static str, StringBuf>, - pub documentation: DecodeDifferentArray<&'static str, StringBuf>, -} - -/// All the metadata about one storage entry. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub struct StorageEntryMetadata { - pub name: DecodeDifferentStr, - pub modifier: StorageEntryModifier, - pub ty: StorageEntryType, - pub default: ByteGetter, - pub documentation: DecodeDifferentArray<&'static str, StringBuf>, -} - -/// All the metadata about one module constant. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub struct ModuleConstantMetadata { - pub name: DecodeDifferentStr, - pub ty: DecodeDifferentStr, - pub value: ByteGetter, - pub documentation: DecodeDifferentArray<&'static str, StringBuf>, -} - -/// All the metadata about a module error. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub struct ErrorMetadata { - pub name: DecodeDifferentStr, - pub documentation: DecodeDifferentArray<&'static str, StringBuf>, -} - -/// All the metadata about errors in a module. -pub trait ModuleErrorMetadata { - fn metadata() -> &'static [ErrorMetadata]; -} - -impl ModuleErrorMetadata for &'static str { - fn metadata() -> &'static [ErrorMetadata] { - &[] +cfg_if::cfg_if! { + if #[cfg(feature = "std")] { + use codec::{Decode, Error, Input}; + use serde::Serialize; + } else { + extern crate alloc; + use alloc::vec::Vec; } } -/// A technical trait to store lazy initiated vec value as static dyn pointer. -pub trait DefaultByte: Send + Sync { - fn default_byte(&self) -> Vec; -} - -/// Wrapper over dyn pointer for accessing a cached once byte value. -#[derive(Clone)] -pub struct DefaultByteGetter(pub &'static dyn DefaultByte); - -/// Decode different for static lazy initiated byte value. -pub type ByteGetter = DecodeDifferent>; - -impl Encode for DefaultByteGetter { - fn encode_to(&self, dest: &mut W) { - self.0.default_byte().encode_to(dest) - } -} - -impl codec::EncodeLike for DefaultByteGetter {} - -impl PartialEq for DefaultByteGetter { - fn eq(&self, other: &DefaultByteGetter) -> bool { - let left = self.0.default_byte(); - let right = other.0.default_byte(); - left.eq(&right) - } -} - -impl Eq for DefaultByteGetter {} - -#[cfg(feature = "std")] -impl serde::Serialize for DefaultByteGetter { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - self.0.default_byte().serialize(serializer) - } -} - -impl core::fmt::Debug for DefaultByteGetter { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - self.0.default_byte().fmt(f) - } -} - -/// Hasher used by storage maps -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub enum StorageHasher { - Blake2_128, - Blake2_256, - Blake2_128Concat, - Twox128, - Twox256, - Twox64Concat, - Identity, -} - -/// A storage entry type. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub enum StorageEntryType { - Plain(DecodeDifferentStr), - Map { - hasher: StorageHasher, - key: DecodeDifferentStr, - value: DecodeDifferentStr, - // is_linked flag previously, unused now to keep backwards compat - unused: bool, - }, - DoubleMap { - hasher: StorageHasher, - key1: DecodeDifferentStr, - key2: DecodeDifferentStr, - value: DecodeDifferentStr, - key2_hasher: StorageHasher, - }, -} - -/// A storage entry modifier. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub enum StorageEntryModifier { - Optional, - Default, -} - -/// All metadata of the storage. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub struct StorageMetadata { - /// The common prefix used by all storage entries. - pub prefix: DecodeDifferent<&'static str, StringBuf>, - pub entries: DecodeDifferent<&'static [StorageEntryMetadata], Vec>, -} +use codec::{Encode, Output}; -/// 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 RuntimeMetadata); +#[cfg(feature = "v12")] +pub mod v12; -/// Metadata of the extrinsic used by the runtime. -#[derive(Eq, Encode, PartialEq)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub struct ExtrinsicMetadata { - /// Extrinsic version. - pub version: u8, - /// The signed extensions in the order they appear in the extrinsic. - pub signed_extensions: Vec, -} +#[cfg(feature = "v13")] +pub mod v13; /// The metadata of a runtime. /// The version ID encoded/decoded through @@ -392,13 +67,25 @@ pub enum RuntimeMetadata { V10(RuntimeMetadataDeprecated), /// Version 11 for runtime metadata. No longer used. V11(RuntimeMetadataDeprecated), - /// Version 12 for runtime metadata. + /// Version 12 for runtime metadata #[cfg(feature = "v12")] - V12(RuntimeMetadataV12), + V12(v12::RuntimeMetadataV12), + /// Version 12 for runtime metadata, as raw encoded bytes. #[cfg(not(feature = "v12"))] - V12(RuntimeMetadataDeprecated), + V12(OpaqueMetadata), + /// Version 13 for runtime metadata. + #[cfg(feature = "v13")] + V13(v13::RuntimeMetadataV13), + /// Version 13 for runtime metadata, as raw encoded bytes. + #[cfg(not(feature = "v13"))] + V13(OpaqueMetadata), } +/// Stores the encoded `RuntimeMetadata` as raw bytes. +#[derive(Encode, Eq, PartialEq)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct OpaqueMetadata(pub Vec); + /// Enum that should fail. #[derive(Eq, PartialEq)] #[cfg_attr(feature = "std", derive(Serialize, Debug))] @@ -416,49 +103,3 @@ impl Decode for RuntimeMetadataDeprecated { Err("Decoding is not supported".into()) } } - -/// The metadata of a runtime. -#[derive(Eq, Encode, PartialEq)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -#[cfg(feature = "v12")] -pub struct RuntimeMetadataV12 { - /// Metadata of all the modules. - pub modules: DecodeDifferentArray, - /// Metadata of the extrinsic. - pub extrinsic: ExtrinsicMetadata, -} - -/// The latest version of the metadata. -#[cfg(feature = "v12")] -pub type RuntimeMetadataLastVersion = RuntimeMetadataV12; - -#[cfg(feature = "v12")] -impl Into for RuntimeMetadataLastVersion { - fn into(self) -> RuntimeMetadataPrefixed { - RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V12(self)) - } -} - -/// All metadata about an runtime module. -#[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] -pub struct ModuleMetadata { - pub name: DecodeDifferentStr, - pub storage: Option, StorageMetadata>>, - pub calls: ODFnA, - pub event: ODFnA, - pub constants: DFnA, - pub errors: DFnA, - /// Define the index of the module, this index will be used for the encoding of module event, - /// call and origin variants. - pub index: u8, -} - -type ODFnA = Option>; -type DFnA = DecodeDifferent, Vec>; - -impl Into> for RuntimeMetadataPrefixed { - fn into(self) -> Vec { - self.encode() - } -} diff --git a/frame-metadata/src/v12.rs b/frame-metadata/src/v12.rs new file mode 100644 index 0000000..99562de --- /dev/null +++ b/frame-metadata/src/v12.rs @@ -0,0 +1,397 @@ +// This file is part of Substrate. + +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Decodable variant of the RuntimeMetadata. + +use codec::{Encode, Output}; + +cfg_if::cfg_if! { + if #[cfg(feature = "std")] { + use codec::{Decode, Error, Input}; + use serde::Serialize; + + type StringBuf = String; + } else { + extern crate alloc; + use alloc::vec::Vec; + + /// On `no_std` we do not support `Decode` and thus `StringBuf` is just `&'static str`. + /// So, if someone tries to decode this stuff on `no_std`, they will get a compilation error. + type StringBuf = &'static str; + } +} + +/// Current prefix of metadata +pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness + +/// A type that decodes to a different type than it encodes. +/// The user needs to make sure that both types use the same encoding. +/// +/// For example a `&'static [ &'static str ]` can be decoded to a `Vec`. +#[derive(Clone)] +pub enum DecodeDifferent +where + B: 'static, + O: 'static, +{ + Encode(B), + Decoded(O), +} + +impl Encode for DecodeDifferent +where + B: Encode + 'static, + O: Encode + 'static, +{ + fn encode_to(&self, dest: &mut W) { + match self { + DecodeDifferent::Encode(b) => b.encode_to(dest), + DecodeDifferent::Decoded(o) => o.encode_to(dest), + } + } +} + +impl codec::EncodeLike for DecodeDifferent +where + B: Encode + 'static, + O: Encode + 'static, +{ +} + +#[cfg(feature = "std")] +impl Decode for DecodeDifferent +where + B: 'static, + O: Decode + 'static, +{ + fn decode(input: &mut I) -> Result { + ::decode(input).map(|val| DecodeDifferent::Decoded(val)) + } +} + +impl PartialEq for DecodeDifferent +where + B: Encode + Eq + PartialEq + 'static, + O: Encode + Eq + PartialEq + 'static, +{ + fn eq(&self, other: &Self) -> bool { + self.encode() == other.encode() + } +} + +impl Eq for DecodeDifferent +where + B: Encode + Eq + PartialEq + 'static, + O: Encode + Eq + PartialEq + 'static, +{ +} + +impl core::fmt::Debug for DecodeDifferent +where + B: core::fmt::Debug + Eq + 'static, + O: core::fmt::Debug + Eq + 'static, +{ + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + match self { + DecodeDifferent::Encode(b) => b.fmt(f), + DecodeDifferent::Decoded(o) => o.fmt(f), + } + } +} + +#[cfg(feature = "std")] +impl serde::Serialize for DecodeDifferent +where + B: serde::Serialize + 'static, + O: serde::Serialize + 'static, +{ + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + match self { + DecodeDifferent::Encode(b) => b.serialize(serializer), + DecodeDifferent::Decoded(o) => o.serialize(serializer), + } + } +} + +pub type DecodeDifferentArray = DecodeDifferent<&'static [B], Vec>; + +type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>; + +/// All the metadata about a function. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct FunctionMetadata { + pub name: DecodeDifferentStr, + pub arguments: DecodeDifferentArray, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about a function argument. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct FunctionArgumentMetadata { + pub name: DecodeDifferentStr, + pub ty: DecodeDifferentStr, +} + +/// Newtype wrapper for support encoding functions (actual the result of the function). +#[derive(Clone, Eq)] +pub struct FnEncode(pub fn() -> E) +where + E: Encode + 'static; + +impl Encode for FnEncode { + fn encode_to(&self, dest: &mut W) { + self.0().encode_to(dest); + } +} + +impl codec::EncodeLike for FnEncode {} + +impl PartialEq for FnEncode { + fn eq(&self, other: &Self) -> bool { + self.0().eq(&other.0()) + } +} + +impl core::fmt::Debug for FnEncode { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + self.0().fmt(f) + } +} + +#[cfg(feature = "std")] +impl serde::Serialize for FnEncode { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.0().serialize(serializer) + } +} + +/// All the metadata about an outer event. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct OuterEventMetadata { + pub name: DecodeDifferentStr, + pub events: DecodeDifferentArray< + (&'static str, FnEncode<&'static [EventMetadata]>), + (StringBuf, Vec), + >, +} + +/// All the metadata about an event. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct EventMetadata { + pub name: DecodeDifferentStr, + pub arguments: DecodeDifferentArray<&'static str, StringBuf>, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about one storage entry. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct StorageEntryMetadata { + pub name: DecodeDifferentStr, + pub modifier: StorageEntryModifier, + pub ty: StorageEntryType, + pub default: ByteGetter, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about one module constant. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct ModuleConstantMetadata { + pub name: DecodeDifferentStr, + pub ty: DecodeDifferentStr, + pub value: ByteGetter, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about a module error. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct ErrorMetadata { + pub name: DecodeDifferentStr, + pub documentation: DecodeDifferentArray<&'static str, StringBuf>, +} + +/// All the metadata about errors in a module. +pub trait ModuleErrorMetadata { + fn metadata() -> &'static [ErrorMetadata]; +} + +impl ModuleErrorMetadata for &'static str { + fn metadata() -> &'static [ErrorMetadata] { + &[] + } +} + +/// A technical trait to store lazy initiated vec value as static dyn pointer. +pub trait DefaultByte: Send + Sync { + fn default_byte(&self) -> Vec; +} + +/// Wrapper over dyn pointer for accessing a cached once byte value. +#[derive(Clone)] +pub struct DefaultByteGetter(pub &'static dyn DefaultByte); + +/// Decode different for static lazy initiated byte value. +pub type ByteGetter = DecodeDifferent>; + +impl Encode for DefaultByteGetter { + fn encode_to(&self, dest: &mut W) { + self.0.default_byte().encode_to(dest) + } +} + +impl codec::EncodeLike for DefaultByteGetter {} + +impl PartialEq for DefaultByteGetter { + fn eq(&self, other: &DefaultByteGetter) -> bool { + let left = self.0.default_byte(); + let right = other.0.default_byte(); + left.eq(&right) + } +} + +impl Eq for DefaultByteGetter {} + +#[cfg(feature = "std")] +impl serde::Serialize for DefaultByteGetter { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.0.default_byte().serialize(serializer) + } +} + +impl core::fmt::Debug for DefaultByteGetter { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + self.0.default_byte().fmt(f) + } +} + +/// Hasher used by storage maps +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub enum StorageHasher { + Blake2_128, + Blake2_256, + Blake2_128Concat, + Twox128, + Twox256, + Twox64Concat, + Identity, +} + +/// A storage entry type. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub enum StorageEntryType { + Plain(DecodeDifferentStr), + Map { + hasher: StorageHasher, + key: DecodeDifferentStr, + value: DecodeDifferentStr, + // is_linked flag previously, unused now to keep backwards compat + unused: bool, + }, + DoubleMap { + hasher: StorageHasher, + key1: DecodeDifferentStr, + key2: DecodeDifferentStr, + value: DecodeDifferentStr, + key2_hasher: StorageHasher, + }, +} + +/// A storage entry modifier. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub enum StorageEntryModifier { + Optional, + Default, +} + +/// All metadata of the storage. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct StorageMetadata { + /// The common prefix used by all storage entries. + pub prefix: DecodeDifferent<&'static str, StringBuf>, + pub entries: DecodeDifferent<&'static [StorageEntryMetadata], 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); + +/// Metadata of the extrinsic used by the runtime. +#[derive(Eq, Encode, PartialEq)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct ExtrinsicMetadata { + /// Extrinsic version. + pub version: u8, + /// The signed extensions in the order they appear in the extrinsic. + pub signed_extensions: Vec, +} + +/// The metadata of a runtime. +#[derive(Eq, Encode, PartialEq)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct RuntimeMetadataV12 { + /// Metadata of all the modules. + pub modules: DecodeDifferentArray, + /// Metadata of the extrinsic. + pub extrinsic: ExtrinsicMetadata, +} + +/// The latest version of the metadata. +pub type RuntimeMetadataLastVersion = RuntimeMetadataV12; + +/// All metadata about an runtime module. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct ModuleMetadata { + pub name: DecodeDifferentStr, + pub storage: Option, StorageMetadata>>, + pub calls: ODFnA, + pub event: ODFnA, + pub constants: DFnA, + pub errors: DFnA, + /// Define the index of the module, this index will be used for the encoding of module event, + /// call and origin variants. + pub index: u8, +} + +type ODFnA = Option>; +type DFnA = DecodeDifferent, Vec>; + +impl Into> for RuntimeMetadataPrefixed { + fn into(self) -> Vec { + self.encode() + } +} diff --git a/frame-metadata/src/v13.rs b/frame-metadata/src/v13.rs new file mode 100644 index 0000000..b5b744e --- /dev/null +++ b/frame-metadata/src/v13.rs @@ -0,0 +1,414 @@ +// This file is part of Substrate. + +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +cfg_if::cfg_if! { + if #[cfg(feature = "std")] { + use codec::{Decode, Error, Input}; + use serde::Serialize; + } +} + +use codec::Encode; +use scale_info::prelude::vec::Vec; +use scale_info::{ + form::{Form, FormString, MetaForm, PortableForm}, + meta_type, IntoPortable, PortableRegistry, Registry, TypeInfo, +}; + +/// Current prefix of metadata +pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness + +/// Type alias placeholder for `ByteGetter` equivalent. todo: [AJ] figure out what to do here +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); + +pub type RuntimeMetadataLastVersion = RuntimeMetadataV13; + +impl From for RuntimeMetadataPrefixed { + fn from(metadata: RuntimeMetadataLastVersion) -> RuntimeMetadataPrefixed { + RuntimeMetadataPrefixed(META_RESERVED, super::RuntimeMetadata::V13(metadata)) + } +} + +/// The metadata of a runtime. +// 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))] +pub struct RuntimeMetadataV13 { + pub types: PortableRegistry, + /// Metadata of all the modules. + pub modules: Vec>, + /// Metadata of the extrinsic. + pub extrinsic: ExtrinsicMetadata, +} + +impl RuntimeMetadataV13 { + pub fn new(modules: Vec, extrinsic: ExtrinsicMetadata) -> Self { + let mut registry = Registry::new(); + let modules = registry.map_into_portable(modules); + let extrinsic = extrinsic.into_portable(&mut registry); + Self { + types: registry.into(), + modules, + extrinsic, + } + } +} + +/// Metadata of the extrinsic used by the runtime. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "std", derive(Decode))] +pub struct ExtrinsicMetadata { + /// Extrinsic version. + pub version: u8, + /// The signed extensions in the order they appear in the extrinsic. + pub signed_extensions: Vec, +} + +impl IntoPortable for ExtrinsicMetadata { + type Output = ExtrinsicMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + ExtrinsicMetadata { + version: self.version, + signed_extensions: registry.register_types(self.signed_extensions), + } + } +} + +/// All metadata about an runtime module. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct ModuleMetadata { + pub name: T::String, + pub storage: Option>>, + pub calls: Option>>, + pub event: Option>>, + // pub constants: DFnA, + pub errors: Vec>, +} + +impl IntoPortable for ModuleMetadata { + type Output = ModuleMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + ModuleMetadata { + name: self.name.into_portable(registry), + storage: self + .storage + .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)), + errors: registry.map_into_portable(self.errors), + } + } +} + +/// All metadata of the storage. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct StorageMetadata { + /// The common prefix used by all storage entries. + pub prefix: T::String, + pub entries: Vec>, +} + +impl IntoPortable for StorageMetadata { + type Output = StorageMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + StorageMetadata { + prefix: self.prefix.into_portable(registry), + entries: registry.map_into_portable(self.entries), + } + } +} + +/// All the metadata about one storage entry. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct StorageEntryMetadata { + pub name: T::String, + pub modifier: StorageEntryModifier, + pub ty: StorageEntryType, + pub default: ByteGetter, + pub documentation: Vec, +} + +impl IntoPortable for StorageEntryMetadata { + type Output = StorageEntryMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + StorageEntryMetadata { + name: self.name.into_portable(registry), + modifier: self.modifier, + ty: self.ty.into_portable(registry), + default: self.default, + documentation: registry.map_into_portable(self.documentation), + } + } +} + +/// A storage entry modifier. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub enum StorageEntryModifier { + Optional, + Default, +} + +/// Hasher used by storage maps +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub enum StorageHasher { + Blake2_128, + Blake2_256, + Blake2_128Concat, + Twox128, + Twox256, + Twox64Concat, + Identity, +} + +/// A storage entry type. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub enum StorageEntryType { + Plain(T::String), + Map { + hasher: StorageHasher, + key: T::String, + value: T::String, + // is_linked flag previously, unused now to keep backwards compat + unused: bool, + }, + DoubleMap { + hasher: StorageHasher, + key1: T::String, + key2: T::String, + value: T::String, + key2_hasher: StorageHasher, + }, +} + +impl IntoPortable for StorageEntryType { + type Output = StorageEntryType; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + match self { + Self::Plain(plain) => StorageEntryType::Plain(plain.into_portable(registry)), + Self::Map { + hasher, + key, + value, + unused, + } => StorageEntryType::Map { + hasher, + key: key.into_portable(registry), + value: value.into_portable(registry), + unused, + }, + Self::DoubleMap { + hasher, + key1, + key2, + value, + key2_hasher, + } => StorageEntryType::DoubleMap { + hasher, + key1: key1.into_portable(registry), + key2: key2.into_portable(registry), + value: value.into_portable(registry), + key2_hasher, + }, + } + } +} + +/// All the metadata about a function. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "std", derive(Decode))] +pub struct FunctionMetadata { + pub name: T::String, + pub arguments: Vec>, + pub documentation: Vec, +} + +impl IntoPortable for FunctionMetadata { + type Output = FunctionMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + FunctionMetadata { + name: self.name.into_portable(registry), + arguments: registry.map_into_portable(self.arguments), + documentation: registry.map_into_portable(self.documentation), + } + } +} + +/// All the metadata about a function argument. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "std", derive(Decode))] +pub struct FunctionArgumentMetadata { + pub name: T::String, + pub ty: T::Type, + pub is_compact: bool, +} + +impl IntoPortable for FunctionArgumentMetadata { + type Output = FunctionArgumentMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + FunctionArgumentMetadata { + name: self.name.into_portable(registry), + ty: registry.register_type(&self.ty), + is_compact: self.is_compact, + } + } +} + +/// All the metadata about an outer event. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "std", derive(Decode))] +pub struct OuterEventMetadata { + pub name: T::String, + pub events: Vec>, +} + +impl IntoPortable for OuterEventMetadata { + type Output = OuterEventMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + OuterEventMetadata { + name: self.name.into_portable(registry), + events: registry.map_into_portable(self.events), + } + } +} + +/// Metadata about a module event. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "std", derive(Decode))] +pub struct ModuleEventMetadata { + pub name: T::String, + pub events: Vec>, +} + +impl IntoPortable for ModuleEventMetadata { + type Output = ModuleEventMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + ModuleEventMetadata { + name: self.name.into_portable(registry), + events: registry.map_into_portable(self.events), + } + } +} + +/// All the metadata about an event. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "std", derive(Decode))] +pub struct EventMetadata { + pub name: T::String, + pub arguments: Vec>, + pub documentation: Vec, +} + +impl IntoPortable for EventMetadata { + type Output = EventMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + EventMetadata { + name: self.name.into_portable(registry), + arguments: registry.map_into_portable(self.arguments), + 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))] +pub struct ErrorMetadata { + pub name: T::String, + pub documentation: Vec, +} + +impl IntoPortable for ErrorMetadata { + type Output = ErrorMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + ErrorMetadata { + name: self.name.into_portable(registry), + documentation: registry.map_into_portable(self.documentation), + } + } +} + +/// A type specification. +/// +/// This contains the actual type as well as an optional compile-time +/// known displayed representation of the type. This is useful for cases +/// where the type is used through a type alias in order to provide +/// information about the alias name. +/// +/// # Examples +/// +/// Consider the following Rust function: +/// ```no_compile +/// fn is_sorted(input: &[i32], pred: Predicate) -> bool; +/// ``` +/// In this above example `input` would have no displayable name, +/// `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))] +pub struct TypeSpec { + /// The actual type. + pub ty: T::Type, + /// The compile-time known displayed representation of the type. + pub name: T::String, +} + +impl IntoPortable for TypeSpec { + type Output = TypeSpec; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + TypeSpec { + ty: registry.register_type(&self.ty), + name: self.name.into_portable(registry), + } + } +} + +impl TypeSpec { + /// Creates a new type specification without a display name. + pub fn new(name: &'static str) -> Self + where + T: TypeInfo + 'static, + { + Self { + ty: meta_type::(), + name, + } + } +}