diff --git a/frame-metadata/Cargo.toml b/frame-metadata/Cargo.toml index 7eae1e8..2030da2 100644 --- a/frame-metadata/Cargo.toml +++ b/frame-metadata/Cargo.toml @@ -20,8 +20,13 @@ serde = { version = "1.0.101", optional = true, features = ["derive"] } [features] default = ["std", "v14"] +v8 = [] +v9 = [] +v10 = [] +v11 = [] v12 = [] v13 = [] +legacy = ["v13", "v12", "v11", "v10", "v9", "v8"] v14 = ["scale-info"] std = [ "codec/std", diff --git a/frame-metadata/src/lib.rs b/frame-metadata/src/lib.rs index a8e93b5..e743824 100644 --- a/frame-metadata/src/lib.rs +++ b/frame-metadata/src/lib.rs @@ -34,9 +34,29 @@ cfg_if::cfg_if! { use codec::{Encode, Output}; -#[cfg(any(feature = "v12", feature = "v13"))] +#[cfg(any( + feature = "v13", + feature = "v12", + feature = "v11", + feature = "v10", + feature = "v9", + feature = "v8", + feature = "legacy" +))] pub mod decode_different; +#[cfg(feature = "v8")] +pub mod v8; + +#[cfg(feature = "v9")] +pub mod v9; + +#[cfg(feature = "v10")] +pub mod v10; + +#[cfg(feature = "v11")] +pub mod v11; + #[cfg(feature = "v12")] pub mod v12; @@ -85,22 +105,38 @@ pub enum RuntimeMetadata { V6(RuntimeMetadataDeprecated), /// Version 7 for runtime metadata. No longer used. V7(RuntimeMetadataDeprecated), - /// Version 8 for runtime metadata. No longer used. - V8(RuntimeMetadataDeprecated), - /// Version 9 for runtime metadata. No longer used. - V9(RuntimeMetadataDeprecated), - /// Version 10 for runtime metadata. No longer used. - V10(RuntimeMetadataDeprecated), - /// Version 11 for runtime metadata. No longer used. - V11(RuntimeMetadataDeprecated), + /// Version 8 for runtime metadata. + #[cfg(any(feature = "v8", feature = "legacy"))] + V8(v8::RuntimeMetadataV8), + /// Version 8 for runtime metadata, as raw encoded bytes. + #[cfg(not(feature = "v8"))] + V8(OpaqueMetadata), + /// Version 9 for runtime metadata. + #[cfg(any(feature = "v9", feature = "legacy"))] + V9(v9::RuntimeMetadataV9), + /// Version 9 for runtime metadata, as raw encoded bytes. + #[cfg(not(feature = "v9"))] + V9(OpaqueMetadata), + /// Version 10 for runtime metadata. + #[cfg(any(feature = "v10", feature = "legacy"))] + V10(v10::RuntimeMetadataV10), + /// Version 10 for runtime metadata, as raw encoded bytes. + #[cfg(not(feature = "v10"))] + V10(OpaqueMetadata), + /// Version 11 for runtime metadata. + #[cfg(any(feature = "v11", feature = "legacy"))] + V11(v11::RuntimeMetadataV11), + /// Version 11 for runtime metadata, as raw encoded bytes. + #[cfg(not(feature = "v11"))] + V11(OpaqueMetadata), /// Version 12 for runtime metadata - #[cfg(feature = "v12")] + #[cfg(any(feature = "v12", feature = "legacy"))] 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")] + #[cfg(any(feature = "v13", feature = "legacy"))] V13(v13::RuntimeMetadataV13), /// Version 13 for runtime metadata, as raw encoded bytes. #[cfg(not(feature = "v13"))] @@ -135,3 +171,55 @@ impl Decode for RuntimeMetadataDeprecated { Err("Decoding is not supported".into()) } } + +#[cfg(test)] +mod test { + use super::*; + use std::fs; + + fn load_metadata(version: u32) -> Vec { + fs::read(format!("./test_data/ksm_metadata_v{}.bin", version)).unwrap() + } + + #[test] + fn should_decode_metadatav9() { + let meta: RuntimeMetadataPrefixed = + Decode::decode(&mut load_metadata(9).as_slice()).unwrap(); + assert!(matches!(meta.1, RuntimeMetadata::V9(_))); + } + + #[test] + fn should_decode_metadatav10() { + let meta: RuntimeMetadataPrefixed = + Decode::decode(&mut load_metadata(10).as_slice()).unwrap(); + assert!(matches!(meta.1, RuntimeMetadata::V10(_))); + } + + #[test] + fn should_decode_metadatav11() { + let meta: RuntimeMetadataPrefixed = + Decode::decode(&mut load_metadata(11).as_slice()).unwrap(); + assert!(matches!(meta.1, RuntimeMetadata::V11(_))); + } + + #[test] + fn should_decode_metadatav12() { + let meta: RuntimeMetadataPrefixed = + Decode::decode(&mut load_metadata(12).as_slice()).unwrap(); + assert!(matches!(meta.1, RuntimeMetadata::V12(_))); + } + + #[test] + fn should_decode_metadatav13() { + let meta: RuntimeMetadataPrefixed = + Decode::decode(&mut load_metadata(13).as_slice()).unwrap(); + assert!(matches!(meta.1, RuntimeMetadata::V13(_))); + } + + #[test] + fn should_decode_metadatav14() { + let meta: RuntimeMetadataPrefixed = + Decode::decode(&mut load_metadata(14).as_slice()).unwrap(); + assert!(matches!(meta.1, RuntimeMetadata::V14(_))); + } +} diff --git a/frame-metadata/src/v10.rs b/frame-metadata/src/v10.rs new file mode 100644 index 0000000..77b1fbf --- /dev/null +++ b/frame-metadata/src/v10.rs @@ -0,0 +1,235 @@ +// 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. + +//! Metadata Version 10. Networks like Kusama contain this version on-chain. +//! Chains old enough to contain this metadata need a way to decode it. + +use crate::decode_different::*; +use codec::{Encode, Output}; + +cfg_if::cfg_if! { + if #[cfg(feature = "std")] { + use codec::Decode; + 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; + } +} + +/// Curent prefix of metadata +pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness + +/// 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, +} + +/// 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, +} + +/// 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: 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>, +} + +/// The metadata of a runtime. +#[derive(Eq, Encode, PartialEq)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct RuntimeMetadataV10 { + pub modules: DecodeDifferentArray, +} + +/// 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, +} + +type ODFnA = Option>; +type DFnA = DecodeDifferent, Vec>; diff --git a/frame-metadata/src/v11.rs b/frame-metadata/src/v11.rs new file mode 100644 index 0000000..cf26f02 --- /dev/null +++ b/frame-metadata/src/v11.rs @@ -0,0 +1,250 @@ +// 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. + +//! Metadata Version 11. Networks like Kusama contain this version on-chain. +//! Chains old enough to contain this metadata need a way to decode it. + +use crate::decode_different::*; +use codec::{Encode, Output}; + +cfg_if::cfg_if! { + if #[cfg(feature = "std")] { + use codec::Decode; + 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 + +/// 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, +} + +/// 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 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 RuntimeMetadataV11 { + /// Metadata of all the modules. + pub modules: DecodeDifferentArray, + /// Metadata of the extrinsic. + pub extrinsic: ExtrinsicMetadata, +} + +/// 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, +} + +type ODFnA = Option>; +type DFnA = DecodeDifferent, Vec>; diff --git a/frame-metadata/src/v12.rs b/frame-metadata/src/v12.rs index be90094..19dfa85 100644 --- a/frame-metadata/src/v12.rs +++ b/frame-metadata/src/v12.rs @@ -15,6 +15,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! Metadata Version 12. Networks like Kusama contain this version on-chain. +//! Chains old enough to contain this metadata need a way to decode it. + use crate::decode_different::*; use codec::{Encode, Output}; diff --git a/frame-metadata/src/v13.rs b/frame-metadata/src/v13.rs index 800f1a3..3f6c017 100644 --- a/frame-metadata/src/v13.rs +++ b/frame-metadata/src/v13.rs @@ -15,6 +15,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! Metadata Version 13. Networks like Kusama contain this version on-chain. +//! Chains old enough to contain this metadata need a way to decode it. + use crate::decode_different::*; use codec::{Encode, Output}; diff --git a/frame-metadata/src/v8.rs b/frame-metadata/src/v8.rs new file mode 100644 index 0000000..902c8ef --- /dev/null +++ b/frame-metadata/src/v8.rs @@ -0,0 +1,237 @@ +// 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. + +//! Metadata Version 8. Chains old enough to contain this metadata need a way to decode it. + +use crate::decode_different::*; +use codec::{Encode, Output}; + +cfg_if::cfg_if! { + if #[cfg(feature = "std")] { + use codec::Decode; + 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; + } +} + +/// Curent prefix of metadata +pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness + +/// All the metadata about a function. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +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, Debug, Serialize))] +pub struct FunctionArgumentMetadata { + pub name: DecodeDifferentStr, + pub ty: DecodeDifferentStr, +} + +/// All the metadata about an outer event. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +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, Debug, Serialize))] +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, Debug, Serialize))] +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, Debug, Serialize))] +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, Debug, Serialize))] +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) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Debug for DefaultByteGetter { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + self.0.default_byte().fmt(f) + } +} + +/// Hasher used by storage maps +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub enum StorageHasher { + Blake2_128, + Blake2_256, + Twox128, + Twox256, + Twox64Concat, +} + +/// A storage entry type. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub enum StorageEntryType { + Plain(DecodeDifferentStr), + Map { + hasher: StorageHasher, + key: DecodeDifferentStr, + value: DecodeDifferentStr, + is_linked: 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, Debug, Serialize))] +pub enum StorageEntryModifier { + Optional, + Default, +} + +/// All metadata of the storage. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct StorageMetadata { + /// The common prefix used by all storage entries. + pub prefix: DecodeDifferent<&'static str, StringBuf>, + pub entries: DecodeDifferent<&'static [StorageEntryMetadata], Vec>, +} + +/// The metadata of a runtime. +#[derive(Eq, Encode, PartialEq)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct RuntimeMetadataV8 { + pub modules: DecodeDifferentArray, +} + +/// The latest version of the metadata. +pub type RuntimeMetadataLastVersion = RuntimeMetadataV8; + +/// All metadata about an runtime module. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct ModuleMetadata { + pub name: DecodeDifferentStr, + pub storage: Option, StorageMetadata>>, + pub calls: ODFnA, + pub event: ODFnA, + pub constants: DFnA, + pub errors: DFnA, +} + +type ODFnA = Option>; +type DFnA = DecodeDifferent, Vec>; diff --git a/frame-metadata/src/v9.rs b/frame-metadata/src/v9.rs new file mode 100644 index 0000000..77a6b4f --- /dev/null +++ b/frame-metadata/src/v9.rs @@ -0,0 +1,235 @@ +// 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. + +//! Metadata Version 9. Networks like/as old as Kusama start here. +//! Chains old enough to contain this metadata need a way to decode it. + +use crate::decode_different::*; +use codec::{Encode, Output}; + +cfg_if::cfg_if! { + if #[cfg(feature = "std")] { + use codec::Decode; + 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; + } +} + +/// Curent prefix of metadata +pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness + +/// 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, +} + +/// All the metadata about an outer event. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +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, +} + +/// 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: 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>, +} + +/// The metadata of a runtime. +#[derive(Eq, Encode, PartialEq)] +#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))] +pub struct RuntimeMetadataV9 { + pub modules: DecodeDifferentArray, +} + +/// 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, +} + +type ODFnA = Option>; +type DFnA = DecodeDifferent, Vec>; diff --git a/frame-metadata/test_data/ksm_metadata_v10.bin b/frame-metadata/test_data/ksm_metadata_v10.bin new file mode 100644 index 0000000..04dae28 Binary files /dev/null and b/frame-metadata/test_data/ksm_metadata_v10.bin differ diff --git a/frame-metadata/test_data/ksm_metadata_v11.bin b/frame-metadata/test_data/ksm_metadata_v11.bin new file mode 100644 index 0000000..4039943 Binary files /dev/null and b/frame-metadata/test_data/ksm_metadata_v11.bin differ diff --git a/frame-metadata/test_data/ksm_metadata_v12.bin b/frame-metadata/test_data/ksm_metadata_v12.bin new file mode 100644 index 0000000..1074a40 Binary files /dev/null and b/frame-metadata/test_data/ksm_metadata_v12.bin differ diff --git a/frame-metadata/test_data/ksm_metadata_v13.bin b/frame-metadata/test_data/ksm_metadata_v13.bin new file mode 100644 index 0000000..8c7ea87 Binary files /dev/null and b/frame-metadata/test_data/ksm_metadata_v13.bin differ diff --git a/frame-metadata/test_data/ksm_metadata_v14.bin b/frame-metadata/test_data/ksm_metadata_v14.bin new file mode 100644 index 0000000..7c214ee Binary files /dev/null and b/frame-metadata/test_data/ksm_metadata_v14.bin differ diff --git a/frame-metadata/test_data/ksm_metadata_v9.bin b/frame-metadata/test_data/ksm_metadata_v9.bin new file mode 100644 index 0000000..f287c52 Binary files /dev/null and b/frame-metadata/test_data/ksm_metadata_v9.bin differ