Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add metadata versions v8-v11 #28

Merged
merged 17 commits into from
Oct 21, 2021
5 changes: 5 additions & 0 deletions frame-metadata/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
110 changes: 99 additions & 11 deletions frame-metadata/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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"))]
insipx marked this conversation as resolved.
Show resolved Hide resolved
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"))]
Expand Down Expand Up @@ -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<u8> {
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(_)));
}
}
235 changes: 235 additions & 0 deletions frame-metadata/src/v10.rs
Original file line number Diff line number Diff line change
@@ -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<FunctionArgumentMetadata>,
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<EventMetadata>),
>,
}

/// 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<u8>;
}

/// 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<DefaultByteGetter, Vec<u8>>;

impl Encode for DefaultByteGetter {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
self.0.default_byte().encode_to(dest)
}
}

impl codec::EncodeLike for DefaultByteGetter {}

impl PartialEq<DefaultByteGetter> 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<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
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<StorageEntryMetadata>>,
}

/// The metadata of a runtime.
#[derive(Eq, Encode, PartialEq)]
#[cfg_attr(feature = "std", derive(Decode, Serialize, Debug))]
pub struct RuntimeMetadataV10 {
pub modules: DecodeDifferentArray<ModuleMetadata>,
}

/// 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<DecodeDifferent<FnEncode<StorageMetadata>, StorageMetadata>>,
pub calls: ODFnA<FunctionMetadata>,
pub event: ODFnA<EventMetadata>,
pub constants: DFnA<ModuleConstantMetadata>,
pub errors: DFnA<ErrorMetadata>,
}

type ODFnA<T> = Option<DFnA<T>>;
type DFnA<T> = DecodeDifferent<FnEncode<&'static [T]>, Vec<T>>;
Loading