From a25933858706baa6281c43df82bad4a14c50a643 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 21 Apr 2021 09:44:45 +0200 Subject: [PATCH 01/11] update jsonrpsee to 0.2.0-alpha.5 --- Cargo.toml | 5 +- client/Cargo.toml | 3 +- src/error.rs | 2 +- src/lib.rs | 25 ++++---- src/rpc.rs | 146 ++++++++++++++++++++++++++------------------ src/subscription.rs | 2 +- 6 files changed, 102 insertions(+), 81 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7074677a48..99d3a12f08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,9 +28,8 @@ async-trait = "0.1.49" log = "0.4.14" thiserror = "1.0.24" futures = "0.3.13" -jsonrpsee-types = "=0.2.0-alpha.3" -jsonrpsee-ws-client = "=0.2.0-alpha.3" -jsonrpsee-http-client = { version = "=0.2.0-alpha.3", default-features = false } +jsonrpsee-ws-client = "=0.2.0-alpha.5" +jsonrpsee-http-client = { version = "=0.2.0-alpha.5", default-features = false } num-traits = { version = "0.2.14", default-features = false } serde = { version = "1.0.124", features = ["derive"] } serde_json = "1.0.64" diff --git a/client/Cargo.toml b/client/Cargo.toml index 007a8ebd5a..44023e0730 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -15,8 +15,7 @@ keywords = ["parity", "substrate", "blockchain"] async-std = "1.8.0" futures = { version = "0.3.9", features = ["compat"], package = "futures" } futures01 = { package = "futures", version = "0.1.29" } -jsonrpsee-types = "=0.2.0-alpha.3" -jsonrpsee-ws-client = "=0.2.0-alpha.3" +jsonrpsee-types = "=0.2.0-alpha.5" log = "0.4.13" sc-network = { version = "0.9.0", default-features = false } sc-client-db = "0.9.0" diff --git a/src/error.rs b/src/error.rs index 377684384a..a86bfe984c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with substrate-subxt. If not, see . -use jsonrpsee_types::error::Error as RequestError; +use jsonrpsee_ws_client::Error as RequestError; use sp_core::crypto::SecretStringError; use sp_runtime::{ transaction_validity::TransactionValidityError, diff --git a/src/lib.rs b/src/lib.rs index c229e21f19..043aeca44e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,14 +51,10 @@ use codec::{ Decode, }; use futures::future; -use jsonrpsee_http_client::{ - HttpClient, - HttpConfig, -}; +use jsonrpsee_http_client::HttpClientBuilder; use jsonrpsee_ws_client::{ - WsClient, - WsConfig, - WsSubscription as Subscription, + Subscription, + WsClientBuilder, }; use sp_core::{ storage::{ @@ -212,11 +208,13 @@ impl ClientBuilder { } else { let url = self.url.as_deref().unwrap_or("ws://127.0.0.1:9944"); if url.starts_with("ws://") || url.starts_with("wss://") { - let mut config = WsConfig::with_url(&url); - config.max_notifs_per_subscription = 4096; - RpcClient::WebSocket(Arc::new(WsClient::new(config).await?)) + let client = WsClientBuilder::default() + .max_notifs_per_subscription(4096) + .build(&url) + .await?; + RpcClient::WebSocket(Arc::new(client)) } else { - let client = HttpClient::new(url, HttpConfig::default())?; + let client = HttpClientBuilder::default().build(&url)?; RpcClient::Http(Arc::new(client)) } }; @@ -505,7 +503,7 @@ impl Client { /// Subscribe to new blocks. pub async fn subscribe_blocks(&self) -> Result, Error> { - let headers = self.rpc.subscribe_blocks().await?; + let headers: Subscription = self.rpc.subscribe_blocks().await?; Ok(headers) } @@ -513,7 +511,8 @@ impl Client { pub async fn subscribe_finalized_blocks( &self, ) -> Result, Error> { - let headers = self.rpc.subscribe_finalized_blocks().await?; + let headers: Subscription = + self.rpc.subscribe_finalized_blocks().await?; Ok(headers) } diff --git a/src/rpc.rs b/src/rpc.rs index 25705b3984..57b7f8aacd 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -31,22 +31,18 @@ use core::{ marker::PhantomData, }; use frame_metadata::RuntimeMetadataPrefixed; -use jsonrpsee_http_client::HttpClient; -use jsonrpsee_types::{ - error::Error as RpcError, - jsonrpc::{ - to_value as to_json_value, - DeserializeOwned, - Params, - }, - traits::{ - Client, - SubscriptionClient, - }, +use jsonrpsee_http_client::{ + to_json_value, + traits::Client, + v2::params::JsonRpcParams, + DeserializeOwned, + Error as RpcError, + HttpClient, }; use jsonrpsee_ws_client::{ + traits::SubscriptionClient, + Subscription, WsClient, - WsSubscription as Subscription, }; use serde::{ Deserialize, @@ -176,10 +172,10 @@ pub enum RpcClient { impl RpcClient { /// Start a JSON-RPC request. - pub async fn request( + pub async fn request<'a, T: DeserializeOwned>( &self, method: &str, - params: Params, + params: JsonRpcParams<'a>, ) -> Result { match self { Self::WebSocket(inner) => { @@ -192,10 +188,10 @@ impl RpcClient { } /// Start a JSON-RPC Subscription. - pub async fn subscribe( + pub async fn subscribe<'a, T: DeserializeOwned>( &self, subscribe_method: &str, - params: Params, + params: JsonRpcParams<'a>, unsubscribe_method: &str, ) -> Result, Error> { match self { @@ -294,8 +290,11 @@ impl Rpc { key: &StorageKey, hash: Option, ) -> Result, Error> { - let params = Params::Array(vec![to_json_value(key)?, to_json_value(hash)?]); - let data = self.client.request("state_getStorage", params).await?; + let params: &[_] = &[to_json_value(key)?, to_json_value(hash)?]; + let data = self + .client + .request("state_getStorage", params.into()) + .await?; log::debug!("state_getStorage {:?}", data); Ok(data) } @@ -310,13 +309,16 @@ impl Rpc { start_key: Option, hash: Option, ) -> Result, Error> { - let params = Params::Array(vec![ + let params: &[_] = &[ to_json_value(prefix)?, to_json_value(count)?, to_json_value(start_key)?, to_json_value(hash)?, - ]); - let data = self.client.request("state_getKeysPaged", params).await?; + ]; + let data = self + .client + .request("state_getKeysPaged", params.into()) + .await?; log::debug!("state_getKeysPaged {:?}", data); Ok(data) } @@ -328,13 +330,13 @@ impl Rpc { from: T::Hash, to: Option, ) -> Result::Hash>>, Error> { - let params = Params::Array(vec![ + let params: &[_] = &[ to_json_value(keys)?, to_json_value(from)?, to_json_value(to)?, - ]); + ]; self.client - .request("state_queryStorage", params) + .request("state_queryStorage", params.into()) .await .map_err(Into::into) } @@ -345,9 +347,9 @@ impl Rpc { keys: &[StorageKey], at: Option, ) -> Result::Hash>>, Error> { - let params = Params::Array(vec![to_json_value(keys)?, to_json_value(at)?]); + let params: &[_] = &[to_json_value(keys)?, to_json_value(at)?]; self.client - .request("state_queryStorageAt", params) + .request("state_queryStorageAt", params.into()) .await .map_err(Into::into) } @@ -355,9 +357,11 @@ impl Rpc { /// Fetch the genesis hash pub async fn genesis_hash(&self) -> Result { let block_zero = Some(ListOrValue::Value(NumberOrHex::Number(0))); - let params = Params::Array(vec![to_json_value(block_zero)?]); - let list_or_value: ListOrValue> = - self.client.request("chain_getBlockHash", params).await?; + let params: &[_] = &[to_json_value(block_zero)?]; + let list_or_value: ListOrValue> = self + .client + .request("chain_getBlockHash", params.into()) + .await?; match list_or_value { ListOrValue::Value(genesis_hash) => { genesis_hash.ok_or_else(|| "Genesis hash not found".into()) @@ -370,7 +374,7 @@ impl Rpc { pub async fn metadata(&self) -> Result { let bytes: Bytes = self .client - .request("state_getMetadata", Params::None) + .request("state_getMetadata", JsonRpcParams::NoParams) .await?; let meta: RuntimeMetadataPrefixed = Decode::decode(&mut &bytes[..])?; let metadata: Metadata = meta.try_into()?; @@ -381,7 +385,7 @@ impl Rpc { pub async fn system_properties(&self) -> Result { Ok(self .client - .request("system_properties", Params::None) + .request("system_properties", JsonRpcParams::NoParams) .await?) } @@ -390,8 +394,11 @@ impl Rpc { &self, hash: Option, ) -> Result, Error> { - let params = Params::Array(vec![to_json_value(hash)?]); - let header = self.client.request("chain_getHeader", params).await?; + let params: &[_] = &[to_json_value(hash)?]; + let header = self + .client + .request("chain_getHeader", params.into()) + .await?; Ok(header) } @@ -401,8 +408,11 @@ impl Rpc { block_number: Option, ) -> Result, Error> { let block_number = block_number.map(ListOrValue::Value); - let params = Params::Array(vec![to_json_value(block_number)?]); - let list_or_value = self.client.request("chain_getBlockHash", params).await?; + let params = [to_json_value(block_number)?]; + let list_or_value = self + .client + .request("chain_getBlockHash", (¶ms[..]).into()) + .await?; match list_or_value { ListOrValue::Value(hash) => Ok(hash), ListOrValue::List(_) => Err("Expected a Value, got a List".into()), @@ -413,7 +423,7 @@ impl Rpc { pub async fn finalized_head(&self) -> Result { let hash = self .client - .request("chain_getFinalizedHead", Params::None) + .request("chain_getFinalizedHead", JsonRpcParams::NoParams) .await?; Ok(hash) } @@ -423,8 +433,11 @@ impl Rpc { &self, hash: Option, ) -> Result>, Error> { - let params = Params::Array(vec![to_json_value(hash)?]); - let block = self.client.request("chain_getBlock", params).await?; + let params = [to_json_value(hash)?]; + let block = self + .client + .request("chain_getBlock", (¶ms[..]).into()) + .await?; Ok(block) } @@ -434,8 +447,11 @@ impl Rpc { keys: Vec, hash: Option, ) -> Result, Error> { - let params = Params::Array(vec![to_json_value(keys)?, to_json_value(hash)?]); - let proof = self.client.request("state_getReadProof", params).await?; + let params = [to_json_value(keys)?, to_json_value(hash)?]; + let proof = self + .client + .request("state_getReadProof", (¶ms[..]).into()) + .await?; Ok(proof) } @@ -444,10 +460,10 @@ impl Rpc { &self, at: Option, ) -> Result { - let params = Params::Array(vec![to_json_value(at)?]); + let params: &[_] = &[to_json_value(at)?]; let version = self .client - .request("state_getRuntimeVersion", params) + .request("state_getRuntimeVersion", params.into()) .await?; Ok(version) } @@ -458,11 +474,15 @@ impl Rpc { /// `subscribe_finalized_events` to ensure events are finalized. pub async fn subscribe_events(&self) -> Result, Error> { let keys = Some(vec![StorageKey::from(SystemEvents::new())]); - let params = Params::Array(vec![to_json_value(keys)?]); + let params: &[_] = &[to_json_value(keys)?]; - let subscription = self + let subscription: Subscription> = self .client - .subscribe("state_subscribeStorage", params, "state_unsubscribeStorage") + .subscribe( + "state_subscribeStorage", + params.into(), + "state_unsubscribeStorage", + ) .await?; Ok(EventStorageSubscription::Imported(subscription)) } @@ -485,7 +505,7 @@ impl Rpc { .client .subscribe( "chain_subscribeNewHeads", - Params::None, + JsonRpcParams::NoParams, "chain_unsubscribeNewHeads", ) .await?; @@ -501,7 +521,7 @@ impl Rpc { .client .subscribe( "chain_subscribeFinalizedHeads", - Params::None, + JsonRpcParams::NoParams, "chain_unsubscribeFinalizedHeads", ) .await?; @@ -514,10 +534,10 @@ impl Rpc { extrinsic: E, ) -> Result { let bytes: Bytes = extrinsic.encode().into(); - let params = Params::Array(vec![to_json_value(bytes)?]); + let params: &[_] = &[to_json_value(bytes)?]; let xt_hash = self .client - .request("author_submitExtrinsic", params) + .request("author_submitExtrinsic", params.into()) .await?; Ok(xt_hash) } @@ -527,12 +547,12 @@ impl Rpc { extrinsic: E, ) -> Result>, Error> { let bytes: Bytes = extrinsic.encode().into(); - let params = Params::Array(vec![to_json_value(bytes)?]); + let params: &[_] = &[to_json_value(bytes)?]; let subscription = self .client .subscribe( "author_submitAndWatchExtrinsic", - params, + params.into(), "author_unwatchExtrinsic", ) .await?; @@ -641,12 +661,14 @@ impl Rpc { suri: String, public: Bytes, ) -> Result<(), Error> { - let params = Params::Array(vec![ + let params: &[_] = &[ to_json_value(key_type)?, to_json_value(suri)?, to_json_value(public)?, - ]); - self.client.request("author_insertKey", params).await?; + ]; + self.client + .request("author_insertKey", params.into()) + .await?; Ok(()) } @@ -654,7 +676,7 @@ impl Rpc { pub async fn rotate_keys(&self) -> Result { Ok(self .client - .request("author_rotateKeys", Params::None) + .request("author_rotateKeys", JsonRpcParams::NoParams) .await?) } @@ -664,8 +686,11 @@ impl Rpc { /// /// Returns `true` iff all private keys could be found. pub async fn has_session_keys(&self, session_keys: Bytes) -> Result { - let params = Params::Array(vec![to_json_value(session_keys)?]); - Ok(self.client.request("author_hasSessionKeys", params).await?) + let params: &[_] = &[to_json_value(session_keys)?]; + Ok(self + .client + .request("author_hasSessionKeys", params.into()) + .await?) } /// Checks if the keystore has private keys for the given public key and key type. @@ -676,9 +701,8 @@ impl Rpc { public_key: Bytes, key_type: String, ) -> Result { - let params = - Params::Array(vec![to_json_value(public_key)?, to_json_value(key_type)?]); - Ok(self.client.request("author_hasKey", params).await?) + let params: &[_] = &[to_json_value(public_key)?, to_json_value(key_type)?]; + Ok(self.client.request("author_hasKey", params.into()).await?) } } diff --git a/src/subscription.rs b/src/subscription.rs index 8ade68a789..a6d870739a 100644 --- a/src/subscription.rs +++ b/src/subscription.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with substrate-subxt. If not, see . -use jsonrpsee_ws_client::WsSubscription as Subscription; +use jsonrpsee_ws_client::Subscription; use sp_core::{ storage::{ StorageChangeSet, From 516739717b8bc732f620fdddb7de6d5192ba8d20 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 21 Apr 2021 10:33:34 +0200 Subject: [PATCH 02/11] downgrade subxt client --- client/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/Cargo.toml b/client/Cargo.toml index 44023e0730..d73f00d288 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -15,7 +15,7 @@ keywords = ["parity", "substrate", "blockchain"] async-std = "1.8.0" futures = { version = "0.3.9", features = ["compat"], package = "futures" } futures01 = { package = "futures", version = "0.1.29" } -jsonrpsee-types = "=0.2.0-alpha.5" +jsonrpsee-types = "=0.2.0-alpha.3" log = "0.4.13" sc-network = { version = "0.9.0", default-features = false } sc-client-db = "0.9.0" From fc3a97263199982c99492d555061050b8a438657 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 21 Apr 2021 13:02:57 +0200 Subject: [PATCH 03/11] cleanup --- Cargo.toml | 1 + client/Cargo.toml | 2 +- src/rpc.rs | 15 ++++++--------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 99d3a12f08..7ff6c57fb1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ async-trait = "0.1.49" log = "0.4.14" thiserror = "1.0.24" futures = "0.3.13" +jsonrpsee-proc-macros = "=0.2.0-alpha.5" jsonrpsee-ws-client = "=0.2.0-alpha.5" jsonrpsee-http-client = { version = "=0.2.0-alpha.5", default-features = false } num-traits = { version = "0.2.14", default-features = false } diff --git a/client/Cargo.toml b/client/Cargo.toml index d73f00d288..44023e0730 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -15,7 +15,7 @@ keywords = ["parity", "substrate", "blockchain"] async-std = "1.8.0" futures = { version = "0.3.9", features = ["compat"], package = "futures" } futures01 = { package = "futures", version = "0.1.29" } -jsonrpsee-types = "=0.2.0-alpha.3" +jsonrpsee-types = "=0.2.0-alpha.5" log = "0.4.13" sc-network = { version = "0.9.0", default-features = false } sc-client-db = "0.9.0" diff --git a/src/rpc.rs b/src/rpc.rs index 57b7f8aacd..6da28a1d08 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -408,10 +408,10 @@ impl Rpc { block_number: Option, ) -> Result, Error> { let block_number = block_number.map(ListOrValue::Value); - let params = [to_json_value(block_number)?]; + let params: &[_] = &[to_json_value(block_number)?]; let list_or_value = self .client - .request("chain_getBlockHash", (¶ms[..]).into()) + .request("chain_getBlockHash", params.into()) .await?; match list_or_value { ListOrValue::Value(hash) => Ok(hash), @@ -433,11 +433,8 @@ impl Rpc { &self, hash: Option, ) -> Result>, Error> { - let params = [to_json_value(hash)?]; - let block = self - .client - .request("chain_getBlock", (¶ms[..]).into()) - .await?; + let params: &[_] = &[to_json_value(hash)?]; + let block = self.client.request("chain_getBlock", params.into()).await?; Ok(block) } @@ -447,10 +444,10 @@ impl Rpc { keys: Vec, hash: Option, ) -> Result, Error> { - let params = [to_json_value(keys)?, to_json_value(hash)?]; + let params: &[_] = &[to_json_value(keys)?, to_json_value(hash)?]; let proof = self .client - .request("state_getReadProof", (¶ms[..]).into()) + .request("state_getReadProof", params.into()) .await?; Ok(proof) } From caa362b624ccb2d7c6a051189625cc5b0644828d Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 21 Apr 2021 18:24:18 +0200 Subject: [PATCH 04/11] make subxt-client compile again --- client/src/lib.rs | 342 ++++++++++++++++++++++------------------------ 1 file changed, 166 insertions(+), 176 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index 4ce993f12b..dc84c332d4 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -40,27 +40,35 @@ use futures::{ }; use futures01::sync::mpsc as mpsc01; use jsonrpsee_types::{ - client::{ - FrontToBack, - NotificationMessage, - RequestMessage, - Subscription, - SubscriptionMessage, - }, - error::Error as JsonRpseeError, - jsonrpc::{ - self, - Call, - DeserializeOwned, - Id, - MethodCall, - Notification, - Output, - Request, - SubscriptionId, - SubscriptionNotif, - Version, + v2::{ + error::{ + ErrorCode, + JsonRpcErrorAlloc, + }, + params::{ + Id, + JsonRpcParams, + SubscriptionId, + TwoPointZero, + }, + parse_request_id, + request::{ + JsonRpcCallSer, + JsonRpcInvalidRequest, + JsonRpcNotificationSer, + }, + response::{ + JsonRpcNotifResponse, + JsonRpcResponse, + }, }, + DeserializeOwned, + Error as JsonRpseeError, + FrontToBack, + JsonValue, + RequestMessage, + Subscription, + SubscriptionMessage, }; use sc_network::config::TransportConfig; pub use sc_service::{ @@ -87,6 +95,10 @@ use sc_service::{ use std::{ collections::HashMap, marker::PhantomData, + sync::atomic::{ + AtomicU64, + Ordering, + }, }; use thiserror::Error; @@ -107,15 +119,15 @@ pub enum SubxtClientError { #[derive(Clone)] pub struct SubxtClient { to_back: mpsc::Sender, + next_id: Arc, } impl SubxtClient { /// Create a new client. pub fn new(mut task_manager: TaskManager, rpc: RpcHandlers) -> Self { let (to_back, from_front) = mpsc::channel(DEFAULT_CHANNEL_SIZE); - - let request_id = Arc::new(RwLock::new(u64::MIN)); - let subscriptions = Arc::new(RwLock::new(HashMap::::new())); + let subscriptions = + Arc::new(RwLock::new(HashMap::::new())); task::spawn( select( @@ -124,118 +136,72 @@ impl SubxtClient { let (to_front, from_back) = mpsc01::channel(DEFAULT_CHANNEL_SIZE); let session = RpcSession::new(to_front.clone()); - let request_id = request_id.clone(); let subscriptions = subscriptions.clone(); async move { - let request_id = { - let mut request_id = request_id.write().await; - *request_id = request_id.wrapping_add(1); - *request_id - }; - match message { - FrontToBack::Notification(NotificationMessage { - method, - params, - }) => { - let request = - Request::Single(Call::Notification(Notification { - jsonrpc: Version::V2, - method, - params, - })); - if let Ok(message) = serde_json::to_string(&request) { - rpc.rpc_query(&session, &message).await; - } + FrontToBack::Notification(raw) => { + let _ = rpc.rpc_query(&session, &raw).await; } - - FrontToBack::StartRequest(RequestMessage { - method, - params, + FrontToBack::Request(RequestMessage { + raw, + id, send_back, }) => { - let request = - Request::Single(Call::MethodCall(MethodCall { - jsonrpc: Version::V2, - method: method.into(), - params: params.into(), - id: Id::Num(request_id), - })); - if let Ok(message) = serde_json::to_string(&request) { - if let Some(response) = - rpc.rpc_query(&session, &message).await - { - let result = match serde_json::from_str::( - &response, - ) - .expect("failed to decode request response") - { - Output::Success(success) => { - Ok(success.result) - } - Output::Failure(failure) => { - Err(JsonRpseeError::Request( - failure.error, - )) - } - }; - - send_back.map(|tx| { - tx.send(result) - .expect("failed to send request response") - }); - } - } + let raw_response = rpc.rpc_query(&session, &raw).await; + let to_front = match read_jsonrpc_response( + raw_response, + Id::Number(id), + ) { + Some(Err(e)) => Err(e), + Some(Ok(rp)) => Ok(rp), + None => return, + }; + + send_back + .expect("request should have send_back") + .send(to_front) + .expect("failed to send request response"); } FrontToBack::Subscribe(SubscriptionMessage { - subscribe_method, - params, + raw, + subscribe_id, + unsubscribe_id, unsubscribe_method, send_back, }) => { - { - let mut subscriptions = subscriptions.write().await; - subscriptions.insert(request_id, unsubscribe_method); - } - - let request = - Request::Single(Call::MethodCall(MethodCall { - jsonrpc: Version::V2, - method: subscribe_method, - params, - id: Id::Num(request_id), - })); + let raw_response = rpc.rpc_query(&session, &raw).await; + let sub_id: SubscriptionId = match read_jsonrpc_response( + raw_response, + Id::Number(subscribe_id), + ) { + Some(Ok(rp)) => { + serde_json::from_value(rp) + .expect("infalliable; qed") + } + Some(Err(e)) => { + send_back + .send(Err(e)) + .expect("failed to send request response"); + return + } + None => return, + }; let (mut send_front_sub, send_back_sub) = mpsc::channel(DEFAULT_CHANNEL_SIZE); - if let Ok(message) = serde_json::to_string(&request) { - if let Some(response) = - rpc.rpc_query(&session, &message).await - { - let result = match serde_json::from_str::( - &response, - ) - .expect("failed to decode subscription response") - { - Output::Success(_) => { - Ok(( - send_back_sub, - SubscriptionId::Num(request_id), - )) - } - Output::Failure(failure) => { - Err(JsonRpseeError::Request( - failure.error, - )) - } - }; - - send_back.send(result).expect( - "failed to send subscription response", - ); - } + + send_back + .send(Ok((send_back_sub, sub_id.clone()))) + .expect("failed to send request response"); + + { + let mut subscriptions = subscriptions.write().await; + subscriptions.insert( + sub_id.clone(), + (unsubscribe_method, Id::Number(unsubscribe_id)), + ); } task::spawn(async move { @@ -245,7 +211,7 @@ impl SubxtClient { while let Some(Ok(response)) = from_back.next().await { let notif = serde_json::from_str::< - SubscriptionNotif, + JsonRpcNotifResponse, >( &response ) @@ -258,31 +224,24 @@ impl SubxtClient { }); } - FrontToBack::SubscriptionClosed(subscription_id) => { - let sub_id = - if let SubscriptionId::Num(num) = subscription_id { - num - } else { - unreachable!("subscription id should be num") - }; - let json_sub_id = jsonrpc::to_value(sub_id).unwrap(); + FrontToBack::SubscriptionClosed(sub_id) => { + let params: &[JsonValue] = &[sub_id.clone().into()]; let subscriptions = subscriptions.read().await; - if let Some(unsubscribe) = subscriptions.get(&sub_id) { - let request = - Request::Single(Call::MethodCall(MethodCall { - jsonrpc: Version::V2, - method: unsubscribe.into(), - params: jsonrpc::Params::Array(vec![ - json_sub_id, - ]), - id: Id::Num(request_id), - })); - if let Ok(message) = serde_json::to_string(&request) { - rpc.rpc_query(&session, &message).await; - } + if let Some((unsub_method, unsub_id)) = + subscriptions.get(&sub_id) + { + let message = + serde_json::to_string(&JsonRpcCallSer::new( + unsub_id.clone(), + unsub_method, + params.into(), + )) + .unwrap(); + let _ = rpc.rpc_query(&session, &message).await; } } + FrontToBack::Batch(_) => (), } } })), @@ -293,7 +252,10 @@ impl SubxtClient { .map(drop), ); - Self { to_back } + Self { + to_back, + next_id: Arc::new(AtomicU64::new(0)), + } } /// Creates a new client from a config. @@ -307,43 +269,40 @@ impl SubxtClient { } /// Send a JSONRPC notification. - pub async fn notification( + pub async fn notification<'a>( &self, - method: M, - params: P, - ) -> Result<(), JsonRpseeError> - where - M: Into + Send, - P: Into + Send, - { + method: &'a str, + params: JsonRpcParams<'a>, + ) -> Result<(), JsonRpseeError> { + let msg = serde_json::to_string(&JsonRpcNotificationSer::new(method, params)) + .map_err(JsonRpseeError::ParseError)?; self.to_back .clone() - .send(FrontToBack::Notification(NotificationMessage { - method: method.into(), - params: params.into(), - })) + .send(FrontToBack::Notification(msg)) .await .map_err(|e| JsonRpseeError::TransportError(Box::new(e))) } /// Send a JSONRPC request. - pub async fn request( + pub async fn request<'a, T>( &self, - method: M, - params: P, + method: &'a str, + params: JsonRpcParams<'a>, ) -> Result where T: DeserializeOwned, - M: Into + Send, - P: Into + Send, { let (send_back_tx, send_back_rx) = oneshot::channel(); + let id = self.next_id.fetch_add(1, Ordering::Relaxed); + let msg = + serde_json::to_string(&JsonRpcCallSer::new(Id::Number(id), method, params)) + .map_err(JsonRpseeError::ParseError)?; self.to_back .clone() - .send(FrontToBack::StartRequest(RequestMessage { - method: method.into(), - params: params.into(), + .send(FrontToBack::Request(RequestMessage { + raw: msg, + id, send_back: Some(send_back_tx), })) .await @@ -354,33 +313,36 @@ impl SubxtClient { Ok(Err(err)) => return Err(err), Err(err) => return Err(JsonRpseeError::TransportError(Box::new(err))), }; - jsonrpc::from_value(json_value).map_err(JsonRpseeError::ParseError) + serde_json::from_value(json_value).map_err(JsonRpseeError::ParseError) } /// Send a subscription request to the server. - pub async fn subscribe( + pub async fn subscribe<'a, N>( &self, - subscribe_method: SM, - params: P, - unsubscribe_method: UM, + subscribe_method: &'a str, + params: JsonRpcParams<'a>, + unsubscribe_method: &'a str, ) -> Result, JsonRpseeError> where - SM: Into + Send, - UM: Into + Send, - P: Into + Send, N: DeserializeOwned, { - let subscribe_method = subscribe_method.into(); - let unsubscribe_method = unsubscribe_method.into(); - let params = params.into(); + let sub_req_id = self.next_id.fetch_add(1, Ordering::Relaxed); + let unsub_req_id = self.next_id.fetch_add(1, Ordering::Relaxed); + let msg = serde_json::to_string(&JsonRpcCallSer::new( + Id::Number(sub_req_id), + subscribe_method, + params, + )) + .map_err(JsonRpseeError::ParseError)?; let (send_back_tx, send_back_rx) = oneshot::channel(); self.to_back .clone() .send(FrontToBack::Subscribe(SubscriptionMessage { - subscribe_method, - unsubscribe_method, - params, + raw: msg, + subscribe_id: sub_req_id, + unsubscribe_id: unsub_req_id, + unsubscribe_method: unsubscribe_method.to_owned(), send_back: send_back_tx, })) .await @@ -545,3 +507,31 @@ impl SubxtClientConfig { service_config } } + +fn read_jsonrpc_response( + maybe_msg: Option, + id: Id, +) -> Option> { + let msg = maybe_msg?; + match serde_json::from_str::>(&msg) { + Ok(rp) => { + match parse_request_id::(rp.id) { + Ok(rp_id) if rp_id == id => Some(Ok(rp.result)), + _ => Some(Err(JsonRpseeError::InvalidRequestId)), + } + } + Err(_) => { + match serde_json::from_str::>(&msg) { + Ok(err) => { + let err = JsonRpcErrorAlloc { + jsonrpc: TwoPointZero, + error: ErrorCode::InvalidParams, + id: parse_request_id(err.id).ok()?, + }; + Some(Err(JsonRpseeError::Request(err))) + } + Err(_) => None, + } + } + } +} From 87a15db154d56b36efe0d313ff274af36ec5a2bd Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Tue, 27 Apr 2021 17:31:23 +0200 Subject: [PATCH 05/11] update jsonrpsee v0.2.0-alpha.6 --- Cargo.toml | 6 +++--- client/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7ff6c57fb1..a4644b2996 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,9 +28,9 @@ async-trait = "0.1.49" log = "0.4.14" thiserror = "1.0.24" futures = "0.3.13" -jsonrpsee-proc-macros = "=0.2.0-alpha.5" -jsonrpsee-ws-client = "=0.2.0-alpha.5" -jsonrpsee-http-client = { version = "=0.2.0-alpha.5", default-features = false } +jsonrpsee-proc-macros = "=0.2.0-alpha.6" +jsonrpsee-ws-client = "=0.2.0-alpha.6" +jsonrpsee-http-client = { version = "=0.2.0-alpha.6", default-features = false } num-traits = { version = "0.2.14", default-features = false } serde = { version = "1.0.124", features = ["derive"] } serde_json = "1.0.64" diff --git a/client/Cargo.toml b/client/Cargo.toml index 44023e0730..776fc9bb42 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -15,7 +15,7 @@ keywords = ["parity", "substrate", "blockchain"] async-std = "1.8.0" futures = { version = "0.3.9", features = ["compat"], package = "futures" } futures01 = { package = "futures", version = "0.1.29" } -jsonrpsee-types = "=0.2.0-alpha.5" +jsonrpsee-types = "=0.2.0-alpha.6" log = "0.4.13" sc-network = { version = "0.9.0", default-features = false } sc-client-db = "0.9.0" From 7b64808075bea0339d2624a3ecb8e8af823d5d50 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 29 Apr 2021 10:13:39 +0200 Subject: [PATCH 06/11] fix build again --- client/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index dc84c332d4..f1dbff5526 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -42,7 +42,7 @@ use futures01::sync::mpsc as mpsc01; use jsonrpsee_types::{ v2::{ error::{ - ErrorCode, + JsonRpcErrorCode, JsonRpcErrorAlloc, }, params::{ @@ -525,7 +525,7 @@ fn read_jsonrpc_response( Ok(err) => { let err = JsonRpcErrorAlloc { jsonrpc: TwoPointZero, - error: ErrorCode::InvalidParams, + error: JsonRpcErrorCode::InvalidRequest.into(), id: parse_request_id(err.id).ok()?, }; Some(Err(JsonRpseeError::Request(err))) From 3d8beb300cb352ef04763fdba6f50090a6297333 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 29 Apr 2021 10:18:04 +0200 Subject: [PATCH 07/11] remove needless type hints --- src/lib.rs | 5 ++--- src/rpc.rs | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 043aeca44e..170800f589 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -503,7 +503,7 @@ impl Client { /// Subscribe to new blocks. pub async fn subscribe_blocks(&self) -> Result, Error> { - let headers: Subscription = self.rpc.subscribe_blocks().await?; + let headers = self.rpc.subscribe_blocks().await?; Ok(headers) } @@ -511,8 +511,7 @@ impl Client { pub async fn subscribe_finalized_blocks( &self, ) -> Result, Error> { - let headers: Subscription = - self.rpc.subscribe_finalized_blocks().await?; + let headers = self.rpc.subscribe_finalized_blocks().await?; Ok(headers) } diff --git a/src/rpc.rs b/src/rpc.rs index 6da28a1d08..ef5ff3171a 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -473,7 +473,7 @@ impl Rpc { let keys = Some(vec![StorageKey::from(SystemEvents::new())]); let params: &[_] = &[to_json_value(keys)?]; - let subscription: Subscription> = self + let subscription = self .client .subscribe( "state_subscribeStorage", From 768e1bc958a545281fb06c0fba0b65e53e99d97e Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 29 Apr 2021 10:18:27 +0200 Subject: [PATCH 08/11] cargo fmt --- client/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index f1dbff5526..c6ad4fa32c 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -42,8 +42,8 @@ use futures01::sync::mpsc as mpsc01; use jsonrpsee_types::{ v2::{ error::{ - JsonRpcErrorCode, JsonRpcErrorAlloc, + JsonRpcErrorCode, }, params::{ Id, From 7d8e1dfd1d7e07c824076c13b5f4d459375d643a Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 29 Apr 2021 11:28:22 +0200 Subject: [PATCH 09/11] address grumbles --- src/rpc.rs | 90 +++++++++++++++++++----------------------------------- 1 file changed, 31 insertions(+), 59 deletions(-) diff --git a/src/rpc.rs b/src/rpc.rs index ef5ff3171a..24676474fb 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -34,10 +34,10 @@ use frame_metadata::RuntimeMetadataPrefixed; use jsonrpsee_http_client::{ to_json_value, traits::Client, - v2::params::JsonRpcParams, DeserializeOwned, Error as RpcError, HttpClient, + JsonValue, }; use jsonrpsee_ws_client::{ traits::SubscriptionClient, @@ -172,28 +172,32 @@ pub enum RpcClient { impl RpcClient { /// Start a JSON-RPC request. - pub async fn request<'a, T: DeserializeOwned>( + pub async fn request<'a, T: DeserializeOwned + std::fmt::Debug>( &self, method: &str, - params: JsonRpcParams<'a>, + params: &[JsonValue], ) -> Result { - match self { + let params = params.into(); + let data = match self { Self::WebSocket(inner) => { inner.request(method, params).await.map_err(Into::into) } Self::Http(inner) => inner.request(method, params).await.map_err(Into::into), #[cfg(feature = "client")] Self::Subxt(inner) => inner.request(method, params).await.map_err(Into::into), - } + }; + log::debug!("{}: {:?}", method, data); + data } /// Start a JSON-RPC Subscription. pub async fn subscribe<'a, T: DeserializeOwned>( &self, subscribe_method: &str, - params: JsonRpcParams<'a>, + params: &[JsonValue], unsubscribe_method: &str, ) -> Result, Error> { + let params = params.into(); match self { Self::WebSocket(inner) => { inner @@ -290,12 +294,8 @@ impl Rpc { key: &StorageKey, hash: Option, ) -> Result, Error> { - let params: &[_] = &[to_json_value(key)?, to_json_value(hash)?]; - let data = self - .client - .request("state_getStorage", params.into()) - .await?; - log::debug!("state_getStorage {:?}", data); + let params = &[to_json_value(key)?, to_json_value(hash)?]; + let data = self.client.request("state_getStorage", params).await?; Ok(data) } @@ -309,17 +309,13 @@ impl Rpc { start_key: Option, hash: Option, ) -> Result, Error> { - let params: &[_] = &[ + let params = &[ to_json_value(prefix)?, to_json_value(count)?, to_json_value(start_key)?, to_json_value(hash)?, ]; - let data = self - .client - .request("state_getKeysPaged", params.into()) - .await?; - log::debug!("state_getKeysPaged {:?}", data); + let data = self.client.request("state_getKeysPaged", params).await?; Ok(data) } @@ -330,13 +326,13 @@ impl Rpc { from: T::Hash, to: Option, ) -> Result::Hash>>, Error> { - let params: &[_] = &[ + let params = &[ to_json_value(keys)?, to_json_value(from)?, to_json_value(to)?, ]; self.client - .request("state_queryStorage", params.into()) + .request("state_queryStorage", params) .await .map_err(Into::into) } @@ -347,9 +343,9 @@ impl Rpc { keys: &[StorageKey], at: Option, ) -> Result::Hash>>, Error> { - let params: &[_] = &[to_json_value(keys)?, to_json_value(at)?]; + let params = &[to_json_value(keys)?, to_json_value(at)?]; self.client - .request("state_queryStorageAt", params.into()) + .request("state_queryStorageAt", params) .await .map_err(Into::into) } @@ -357,11 +353,9 @@ impl Rpc { /// Fetch the genesis hash pub async fn genesis_hash(&self) -> Result { let block_zero = Some(ListOrValue::Value(NumberOrHex::Number(0))); - let params: &[_] = &[to_json_value(block_zero)?]; - let list_or_value: ListOrValue> = self - .client - .request("chain_getBlockHash", params.into()) - .await?; + let params = &[to_json_value(block_zero)?]; + let list_or_value: ListOrValue> = + self.client.request("chain_getBlockHash", params).await?; match list_or_value { ListOrValue::Value(genesis_hash) => { genesis_hash.ok_or_else(|| "Genesis hash not found".into()) @@ -372,10 +366,7 @@ impl Rpc { /// Fetch the metadata pub async fn metadata(&self) -> Result { - let bytes: Bytes = self - .client - .request("state_getMetadata", JsonRpcParams::NoParams) - .await?; + let bytes: Bytes = self.client.request("state_getMetadata", &[]).await?; let meta: RuntimeMetadataPrefixed = Decode::decode(&mut &bytes[..])?; let metadata: Metadata = meta.try_into()?; Ok(metadata) @@ -383,10 +374,7 @@ impl Rpc { /// Fetch system properties pub async fn system_properties(&self) -> Result { - Ok(self - .client - .request("system_properties", JsonRpcParams::NoParams) - .await?) + Ok(self.client.request("system_properties", &[]).await?) } /// Get a header @@ -394,11 +382,8 @@ impl Rpc { &self, hash: Option, ) -> Result, Error> { - let params: &[_] = &[to_json_value(hash)?]; - let header = self - .client - .request("chain_getHeader", params.into()) - .await?; + let params = &[to_json_value(hash)?]; + let header = self.client.request("chain_getHeader", params).await?; Ok(header) } @@ -408,11 +393,8 @@ impl Rpc { block_number: Option, ) -> Result, Error> { let block_number = block_number.map(ListOrValue::Value); - let params: &[_] = &[to_json_value(block_number)?]; - let list_or_value = self - .client - .request("chain_getBlockHash", params.into()) - .await?; + let params = &[to_json_value(block_number)?]; + let list_or_value = self.client.request("chain_getBlockHash", params).await?; match list_or_value { ListOrValue::Value(hash) => Ok(hash), ListOrValue::List(_) => Err("Expected a Value, got a List".into()), @@ -421,10 +403,7 @@ impl Rpc { /// Get a block hash of the latest finalized block pub async fn finalized_head(&self) -> Result { - let hash = self - .client - .request("chain_getFinalizedHead", JsonRpcParams::NoParams) - .await?; + let hash = self.client.request("chain_getFinalizedHead", &[]).await?; Ok(hash) } @@ -500,11 +479,7 @@ impl Rpc { pub async fn subscribe_blocks(&self) -> Result, Error> { let subscription = self .client - .subscribe( - "chain_subscribeNewHeads", - JsonRpcParams::NoParams, - "chain_unsubscribeNewHeads", - ) + .subscribe("chain_subscribeNewHeads", &[], "chain_unsubscribeNewHeads") .await?; Ok(subscription) @@ -518,7 +493,7 @@ impl Rpc { .client .subscribe( "chain_subscribeFinalizedHeads", - JsonRpcParams::NoParams, + &[], "chain_unsubscribeFinalizedHeads", ) .await?; @@ -671,10 +646,7 @@ impl Rpc { /// Generate new session keys and returns the corresponding public keys. pub async fn rotate_keys(&self) -> Result { - Ok(self - .client - .request("author_rotateKeys", JsonRpcParams::NoParams) - .await?) + Ok(self.client.request("author_rotateKeys", &[]).await?) } /// Checks if the keystore has private keys for the given session public keys. From 62557409930eefa982525082ac1456ac0dd84d09 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 29 Apr 2021 13:33:01 +0200 Subject: [PATCH 10/11] remove remaining type hints --- src/rpc.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/rpc.rs b/src/rpc.rs index 24676474fb..62a75fee59 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -412,8 +412,8 @@ impl Rpc { &self, hash: Option, ) -> Result>, Error> { - let params: &[_] = &[to_json_value(hash)?]; - let block = self.client.request("chain_getBlock", params.into()).await?; + let params = &[to_json_value(hash)?]; + let block = self.client.request("chain_getBlock", params).await?; Ok(block) } @@ -423,10 +423,10 @@ impl Rpc { keys: Vec, hash: Option, ) -> Result, Error> { - let params: &[_] = &[to_json_value(keys)?, to_json_value(hash)?]; + let params = &[to_json_value(keys)?, to_json_value(hash)?]; let proof = self .client - .request("state_getReadProof", params.into()) + .request("state_getReadProof", params) .await?; Ok(proof) } @@ -436,10 +436,10 @@ impl Rpc { &self, at: Option, ) -> Result { - let params: &[_] = &[to_json_value(at)?]; + let params = &[to_json_value(at)?]; let version = self .client - .request("state_getRuntimeVersion", params.into()) + .request("state_getRuntimeVersion", params) .await?; Ok(version) } @@ -450,13 +450,13 @@ impl Rpc { /// `subscribe_finalized_events` to ensure events are finalized. pub async fn subscribe_events(&self) -> Result, Error> { let keys = Some(vec![StorageKey::from(SystemEvents::new())]); - let params: &[_] = &[to_json_value(keys)?]; + let params = &[to_json_value(keys)?]; let subscription = self .client .subscribe( "state_subscribeStorage", - params.into(), + params, "state_unsubscribeStorage", ) .await?; @@ -506,10 +506,10 @@ impl Rpc { extrinsic: E, ) -> Result { let bytes: Bytes = extrinsic.encode().into(); - let params: &[_] = &[to_json_value(bytes)?]; + let params = &[to_json_value(bytes)?]; let xt_hash = self .client - .request("author_submitExtrinsic", params.into()) + .request("author_submitExtrinsic", params) .await?; Ok(xt_hash) } @@ -519,12 +519,12 @@ impl Rpc { extrinsic: E, ) -> Result>, Error> { let bytes: Bytes = extrinsic.encode().into(); - let params: &[_] = &[to_json_value(bytes)?]; + let params = &[to_json_value(bytes)?]; let subscription = self .client .subscribe( "author_submitAndWatchExtrinsic", - params.into(), + params, "author_unwatchExtrinsic", ) .await?; @@ -633,13 +633,13 @@ impl Rpc { suri: String, public: Bytes, ) -> Result<(), Error> { - let params: &[_] = &[ + let params = &[ to_json_value(key_type)?, to_json_value(suri)?, to_json_value(public)?, ]; self.client - .request("author_insertKey", params.into()) + .request("author_insertKey", params) .await?; Ok(()) } @@ -655,10 +655,10 @@ impl Rpc { /// /// Returns `true` iff all private keys could be found. pub async fn has_session_keys(&self, session_keys: Bytes) -> Result { - let params: &[_] = &[to_json_value(session_keys)?]; + let params = &[to_json_value(session_keys)?]; Ok(self .client - .request("author_hasSessionKeys", params.into()) + .request("author_hasSessionKeys", params) .await?) } @@ -670,7 +670,7 @@ impl Rpc { public_key: Bytes, key_type: String, ) -> Result { - let params: &[_] = &[to_json_value(public_key)?, to_json_value(key_type)?]; + let params = &[to_json_value(public_key)?, to_json_value(key_type)?]; Ok(self.client.request("author_hasKey", params.into()).await?) } } From 77df29c6705252a3114d97e8260798317530b118 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 29 Apr 2021 13:48:12 +0200 Subject: [PATCH 11/11] cargo fmt --- src/rpc.rs | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/rpc.rs b/src/rpc.rs index 62a75fee59..75c67b22d5 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -424,10 +424,7 @@ impl Rpc { hash: Option, ) -> Result, Error> { let params = &[to_json_value(keys)?, to_json_value(hash)?]; - let proof = self - .client - .request("state_getReadProof", params) - .await?; + let proof = self.client.request("state_getReadProof", params).await?; Ok(proof) } @@ -454,11 +451,7 @@ impl Rpc { let subscription = self .client - .subscribe( - "state_subscribeStorage", - params, - "state_unsubscribeStorage", - ) + .subscribe("state_subscribeStorage", params, "state_unsubscribeStorage") .await?; Ok(EventStorageSubscription::Imported(subscription)) } @@ -638,9 +631,7 @@ impl Rpc { to_json_value(suri)?, to_json_value(public)?, ]; - self.client - .request("author_insertKey", params) - .await?; + self.client.request("author_insertKey", params).await?; Ok(()) } @@ -656,10 +647,7 @@ impl Rpc { /// Returns `true` iff all private keys could be found. pub async fn has_session_keys(&self, session_keys: Bytes) -> Result { let params = &[to_json_value(session_keys)?]; - Ok(self - .client - .request("author_hasSessionKeys", params) - .await?) + Ok(self.client.request("author_hasSessionKeys", params).await?) } /// Checks if the keystore has private keys for the given public key and key type. @@ -671,7 +659,7 @@ impl Rpc { key_type: String, ) -> Result { let params = &[to_json_value(public_key)?, to_json_value(key_type)?]; - Ok(self.client.request("author_hasKey", params.into()).await?) + Ok(self.client.request("author_hasKey", params).await?) } }