RPC: Mark storage methods as blocking (#11459)

* client/api: Make `storage_keys` blocking

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* client/api: Ensure `state_*` RPC methods are blocking

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* client/rpc: Ensure `childstate_*` RPC methods are blocking

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* client/rpc: `ChainApi` make RPC methods sync

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Remove unused async-traits

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* client/rpc-api: Make chain RPC methods blocking

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update client/rpc/src/state/state_full.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Add `blocking` to `state_getKeysPaged` RPC call

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Fix build and warning

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Remove `async_trait` tidyup

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Alexandru Vasile
2022-05-20 22:16:35 +03:00
committed by GitHub
parent 4a71017dd3
commit 87de1e7e0d
8 changed files with 163 additions and 222 deletions
+58 -78
View File
@@ -28,7 +28,7 @@ use std::sync::Arc;
use crate::SubscriptionTaskExecutor;
use jsonrpsee::{
core::{async_trait, Error as JsonRpseeError, RpcResult},
core::{Error as JsonRpseeError, RpcResult},
ws_server::PendingSubscription,
};
@@ -53,14 +53,13 @@ use sp_blockchain::{HeaderBackend, HeaderMetadata};
const STORAGE_KEYS_PAGED_MAX_COUNT: u32 = 1000;
/// State backend API.
#[async_trait]
pub trait StateBackend<Block: BlockT, Client>: Send + Sync + 'static
where
Block: BlockT + 'static,
Client: Send + Sync + 'static,
{
/// Call runtime method at given block.
async fn call(
fn call(
&self,
block: Option<Block::Hash>,
method: String,
@@ -68,21 +67,21 @@ where
) -> Result<Bytes, Error>;
/// Returns the keys with prefix, leave empty to get all the keys.
async fn storage_keys(
fn storage_keys(
&self,
block: Option<Block::Hash>,
prefix: StorageKey,
) -> Result<Vec<StorageKey>, Error>;
/// Returns the keys with prefix along with their values, leave empty to get all the pairs.
async fn storage_pairs(
fn storage_pairs(
&self,
block: Option<Block::Hash>,
prefix: StorageKey,
) -> Result<Vec<(StorageKey, StorageData)>, Error>;
/// Returns the keys with prefix with pagination support.
async fn storage_keys_paged(
fn storage_keys_paged(
&self,
block: Option<Block::Hash>,
prefix: Option<StorageKey>,
@@ -91,14 +90,14 @@ where
) -> Result<Vec<StorageKey>, Error>;
/// Returns a storage entry at a specific block's state.
async fn storage(
fn storage(
&self,
block: Option<Block::Hash>,
key: StorageKey,
) -> Result<Option<StorageData>, Error>;
/// Returns the hash of a storage entry at a block's state.
async fn storage_hash(
fn storage_hash(
&self,
block: Option<Block::Hash>,
key: StorageKey,
@@ -108,24 +107,24 @@ where
///
/// 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.
async fn storage_size(
fn storage_size(
&self,
block: Option<Block::Hash>,
key: StorageKey,
) -> Result<Option<u64>, Error>;
/// Returns the runtime metadata as an opaque blob.
async fn metadata(&self, block: Option<Block::Hash>) -> Result<Bytes, Error>;
fn metadata(&self, block: Option<Block::Hash>) -> Result<Bytes, Error>;
/// Get the runtime version.
async fn runtime_version(&self, block: Option<Block::Hash>) -> Result<RuntimeVersion, Error>;
fn runtime_version(&self, block: Option<Block::Hash>) -> Result<RuntimeVersion, Error>;
/// Query historical storage entries (by key) starting from a block given as the second
/// parameter.
///
/// NOTE This first returned result contains the initial state of storage for all keys.
/// Subsequent values in the vector represent changes to the previous state (diffs).
async fn query_storage(
fn query_storage(
&self,
from: Block::Hash,
to: Option<Block::Hash>,
@@ -133,21 +132,21 @@ where
) -> Result<Vec<StorageChangeSet<Block::Hash>>, Error>;
/// Query storage entries (by key) starting at block hash given as the second parameter.
async fn query_storage_at(
fn query_storage_at(
&self,
keys: Vec<StorageKey>,
at: Option<Block::Hash>,
) -> Result<Vec<StorageChangeSet<Block::Hash>>, Error>;
/// Returns proof of storage entries at a specific block's state.
async fn read_proof(
fn read_proof(
&self,
block: Option<Block::Hash>,
keys: Vec<StorageKey>,
) -> Result<ReadProof<Block::Hash>, Error>;
/// Trace storage changes for block
async fn trace_block(
fn trace_block(
&self,
block: Block::Hash,
targets: Option<String>,
@@ -203,39 +202,33 @@ pub struct StateApi<Block, Client> {
deny_unsafe: DenyUnsafe,
}
#[async_trait]
impl<Block, Client> StateApiServer<Block::Hash> for StateApi<Block, Client>
where
Block: BlockT + 'static,
Client: Send + Sync + 'static,
{
async fn call(
&self,
method: String,
data: Bytes,
block: Option<Block::Hash>,
) -> RpcResult<Bytes> {
self.backend.call(block, method, data).await.map_err(Into::into)
fn call(&self, method: String, data: Bytes, block: Option<Block::Hash>) -> RpcResult<Bytes> {
self.backend.call(block, method, data).map_err(Into::into)
}
async fn storage_keys(
fn storage_keys(
&self,
key_prefix: StorageKey,
block: Option<Block::Hash>,
) -> RpcResult<Vec<StorageKey>> {
self.backend.storage_keys(block, key_prefix).await.map_err(Into::into)
self.backend.storage_keys(block, key_prefix).map_err(Into::into)
}
async fn storage_pairs(
fn storage_pairs(
&self,
key_prefix: StorageKey,
block: Option<Block::Hash>,
) -> RpcResult<Vec<(StorageKey, StorageData)>> {
self.deny_unsafe.check_if_safe()?;
self.backend.storage_pairs(block, key_prefix).await.map_err(Into::into)
self.backend.storage_pairs(block, key_prefix).map_err(Into::into)
}
async fn storage_keys_paged(
fn storage_keys_paged(
&self,
prefix: Option<StorageKey>,
count: u32,
@@ -250,66 +243,61 @@ where
}
self.backend
.storage_keys_paged(block, prefix, count, start_key)
.await
.map_err(Into::into)
}
async fn storage(
fn storage(
&self,
key: StorageKey,
block: Option<Block::Hash>,
) -> RpcResult<Option<StorageData>> {
self.backend.storage(block, key).await.map_err(Into::into)
self.backend.storage(block, key).map_err(Into::into)
}
async fn storage_hash(
fn storage_hash(
&self,
key: StorageKey,
block: Option<Block::Hash>,
) -> RpcResult<Option<Block::Hash>> {
self.backend.storage_hash(block, key).await.map_err(Into::into)
self.backend.storage_hash(block, key).map_err(Into::into)
}
async fn storage_size(
&self,
key: StorageKey,
block: Option<Block::Hash>,
) -> RpcResult<Option<u64>> {
self.backend.storage_size(block, key).await.map_err(Into::into)
fn storage_size(&self, key: StorageKey, block: Option<Block::Hash>) -> RpcResult<Option<u64>> {
self.backend.storage_size(block, key).map_err(Into::into)
}
async fn metadata(&self, block: Option<Block::Hash>) -> RpcResult<Bytes> {
self.backend.metadata(block).await.map_err(Into::into)
fn metadata(&self, block: Option<Block::Hash>) -> RpcResult<Bytes> {
self.backend.metadata(block).map_err(Into::into)
}
async fn runtime_version(&self, at: Option<Block::Hash>) -> RpcResult<RuntimeVersion> {
self.backend.runtime_version(at).await.map_err(Into::into)
fn runtime_version(&self, at: Option<Block::Hash>) -> RpcResult<RuntimeVersion> {
self.backend.runtime_version(at).map_err(Into::into)
}
async fn query_storage(
fn query_storage(
&self,
keys: Vec<StorageKey>,
from: Block::Hash,
to: Option<Block::Hash>,
) -> RpcResult<Vec<StorageChangeSet<Block::Hash>>> {
self.deny_unsafe.check_if_safe()?;
self.backend.query_storage(from, to, keys).await.map_err(Into::into)
self.backend.query_storage(from, to, keys).map_err(Into::into)
}
async fn query_storage_at(
fn query_storage_at(
&self,
keys: Vec<StorageKey>,
at: Option<Block::Hash>,
) -> RpcResult<Vec<StorageChangeSet<Block::Hash>>> {
self.backend.query_storage_at(keys, at).await.map_err(Into::into)
self.backend.query_storage_at(keys, at).map_err(Into::into)
}
async fn read_proof(
fn read_proof(
&self,
keys: Vec<StorageKey>,
block: Option<Block::Hash>,
) -> RpcResult<ReadProof<Block::Hash>> {
self.backend.read_proof(block, keys).await.map_err(Into::into)
self.backend.read_proof(block, keys).map_err(Into::into)
}
/// Re-execute the given block with the tracing targets given in `targets`
@@ -317,7 +305,7 @@ where
///
/// Note: requires the node to run with `--rpc-methods=Unsafe`.
/// Note: requires runtimes compiled with wasm tracing support, `--features with-tracing`.
async fn trace_block(
fn trace_block(
&self,
block: Block::Hash,
targets: Option<String>,
@@ -327,7 +315,6 @@ where
self.deny_unsafe.check_if_safe()?;
self.backend
.trace_block(block, targets, storage_keys, methods)
.await
.map_err(Into::into)
}
@@ -348,14 +335,13 @@ where
}
/// Child state backend API.
#[async_trait]
pub trait ChildStateBackend<Block: BlockT, Client>: Send + Sync + 'static
where
Block: BlockT + 'static,
Client: Send + Sync + 'static,
{
/// Returns proof of storage for a child key entries at a specific block's state.
async fn read_child_proof(
fn read_child_proof(
&self,
block: Option<Block::Hash>,
storage_key: PrefixedStorageKey,
@@ -364,7 +350,7 @@ where
/// Returns the keys with prefix from a child storage,
/// leave prefix empty to get all the keys.
async fn storage_keys(
fn storage_keys(
&self,
block: Option<Block::Hash>,
storage_key: PrefixedStorageKey,
@@ -372,7 +358,7 @@ where
) -> Result<Vec<StorageKey>, Error>;
/// Returns the keys with prefix from a child storage with pagination support.
async fn storage_keys_paged(
fn storage_keys_paged(
&self,
block: Option<Block::Hash>,
storage_key: PrefixedStorageKey,
@@ -382,7 +368,7 @@ where
) -> Result<Vec<StorageKey>, Error>;
/// Returns a child storage entry at a specific block's state.
async fn storage(
fn storage(
&self,
block: Option<Block::Hash>,
storage_key: PrefixedStorageKey,
@@ -390,7 +376,7 @@ where
) -> Result<Option<StorageData>, Error>;
/// Returns child storage entries at a specific block's state.
async fn storage_entries(
fn storage_entries(
&self,
block: Option<Block::Hash>,
storage_key: PrefixedStorageKey,
@@ -398,7 +384,7 @@ where
) -> Result<Vec<Option<StorageData>>, Error>;
/// Returns the hash of a child storage entry at a block's state.
async fn storage_hash(
fn storage_hash(
&self,
block: Option<Block::Hash>,
storage_key: PrefixedStorageKey,
@@ -406,13 +392,13 @@ where
) -> Result<Option<Block::Hash>, Error>;
/// Returns the size of a child storage entry at a block's state.
async fn storage_size(
fn storage_size(
&self,
block: Option<Block::Hash>,
storage_key: PrefixedStorageKey,
key: StorageKey,
) -> Result<Option<u64>, Error> {
self.storage(block, storage_key, key).await.map(|x| x.map(|x| x.0.len() as u64))
self.storage(block, storage_key, key).map(|x| x.map(|x| x.0.len() as u64))
}
}
@@ -421,25 +407,21 @@ pub struct ChildState<Block, Client> {
backend: Box<dyn ChildStateBackend<Block, Client>>,
}
#[async_trait]
impl<Block, Client> ChildStateApiServer<Block::Hash> for ChildState<Block, Client>
where
Block: BlockT + 'static,
Client: Send + Sync + 'static,
{
async fn storage_keys(
fn storage_keys(
&self,
storage_key: PrefixedStorageKey,
key_prefix: StorageKey,
block: Option<Block::Hash>,
) -> RpcResult<Vec<StorageKey>> {
self.backend
.storage_keys(block, storage_key, key_prefix)
.await
.map_err(Into::into)
self.backend.storage_keys(block, storage_key, key_prefix).map_err(Into::into)
}
async fn storage_keys_paged(
fn storage_keys_paged(
&self,
storage_key: PrefixedStorageKey,
prefix: Option<StorageKey>,
@@ -449,47 +431,46 @@ where
) -> RpcResult<Vec<StorageKey>> {
self.backend
.storage_keys_paged(block, storage_key, prefix, count, start_key)
.await
.map_err(Into::into)
}
async fn storage(
fn storage(
&self,
storage_key: PrefixedStorageKey,
key: StorageKey,
block: Option<Block::Hash>,
) -> RpcResult<Option<StorageData>> {
self.backend.storage(block, storage_key, key).await.map_err(Into::into)
self.backend.storage(block, storage_key, key).map_err(Into::into)
}
async fn storage_entries(
fn storage_entries(
&self,
storage_key: PrefixedStorageKey,
keys: Vec<StorageKey>,
block: Option<Block::Hash>,
) -> RpcResult<Vec<Option<StorageData>>> {
self.backend.storage_entries(block, storage_key, keys).await.map_err(Into::into)
self.backend.storage_entries(block, storage_key, keys).map_err(Into::into)
}
async fn storage_hash(
fn storage_hash(
&self,
storage_key: PrefixedStorageKey,
key: StorageKey,
block: Option<Block::Hash>,
) -> RpcResult<Option<Block::Hash>> {
self.backend.storage_hash(block, storage_key, key).await.map_err(Into::into)
self.backend.storage_hash(block, storage_key, key).map_err(Into::into)
}
async fn storage_size(
fn storage_size(
&self,
storage_key: PrefixedStorageKey,
key: StorageKey,
block: Option<Block::Hash>,
) -> RpcResult<Option<u64>> {
self.backend.storage_size(block, storage_key, key).await.map_err(Into::into)
self.backend.storage_size(block, storage_key, key).map_err(Into::into)
}
async fn read_child_proof(
fn read_child_proof(
&self,
child_storage_key: PrefixedStorageKey,
keys: Vec<StorageKey>,
@@ -497,7 +478,6 @@ where
) -> RpcResult<ReadProof<Block::Hash>> {
self.backend
.read_child_proof(block, child_storage_key, keys)
.await
.map_err(Into::into)
}
}