Add Runtime API to execute runtime calls (#777)

* rpc: Add RuntimeAPI call via `state_call` method

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

* subxt: Add runtime API

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

* Expose the RuntimeAPI client

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

* tests: Test the runtime API call against the metadata

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

* client: Fetch the metadata from runtime API

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

* blocks: Fix doc typo

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

* blocks: Use &str instead of String to identify fn names

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

* Update subxt/src/runtime_api/runtime_client.rs

Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
This commit is contained in:
Alexandru Vasile
2023-01-18 17:49:20 +02:00
committed by GitHub
parent 8ef80638d0
commit b4bb17662a
10 changed files with 252 additions and 1 deletions
+6
View File
@@ -7,6 +7,7 @@ use crate::{
constants::ConstantsClient,
events::EventsClient,
rpc::types::RuntimeVersion,
runtime_api::RuntimeApiClient,
storage::StorageClient,
tx::TxClient,
Config,
@@ -49,6 +50,11 @@ pub trait OfflineClientT<T: Config>: Clone + Send + Sync + 'static {
fn blocks(&self) -> BlocksClient<T, Self> {
BlocksClient::new(self.clone())
}
/// Work with runtime API.
fn runtime_api(&self) -> RuntimeApiClient<T, Self> {
RuntimeApiClient::new(self.clone())
}
}
/// A client that is capable of performing offline-only operations.
+21 -1
View File
@@ -19,12 +19,18 @@ use crate::{
Rpc,
RpcClientT,
},
runtime_api::RuntimeApiClient,
storage::StorageClient,
tx::TxClient,
Config,
Metadata,
};
use codec::{
Compact,
Decode,
};
use derivative::Derivative;
use frame_metadata::RuntimeMetadataPrefixed;
use futures::future;
use parking_lot::RwLock;
use std::sync::Arc;
@@ -95,7 +101,7 @@ impl<T: Config> OnlineClient<T> {
let (genesis_hash, runtime_version, metadata) = future::join3(
rpc.genesis_hash(),
rpc.runtime_version(None),
rpc.metadata(None),
OnlineClient::fetch_metadata(&rpc),
)
.await;
@@ -109,6 +115,15 @@ impl<T: Config> OnlineClient<T> {
})
}
/// Fetch the metadata from substrate using the runtime API.
async fn fetch_metadata(rpc: &Rpc<T>) -> Result<Metadata, Error> {
let bytes = rpc.state_call("Metadata_metadata", None, None).await?;
let cursor = &mut &*bytes;
let _ = <Compact<u32>>::decode(cursor)?;
let meta: RuntimeMetadataPrefixed = Decode::decode(cursor)?;
Ok(meta.try_into()?)
}
/// Create an object which can be used to keep the runtime up to date
/// in a separate thread.
///
@@ -214,6 +229,11 @@ impl<T: Config> OnlineClient<T> {
pub fn blocks(&self) -> BlocksClient<T, Self> {
<Self as OfflineClientT<T>>::blocks(self)
}
/// Work with runtime API.
pub fn runtime_api(&self) -> RuntimeApiClient<T, Self> {
<Self as OfflineClientT<T>>::runtime_api(self)
}
}
impl<T: Config> OfflineClientT<T> for OnlineClient<T> {