mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-16 22:31:03 +00:00
state_getSize RPC for storage maps (#6847)
* Fancy compact encode/decode impl for compact solution * Make it optional * Remove extra file * Update primitives/npos-elections/compact/src/lib.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Final fixes. * getSize rpc should work for maps as well * Fix future types * Remove minimum_validator_count stale const * Update client/rpc/src/state/mod.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * "Optimize" `storage_size` * Remove unused import * Update doc Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
@@ -97,14 +97,14 @@ pub trait StateBackend<Block: BlockT, Client>: Send + Sync + 'static
|
|||||||
) -> FutureResult<Option<Block::Hash>>;
|
) -> FutureResult<Option<Block::Hash>>;
|
||||||
|
|
||||||
/// Returns the size of a storage entry at a block's state.
|
/// Returns the size of a storage entry at a block's state.
|
||||||
|
///
|
||||||
|
/// If data is available at `key`, it is returned. Else, the sum of values who's key has `key`
|
||||||
|
/// prefix is returned, i.e. all the storage (double) maps that have this prefix.
|
||||||
fn storage_size(
|
fn storage_size(
|
||||||
&self,
|
&self,
|
||||||
block: Option<Block::Hash>,
|
block: Option<Block::Hash>,
|
||||||
key: StorageKey,
|
key: StorageKey,
|
||||||
) -> FutureResult<Option<u64>> {
|
) -> FutureResult<Option<u64>>;
|
||||||
Box::new(self.storage(block, key)
|
|
||||||
.map(|x| x.map(|x| x.0.len() as u64)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the runtime metadata as an opaque blob.
|
/// Returns the runtime metadata as an opaque blob.
|
||||||
fn metadata(&self, block: Option<Block::Hash>) -> FutureResult<Bytes>;
|
fn metadata(&self, block: Option<Block::Hash>) -> FutureResult<Bytes>;
|
||||||
|
|||||||
@@ -298,6 +298,36 @@ impl<BE, Block, Client> StateBackend<Block, Client> for FullState<BE, Block, Cli
|
|||||||
.map_err(client_err)))
|
.map_err(client_err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_size(
|
||||||
|
&self,
|
||||||
|
block: Option<Block::Hash>,
|
||||||
|
key: StorageKey,
|
||||||
|
) -> FutureResult<Option<u64>> {
|
||||||
|
let block = match self.block_or_best(block) {
|
||||||
|
Ok(b) => b,
|
||||||
|
Err(e) => return Box::new(result(Err(client_err(e)))),
|
||||||
|
};
|
||||||
|
|
||||||
|
match self.client.storage(&BlockId::Hash(block), &key) {
|
||||||
|
Ok(Some(d)) => return Box::new(result(Ok(Some(d.0.len() as u64)))),
|
||||||
|
Err(e) => return Box::new(result(Err(client_err(e)))),
|
||||||
|
Ok(None) => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
Box::new(result(
|
||||||
|
self.client.storage_pairs(&BlockId::Hash(block), &key)
|
||||||
|
.map(|kv| {
|
||||||
|
let item_sum = kv.iter().map(|(_, v)| v.0.len() as u64).sum::<u64>();
|
||||||
|
if item_sum > 0 {
|
||||||
|
Some(item_sum)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map_err(client_err)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
fn storage_hash(
|
fn storage_hash(
|
||||||
&self,
|
&self,
|
||||||
block: Option<Block::Hash>,
|
block: Option<Block::Hash>,
|
||||||
|
|||||||
@@ -214,6 +214,14 @@ impl<Block, F, Client> StateBackend<Block, Client> for LightState<Block, F, Clie
|
|||||||
Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
|
Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_size(
|
||||||
|
&self,
|
||||||
|
_: Option<Block::Hash>,
|
||||||
|
_: StorageKey,
|
||||||
|
) -> FutureResult<Option<u64>> {
|
||||||
|
Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
|
||||||
|
}
|
||||||
|
|
||||||
fn storage(
|
fn storage(
|
||||||
&self,
|
&self,
|
||||||
block: Option<Block::Hash>,
|
block: Option<Block::Hash>,
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ fn should_return_storage() {
|
|||||||
let client = TestClientBuilder::new()
|
let client = TestClientBuilder::new()
|
||||||
.add_extra_storage(KEY.to_vec(), VALUE.to_vec())
|
.add_extra_storage(KEY.to_vec(), VALUE.to_vec())
|
||||||
.add_extra_child_storage(&child_info, KEY.to_vec(), CHILD_VALUE.to_vec())
|
.add_extra_child_storage(&child_info, KEY.to_vec(), CHILD_VALUE.to_vec())
|
||||||
|
// similar to a map with two keys
|
||||||
|
.add_extra_storage(b":map:acc1".to_vec(), vec![1, 2])
|
||||||
|
.add_extra_storage(b":map:acc2".to_vec(), vec![1, 2, 3])
|
||||||
.build();
|
.build();
|
||||||
let genesis_hash = client.genesis_hash();
|
let genesis_hash = client.genesis_hash();
|
||||||
let (client, child) = new_full(Arc::new(client), SubscriptionManager::new(Arc::new(TaskExecutor)));
|
let (client, child) = new_full(Arc::new(client), SubscriptionManager::new(Arc::new(TaskExecutor)));
|
||||||
@@ -72,6 +75,10 @@ fn should_return_storage() {
|
|||||||
client.storage_size(key.clone(), None).wait().unwrap().unwrap() as usize,
|
client.storage_size(key.clone(), None).wait().unwrap().unwrap() as usize,
|
||||||
VALUE.len(),
|
VALUE.len(),
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
client.storage_size(StorageKey(b":map".to_vec()), None).wait().unwrap().unwrap() as usize,
|
||||||
|
2 + 3,
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
executor::block_on(
|
executor::block_on(
|
||||||
child.storage(prefixed_storage_key(), key, Some(genesis_hash).into())
|
child.storage(prefixed_storage_key(), key, Some(genesis_hash).into())
|
||||||
@@ -80,7 +87,6 @@ fn should_return_storage() {
|
|||||||
).unwrap().unwrap() as usize,
|
).unwrap().unwrap() as usize,
|
||||||
CHILD_VALUE.len(),
|
CHILD_VALUE.len(),
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user