diff --git a/frame-metadata/Cargo.toml b/frame-metadata/Cargo.toml index 31155e5..28711e7 100644 --- a/frame-metadata/Cargo.toml +++ b/frame-metadata/Cargo.toml @@ -28,6 +28,7 @@ v12 = [] v13 = [] legacy = ["v13", "v12", "v11", "v10", "v9", "v8"] v14 = ["scale-info"] +v15-unstable = ["scale-info"] # Serde support without relying on std features serde_full = [ diff --git a/frame-metadata/src/decode_different.rs b/frame-metadata/src/decode_different.rs index aeaf7eb..0c13254 100644 --- a/frame-metadata/src/decode_different.rs +++ b/frame-metadata/src/decode_different.rs @@ -1,6 +1,4 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame-metadata/src/lib.rs b/frame-metadata/src/lib.rs index 3e51be6..d884eb2 100644 --- a/frame-metadata/src/lib.rs +++ b/frame-metadata/src/lib.rs @@ -1,6 +1,4 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); @@ -89,12 +87,19 @@ pub mod v13; #[cfg(feature = "v14")] pub mod v14; +/// Metadata v15 +#[cfg(feature = "v15-unstable")] +pub mod v15; + // Reexport all the types from the latest version. // // When a new version becomes available, update this. #[cfg(feature = "v14")] pub use self::v14::*; +/// Metadata prefix. +pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warning for endianness. + /// Metadata prefixed by a u32 for reserved usage #[derive(Eq, Encode, PartialEq, Debug)] #[cfg_attr(feature = "decode", derive(Decode))] @@ -172,6 +177,12 @@ pub enum RuntimeMetadata { /// Version 14 for runtime metadata, as raw encoded bytes. #[cfg(not(feature = "v14"))] V14(OpaqueMetadata), + /// Version 15 for runtime metadata. + #[cfg(feature = "v15-unstable")] + V15(v15::RuntimeMetadataV15), + /// Version 15 for runtime metadata, as raw encoded bytes. + #[cfg(not(feature = "v15-unstable"))] + V15(OpaqueMetadata), } impl RuntimeMetadata { @@ -193,6 +204,7 @@ impl RuntimeMetadata { RuntimeMetadata::V12(_) => 12, RuntimeMetadata::V13(_) => 13, RuntimeMetadata::V14(_) => 14, + RuntimeMetadata::V15(_) => 15, } } } diff --git a/frame-metadata/src/v10.rs b/frame-metadata/src/v10.rs index 16c2b24..9306c9a 100644 --- a/frame-metadata/src/v10.rs +++ b/frame-metadata/src/v10.rs @@ -1,6 +1,4 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame-metadata/src/v11.rs b/frame-metadata/src/v11.rs index 986f9c7..077f07d 100644 --- a/frame-metadata/src/v11.rs +++ b/frame-metadata/src/v11.rs @@ -1,6 +1,4 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame-metadata/src/v12.rs b/frame-metadata/src/v12.rs index 2e2dd23..63d7523 100644 --- a/frame-metadata/src/v12.rs +++ b/frame-metadata/src/v12.rs @@ -1,6 +1,4 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame-metadata/src/v14.rs b/frame-metadata/src/v14.rs index 2334931..d4ef844 100644 --- a/frame-metadata/src/v14.rs +++ b/frame-metadata/src/v14.rs @@ -1,6 +1,4 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame-metadata/src/v15.rs b/frame-metadata/src/v15.rs new file mode 100644 index 0000000..4f6f823 --- /dev/null +++ b/frame-metadata/src/v15.rs @@ -0,0 +1,516 @@ +// Copyright (C) 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(feature = "decode")] +use codec::Decode; +#[cfg(feature = "serde_full")] +use serde::Serialize; + +use super::{RuntimeMetadataPrefixed, META_RESERVED}; +use codec::Encode; +use scale_info::prelude::vec::Vec; +use scale_info::{ + form::{Form, MetaForm, PortableForm}, + IntoPortable, MetaType, PortableRegistry, Registry, +}; + +/// Latest runtime metadata +pub type RuntimeMetadataLastVersion = RuntimeMetadataV15; + +impl From for super::RuntimeMetadataPrefixed { + fn from(metadata: RuntimeMetadataLastVersion) -> RuntimeMetadataPrefixed { + RuntimeMetadataPrefixed(META_RESERVED, super::RuntimeMetadata::V15(metadata)) + } +} + +/// The metadata of a runtime. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +pub struct RuntimeMetadataV15 { + /// Type registry containing all types used in the metadata. + pub types: PortableRegistry, + /// Metadata of all the pallets. + pub pallets: Vec>, + /// Metadata of the extrinsic. + pub extrinsic: ExtrinsicMetadata, + /// The type of the `Runtime`. + pub ty: ::Type, + /// Metadata of the Runtime API. + pub apis: Vec>, +} + +impl RuntimeMetadataV15 { + /// Create a new instance of [`RuntimeMetadataV15`]. + pub fn new( + pallets: Vec, + extrinsic: ExtrinsicMetadata, + runtime_type: MetaType, + apis: Vec, + ) -> Self { + let mut registry = Registry::new(); + let pallets = registry.map_into_portable(pallets); + let extrinsic = extrinsic.into_portable(&mut registry); + let ty = registry.register_type(&runtime_type); + let apis = registry.map_into_portable(apis); + Self { + types: registry.into(), + pallets, + extrinsic, + ty, + apis, + } + } +} + +/// Metadata of a runtime trait. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +#[cfg_attr( + feature = "serde_full", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] +pub struct RuntimeApiMetadata { + /// Trait name. + pub name: T::String, + /// Trait methods. + pub methods: Vec>, + /// Trait documentation. + pub docs: Vec, +} + +impl IntoPortable for RuntimeApiMetadata { + type Output = RuntimeApiMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + RuntimeApiMetadata { + name: self.name.into_portable(registry), + methods: registry.map_into_portable(self.methods), + docs: registry.map_into_portable(self.docs), + } + } +} + +/// Metadata of a runtime method. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +#[cfg_attr( + feature = "serde_full", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] +pub struct RuntimeApiMethodMetadata { + /// Method name. + pub name: T::String, + /// Method parameters. + pub inputs: Vec>, + /// Method output. + pub output: T::Type, + /// Method documentation. + pub docs: Vec, +} + +impl IntoPortable for RuntimeApiMethodMetadata { + type Output = RuntimeApiMethodMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + RuntimeApiMethodMetadata { + name: self.name.into_portable(registry), + inputs: registry.map_into_portable(self.inputs), + output: registry.register_type(&self.output), + docs: registry.map_into_portable(self.docs), + } + } +} + +/// Metadata of a runtime method parameter. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +#[cfg_attr( + feature = "serde_full", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] +pub struct RuntimeApiMethodParamMetadata { + /// Parameter name. + pub name: T::String, + /// Parameter type. + pub ty: T::Type, +} + +impl IntoPortable for RuntimeApiMethodParamMetadata { + type Output = RuntimeApiMethodParamMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + RuntimeApiMethodParamMetadata { + name: self.name.into_portable(registry), + ty: registry.register_type(&self.ty), + } + } +} + +/// Metadata of the extrinsic used by the runtime. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +#[cfg_attr( + feature = "serde_full", + 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>, +} + +impl IntoPortable for ExtrinsicMetadata { + type Output = ExtrinsicMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + ExtrinsicMetadata { + ty: registry.register_type(&self.ty), + version: self.version, + signed_extensions: registry.map_into_portable(self.signed_extensions), + } + } +} + +/// Metadata of an extrinsic's signed extension. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +#[cfg_attr( + feature = "serde_full", + 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 type of the signed extension, with the data to be included in the extrinsic. + pub ty: T::Type, + /// The type of the additional signed data, with the data to be included in the signed payload + pub additional_signed: 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), + additional_signed: registry.register_type(&self.additional_signed), + } + } +} + +/// All metadata about an runtime pallet. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +#[cfg_attr( + feature = "serde_full", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] +pub struct PalletMetadata { + /// Pallet name. + pub name: T::String, + /// Pallet storage metadata. + pub storage: Option>, + /// Pallet calls metadata. + pub calls: Option>, + /// Pallet event metadata. + pub event: Option>, + /// Pallet constants metadata. + pub constants: Vec>, + /// Pallet error metadata. + pub error: Option>, + /// Define the index of the pallet, this index will be used for the encoding of pallet event, + /// call and origin variants. + pub index: u8, + /// Pallet documentation. + pub docs: Vec, +} + +impl IntoPortable for PalletMetadata { + type Output = PalletMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + PalletMetadata { + name: self.name.into_portable(registry), + storage: self.storage.map(|storage| storage.into_portable(registry)), + calls: self.calls.map(|calls| calls.into_portable(registry)), + event: self.event.map(|event| event.into_portable(registry)), + constants: registry.map_into_portable(self.constants), + error: self.error.map(|error| error.into_portable(registry)), + index: self.index, + docs: registry.map_into_portable(self.docs), + } + } +} + +/// All metadata of the pallet's storage. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +#[cfg_attr( + feature = "serde_full", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] +pub struct PalletStorageMetadata { + /// The common prefix used by all storage entries. + pub prefix: T::String, + /// Metadata for all storage entries. + pub entries: Vec>, +} + +impl IntoPortable for PalletStorageMetadata { + type Output = PalletStorageMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + PalletStorageMetadata { + prefix: self.prefix.into_portable(registry), + entries: registry.map_into_portable(self.entries), + } + } +} + +/// Metadata about one storage entry. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +#[cfg_attr( + feature = "serde_full", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] +pub struct StorageEntryMetadata { + /// Variable name of the storage entry. + pub name: T::String, + /// An `Option` modifier of that storage entry. + pub modifier: StorageEntryModifier, + /// Type of the value stored in the entry. + pub ty: StorageEntryType, + /// Default value (SCALE encoded). + pub default: Vec, + /// Storage entry documentation. + pub docs: 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, + docs: registry.map_into_portable(self.docs), + } + } +} + +/// A storage entry modifier indicates how a storage entry is returned when fetched and what the value will be if the key is not present. +/// Specifically this refers to the "return type" when fetching a storage entry, and what the value will be if the key is not present. +/// +/// `Optional` means you should expect an `Option`, with `None` returned if the key is not present. +/// `Default` means you should expect a `T` with the default value of default if the key is not present. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +pub enum StorageEntryModifier { + /// The storage entry returns an `Option`, with `None` if the key is not present. + Optional, + /// The storage entry returns `T::Default` if the key is not present. + Default, +} + +/// Hasher used by storage maps +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +pub enum StorageHasher { + /// 128-bit Blake2 hash. + Blake2_128, + /// 256-bit Blake2 hash. + Blake2_256, + /// Multiple 128-bit Blake2 hashes concatenated. + Blake2_128Concat, + /// 128-bit XX hash. + Twox128, + /// 256-bit XX hash. + Twox256, + /// Multiple 64-bit XX hashes concatenated. + Twox64Concat, + /// Identity hashing (no hashing). + Identity, +} + +/// A type of storage value. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +#[cfg_attr( + feature = "serde_full", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] +pub enum StorageEntryType { + /// Plain storage entry (just the value). + Plain(T::Type), + /// A storage map. + Map { + /// One or more hashers, should be one hasher per key element. + hashers: Vec, + /// The type of the key, can be a tuple with elements for each of the hashers. + key: T::Type, + /// The type of the value. + value: T::Type, + }, +} + +impl IntoPortable for StorageEntryType { + type Output = StorageEntryType; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + match self { + Self::Plain(plain) => StorageEntryType::Plain(registry.register_type(&plain)), + Self::Map { + hashers, + key, + value, + } => StorageEntryType::Map { + hashers, + key: registry.register_type(&key), + value: registry.register_type(&value), + }, + } + } +} + +/// Metadata for all calls in a pallet +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +#[cfg_attr( + feature = "serde_full", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] +pub struct PalletCallMetadata { + /// The corresponding enum type for the pallet call. + pub ty: T::Type, +} + +impl IntoPortable for PalletCallMetadata { + type Output = PalletCallMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + PalletCallMetadata { + ty: registry.register_type(&self.ty), + } + } +} + +impl From for PalletCallMetadata { + fn from(ty: MetaType) -> Self { + Self { ty } + } +} + +/// Metadata about the pallet Event type. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +pub struct PalletEventMetadata { + /// The Event type. + pub ty: T::Type, +} + +impl IntoPortable for PalletEventMetadata { + type Output = PalletEventMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + PalletEventMetadata { + ty: registry.register_type(&self.ty), + } + } +} + +impl From for PalletEventMetadata { + fn from(ty: MetaType) -> Self { + Self { ty } + } +} + +/// Metadata about one pallet constant. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +#[cfg_attr( + feature = "serde_full", + serde(bound(serialize = "T::Type: Serialize, T::String: Serialize")) +)] +pub struct PalletConstantMetadata { + /// Name of the pallet constant. + pub name: T::String, + /// Type of the pallet constant. + pub ty: T::Type, + /// Value stored in the constant (SCALE encoded). + pub value: Vec, + /// Documentation of the constant. + pub docs: Vec, +} + +impl IntoPortable for PalletConstantMetadata { + type Output = PalletConstantMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + PalletConstantMetadata { + name: self.name.into_portable(registry), + ty: registry.register_type(&self.ty), + value: self.value, + docs: registry.map_into_portable(self.docs), + } + } +} + +/// Metadata about a pallet error. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +#[cfg_attr(feature = "decode", derive(Decode))] +#[cfg_attr(feature = "serde_full", derive(Serialize))] +#[cfg_attr(feature = "serde_full", serde(bound(serialize = "T::Type: Serialize")))] +pub struct PalletErrorMetadata { + /// The error type information. + pub ty: T::Type, +} + +impl IntoPortable for PalletErrorMetadata { + type Output = PalletErrorMetadata; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + PalletErrorMetadata { + ty: registry.register_type(&self.ty), + } + } +} + +impl From for PalletErrorMetadata { + fn from(ty: MetaType) -> Self { + Self { ty } + } +} diff --git a/frame-metadata/src/v8.rs b/frame-metadata/src/v8.rs index c10e348..c357271 100644 --- a/frame-metadata/src/v8.rs +++ b/frame-metadata/src/v8.rs @@ -1,6 +1,4 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame-metadata/src/v9.rs b/frame-metadata/src/v9.rs index a6c57e0..2d11ee3 100644 --- a/frame-metadata/src/v9.rs +++ b/frame-metadata/src/v9.rs @@ -1,6 +1,4 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License");