try-runtime-cli: Add execute-block subcommand (#9077)

* Refactor remote_externalities::rpc_api

* try-runtime-cli: Adde `execute-block` subcommand

* Trivial

* Address some comments

* Use required_if & remove header-at usage

* Improve doc

* Update comment

* small tweaks

* add overwrite-code to shared params

* Update utils/frame/try-runtime/cli/src/lib.rs

Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com>

* make url a shared param

* add helper for block_at (#9153)

* add helper for block_at

* remove redundant bound

* doc for fn block_at

* Update error message

Co-authored-by: kianenigma <kian@parity.io>
Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com>
This commit is contained in:
Zeke Mostov
2021-06-22 13:36:12 -07:00
committed by GitHub
parent 1eca7767fe
commit b9d03f25da
6 changed files with 298 additions and 102 deletions
@@ -18,36 +18,65 @@
//! WS RPC API for one off RPC calls to a substrate node.
// TODO: Consolidate one off RPC calls https://github.com/paritytech/substrate/issues/8988
use super::*;
use sp_runtime::{generic::SignedBlock, traits::{Block as BlockT, Header as HeaderT}};
use jsonrpsee_ws_client::{WsClientBuilder, WsClient, v2::params::JsonRpcParams, traits::Client};
/// Get the header of the block identified by `at`
pub async fn get_header<B: BlockT, S: AsRef<str>>(from: S, at: B::Hash) -> Result<B::Header, String>
pub async fn get_header<Block, S>(from: S, at: Block::Hash) -> Result<Block::Header, String>
where
B::Header: serde::de::DeserializeOwned,
Block: BlockT,
Block::Header: serde::de::DeserializeOwned,
S: AsRef<str>,
{
use jsonrpsee_ws_client::traits::Client;
let at = serde_json::to_value(at)
.map_err(|e| format!("Block hash could not be converted to JSON due to {:?}", e))?;
let params = vec![at];
let client = WsClientBuilder::default()
.max_request_body_size(u32::MAX)
.build(from.as_ref())
let params = vec![hash_to_json::<Block>(at)?];
let client = build_client(from).await?;
client.request::<Block::Header>("chain_getHeader", JsonRpcParams::Array(params))
.await
.map_err(|e| format!("`WsClientBuilder` failed to build do to {:?}", e))?;
client.request::<B::Header>("chain_getHeader", JsonRpcParams::Array(params))
.await
.map_err(|e| format!("chain_getHeader request failed due to {:?}", e))
.map_err(|e| format!("chain_getHeader request failed: {:?}", e))
}
/// Get the finalized head
pub async fn get_finalized_head<B: BlockT, S: AsRef<str>>(from: S) -> Result<B::Hash, String> {
use jsonrpsee_ws_client::traits::Client;
let client = WsClientBuilder::default()
pub async fn get_finalized_head<Block, S>(from: S) -> Result<Block::Hash, String>
where
Block: BlockT,
S: AsRef<str>,
{
let client = build_client(from).await?;
client.request::<Block::Hash>("chain_getFinalizedHead", JsonRpcParams::NoParams)
.await
.map_err(|e| format!("chain_getFinalizedHead request failed: {:?}", e))
}
/// Get the signed block identified by `at`.
pub async fn get_block<Block, S>(from: S, at: Block::Hash) -> Result<Block, String>
where
S: AsRef<str>,
Block: BlockT + serde::de::DeserializeOwned,
Block::Header: HeaderT,
{
let params = vec![hash_to_json::<Block>(at)?];
let client = build_client(from).await?;
let signed_block = client
.request::<SignedBlock<Block>>("chain_getBlock", JsonRpcParams::Array(params))
.await
.map_err(|e| format!("chain_getBlock request failed: {:?}", e))?;
Ok(signed_block.block)
}
/// Convert a block hash to a serde json value.
fn hash_to_json<Block: BlockT>(hash: Block::Hash) -> Result<serde_json::Value, String> {
serde_json::to_value(hash)
.map_err(|e| format!("Block hash could not be converted to JSON: {:?}", e))
}
/// Build a website client that connects to `from`.
async fn build_client<S: AsRef<str>>(from: S) -> Result<WsClient, String> {
WsClientBuilder::default()
.max_request_body_size(u32::MAX)
.build(from.as_ref())
.await
.map_err(|e| format!("`WsClientBuilder` failed to build do to {:?}", e))?;
client.request::<B::Hash>("chain_getFinalizedHead", JsonRpcParams::NoParams)
.await
.map_err(|e| format!("chain_getFinalizedHead request failed due to {:?}", e))
.map_err(|e| format!("`WsClientBuilder` failed to build: {:?}", e))
}