diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index f801068b10fda..feb1a61719852 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -359,6 +359,9 @@ impl_runtime_apis! { } impl sp_api::Metadata for Runtime { + fn metadata_for_pallets(pallets_to_keep: Vec>) -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata_for_pallets(pallets_to_keep).into()) + } fn metadata() -> OpaqueMetadata { OpaqueMetadata::new(Runtime::metadata().into()) } diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 8ed5f1c847f5e..bd03da1e9c607 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1799,6 +1799,9 @@ impl_runtime_apis! { } impl sp_api::Metadata for Runtime { + fn metadata_for_pallets(pallets_to_keep: Vec>) -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata_for_pallets(pallets_to_keep).into()) + } fn metadata() -> OpaqueMetadata { OpaqueMetadata::new(Runtime::metadata().into()) } diff --git a/client/rpc-api/src/state/mod.rs b/client/rpc-api/src/state/mod.rs index 40e208c2eba8d..9ad8e58e4d9d5 100644 --- a/client/rpc-api/src/state/mod.rs +++ b/client/rpc-api/src/state/mod.rs @@ -76,7 +76,7 @@ pub trait StateApi { /// Returns the runtime metadata as an opaque blob. #[method(name = "state_getMetadata", blocking)] - fn metadata(&self, hash: Option) -> RpcResult; + fn metadata(&self, pallets: Option>, hash: Option) -> RpcResult; /// Get the runtime version. #[method(name = "state_getRuntimeVersion", aliases = ["chain_getRuntimeVersion"], blocking)] diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index 7213e4360ae2b..19690ebebca47 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -115,7 +115,9 @@ where ) -> Result, Error>; /// Returns the runtime metadata as an opaque blob. - fn metadata(&self, block: Option) -> Result; + /// + /// If a list of pallet names is provided, only metadata for those pallets will be returned. + fn metadata(&self, pallets: Option>, block: Option) -> Result; /// Get the runtime version. fn runtime_version(&self, block: Option) -> Result; @@ -267,8 +269,8 @@ where self.backend.storage_size(block, key).map_err(Into::into) } - fn metadata(&self, block: Option) -> RpcResult { - self.backend.metadata(block).map_err(Into::into) + fn metadata(&self, pallets: Option>, block: Option) -> RpcResult { + self.backend.metadata(pallets, block).map_err(Into::into) } fn runtime_version(&self, at: Option) -> RpcResult { diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index 42ba70b0af7e7..db3ba3e0b681d 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -296,11 +296,19 @@ where .map_err(client_err) } - fn metadata(&self, block: Option) -> std::result::Result { + fn metadata(&self, pallets: Option>, block: Option) -> std::result::Result { self.block_or_best(block).map_err(client_err).and_then(|block| { - self.client - .runtime_api() - .metadata(&BlockId::Hash(block)) + let api = self.client.runtime_api(); + + let metadata = match pallets { + Some(pallet_names) => { + let name_bytes = pallet_names.into_iter().map(|n| n.into_bytes()).collect(); + api.metadata_for_pallets(&BlockId::Hash(block), name_bytes) + }, + None => api.metadata(&BlockId::Hash(block)) + }; + + metadata .map(Into::into) .map_err(|e| Error::Client(Box::new(e))) }) diff --git a/frame/support/procedural/src/construct_runtime/expand/metadata.rs b/frame/support/procedural/src/construct_runtime/expand/metadata.rs index ec90a0d30f98b..3b7cd4980c4ed 100644 --- a/frame/support/procedural/src/construct_runtime/expand/metadata.rs +++ b/frame/support/procedural/src/construct_runtime/expand/metadata.rs @@ -74,9 +74,25 @@ pub fn expand_runtime_metadata( quote! { impl #runtime { + pub fn metadata_for_pallets(pallets_to_keep: #scrate::sp_std::vec::Vec<#scrate::sp_std::vec::Vec>) -> #scrate::metadata::RuntimeMetadataPrefixed { + Self::metadata_inner(Some(pallets_to_keep)) + } pub fn metadata() -> #scrate::metadata::RuntimeMetadataPrefixed { + Self::metadata_inner(None) + } + fn metadata_inner(pallets_to_keep: Option<#scrate::sp_std::vec::Vec<#scrate::sp_std::vec::Vec>>) -> #scrate::metadata::RuntimeMetadataPrefixed { + let mut pallets = #scrate::sp_std::vec![ #(#pallets),* ]; + + // Filter pallet list to only include those asked for, if provided. + if let Some(pallet_names_to_keep) = pallets_to_keep { + pallets = pallets + .into_iter() + .filter(|p| pallet_names_to_keep.iter().any(|n| n == p.name.as_bytes())) + .collect(); + } + #scrate::metadata::RuntimeMetadataLastVersion::new( - #scrate::sp_std::vec![ #(#pallets),* ], + pallets, #scrate::metadata::ExtrinsicMetadata { ty: #scrate::scale_info::meta_type::<#extrinsic>(), version: <#extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata>::VERSION, diff --git a/primitives/api/src/lib.rs b/primitives/api/src/lib.rs index 91d4b07a1cefc..1af1e46eea001 100644 --- a/primitives/api/src/lib.rs +++ b/primitives/api/src/lib.rs @@ -730,6 +730,9 @@ decl_runtime_apis! { /// The `Metadata` api trait that returns metadata for the runtime. pub trait Metadata { + /// Returns the metadata of a runtime filtered to contain only + /// details about the list of pallets provided. + fn metadata_for_pallets(pallets_to_keep: sp_std::vec::Vec>) -> OpaqueMetadata; /// Returns the metadata of a runtime. fn metadata() -> OpaqueMetadata; } diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index a64e3f25ef041..50bba9060d4f6 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -710,6 +710,9 @@ cfg_if! { } impl sp_api::Metadata for Runtime { + fn metadata_for_pallets(_pallet_names: Vec>) -> OpaqueMetadata { + unimplemented!() + } fn metadata() -> OpaqueMetadata { unimplemented!() } @@ -980,6 +983,9 @@ cfg_if! { } impl sp_api::Metadata for Runtime { + fn metadata_for_pallets(pallet_names_to_keep: Vec>) -> OpaqueMetadata { + unimplemented!() + } fn metadata() -> OpaqueMetadata { unimplemented!() }