diff --git a/substrate/client/rpc-api/src/child_state/mod.rs b/substrate/client/rpc-api/src/child_state/mod.rs index 7efff74225..cffb1590c7 100644 --- a/substrate/client/rpc-api/src/child_state/mod.rs +++ b/substrate/client/rpc-api/src/child_state/mod.rs @@ -23,6 +23,7 @@ use sp_core::storage::{StorageKey, PrefixedStorageKey, StorageData}; use crate::state::error::FutureResult; pub use self::gen_client::Client as ChildStateClient; +use crate::state::ReadProof; /// Substrate child state API /// @@ -68,4 +69,13 @@ pub trait ChildStateApi { key: StorageKey, hash: Option ) -> FutureResult>; + + /// Returns proof of storage for child key entries at a specific block's state. + #[rpc(name = "state_getChildReadProof")] + fn read_child_proof( + &self, + child_storage_key: PrefixedStorageKey, + keys: Vec, + hash: Option, + ) -> FutureResult>; } diff --git a/substrate/client/rpc/src/state/mod.rs b/substrate/client/rpc/src/state/mod.rs index dc36c2f561..803fc6797e 100644 --- a/substrate/client/rpc/src/state/mod.rs +++ b/substrate/client/rpc/src/state/mod.rs @@ -382,6 +382,14 @@ pub trait ChildStateBackend: Send + Sync + 'static Block: BlockT + 'static, Client: Send + Sync + 'static, { + /// Returns proof of storage for a child key entries at a specific block's state. + fn read_child_proof( + &self, + block: Option, + storage_key: PrefixedStorageKey, + keys: Vec, + ) -> FutureResult>; + /// Returns the keys with prefix from a child storage, /// leave prefix empty to get all the keys. fn storage_keys( @@ -431,6 +439,15 @@ impl ChildStateApi for ChildState { type Metadata = crate::Metadata; + fn read_child_proof( + &self, + child_storage_key: PrefixedStorageKey, + keys: Vec, + block: Option, + ) -> FutureResult> { + self.backend.read_child_proof(block, child_storage_key, keys) + } + fn storage( &self, storage_key: PrefixedStorageKey, @@ -466,6 +483,7 @@ impl ChildStateApi for ChildState ) -> FutureResult> { self.backend.storage_size(block, storage_key, key) } + } fn client_err(err: sp_blockchain::Error) -> Error { diff --git a/substrate/client/rpc/src/state/state_full.rs b/substrate/client/rpc/src/state/state_full.rs index c75106512d..bea7ddfbb3 100644 --- a/substrate/client/rpc/src/state/state_full.rs +++ b/substrate/client/rpc/src/state/state_full.rs @@ -552,12 +552,39 @@ impl ChildStateBackend for FullState + 'static, Client: ExecutorProvider + StorageProvider + + ProofProvider + HeaderBackend + BlockBackend + HeaderMetadata + BlockchainEvents + CallApiAt + ProvideRuntimeApi + Send + Sync + 'static, Client::Api: Metadata, { + fn read_child_proof( + &self, + block: Option, + storage_key: PrefixedStorageKey, + keys: Vec, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| { + let child_info = match ChildType::from_prefixed_key(&storage_key) { + Some((ChildType::ParentKeyId, storage_key)) => ChildInfo::new_default(storage_key), + None => return Err(sp_blockchain::Error::InvalidChildStorageKey), + }; + self.client + .read_child_proof( + &BlockId::Hash(block), + &child_info, + &mut keys.iter().map(|key| key.0.as_ref()), + ) + .map(|proof| proof.iter_nodes().map(|node| node.into()).collect()) + .map(|proof| ReadProof { at: block, proof }) + }) + .map_err(client_err), + )) + } + fn storage_keys( &self, block: Option, diff --git a/substrate/client/rpc/src/state/state_light.rs b/substrate/client/rpc/src/state/state_light.rs index 21b99befc0..09fefd2e02 100644 --- a/substrate/client/rpc/src/state/state_light.rs +++ b/substrate/client/rpc/src/state/state_light.rs @@ -491,6 +491,15 @@ impl ChildStateBackend for LightState + HeaderBackend + Send + Sync + 'static, F: Fetcher + 'static { + fn read_child_proof( + &self, + _block: Option, + _storage_key: PrefixedStorageKey, + _keys: Vec, + ) -> FutureResult> { + Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) + } + fn storage_keys( &self, _block: Option,