Skip to content

Commit

Permalink
Additional RPC for dumping all main storage key pairs under a prefix (p…
Browse files Browse the repository at this point in the history
…aritytech#4803)

* Merge branch 'gav-split-balanecs-vesting' into gav-upsub

# Conflicts:
#	Cargo.lock
#	cli/Cargo.toml
#	collator/Cargo.toml
#	primitives/Cargo.toml
#	runtime/common/Cargo.toml
#	runtime/common/src/claims.rs
#	runtime/kusama/Cargo.toml
#	runtime/polkadot/Cargo.toml
#	service/Cargo.toml

* Update client/src/client.rs

* Update client/src/client.rs

* Fix merge conflict

Co-authored-by: Bastian Köcher <[email protected]>
  • Loading branch information
gavofyork and bkchr authored Feb 5, 2020
1 parent 4e0e8c1 commit 53008ba
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 2 deletions.
4 changes: 4 additions & 0 deletions client/rpc-api/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ pub trait StateApi<Hash> {
#[rpc(name = "state_getKeys")]
fn storage_keys(&self, prefix: StorageKey, hash: Option<Hash>) -> FutureResult<Vec<StorageKey>>;

/// Returns the keys with prefix, leave empty to get all the keys
#[rpc(name = "state_getPairs")]
fn storage_pairs(&self, prefix: StorageKey, hash: Option<Hash>) -> FutureResult<Vec<(StorageKey, StorageData)>>;

/// Returns the keys with prefix with pagination support.
/// Up to `count` keys will be returned.
/// If `start_key` is passed, return next keys in storage in lexicographic order.
Expand Down
15 changes: 15 additions & 0 deletions client/rpc/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ pub trait StateBackend<B, E, Block: BlockT, RA>: Send + Sync + 'static
prefix: StorageKey,
) -> FutureResult<Vec<StorageKey>>;

/// Returns the keys with prefix along with their values, leave empty to get all the pairs.
fn storage_pairs(
&self,
block: Option<Block::Hash>,
prefix: StorageKey,
) -> FutureResult<Vec<(StorageKey, StorageData)>>;

/// Returns the keys with prefix with pagination support.
fn storage_keys_paged(
&self,
Expand Down Expand Up @@ -255,6 +262,14 @@ impl<B, E, Block, RA> StateApi<Block::Hash> for State<B, E, Block, RA>
self.backend.storage_keys(block, key_prefix)
}

fn storage_pairs(
&self,
key_prefix: StorageKey,
block: Option<Block::Hash>,
) -> FutureResult<Vec<(StorageKey, StorageData)>> {
self.backend.storage_pairs(block, key_prefix)
}

fn storage_keys_paged(
&self,
prefix: Option<StorageKey>,
Expand Down
11 changes: 11 additions & 0 deletions client/rpc/src/state/state_full.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,17 @@ impl<B, E, Block, RA> StateBackend<B, E, Block, RA> for FullState<B, E, Block, R
.map_err(client_err)))
}

fn storage_pairs(
&self,
block: Option<Block::Hash>,
prefix: StorageKey,
) -> FutureResult<Vec<(StorageKey, StorageData)>> {
Box::new(result(
self.block_or_best(block)
.and_then(|block| self.client.storage_pairs(&BlockId::Hash(block), &prefix))
.map_err(client_err)))
}

fn storage_keys_paged(
&self,
block: Option<Block::Hash>,
Expand Down
8 changes: 8 additions & 0 deletions client/rpc/src/state/state_light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,14 @@ impl<Block, F, B, E, RA> StateBackend<B, E, Block, RA> for LightState<Block, F,
Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
}

fn storage_pairs(
&self,
_block: Option<Block::Hash>,
_prefix: StorageKey,
) -> FutureResult<Vec<(StorageKey, StorageData)>> {
Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
}

fn storage_keys_paged(
&self,
_block: Option<Block::Hash>,
Expand Down
23 changes: 21 additions & 2 deletions client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,22 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
Ok(keys)
}

/// Given a `BlockId` and a key prefix, return the matching child storage keys and values in that block.
pub fn storage_pairs(&self, id: &BlockId<Block>, key_prefix: &StorageKey)
-> sp_blockchain::Result<Vec<(StorageKey, StorageData)>>
{
let state = self.state_at(id)?;
let keys = state
.keys(&key_prefix.0)
.into_iter()
.map(|k| {
let d = state.storage(&k).ok().flatten().unwrap_or_default();
(StorageKey(k), StorageData(d))
})
.collect();
Ok(keys)
}

/// Given a `BlockId` and a key prefix, return a `KeyIterator` iterates matching storage keys in that block.
pub fn storage_keys_iter<'a>(
&self,
Expand All @@ -296,7 +312,9 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
}

/// Given a `BlockId` and a key, return the value under the key in that block.
pub fn storage(&self, id: &BlockId<Block>, key: &StorageKey) -> sp_blockchain::Result<Option<StorageData>> {
pub fn storage(&self, id: &BlockId<Block>, key: &StorageKey)
-> sp_blockchain::Result<Option<StorageData>>
{
Ok(self.state_at(id)?
.storage(&key.0).map_err(|e| sp_blockchain::Error::from_state(Box::new(e)))?
.map(StorageData)
Expand All @@ -305,7 +323,8 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where

/// Given a `BlockId` and a key, return the value under the hash in that block.
pub fn storage_hash(&self, id: &BlockId<Block>, key: &StorageKey)
-> sp_blockchain::Result<Option<Block::Hash>> {
-> sp_blockchain::Result<Option<Block::Hash>>
{
Ok(self.state_at(id)?
.storage_hash(&key.0).map_err(|e| sp_blockchain::Error::from_state(Box::new(e)))?
)
Expand Down

0 comments on commit 53008ba

Please sign in to comment.