From bd52212085051561aee5784ff48b295894b6509d Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Wed, 15 Mar 2023 19:49:28 +0200 Subject: [PATCH] Metadata V15: Expose API to fetch metadata for version (#13287) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * impl_runtime_apis: Generate getters for `metadata_at` functions Signed-off-by: Alexandru Vasile * runtime: Implement new `Metadata` runtime trait Signed-off-by: Alexandru Vasile * runtime: Move `metadata_at` functions to construct_runtime macro Signed-off-by: Alexandru Vasile * contruct_runtime: Use `OpaqueMetadata` from hidden imports Signed-off-by: Alexandru Vasile * Adjust testing Signed-off-by: Alexandru Vasile * frame/tests: Add tests for the new API Signed-off-by: Alexandru Vasile * frame/tests: Adjust metdata naming Signed-off-by: Alexandru Vasile * frame/support: Expose `metadata-v14` feature flag Signed-off-by: Alexandru Vasile * frame/support: Expose metadata only under feature flags Signed-off-by: Alexandru Vasile * frame/support: Expose v14 metadata by default Signed-off-by: Alexandru Vasile * frame/support: Expose metadata feature for testing Signed-off-by: Alexandru Vasile * frame/support: Test metadata under different feature flags Signed-off-by: Alexandru Vasile * Update primitives/api/src/lib.rs Co-authored-by: Bastian Köcher * Update primitives/api/src/lib.rs Co-authored-by: Bastian Köcher * client/tests: Adjust testing to reflect trait Metadata change Signed-off-by: Alexandru Vasile * frame/metadata-ir: Add intermediate representation types for metadata Signed-off-by: Alexandru Vasile * frame/metadata-ir: Convert metadata to V14 Signed-off-by: Alexandru Vasile * frame/metadata-ir: Add API to convert metadata to multiple versions Signed-off-by: Alexandru Vasile * frame/metadata-ir: Expose V14 under feature flag Signed-off-by: Alexandru Vasile * frame/support: Adjust to metadata IR Signed-off-by: Alexandru Vasile * frame/support: More adjustments Signed-off-by: Alexandru Vasile * frame/support: Guard v14 details under feature flag Signed-off-by: Alexandru Vasile * frame/support: Adjust testing Signed-off-by: Alexandru Vasile * CI: Ensure `quick-benchmarks` uses `metadata-v14` Signed-off-by: Alexandru Vasile * frame/support: Use `metadata-v14` for benchmarks Signed-off-by: Alexandru Vasile * Adjust cargo fmt Signed-off-by: Alexandru Vasile * kitchensink-runtime: Add feature flag for `metadata-v14` Signed-off-by: Alexandru Vasile * frame/support/test: Adjust testing Signed-off-by: Alexandru Vasile * frame/support/test: Check crates locally Signed-off-by: Alexandru Vasile * Activate metadata-v14 for pallets Signed-off-by: Alexandru Vasile * Remove metadata-v14 feature flag Signed-off-by: Alexandru Vasile * frame/metadata_ir: Move `api.rs` to `mod.rs` Signed-off-by: Alexandru Vasile * frame/support: Handle latest metadata conversion via IR Signed-off-by: Alexandru Vasile * frame/tests: Add constant for metadata version 14 Signed-off-by: Alexandru Vasile * frame/support/test: Fix merge conflict Signed-off-by: Alexandru Vasile * Update frame/support/Cargo.toml Co-authored-by: Bastian Köcher * Update frame/support/src/metadata_ir/mod.rs Co-authored-by: Bastian Köcher * Update frame/support/test/Cargo.toml Co-authored-by: Bastian Köcher * Update primitives/api/src/lib.rs Co-authored-by: Bastian Köcher * frame/metadata: Collect pallet documentation for MetadataIR Signed-off-by: Alexandru Vasile * frame/tests: Check pallet documentation is propagated to MetadataIR Signed-off-by: Alexandru Vasile * frame/support: Improve documentation Signed-off-by: Alexandru Vasile --------- Signed-off-by: Alexandru Vasile Co-authored-by: parity-processbot <> Co-authored-by: Bastian Köcher --- bin/node-template/runtime/src/lib.rs | 8 + bin/node/runtime/src/lib.rs | 8 + client/rpc-spec-v2/src/chain_head/tests.rs | 2 +- client/rpc/src/state/tests.rs | 2 +- .../src/construct_runtime/expand/metadata.rs | 43 ++- frame/support/procedural/src/lib.rs | 6 +- .../procedural/src/pallet/expand/call.rs | 2 +- .../procedural/src/pallet/expand/constants.rs | 4 +- .../src/pallet/expand/documentation.rs | 4 +- .../src/pallet/expand/pallet_struct.rs | 6 +- .../procedural/src/pallet/expand/storage.rs | 4 +- .../procedural/src/storage/metadata.rs | 26 +- frame/support/procedural/src/storage/mod.rs | 14 +- frame/support/src/dispatch.rs | 16 +- frame/support/src/hash.rs | 18 +- frame/support/src/lib.rs | 92 ++--- frame/support/src/metadata_ir/mod.rs | 82 +++++ frame/support/src/metadata_ir/types.rs | 329 ++++++++++++++++++ frame/support/src/metadata_ir/v14.rs | 158 +++++++++ .../support/src/storage/types/counted_map.rs | 20 +- frame/support/src/storage/types/double_map.rs | 30 +- frame/support/src/storage/types/key.rs | 6 +- frame/support/src/storage/types/map.rs | 26 +- frame/support/src/storage/types/mod.rs | 12 +- frame/support/src/storage/types/nmap.rs | 70 ++-- frame/support/src/storage/types/value.rs | 22 +- frame/support/test/tests/decl_storage.rs | 207 +++++------ frame/support/test/tests/instance.rs | 32 +- frame/support/test/tests/pallet.rs | 40 +++ primitives/api/src/lib.rs | 12 + test-utils/runtime/src/lib.rs | 17 +- 31 files changed, 1002 insertions(+), 316 deletions(-) create mode 100644 frame/support/src/metadata_ir/mod.rs create mode 100644 frame/support/src/metadata_ir/types.rs create mode 100644 frame/support/src/metadata_ir/v14.rs diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index ac01aa95f4f12..41871c06bd923 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -354,6 +354,14 @@ impl_runtime_apis! { fn metadata() -> OpaqueMetadata { OpaqueMetadata::new(Runtime::metadata().into()) } + + fn metadata_at_version(version: u32) -> Option { + Runtime::metadata_at_version(version) + } + + fn metadata_versions() -> sp_std::vec::Vec { + Runtime::metadata_versions() + } } impl sp_block_builder::BlockBuilder for Runtime { diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index d8426d3b35e15..5d1dea02e8256 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1942,6 +1942,14 @@ impl_runtime_apis! { fn metadata() -> OpaqueMetadata { OpaqueMetadata::new(Runtime::metadata().into()) } + + fn metadata_at_version(version: u32) -> Option { + Runtime::metadata_at_version(version) + } + + fn metadata_versions() -> sp_std::vec::Vec { + Runtime::metadata_versions() + } } impl sp_block_builder::BlockBuilder for Runtime { diff --git a/client/rpc-spec-v2/src/chain_head/tests.rs b/client/rpc-spec-v2/src/chain_head/tests.rs index 0886efa94a756..fcd906dcf5be0 100644 --- a/client/rpc-spec-v2/src/chain_head/tests.rs +++ b/client/rpc-spec-v2/src/chain_head/tests.rs @@ -170,7 +170,7 @@ async fn follow_with_runtime() { let runtime_str = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",4],\ - [\"0x37e397fc7c91f5e4\",1],[\"0xd2bc9897eed08f15\",3],[\"0x40fe3ad401f8959a\",6],\ + [\"0x37e397fc7c91f5e4\",2],[\"0xd2bc9897eed08f15\",3],[\"0x40fe3ad401f8959a\",6],\ [\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",2],\ [\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],[\"0xbc9d89904f5b923f\",1]],\ \"transactionVersion\":1,\"stateVersion\":1}"; diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index 53f8f1d48bc95..1ccc609e4f0e4 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -484,7 +484,7 @@ async fn should_return_runtime_version() { let result = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",4],\ - [\"0x37e397fc7c91f5e4\",1],[\"0xd2bc9897eed08f15\",3],[\"0x40fe3ad401f8959a\",6],\ + [\"0x37e397fc7c91f5e4\",2],[\"0xd2bc9897eed08f15\",3],[\"0x40fe3ad401f8959a\",6],\ [\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",2],\ [\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],[\"0xbc9d89904f5b923f\",1]],\ \"transactionVersion\":1,\"stateVersion\":1}"; diff --git a/frame/support/procedural/src/construct_runtime/expand/metadata.rs b/frame/support/procedural/src/construct_runtime/expand/metadata.rs index e9996121757d7..ba6a621af7523 100644 --- a/frame/support/procedural/src/construct_runtime/expand/metadata.rs +++ b/frame/support/procedural/src/construct_runtime/expand/metadata.rs @@ -48,6 +48,7 @@ pub fn expand_runtime_metadata( let event = expand_pallet_metadata_events(&filtered_names, runtime, scrate, decl); let constants = expand_pallet_metadata_constants(runtime, decl); let errors = expand_pallet_metadata_errors(runtime, decl); + let docs = expand_pallet_metadata_docs(runtime, decl); let attr = decl.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| { let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original())) .expect("was successfully parsed before; qed"); @@ -59,7 +60,7 @@ pub fn expand_runtime_metadata( quote! { #attr - #scrate::metadata::PalletMetadata { + #scrate::metadata_ir::PalletMetadataIR { name: stringify!(#name), index: #index, storage: #storage, @@ -67,6 +68,7 @@ pub fn expand_runtime_metadata( event: #event, constants: #constants, error: #errors, + docs: #docs, } } }) @@ -74,10 +76,10 @@ pub fn expand_runtime_metadata( quote! { impl #runtime { - pub fn metadata() -> #scrate::metadata::RuntimeMetadataPrefixed { - #scrate::metadata::RuntimeMetadataLastVersion::new( - #scrate::sp_std::vec![ #(#pallets),* ], - #scrate::metadata::ExtrinsicMetadata { + fn metadata_ir() -> #scrate::metadata_ir::MetadataIR { + #scrate::metadata_ir::MetadataIR { + pallets: #scrate::sp_std::vec![ #(#pallets),* ], + extrinsic: #scrate::metadata_ir::ExtrinsicMetadataIR { ty: #scrate::scale_info::meta_type::<#extrinsic>(), version: <#extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata>::VERSION, signed_extensions: < @@ -86,15 +88,29 @@ pub fn expand_runtime_metadata( >::SignedExtensions as #scrate::sp_runtime::traits::SignedExtension >::metadata() .into_iter() - .map(|meta| #scrate::metadata::SignedExtensionMetadata { + .map(|meta| #scrate::metadata_ir::SignedExtensionMetadataIR { identifier: meta.identifier, ty: meta.ty, additional_signed: meta.additional_signed, }) .collect(), }, - #scrate::scale_info::meta_type::<#runtime>() - ).into() + ty: #scrate::scale_info::meta_type::<#runtime>() + } + } + + pub fn metadata() -> #scrate::metadata::RuntimeMetadataPrefixed { + #scrate::metadata_ir::into_latest(#runtime::metadata_ir()) + } + + pub fn metadata_at_version(version: u32) -> Option<#scrate::OpaqueMetadata> { + #scrate::metadata_ir::into_version(#runtime::metadata_ir(), version).map(|prefixed| { + #scrate::OpaqueMetadata::new(prefixed.into()) + }) + } + + pub fn metadata_versions() -> #scrate::sp_std::vec::Vec { + #scrate::metadata_ir::supported_versions() } } } @@ -157,7 +173,7 @@ fn expand_pallet_metadata_events( quote! { Some( - #scrate::metadata::PalletEventMetadata { + #scrate::metadata_ir::PalletEventMetadataIR { ty: #scrate::scale_info::meta_type::<#pallet_event>() } ) @@ -184,3 +200,12 @@ fn expand_pallet_metadata_errors(runtime: &Ident, decl: &Pallet) -> TokenStream #path::Pallet::<#runtime #(, #path::#instance)*>::error_metadata() } } + +fn expand_pallet_metadata_docs(runtime: &Ident, decl: &Pallet) -> TokenStream { + let path = &decl.path; + let instance = decl.instance.as_ref().into_iter(); + + quote! { + #path::Pallet::<#runtime #(, #path::#instance)*>::pallet_documentation_metadata() + } +} diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index 1d5dde20e2034..0515a4b7d2f91 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -495,7 +495,7 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream { /// #[doc = include_str!("../README.md")] /// #[pallet_doc("../doc1.md")] /// #[pallet_doc("../doc2.md")] -/// pub struct Pallet(_); +/// pub mod pallet {} /// ``` /// /// The runtime metadata for this pallet contains the following @@ -514,7 +514,7 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream { /// /// Documentation for pallet 1 /// /// Documentation for pallet 2 /// /// Content of README.md -/// pub struct Pallet(_); +/// pub mod pallet {} /// ``` /// /// If you want to specify the file from which the documentation is loaded, you can use the @@ -531,7 +531,7 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream { /// /// This approach is beneficial when you use the `include_str` macro at the beginning of the file /// and want that documentation to extend to the runtime metadata, without reiterating the -/// documentation on the module itself. +/// documentation on the pallet module itself. #[proc_macro_attribute] pub fn pallet(attr: TokenStream, item: TokenStream) -> TokenStream { pallet::pallet(attr, item) diff --git a/frame/support/procedural/src/pallet/expand/call.rs b/frame/support/procedural/src/pallet/expand/call.rs index 3db454eb6211b..7672609a9881e 100644 --- a/frame/support/procedural/src/pallet/expand/call.rs +++ b/frame/support/procedural/src/pallet/expand/call.rs @@ -362,7 +362,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { impl<#type_impl_gen> #pallet_ident<#type_use_gen> #where_clause { #[doc(hidden)] - pub fn call_functions() -> #frame_support::metadata::PalletCallMetadata { + pub fn call_functions() -> #frame_support::metadata_ir::PalletCallMetadataIR { #frame_support::scale_info::meta_type::<#call_ident<#type_use_gen>>().into() } } diff --git a/frame/support/procedural/src/pallet/expand/constants.rs b/frame/support/procedural/src/pallet/expand/constants.rs index 21ac1de3642d5..21fa492a75b56 100644 --- a/frame/support/procedural/src/pallet/expand/constants.rs +++ b/frame/support/procedural/src/pallet/expand/constants.rs @@ -85,7 +85,7 @@ pub fn expand_constants(def: &mut Def) -> proc_macro2::TokenStream { let default_byte_impl = &const_.default_byte_impl; quote::quote!({ - #frame_support::metadata::PalletConstantMetadata { + #frame_support::metadata_ir::PalletConstantMetadataIR { name: #ident_str, ty: #frame_support::scale_info::meta_type::<#const_type>(), value: { #default_byte_impl }, @@ -99,7 +99,7 @@ pub fn expand_constants(def: &mut Def) -> proc_macro2::TokenStream { #[doc(hidden)] pub fn pallet_constants_metadata() - -> #frame_support::sp_std::vec::Vec<#frame_support::metadata::PalletConstantMetadata> + -> #frame_support::sp_std::vec::Vec<#frame_support::metadata_ir::PalletConstantMetadataIR> { #frame_support::sp_std::vec![ #( #consts ),* ] } diff --git a/frame/support/procedural/src/pallet/expand/documentation.rs b/frame/support/procedural/src/pallet/expand/documentation.rs index e158448a89711..1aa46cf572847 100644 --- a/frame/support/procedural/src/pallet/expand/documentation.rs +++ b/frame/support/procedural/src/pallet/expand/documentation.rs @@ -145,7 +145,7 @@ impl ToTokens for DocMetaValue { /// Implement a `pallet_documentation_metadata` function to fetch the /// documentation that is included in the metadata. /// -/// The documentation is placed at the top of the module similar to: +/// The documentation is placed on the pallet similar to: /// /// ```ignore /// #[pallet] @@ -163,7 +163,7 @@ impl ToTokens for DocMetaValue { /// which is the file path that holds the documentation to be added to the metadata. /// /// Unlike the `doc` attribute, the documentation provided to the `proc_macro` attribute is -/// not inserted at the beginning of the module. +/// not added to the pallet. pub fn expand_documentation(def: &mut Def) -> proc_macro2::TokenStream { let frame_support = &def.frame_support; let type_impl_gen = &def.type_impl_generics(proc_macro2::Span::call_site()); diff --git a/frame/support/procedural/src/pallet/expand/pallet_struct.rs b/frame/support/procedural/src/pallet/expand/pallet_struct.rs index 27fe9d3401ea2..7acfb9090698e 100644 --- a/frame/support/procedural/src/pallet/expand/pallet_struct.rs +++ b/frame/support/procedural/src/pallet/expand/pallet_struct.rs @@ -82,8 +82,8 @@ pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream { quote::quote_spanned!(def.pallet_struct.attr_span => impl<#type_impl_gen> #pallet_ident<#type_use_gen> #config_where_clause { #[doc(hidden)] - pub fn error_metadata() -> Option<#frame_support::metadata::PalletErrorMetadata> { - Some(#frame_support::metadata::PalletErrorMetadata { + pub fn error_metadata() -> Option<#frame_support::metadata_ir::PalletErrorMetadataIR> { + Some(#frame_support::metadata_ir::PalletErrorMetadataIR { ty: #frame_support::scale_info::meta_type::<#error_ident<#type_use_gen>>() }) } @@ -93,7 +93,7 @@ pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream { quote::quote_spanned!(def.pallet_struct.attr_span => impl<#type_impl_gen> #pallet_ident<#type_use_gen> #config_where_clause { #[doc(hidden)] - pub fn error_metadata() -> Option<#frame_support::metadata::PalletErrorMetadata> { + pub fn error_metadata() -> Option<#frame_support::metadata_ir::PalletErrorMetadataIR> { None } } diff --git a/frame/support/procedural/src/pallet/expand/storage.rs b/frame/support/procedural/src/pallet/expand/storage.rs index 05d61bb522180..8ba9ee7681ca9 100644 --- a/frame/support/procedural/src/pallet/expand/storage.rs +++ b/frame/support/procedural/src/pallet/expand/storage.rs @@ -639,8 +639,8 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream { #completed_where_clause { #[doc(hidden)] - pub fn storage_metadata() -> #frame_support::metadata::PalletStorageMetadata { - #frame_support::metadata::PalletStorageMetadata { + pub fn storage_metadata() -> #frame_support::metadata_ir::PalletStorageMetadataIR { + #frame_support::metadata_ir::PalletStorageMetadataIR { prefix: < ::PalletInfo as #frame_support::traits::PalletInfo diff --git a/frame/support/procedural/src/storage/metadata.rs b/frame/support/procedural/src/storage/metadata.rs index 3e3e0576f63b5..5561d0564597b 100644 --- a/frame/support/procedural/src/storage/metadata.rs +++ b/frame/support/procedural/src/storage/metadata.rs @@ -27,7 +27,7 @@ fn storage_line_metadata_type(scrate: &TokenStream, line: &StorageLineDefExt) -> match &line.storage_type { StorageLineTypeDef::Simple(_) => { quote! { - #scrate::metadata::StorageEntryType::Plain( + #scrate::metadata_ir::StorageEntryTypeIR::Plain( #scrate::scale_info::meta_type::<#value_type>() ) } @@ -36,8 +36,8 @@ fn storage_line_metadata_type(scrate: &TokenStream, line: &StorageLineDefExt) -> let hasher = map.hasher.into_metadata(); let key = &map.key; quote! { - #scrate::metadata::StorageEntryType::Map { - hashers: #scrate::sp_std::vec! [ #scrate::metadata::#hasher ], + #scrate::metadata_ir::StorageEntryTypeIR::Map { + hashers: #scrate::sp_std::vec! [ #scrate::metadata_ir::#hasher ], key: #scrate::scale_info::meta_type::<#key>(), value: #scrate::scale_info::meta_type::<#value_type>(), } @@ -49,10 +49,10 @@ fn storage_line_metadata_type(scrate: &TokenStream, line: &StorageLineDefExt) -> let key1 = &map.key1; let key2 = &map.key2; quote! { - #scrate::metadata::StorageEntryType::Map { + #scrate::metadata_ir::StorageEntryTypeIR::Map { hashers: #scrate::sp_std::vec! [ - #scrate::metadata::#hasher1, - #scrate::metadata::#hasher2, + #scrate::metadata_ir::#hasher1, + #scrate::metadata_ir::#hasher2, ], key: #scrate::scale_info::meta_type::<(#key1, #key2)>(), value: #scrate::scale_info::meta_type::<#value_type>(), @@ -67,9 +67,9 @@ fn storage_line_metadata_type(scrate: &TokenStream, line: &StorageLineDefExt) -> .map(|hasher| hasher.to_storage_hasher_struct()) .collect::>(); quote! { - #scrate::metadata::StorageEntryType::Map { + #scrate::metadata_ir::StorageEntryTypeIR::Map { hashers: #scrate::sp_std::vec! [ - #( #scrate::metadata::StorageHasher::#hashers, )* + #( #scrate::metadata_ir::StorageHasherIR::#hashers, )* ], key: #scrate::scale_info::meta_type::<#key_tuple>(), value: #scrate::scale_info::meta_type::<#value_type>(), @@ -159,9 +159,9 @@ pub fn impl_metadata(def: &DeclStorageDefExt) -> TokenStream { let str_name = line.name.to_string(); let modifier = if line.is_option { - quote!(#scrate::metadata::StorageEntryModifier::Optional) + quote!(#scrate::metadata_ir::StorageEntryModifierIR::Optional) } else { - quote!(#scrate::metadata::StorageEntryModifier::Default) + quote!(#scrate::metadata_ir::StorageEntryModifierIR::Default) }; let ty = storage_line_metadata_type(scrate, line); @@ -172,7 +172,7 @@ pub fn impl_metadata(def: &DeclStorageDefExt) -> TokenStream { let docs = get_doc_literals(&line.attrs); let entry = quote! { - #scrate::metadata::StorageEntryMetadata { + #scrate::metadata_ir::StorageEntryMetadataIR { name: #str_name, modifier: #modifier, ty: #ty, @@ -194,7 +194,7 @@ pub fn impl_metadata(def: &DeclStorageDefExt) -> TokenStream { }; let store_metadata = quote!( - #scrate::metadata::PalletStorageMetadata { + #scrate::metadata_ir::PalletStorageMetadataIR { prefix: #prefix, entries: #scrate::sp_std::vec![ #entries ], } @@ -209,7 +209,7 @@ pub fn impl_metadata(def: &DeclStorageDefExt) -> TokenStream { impl #module_impl #module_struct #where_clause { #[doc(hidden)] - pub fn storage_metadata() -> #scrate::metadata::PalletStorageMetadata { + pub fn storage_metadata() -> #scrate::metadata_ir::PalletStorageMetadataIR { #store_metadata } } diff --git a/frame/support/procedural/src/storage/mod.rs b/frame/support/procedural/src/storage/mod.rs index 1e48a1fbb06d1..3d3b1443d393f 100644 --- a/frame/support/procedural/src/storage/mod.rs +++ b/frame/support/procedural/src/storage/mod.rs @@ -454,13 +454,13 @@ impl HasherKind { fn into_metadata(&self) -> proc_macro2::TokenStream { match self { - HasherKind::Blake2_256 => quote!(StorageHasher::Blake2_256), - HasherKind::Blake2_128 => quote!(StorageHasher::Blake2_128), - HasherKind::Blake2_128Concat => quote!(StorageHasher::Blake2_128Concat), - HasherKind::Twox256 => quote!(StorageHasher::Twox256), - HasherKind::Twox128 => quote!(StorageHasher::Twox128), - HasherKind::Twox64Concat => quote!(StorageHasher::Twox64Concat), - HasherKind::Identity => quote!(StorageHasher::Identity), + HasherKind::Blake2_256 => quote!(StorageHasherIR::Blake2_256), + HasherKind::Blake2_128 => quote!(StorageHasherIR::Blake2_128), + HasherKind::Blake2_128Concat => quote!(StorageHasherIR::Blake2_128Concat), + HasherKind::Twox256 => quote!(StorageHasherIR::Twox256), + HasherKind::Twox128 => quote!(StorageHasherIR::Twox128), + HasherKind::Twox64Concat => quote!(StorageHasherIR::Twox64Concat), + HasherKind::Identity => quote!(StorageHasherIR::Identity), } } } diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index c5f4cc60c1f1b..390555b02d1bb 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -2977,7 +2977,7 @@ macro_rules! __dispatch_impl_metadata { { #[doc(hidden)] #[allow(dead_code)] - pub fn call_functions() -> $crate::metadata::PalletCallMetadata { + pub fn call_functions() -> $crate::metadata_ir::PalletCallMetadataIR { $crate::scale_info::meta_type::<$call_type<$trait_instance $(, $instance)?>>().into() } } @@ -2998,7 +2998,7 @@ macro_rules! __impl_error_metadata { { #[doc(hidden)] #[allow(dead_code)] - pub fn error_metadata() -> Option<$crate::metadata::PalletErrorMetadata> { + pub fn error_metadata() -> Option<$crate::metadata_ir::PalletErrorMetadataIR> { None } } @@ -3013,8 +3013,8 @@ macro_rules! __impl_error_metadata { { #[doc(hidden)] #[allow(dead_code)] - pub fn error_metadata() -> Option<$crate::metadata::PalletErrorMetadata> { - Some($crate::metadata::PalletErrorMetadata { + pub fn error_metadata() -> Option<$crate::metadata_ir::PalletErrorMetadataIR> { + Some($crate::metadata_ir::PalletErrorMetadataIR { ty: $crate::scale_info::meta_type::<$( $error_type )*>() }) } @@ -3109,7 +3109,7 @@ macro_rules! __impl_module_constants_metadata { { #[doc(hidden)] #[allow(dead_code)] - pub fn pallet_constants_metadata() -> $crate::sp_std::vec::Vec<$crate::metadata::PalletConstantMetadata> { + pub fn pallet_constants_metadata() -> $crate::sp_std::vec::Vec<$crate::metadata_ir::PalletConstantMetadataIR> { // Create the `ByteGetter`s $( #[allow(non_upper_case_types)] @@ -3133,7 +3133,7 @@ macro_rules! __impl_module_constants_metadata { )* $crate::sp_std::vec![ $( - $crate::metadata::PalletConstantMetadata { + $crate::metadata_ir::PalletConstantMetadataIR { name: stringify!($name), ty: $crate::scale_info::meta_type::<$type>(), value: $default_byte_name::<$const_trait_instance $(, $const_instance)?>( @@ -3207,7 +3207,7 @@ mod tests { use super::*; use crate::{ dispatch::{DispatchClass, DispatchInfo, Pays}, - metadata::*, + metadata_ir::*, traits::{ CallerTrait, CrateVersion, Get, GetCallName, IntegrityTest, OnFinalize, OnIdle, OnInitialize, OnRuntimeUpgrade, PalletInfo, @@ -3405,7 +3405,7 @@ mod tests { fn module_json_metadata() { let metadata = Module::::call_functions(); let expected_metadata = - PalletCallMetadata { ty: scale_info::meta_type::>() }; + PalletCallMetadataIR { ty: scale_info::meta_type::>() }; assert_eq!(expected_metadata, metadata); } diff --git a/frame/support/src/hash.rs b/frame/support/src/hash.rs index bf9eb2f88b0b1..115ce605d542e 100644 --- a/frame/support/src/hash.rs +++ b/frame/support/src/hash.rs @@ -17,7 +17,7 @@ //! Hash utilities. -use crate::metadata; +use crate::metadata_ir; use codec::{Codec, MaxEncodedLen}; use sp_io::hashing::{blake2_128, blake2_256, twox_128, twox_256, twox_64}; use sp_std::prelude::Vec; @@ -59,7 +59,7 @@ impl Hashable for T { /// Hasher to use to hash keys to insert to storage. pub trait StorageHasher: 'static { - const METADATA: metadata::StorageHasher; + const METADATA: metadata_ir::StorageHasherIR; type Output: AsRef<[u8]>; fn hash(x: &[u8]) -> Self::Output; @@ -80,7 +80,7 @@ pub trait ReversibleStorageHasher: StorageHasher { /// Store the key directly. pub struct Identity; impl StorageHasher for Identity { - const METADATA: metadata::StorageHasher = metadata::StorageHasher::Identity; + const METADATA: metadata_ir::StorageHasherIR = metadata_ir::StorageHasherIR::Identity; type Output = Vec; fn hash(x: &[u8]) -> Vec { x.to_vec() @@ -98,7 +98,7 @@ impl ReversibleStorageHasher for Identity { /// Hash storage keys with `concat(twox64(key), key)` pub struct Twox64Concat; impl StorageHasher for Twox64Concat { - const METADATA: metadata::StorageHasher = metadata::StorageHasher::Twox64Concat; + const METADATA: metadata_ir::StorageHasherIR = metadata_ir::StorageHasherIR::Twox64Concat; type Output = Vec; fn hash(x: &[u8]) -> Vec { twox_64(x).iter().chain(x.iter()).cloned().collect::>() @@ -120,7 +120,7 @@ impl ReversibleStorageHasher for Twox64Concat { /// Hash storage keys with `concat(blake2_128(key), key)` pub struct Blake2_128Concat; impl StorageHasher for Blake2_128Concat { - const METADATA: metadata::StorageHasher = metadata::StorageHasher::Blake2_128Concat; + const METADATA: metadata_ir::StorageHasherIR = metadata_ir::StorageHasherIR::Blake2_128Concat; type Output = Vec; fn hash(x: &[u8]) -> Vec { blake2_128(x).iter().chain(x.iter()).cloned().collect::>() @@ -142,7 +142,7 @@ impl ReversibleStorageHasher for Blake2_128Concat { /// Hash storage keys with blake2 128 pub struct Blake2_128; impl StorageHasher for Blake2_128 { - const METADATA: metadata::StorageHasher = metadata::StorageHasher::Blake2_128; + const METADATA: metadata_ir::StorageHasherIR = metadata_ir::StorageHasherIR::Blake2_128; type Output = [u8; 16]; fn hash(x: &[u8]) -> [u8; 16] { blake2_128(x) @@ -155,7 +155,7 @@ impl StorageHasher for Blake2_128 { /// Hash storage keys with blake2 256 pub struct Blake2_256; impl StorageHasher for Blake2_256 { - const METADATA: metadata::StorageHasher = metadata::StorageHasher::Blake2_256; + const METADATA: metadata_ir::StorageHasherIR = metadata_ir::StorageHasherIR::Blake2_256; type Output = [u8; 32]; fn hash(x: &[u8]) -> [u8; 32] { blake2_256(x) @@ -168,7 +168,7 @@ impl StorageHasher for Blake2_256 { /// Hash storage keys with twox 128 pub struct Twox128; impl StorageHasher for Twox128 { - const METADATA: metadata::StorageHasher = metadata::StorageHasher::Twox128; + const METADATA: metadata_ir::StorageHasherIR = metadata_ir::StorageHasherIR::Twox128; type Output = [u8; 16]; fn hash(x: &[u8]) -> [u8; 16] { twox_128(x) @@ -181,7 +181,7 @@ impl StorageHasher for Twox128 { /// Hash storage keys with twox 256 pub struct Twox256; impl StorageHasher for Twox256 { - const METADATA: metadata::StorageHasher = metadata::StorageHasher::Twox256; + const METADATA: metadata_ir::StorageHasherIR = metadata_ir::StorageHasherIR::Twox256; type Output = [u8; 32]; fn hash(x: &[u8]) -> [u8; 32] { twox_256(x) diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 4e9bc32b0043b..b845828455793 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -50,7 +50,7 @@ pub use paste; pub use scale_info; #[cfg(feature = "std")] pub use serde; -pub use sp_core::Void; +pub use sp_core::{OpaqueMetadata, Void}; #[doc(hidden)] pub use sp_core_hashing_proc_macro; #[doc(hidden)] @@ -80,10 +80,10 @@ pub mod error; pub mod crypto; pub mod dispatch_context; pub mod instances; +pub mod metadata_ir; pub mod migrations; pub mod traits; pub mod weights; - #[doc(hidden)] pub mod unsigned { #[doc(hidden)] @@ -827,9 +827,9 @@ pub use serde::{Deserialize, Serialize}; #[cfg(test)] pub mod tests { use super::*; - use crate::metadata::{ - PalletStorageMetadata, StorageEntryMetadata, StorageEntryModifier, StorageEntryType, - StorageHasher, + use crate::metadata_ir::{ + PalletStorageMetadataIR, StorageEntryMetadataIR, StorageEntryModifierIR, + StorageEntryTypeIR, StorageHasherIR, }; use codec::{Codec, EncodeLike}; use frame_support::traits::CrateVersion; @@ -1310,101 +1310,107 @@ pub mod tests { }); } - fn expected_metadata() -> PalletStorageMetadata { - PalletStorageMetadata { + fn expected_metadata() -> PalletStorageMetadataIR { + PalletStorageMetadataIR { prefix: "Test", entries: vec![ - StorageEntryMetadata { + StorageEntryMetadataIR { name: "Value", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0, 0, 0, 0, 0, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "Data", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Twox64Concat], + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Twox64Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::(), }, default: vec![0, 0, 0, 0, 0, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "OptionLinkedMap", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat], + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::(), }, default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "GenericData", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Identity], + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Identity], key: scale_info::meta_type::(), value: scale_info::meta_type::(), }, default: vec![0, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "GenericData2", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat], + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::(), }, default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "DataDM", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Twox64Concat, StorageHasher::Blake2_128Concat], + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { + hashers: vec![ + StorageHasherIR::Twox64Concat, + StorageHasherIR::Blake2_128Concat, + ], key: scale_info::meta_type::<(u32, u32)>(), value: scale_info::meta_type::(), }, default: vec![0, 0, 0, 0, 0, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "GenericDataDM", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat, StorageHasher::Identity], + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Blake2_128Concat, StorageHasherIR::Identity], key: scale_info::meta_type::<(u32, u32)>(), value: scale_info::meta_type::(), }, default: vec![0, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "GenericData2DM", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat, StorageHasher::Twox64Concat], + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Map { + hashers: vec![ + StorageHasherIR::Blake2_128Concat, + StorageHasherIR::Twox64Concat, + ], key: scale_info::meta_type::<(u32, u32)>(), value: scale_info::meta_type::(), }, default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "AppendableDM", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { hashers: vec![ - StorageHasher::Blake2_128Concat, - StorageHasher::Blake2_128Concat, + StorageHasherIR::Blake2_128Concat, + StorageHasherIR::Blake2_128Concat, ], key: scale_info::meta_type::<(u32, u32)>(), value: scale_info::meta_type::>(), diff --git a/frame/support/src/metadata_ir/mod.rs b/frame/support/src/metadata_ir/mod.rs new file mode 100644 index 0000000000000..bab205d63c118 --- /dev/null +++ b/frame/support/src/metadata_ir/mod.rs @@ -0,0 +1,82 @@ +// This file is part of Substrate. + +// 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. + +//! Intermediate representation of the runtime metadata. + +mod types; +use frame_metadata::{RuntimeMetadataPrefixed, RuntimeMetadataV14}; +pub use types::*; + +mod v14; + +/// Metadata V14. +const V14: u32 = 14; + +/// Transform the IR to the specified version. +/// +/// Use [`supported_versions`] to find supported versions. +pub fn into_version(metadata: MetadataIR, version: u32) -> Option { + match version { + // Latest stable version. + V14 => { + let v14: frame_metadata::v14::RuntimeMetadataV14 = metadata.into(); + Some(v14.into()) + }, + _ => None, + } +} + +/// Returns the supported metadata versions. +pub fn supported_versions() -> sp_std::vec::Vec { + sp_std::vec![V14,] +} + +/// Transform the IR to the latest stable metadata version. +pub fn into_latest(metadata: MetadataIR) -> RuntimeMetadataPrefixed { + let latest: RuntimeMetadataV14 = metadata.into(); + latest.into() +} + +#[cfg(test)] +mod test { + use super::*; + use crate::metadata_ir::ExtrinsicMetadataIR; + use frame_metadata::{v14::META_RESERVED, RuntimeMetadata}; + use scale_info::meta_type; + + fn ir_metadata() -> MetadataIR { + MetadataIR { + pallets: vec![], + extrinsic: ExtrinsicMetadataIR { + ty: meta_type::<()>(), + version: 0, + signed_extensions: vec![], + }, + ty: meta_type::<()>(), + } + } + + #[test] + fn into_version_14() { + let ir = ir_metadata(); + let metadata = into_version(ir, V14).expect("Should return prefixed metadata"); + + assert_eq!(metadata.0, META_RESERVED); + + assert!(matches!(metadata.1, RuntimeMetadata::V14(_))); + } +} diff --git a/frame/support/src/metadata_ir/types.rs b/frame/support/src/metadata_ir/types.rs new file mode 100644 index 0000000000000..087fd3dcad249 --- /dev/null +++ b/frame/support/src/metadata_ir/types.rs @@ -0,0 +1,329 @@ +// This file is part of Substrate. + +// 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. + +use codec::Encode; +use scale_info::{ + form::{Form, MetaForm, PortableForm}, + prelude::vec::Vec, + IntoPortable, MetaType, Registry, +}; + +/// The intermediate representation for the runtime metadata. +/// Contains the needed context that allows conversion to multiple metadata versions. +/// +/// # Note +/// +/// Further fields could be added or removed to ensure proper conversion. +/// When the IR does not contain enough information to generate a specific version +/// of the runtime metadata an appropriate default value is used (ie, empty vector). +pub struct MetadataIR { + /// Pallet metadata. + pub pallets: Vec>, + /// Metadata of the extrinsic. + pub extrinsic: ExtrinsicMetadataIR, + /// The type of the `Runtime`. + pub ty: T::Type, +} + +/// The intermediate representation for a pallet metadata. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +pub struct PalletMetadataIR { + /// 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 PalletMetadataIR { + type Output = PalletMetadataIR; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + PalletMetadataIR { + 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), + } + } +} + +/// Metadata of the extrinsic used by the runtime. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +pub struct ExtrinsicMetadataIR { + /// 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 ExtrinsicMetadataIR { + type Output = ExtrinsicMetadataIR; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + ExtrinsicMetadataIR { + 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)] +pub struct SignedExtensionMetadataIR { + /// 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 SignedExtensionMetadataIR { + type Output = SignedExtensionMetadataIR; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + SignedExtensionMetadataIR { + identifier: self.identifier.into_portable(registry), + ty: registry.register_type(&self.ty), + additional_signed: registry.register_type(&self.additional_signed), + } + } +} + +/// All metadata of the pallet's storage. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +/// The common prefix used by all storage entries. +pub struct PalletStorageMetadataIR { + /// The common prefix used by all storage entries. + pub prefix: T::String, + /// Metadata for all storage entries. + pub entries: Vec>, +} + +impl IntoPortable for PalletStorageMetadataIR { + type Output = PalletStorageMetadataIR; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + PalletStorageMetadataIR { + prefix: self.prefix.into_portable(registry), + entries: registry.map_into_portable(self.entries), + } + } +} + +/// Metadata about one storage entry. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +pub struct StorageEntryMetadataIR { + /// Variable name of the storage entry. + pub name: T::String, + /// An `Option` modifier of that storage entry. + pub modifier: StorageEntryModifierIR, + /// Type of the value stored in the entry. + pub ty: StorageEntryTypeIR, + /// Default value (SCALE encoded). + pub default: Vec, + /// Storage entry documentation. + pub docs: Vec, +} + +impl IntoPortable for StorageEntryMetadataIR { + type Output = StorageEntryMetadataIR; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + StorageEntryMetadataIR { + 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)] +pub enum StorageEntryModifierIR { + /// 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)] +pub enum StorageHasherIR { + /// 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)] +pub enum StorageEntryTypeIR { + /// 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 StorageEntryTypeIR { + type Output = StorageEntryTypeIR; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + match self { + Self::Plain(plain) => StorageEntryTypeIR::Plain(registry.register_type(&plain)), + Self::Map { hashers, key, value } => StorageEntryTypeIR::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)] +pub struct PalletCallMetadataIR { + /// The corresponding enum type for the pallet call. + pub ty: T::Type, +} + +impl IntoPortable for PalletCallMetadataIR { + type Output = PalletCallMetadataIR; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + PalletCallMetadataIR { ty: registry.register_type(&self.ty) } + } +} + +impl From for PalletCallMetadataIR { + fn from(ty: MetaType) -> Self { + Self { ty } + } +} + +/// Metadata about the pallet Event type. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +pub struct PalletEventMetadataIR { + /// The Event type. + pub ty: T::Type, +} + +impl IntoPortable for PalletEventMetadataIR { + type Output = PalletEventMetadataIR; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + PalletEventMetadataIR { ty: registry.register_type(&self.ty) } + } +} + +impl From for PalletEventMetadataIR { + fn from(ty: MetaType) -> Self { + Self { ty } + } +} + +/// Metadata about one pallet constant. +#[derive(Clone, PartialEq, Eq, Encode, Debug)] +pub struct PalletConstantMetadataIR { + /// 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 PalletConstantMetadataIR { + type Output = PalletConstantMetadataIR; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + PalletConstantMetadataIR { + 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)] +pub struct PalletErrorMetadataIR { + /// The error type information. + pub ty: T::Type, +} + +impl IntoPortable for PalletErrorMetadataIR { + type Output = PalletErrorMetadataIR; + + fn into_portable(self, registry: &mut Registry) -> Self::Output { + PalletErrorMetadataIR { ty: registry.register_type(&self.ty) } + } +} + +impl From for PalletErrorMetadataIR { + fn from(ty: MetaType) -> Self { + Self { ty } + } +} diff --git a/frame/support/src/metadata_ir/v14.rs b/frame/support/src/metadata_ir/v14.rs new file mode 100644 index 0000000000000..e1b7a24f76577 --- /dev/null +++ b/frame/support/src/metadata_ir/v14.rs @@ -0,0 +1,158 @@ +// This file is part of Substrate. + +// 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. + +//! Convert the IR to V14 metadata. + +use super::types::{ + ExtrinsicMetadataIR, MetadataIR, PalletCallMetadataIR, PalletConstantMetadataIR, + PalletErrorMetadataIR, PalletEventMetadataIR, PalletMetadataIR, PalletStorageMetadataIR, + SignedExtensionMetadataIR, StorageEntryMetadataIR, StorageEntryModifierIR, StorageEntryTypeIR, + StorageHasherIR, +}; + +use frame_metadata::v14::{ + ExtrinsicMetadata, PalletCallMetadata, PalletConstantMetadata, PalletErrorMetadata, + PalletEventMetadata, PalletMetadata, PalletStorageMetadata, RuntimeMetadataV14, + SignedExtensionMetadata, StorageEntryMetadata, StorageEntryModifier, StorageEntryType, + StorageHasher, +}; + +impl From for RuntimeMetadataV14 { + fn from(ir: MetadataIR) -> Self { + RuntimeMetadataV14::new( + ir.pallets.into_iter().map(Into::into).collect(), + ir.extrinsic.into(), + ir.ty, + ) + } +} + +impl From for PalletMetadata { + fn from(ir: PalletMetadataIR) -> Self { + PalletMetadata { + name: ir.name, + storage: ir.storage.map(Into::into), + calls: ir.calls.map(Into::into), + event: ir.event.map(Into::into), + constants: ir.constants.into_iter().map(Into::into).collect(), + error: ir.error.map(Into::into), + index: ir.index, + // Note: ir.docs not part of v14. + } + } +} + +impl From for StorageEntryModifier { + fn from(ir: StorageEntryModifierIR) -> Self { + match ir { + StorageEntryModifierIR::Optional => StorageEntryModifier::Optional, + StorageEntryModifierIR::Default => StorageEntryModifier::Default, + } + } +} + +impl From for StorageHasher { + fn from(ir: StorageHasherIR) -> Self { + match ir { + StorageHasherIR::Blake2_128 => StorageHasher::Blake2_128, + StorageHasherIR::Blake2_256 => StorageHasher::Blake2_256, + StorageHasherIR::Blake2_128Concat => StorageHasher::Blake2_128Concat, + StorageHasherIR::Twox128 => StorageHasher::Twox128, + StorageHasherIR::Twox256 => StorageHasher::Twox256, + StorageHasherIR::Twox64Concat => StorageHasher::Twox64Concat, + StorageHasherIR::Identity => StorageHasher::Identity, + } + } +} + +impl From for StorageEntryType { + fn from(ir: StorageEntryTypeIR) -> Self { + match ir { + StorageEntryTypeIR::Plain(ty) => StorageEntryType::Plain(ty), + StorageEntryTypeIR::Map { hashers, key, value } => StorageEntryType::Map { + hashers: hashers.into_iter().map(Into::into).collect(), + key, + value, + }, + } + } +} + +impl From for StorageEntryMetadata { + fn from(ir: StorageEntryMetadataIR) -> Self { + StorageEntryMetadata { + name: ir.name, + modifier: ir.modifier.into(), + ty: ir.ty.into(), + default: ir.default, + docs: ir.docs, + } + } +} + +impl From for PalletStorageMetadata { + fn from(ir: PalletStorageMetadataIR) -> Self { + PalletStorageMetadata { + prefix: ir.prefix, + entries: ir.entries.into_iter().map(Into::into).collect(), + } + } +} + +impl From for PalletCallMetadata { + fn from(ir: PalletCallMetadataIR) -> Self { + PalletCallMetadata { ty: ir.ty } + } +} + +impl From for PalletEventMetadata { + fn from(ir: PalletEventMetadataIR) -> Self { + PalletEventMetadata { ty: ir.ty } + } +} + +impl From for PalletConstantMetadata { + fn from(ir: PalletConstantMetadataIR) -> Self { + PalletConstantMetadata { name: ir.name, ty: ir.ty, value: ir.value, docs: ir.docs } + } +} + +impl From for PalletErrorMetadata { + fn from(ir: PalletErrorMetadataIR) -> Self { + PalletErrorMetadata { ty: ir.ty } + } +} + +impl From for SignedExtensionMetadata { + fn from(ir: SignedExtensionMetadataIR) -> Self { + SignedExtensionMetadata { + identifier: ir.identifier, + ty: ir.ty, + additional_signed: ir.additional_signed, + } + } +} + +impl From for ExtrinsicMetadata { + fn from(ir: ExtrinsicMetadataIR) -> Self { + ExtrinsicMetadata { + ty: ir.ty, + version: ir.version, + signed_extensions: ir.signed_extensions.into_iter().map(Into::into).collect(), + } + } +} diff --git a/frame/support/src/storage/types/counted_map.rs b/frame/support/src/storage/types/counted_map.rs index 24b00be485e49..e57942cbe0667 100644 --- a/frame/support/src/storage/types/counted_map.rs +++ b/frame/support/src/storage/types/counted_map.rs @@ -18,7 +18,7 @@ //! Storage counted map type. use crate::{ - metadata::StorageEntryMetadata, + metadata_ir::StorageEntryMetadataIR, storage::{ generator::StorageMap as _, types::{ @@ -459,7 +459,7 @@ where OnEmpty: Get + 'static, MaxValues: Get>, { - fn build_metadata(docs: Vec<&'static str>, entries: &mut Vec) { + fn build_metadata(docs: Vec<&'static str>, entries: &mut Vec) { ::Map::build_metadata(docs, entries); CounterFor::::build_metadata( if cfg!(feature = "no-metadata-docs") { @@ -512,7 +512,7 @@ mod test { use super::*; use crate::{ hash::*, - metadata::{StorageEntryModifier, StorageEntryType, StorageHasher}, + metadata_ir::{StorageEntryModifierIR, StorageEntryTypeIR, StorageHasherIR}, storage::{bounded_vec::BoundedVec, types::ValueQuery}, traits::ConstU32, }; @@ -1147,21 +1147,21 @@ mod test { assert_eq!( entries, vec![ - StorageEntryMetadata { + StorageEntryMetadataIR { name: "foo", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Twox64Concat], + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Twox64Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::(), }, default: 97u32.encode(), docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "counter_for_foo", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0, 0, 0, 0], docs: if cfg!(feature = "no-metadata-docs") { vec![] diff --git a/frame/support/src/storage/types/double_map.rs b/frame/support/src/storage/types/double_map.rs index 6a4bdc1e68d72..08ac1709c4b68 100644 --- a/frame/support/src/storage/types/double_map.rs +++ b/frame/support/src/storage/types/double_map.rs @@ -19,7 +19,7 @@ //! StoragePrefixedDoubleMap traits and their methods directly. use crate::{ - metadata::{StorageEntryMetadata, StorageEntryType}, + metadata_ir::{StorageEntryMetadataIR, StorageEntryTypeIR}, storage::{ types::{OptionQuery, QueryKindTrait, StorageEntryMetadataBuilder}, KeyLenOf, StorageAppend, StorageDecodeLength, StoragePrefixedMap, StorageTryAppend, @@ -656,13 +656,13 @@ where OnEmpty: Get + 'static, MaxValues: Get>, { - fn build_metadata(docs: Vec<&'static str>, entries: &mut Vec) { + fn build_metadata(docs: Vec<&'static str>, entries: &mut Vec) { let docs = if cfg!(feature = "no-metadata-docs") { vec![] } else { docs }; - let entry = StorageEntryMetadata { + let entry = StorageEntryMetadataIR { name: Prefix::STORAGE_PREFIX, modifier: QueryKind::METADATA, - ty: StorageEntryType::Map { + ty: StorageEntryTypeIR::Map { hashers: vec![Hasher1::METADATA, Hasher2::METADATA], key: scale_info::meta_type::<(Key1, Key2)>(), value: scale_info::meta_type::(), @@ -736,7 +736,7 @@ mod test { use super::*; use crate::{ hash::*, - metadata::{StorageEntryModifier, StorageEntryType, StorageHasher}, + metadata_ir::{StorageEntryModifierIR, StorageEntryTypeIR, StorageHasherIR}, storage::types::ValueQuery, }; use sp_io::{hashing::twox_128, TestExternalities}; @@ -916,13 +916,13 @@ mod test { assert_eq!( entries, vec![ - StorageEntryMetadata { + StorageEntryMetadataIR { name: "foo", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Map { + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Map { hashers: vec![ - StorageHasher::Blake2_128Concat, - StorageHasher::Twox64Concat + StorageHasherIR::Blake2_128Concat, + StorageHasherIR::Twox64Concat ], key: scale_info::meta_type::<(u16, u8)>(), value: scale_info::meta_type::(), @@ -930,13 +930,13 @@ mod test { default: Option::::None.encode(), docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "foo", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { hashers: vec![ - StorageHasher::Blake2_128Concat, - StorageHasher::Twox64Concat + StorageHasherIR::Blake2_128Concat, + StorageHasherIR::Twox64Concat ], key: scale_info::meta_type::<(u16, u8)>(), value: scale_info::meta_type::(), diff --git a/frame/support/src/storage/types/key.rs b/frame/support/src/storage/types/key.rs index 901bdb8b0514c..bf87e593b063a 100755 --- a/frame/support/src/storage/types/key.rs +++ b/frame/support/src/storage/types/key.rs @@ -41,7 +41,7 @@ pub trait KeyGenerator { type HashFn: FnOnce(&[u8]) -> Vec; type HArg; - const HASHER_METADATA: &'static [crate::metadata::StorageHasher]; + const HASHER_METADATA: &'static [crate::metadata_ir::StorageHasherIR]; /// Given a `key` tuple, calculate the final key by encoding each element individually and /// hashing them using the corresponding hasher in the `KeyGenerator`. @@ -74,7 +74,7 @@ impl KeyGenerator for Key type HashFn = Box Vec>; type HArg = (Self::HashFn,); - const HASHER_METADATA: &'static [crate::metadata::StorageHasher] = &[H::METADATA]; + const HASHER_METADATA: &'static [crate::metadata_ir::StorageHasherIR] = &[H::METADATA]; fn final_key + TupleToEncodedIter>(key: KArg) -> Vec { H::hash(&key.to_encoded_iter().next().expect("should have at least one element!")) @@ -114,7 +114,7 @@ impl KeyGenerator for Tuple { for_tuples!( type HArg = ( #(Tuple::HashFn),* ); ); type HashFn = Box Vec>; - const HASHER_METADATA: &'static [crate::metadata::StorageHasher] = + const HASHER_METADATA: &'static [crate::metadata_ir::StorageHasherIR] = &[for_tuples!( #(Tuple::Hasher::METADATA),* )]; fn final_key + TupleToEncodedIter>(key: KArg) -> Vec { diff --git a/frame/support/src/storage/types/map.rs b/frame/support/src/storage/types/map.rs index 53cf74d26f17c..2110732b2f69c 100644 --- a/frame/support/src/storage/types/map.rs +++ b/frame/support/src/storage/types/map.rs @@ -19,7 +19,7 @@ //! methods directly. use crate::{ - metadata::{StorageEntryMetadata, StorageEntryType}, + metadata_ir::{StorageEntryMetadataIR, StorageEntryTypeIR}, storage::{ types::{OptionQuery, QueryKindTrait, StorageEntryMetadataBuilder}, KeyLenOf, StorageAppend, StorageDecodeLength, StoragePrefixedMap, StorageTryAppend, @@ -409,13 +409,13 @@ where OnEmpty: Get + 'static, MaxValues: Get>, { - fn build_metadata(docs: Vec<&'static str>, entries: &mut Vec) { + fn build_metadata(docs: Vec<&'static str>, entries: &mut Vec) { let docs = if cfg!(feature = "no-metadata-docs") { vec![] } else { docs }; - let entry = StorageEntryMetadata { + let entry = StorageEntryMetadataIR { name: Prefix::STORAGE_PREFIX, modifier: QueryKind::METADATA, - ty: StorageEntryType::Map { + ty: StorageEntryTypeIR::Map { hashers: vec![Hasher::METADATA], key: scale_info::meta_type::(), value: scale_info::meta_type::(), @@ -483,7 +483,7 @@ mod test { use super::*; use crate::{ hash::*, - metadata::{StorageEntryModifier, StorageEntryType, StorageHasher}, + metadata_ir::{StorageEntryModifierIR, StorageEntryTypeIR, StorageHasherIR}, storage::types::ValueQuery, }; use sp_io::{hashing::twox_128, TestExternalities}; @@ -706,22 +706,22 @@ mod test { assert_eq!( entries, vec![ - StorageEntryMetadata { + StorageEntryMetadataIR { name: "foo", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat], + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::(), }, default: Option::::None.encode(), docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "foo", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat], + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::(), }, diff --git a/frame/support/src/storage/types/mod.rs b/frame/support/src/storage/types/mod.rs index 9a6f15d1ee820..3a5bae2e608b7 100644 --- a/frame/support/src/storage/types/mod.rs +++ b/frame/support/src/storage/types/mod.rs @@ -18,7 +18,7 @@ //! Storage types to build abstraction on storage, they implements storage traits such as //! StorageMap and others. -use crate::metadata::{StorageEntryMetadata, StorageEntryModifier}; +use crate::metadata_ir::{StorageEntryMetadataIR, StorageEntryModifierIR}; use codec::FullCodec; use sp_std::prelude::*; @@ -50,7 +50,7 @@ pub use value::StorageValue; /// value. pub trait QueryKindTrait { /// Metadata for the storage kind. - const METADATA: StorageEntryModifier; + const METADATA: StorageEntryModifierIR; /// Type returned on query type Query: FullCodec + 'static; @@ -73,7 +73,7 @@ impl QueryKindTrait for OptionQuery where Value: FullCodec + 'static, { - const METADATA: StorageEntryModifier = StorageEntryModifier::Optional; + const METADATA: StorageEntryModifierIR = StorageEntryModifierIR::Optional; type Query = Option; @@ -95,7 +95,7 @@ where Error: FullCodec + 'static, OnEmpty: crate::traits::Get>, { - const METADATA: StorageEntryModifier = StorageEntryModifier::Optional; + const METADATA: StorageEntryModifierIR = StorageEntryModifierIR::Optional; type Query = Result; @@ -118,7 +118,7 @@ where Value: FullCodec + 'static, OnEmpty: crate::traits::Get, { - const METADATA: StorageEntryModifier = StorageEntryModifier::Default; + const METADATA: StorageEntryModifierIR = StorageEntryModifierIR::Default; type Query = Value; @@ -136,5 +136,5 @@ where /// Implemented by each of the storage types: value, map, countedmap, doublemap and nmap. pub trait StorageEntryMetadataBuilder { /// Build into `entries` the storage metadata entries of a storage given some `docs`. - fn build_metadata(doc: Vec<&'static str>, entries: &mut Vec); + fn build_metadata(doc: Vec<&'static str>, entries: &mut Vec); } diff --git a/frame/support/src/storage/types/nmap.rs b/frame/support/src/storage/types/nmap.rs index d971035968ff2..9b63ca7b0f417 100755 --- a/frame/support/src/storage/types/nmap.rs +++ b/frame/support/src/storage/types/nmap.rs @@ -19,7 +19,7 @@ //! StoragePrefixedDoubleMap traits and their methods directly. use crate::{ - metadata::{StorageEntryMetadata, StorageEntryType}, + metadata_ir::{StorageEntryMetadataIR, StorageEntryTypeIR}, storage::{ types::{ EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, OptionQuery, QueryKindTrait, @@ -550,13 +550,13 @@ where OnEmpty: Get + 'static, MaxValues: Get>, { - fn build_metadata(docs: Vec<&'static str>, entries: &mut Vec) { + fn build_metadata(docs: Vec<&'static str>, entries: &mut Vec) { let docs = if cfg!(feature = "no-metadata-docs") { vec![] } else { docs }; - let entry = StorageEntryMetadata { + let entry = StorageEntryMetadataIR { name: Prefix::STORAGE_PREFIX, modifier: QueryKind::METADATA, - ty: StorageEntryType::Map { + ty: StorageEntryTypeIR::Map { key: scale_info::meta_type::(), hashers: Key::HASHER_METADATA.to_vec(), value: scale_info::meta_type::(), @@ -620,7 +620,7 @@ mod test { use super::*; use crate::{ hash::{StorageHasher as _, *}, - metadata::{StorageEntryModifier, StorageHasher}, + metadata_ir::{StorageEntryModifierIR, StorageHasherIR}, storage::types::{Key as NMapKey, ValueQuery}, }; use sp_io::{hashing::twox_128, TestExternalities}; @@ -791,22 +791,22 @@ mod test { assert_eq!( entries, vec![ - StorageEntryMetadata { + StorageEntryMetadataIR { name: "Foo", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat], + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::(), }, default: Option::::None.encode(), docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "Foo", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat], + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::(), }, @@ -991,13 +991,13 @@ mod test { assert_eq!( entries, vec![ - StorageEntryMetadata { + StorageEntryMetadataIR { name: "Foo", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Map { + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Map { hashers: vec![ - StorageHasher::Blake2_128Concat, - StorageHasher::Twox64Concat + StorageHasherIR::Blake2_128Concat, + StorageHasherIR::Twox64Concat ], key: scale_info::meta_type::<(u16, u8)>(), value: scale_info::meta_type::(), @@ -1005,13 +1005,13 @@ mod test { default: Option::::None.encode(), docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "Foo", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { hashers: vec![ - StorageHasher::Blake2_128Concat, - StorageHasher::Twox64Concat + StorageHasherIR::Blake2_128Concat, + StorageHasherIR::Twox64Concat ], key: scale_info::meta_type::<(u16, u8)>(), value: scale_info::meta_type::(), @@ -1232,14 +1232,14 @@ mod test { assert_eq!( entries, vec![ - StorageEntryMetadata { + StorageEntryMetadataIR { name: "Foo", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Map { + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Map { hashers: vec![ - StorageHasher::Blake2_128Concat, - StorageHasher::Blake2_128Concat, - StorageHasher::Twox64Concat + StorageHasherIR::Blake2_128Concat, + StorageHasherIR::Blake2_128Concat, + StorageHasherIR::Twox64Concat ], key: scale_info::meta_type::<(u16, u16, u16)>(), value: scale_info::meta_type::(), @@ -1247,14 +1247,14 @@ mod test { default: Option::::None.encode(), docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "Foo", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { hashers: vec![ - StorageHasher::Blake2_128Concat, - StorageHasher::Blake2_128Concat, - StorageHasher::Twox64Concat + StorageHasherIR::Blake2_128Concat, + StorageHasherIR::Blake2_128Concat, + StorageHasherIR::Twox64Concat ], key: scale_info::meta_type::<(u16, u16, u16)>(), value: scale_info::meta_type::(), diff --git a/frame/support/src/storage/types/value.rs b/frame/support/src/storage/types/value.rs index 64fb432b2dab1..d5fbb0656bbd1 100644 --- a/frame/support/src/storage/types/value.rs +++ b/frame/support/src/storage/types/value.rs @@ -18,7 +18,7 @@ //! Storage value type. Implements StorageValue trait and its method directly. use crate::{ - metadata::{StorageEntryMetadata, StorageEntryType}, + metadata_ir::{StorageEntryMetadataIR, StorageEntryTypeIR}, storage::{ generator::StorageValue as StorageValueT, types::{OptionQuery, QueryKindTrait, StorageEntryMetadataBuilder}, @@ -221,13 +221,13 @@ where QueryKind: QueryKindTrait, OnEmpty: crate::traits::Get + 'static, { - fn build_metadata(docs: Vec<&'static str>, entries: &mut Vec) { + fn build_metadata(docs: Vec<&'static str>, entries: &mut Vec) { let docs = if cfg!(feature = "no-metadata-docs") { vec![] } else { docs }; - let entry = StorageEntryMetadata { + let entry = StorageEntryMetadataIR { name: Prefix::STORAGE_PREFIX, modifier: QueryKind::METADATA, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: OnEmpty::get().encode(), docs, }; @@ -278,7 +278,7 @@ where #[cfg(test)] mod test { use super::*; - use crate::{metadata::StorageEntryModifier, storage::types::ValueQuery}; + use crate::{metadata_ir::StorageEntryModifierIR, storage::types::ValueQuery}; use sp_io::{hashing::twox_128, TestExternalities}; struct Prefix; @@ -363,17 +363,17 @@ mod test { assert_eq!( entries, vec![ - StorageEntryMetadata { + StorageEntryMetadataIR { name: "foo", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: Option::::None.encode(), docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "foo", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: 97u32.encode(), docs: vec![], } diff --git a/frame/support/test/tests/decl_storage.rs b/frame/support/test/tests/decl_storage.rs index c2ee7742426bb..bee1dc83d5589 100644 --- a/frame/support/test/tests/decl_storage.rs +++ b/frame/support/test/tests/decl_storage.rs @@ -19,7 +19,7 @@ // Do not complain about unused `dispatch` and `dispatch_aux`. #[allow(dead_code)] mod tests { - use frame_support::metadata::*; + use frame_support::metadata_ir::*; use sp_io::TestExternalities; frame_support::decl_module! { @@ -104,195 +104,195 @@ mod tests { type Origin2 = u32; } - fn expected_metadata() -> PalletStorageMetadata { - PalletStorageMetadata { + fn expected_metadata() -> PalletStorageMetadataIR { + PalletStorageMetadataIR { prefix: "TestStorage", entries: vec![ - StorageEntryMetadata { + StorageEntryMetadataIR { name: "U32", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![" Hello, this is doc!"], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "PUBU32", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "U32MYDEF", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "PUBU32MYDEF", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "GETU32", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "PUBGETU32", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "GETU32WITHCONFIG", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "PUBGETU32WITHCONFIG", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "GETU32MYDEF", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "PUBGETU32MYDEF", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![3, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "GETU32WITHCONFIGMYDEF", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![2, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "PUBGETU32WITHCONFIGMYDEF", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![1, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "PUBGETU32WITHCONFIGMYDEFOPT", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "GetU32WithBuilder", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "GetOptU32WithBuilderSome", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "GetOptU32WithBuilderNone", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "MAPU32", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat], + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "PUBMAPU32", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat], + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "GETMAPU32", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat], + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![0, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "PUBGETMAPU32", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat], + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![0, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "GETMAPU32MYDEF", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat], + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![109, 97, 112, 100], // "map" docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "PUBGETMAPU32MYDEF", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Blake2_128Concat], + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![112, 117, 98, 109], // "pubmap" docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "DOUBLEMAP", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Map { + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Map { hashers: vec![ - StorageHasher::Blake2_128Concat, - StorageHasher::Blake2_128Concat, + StorageHasherIR::Blake2_128Concat, + StorageHasherIR::Blake2_128Concat, ], key: scale_info::meta_type::<(u32, u32)>(), value: scale_info::meta_type::<[u8; 4]>(), @@ -300,13 +300,13 @@ mod tests { default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "DOUBLEMAP2", - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Map { + modifier: StorageEntryModifierIR::Optional, + ty: StorageEntryTypeIR::Map { hashers: vec![ - StorageHasher::Blake2_128Concat, - StorageHasher::Blake2_128Concat, + StorageHasherIR::Blake2_128Concat, + StorageHasherIR::Blake2_128Concat, ], key: scale_info::meta_type::<(u32, u32)>(), value: scale_info::meta_type::<[u8; 4]>(), @@ -314,47 +314,50 @@ mod tests { default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "COMPLEXTYPE1", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::<(Option,)>()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::<(Option,)>()), default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "COMPLEXTYPE2", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::<( + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::<( [[(u16, Option<()>); 32]; 12], u32, )>()), default: [0u8; 1156].to_vec(), docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "COMPLEXTYPE3", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::<[u32; 25]>()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::<[u32; 25]>()), default: [0u8; 100].to_vec(), docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "NMAP", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { key: scale_info::meta_type::<(u32, u16)>(), - hashers: vec![StorageHasher::Blake2_128Concat, StorageHasher::Twox64Concat], + hashers: vec![ + StorageHasherIR::Blake2_128Concat, + StorageHasherIR::Twox64Concat, + ], value: scale_info::meta_type::(), }, default: vec![0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "NMAP2", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { key: scale_info::meta_type::(), - hashers: vec![StorageHasher::Blake2_128Concat], + hashers: vec![StorageHasherIR::Blake2_128Concat], value: scale_info::meta_type::(), }, default: vec![0], diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index 8780e18405f27..9b08e175b1ca8 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -20,9 +20,9 @@ use codec::{Codec, Decode, Encode, EncodeLike, MaxEncodedLen}; use frame_support::{ inherent::{InherentData, InherentIdentifier, MakeFatalError, ProvideInherent}, - metadata::{ - PalletStorageMetadata, StorageEntryMetadata, StorageEntryModifier, StorageEntryType, - StorageHasher, + metadata_ir::{ + PalletStorageMetadataIR, StorageEntryMetadataIR, StorageEntryModifierIR, + StorageEntryTypeIR, StorageHasherIR, }, traits::{ConstU32, Get}, Parameter, StorageDoubleMap, StorageMap, StorageValue, @@ -410,33 +410,33 @@ fn storage_with_instance_basic_operation() { }); } -fn expected_metadata() -> PalletStorageMetadata { - PalletStorageMetadata { +fn expected_metadata() -> PalletStorageMetadataIR { + PalletStorageMetadataIR { prefix: "Instance2Module2", entries: vec![ - StorageEntryMetadata { + StorageEntryMetadataIR { name: "Value", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Plain(scale_info::meta_type::()), + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Plain(scale_info::meta_type::()), default: vec![0, 0, 0, 0], docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "Map", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Identity], + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Identity], key: scale_info::meta_type::(), value: scale_info::meta_type::(), }, default: [0u8; 8].to_vec(), docs: vec![], }, - StorageEntryMetadata { + StorageEntryMetadataIR { name: "DoubleMap", - modifier: StorageEntryModifier::Default, - ty: StorageEntryType::Map { - hashers: vec![StorageHasher::Identity, StorageHasher::Identity], + modifier: StorageEntryModifierIR::Default, + ty: StorageEntryTypeIR::Map { + hashers: vec![StorageHasherIR::Identity, StorageHasherIR::Identity], key: scale_info::meta_type::<(u64, u64)>(), value: scale_info::meta_type::(), }, diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index fbebbef455f7b..b9e531fb42105 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -37,6 +37,9 @@ use sp_io::{ }; use sp_runtime::{DispatchError, ModuleError}; +/// Latest stable metadata version used for testing. +const LATEST_METADATA_VERSION: u32 = 14; + pub struct SomeType1; impl From for u64 { fn from(_t: SomeType1) -> Self { @@ -1593,6 +1596,43 @@ fn metadata() { pretty_assertions::assert_eq!(actual_metadata.pallets, expected_metadata.pallets); } +#[test] +fn metadata_at_version() { + use frame_support::metadata::*; + use sp_core::Decode; + + let metadata = Runtime::metadata(); + let at_metadata = match Runtime::metadata_at_version(LATEST_METADATA_VERSION) { + Some(opaque) => { + let bytes = &*opaque; + let metadata: RuntimeMetadataPrefixed = Decode::decode(&mut &bytes[..]).unwrap(); + metadata + }, + _ => panic!("metadata has been bumped, test needs to be updated"), + }; + + assert_eq!(metadata, at_metadata); +} + +#[test] +fn metadata_versions() { + assert_eq!(vec![LATEST_METADATA_VERSION], Runtime::metadata_versions()); +} + +#[test] +fn metadata_ir_pallet_runtime_docs() { + let ir = Runtime::metadata_ir(); + let pallet = ir + .pallets + .iter() + .find(|pallet| pallet.name == "Example") + .expect("Pallet should be present"); + + let readme = "Support code for the runtime.\n\nLicense: Apache-2.0"; + let expected = vec![" Pallet documentation", readme, readme]; + assert_eq!(pallet.docs, expected); +} + #[test] fn test_pallet_runtime_docs() { let docs = crate::pallet::Pallet::::pallet_documentation_metadata(); diff --git a/primitives/api/src/lib.rs b/primitives/api/src/lib.rs index 7542ca3f20ccd..ff101c3add947 100644 --- a/primitives/api/src/lib.rs +++ b/primitives/api/src/lib.rs @@ -729,8 +729,20 @@ decl_runtime_apis! { } /// The `Metadata` api trait that returns metadata for the runtime. + #[api_version(2)] pub trait Metadata { /// Returns the metadata of a runtime. fn metadata() -> OpaqueMetadata; + + /// Returns the metadata at a given version. + /// + /// If the given `version` isn't supported, this will return `None`. + /// Use [`Self::metadata_versions`] to find out about supported metadata version of the runtime. + fn metadata_at_version(version: u32) -> Option; + + /// Returns the supported metadata versions. + /// + /// This can be used to call `metadata_at_version`. + fn metadata_versions() -> sp_std::vec::Vec; } } diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 83b4e2977b5cd..c9a0ac04d63ba 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -437,7 +437,6 @@ cfg_if! { #[derive(Clone, Eq, PartialEq, TypeInfo)] pub struct Runtime; - impl GetNodeBlockType for Runtime { type NodeBlock = Block; } @@ -729,6 +728,14 @@ cfg_if! { fn metadata() -> OpaqueMetadata { unimplemented!() } + + fn metadata_at_version(_version: u32) -> Option { + unimplemented!() + } + + fn metadata_versions() -> sp_std::vec::Vec { + unimplemented!() + } } impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { @@ -1021,6 +1028,14 @@ cfg_if! { fn metadata() -> OpaqueMetadata { unimplemented!() } + + fn metadata_at_version(_version: u32) -> Option { + unimplemented!() + } + + fn metadata_versions() -> sp_std::vec::Vec { + unimplemented!() + } } impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime {