Allow generalising over RPC implementation (#634)

* WIP generalising RPC client

* WIP: non-object-safe RpcClientT.. aah generics everywhere

* WIP object-safe RpcClientT trait and no more extra generics

* Get core things compiling again with object-safe RpcClientT trait

* Make jsonrpsee optional and get test-runtime working again

* cargo fmt

* add RpcParams object to enforce correct formatting of rps params

* Wee tweaks

* clippy fixes

* cargo fmt

* TWeak a few types

* make sure we get jsonrpsee-types, too

* Add examples for rpc_params/RpcParams

* more doc tweaks

* remove a now unneeded dev note

* Option<Box<RawValue>> instead to avoid allocations in some cases

* update docs

* tweak RpcClientT trait docs

* Tweak docs around RpcClient and RpcClientT. Don't expose RpcClientT directly

* more doc tweaking about RpcParams and undo decision not to expose RpcParamsT

* Doc tweak

Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>

* more doc tweaks

* Fix doc thing

* Add an example of injecting a custom RPC client

* Fix a typo

* Address clippy things in example

* Fix a silly typo

* another clippy fix

* rpc_params to panic instead of returning a result, like serde_json::json, and deref on Rpc<T>

* fix docs

Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
This commit is contained in:
James Wilson
2022-08-31 10:00:49 +01:00
committed by GitHub
parent 5ff849318b
commit 599107b432
17 changed files with 737 additions and 143 deletions
+86
View File
@@ -0,0 +1,86 @@
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
// see LICENSE for license details.
use super::{
RpcClientT,
RpcFuture,
RpcSubscription,
};
use crate::error::RpcError;
use futures::stream::{
StreamExt,
TryStreamExt,
};
use jsonrpsee::{
core::client::{
Client,
ClientT,
SubscriptionClientT,
},
types::ParamsSer,
};
use serde_json::value::{
RawValue,
Value,
};
impl RpcClientT for Client {
fn request_raw<'a>(
&'a self,
method: &'a str,
params: Option<Box<RawValue>>,
) -> RpcFuture<'a, Box<RawValue>> {
Box::pin(async move {
let params = prep_params_for_jsonrpsee(params)?;
let res = ClientT::request(self, method, Some(params))
.await
.map_err(|e| RpcError(e.to_string()))?;
Ok(res)
})
}
fn subscribe_raw<'a>(
&'a self,
sub: &'a str,
params: Option<Box<RawValue>>,
unsub: &'a str,
) -> RpcFuture<'a, RpcSubscription> {
Box::pin(async move {
let params = prep_params_for_jsonrpsee(params)?;
let sub = SubscriptionClientT::subscribe::<Box<RawValue>>(
self,
sub,
Some(params),
unsub,
)
.await
.map_err(|e| RpcError(e.to_string()))?
.map_err(|e| RpcError(e.to_string()))
.boxed();
Ok(sub)
})
}
}
// This is ugly; we have to encode to Value's to be compat with the jsonrpc interface.
// Remove and simplify this once something like https://github.com/paritytech/jsonrpsee/issues/862 is in:
fn prep_params_for_jsonrpsee(
params: Option<Box<RawValue>>,
) -> Result<ParamsSer<'static>, RpcError> {
let params = match params {
Some(params) => params,
// No params? avoid any work and bail early.
None => return Ok(ParamsSer::Array(Vec::new())),
};
let val = serde_json::to_value(&params).expect("RawValue guarantees valid JSON");
let arr = match val {
Value::Array(arr) => Ok(arr),
_ => {
Err(RpcError(format!(
"RPC Params are expected to be an array but got {params}"
)))
}
}?;
Ok(ParamsSer::Array(arr))
}