mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-25 11:45:47 +00:00
update jsonrpsee to 0.2.0-alpha.6 (#266)
* update jsonrpsee to 0.2.0-alpha.5 * downgrade subxt client * cleanup * make subxt-client compile again * update jsonrpsee v0.2.0-alpha.6 * fix build again * remove needless type hints * cargo fmt * address grumbles * remove remaining type hints * cargo fmt
This commit is contained in:
+3
-3
@@ -28,9 +28,9 @@ async-trait = "0.1.49"
|
|||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
thiserror = "1.0.24"
|
thiserror = "1.0.24"
|
||||||
futures = "0.3.13"
|
futures = "0.3.13"
|
||||||
jsonrpsee-types = "=0.2.0-alpha.3"
|
jsonrpsee-proc-macros = "=0.2.0-alpha.6"
|
||||||
jsonrpsee-ws-client = "=0.2.0-alpha.3"
|
jsonrpsee-ws-client = "=0.2.0-alpha.6"
|
||||||
jsonrpsee-http-client = { version = "=0.2.0-alpha.3", default-features = false }
|
jsonrpsee-http-client = { version = "=0.2.0-alpha.6", default-features = false }
|
||||||
num-traits = { version = "0.2.14", default-features = false }
|
num-traits = { version = "0.2.14", default-features = false }
|
||||||
serde = { version = "1.0.124", features = ["derive"] }
|
serde = { version = "1.0.124", features = ["derive"] }
|
||||||
serde_json = "1.0.64"
|
serde_json = "1.0.64"
|
||||||
|
|||||||
+1
-2
@@ -15,8 +15,7 @@ keywords = ["parity", "substrate", "blockchain"]
|
|||||||
async-std = "1.8.0"
|
async-std = "1.8.0"
|
||||||
futures = { version = "0.3.9", features = ["compat"], package = "futures" }
|
futures = { version = "0.3.9", features = ["compat"], package = "futures" }
|
||||||
futures01 = { package = "futures", version = "0.1.29" }
|
futures01 = { package = "futures", version = "0.1.29" }
|
||||||
jsonrpsee-types = "=0.2.0-alpha.3"
|
jsonrpsee-types = "=0.2.0-alpha.6"
|
||||||
jsonrpsee-ws-client = "=0.2.0-alpha.3"
|
|
||||||
log = "0.4.13"
|
log = "0.4.13"
|
||||||
sc-network = { version = "0.9.0", default-features = false }
|
sc-network = { version = "0.9.0", default-features = false }
|
||||||
sc-client-db = "0.9.0"
|
sc-client-db = "0.9.0"
|
||||||
|
|||||||
+164
-174
@@ -40,27 +40,35 @@ use futures::{
|
|||||||
};
|
};
|
||||||
use futures01::sync::mpsc as mpsc01;
|
use futures01::sync::mpsc as mpsc01;
|
||||||
use jsonrpsee_types::{
|
use jsonrpsee_types::{
|
||||||
client::{
|
v2::{
|
||||||
FrontToBack,
|
error::{
|
||||||
NotificationMessage,
|
JsonRpcErrorAlloc,
|
||||||
RequestMessage,
|
JsonRpcErrorCode,
|
||||||
Subscription,
|
},
|
||||||
SubscriptionMessage,
|
params::{
|
||||||
},
|
Id,
|
||||||
error::Error as JsonRpseeError,
|
JsonRpcParams,
|
||||||
jsonrpc::{
|
SubscriptionId,
|
||||||
self,
|
TwoPointZero,
|
||||||
Call,
|
},
|
||||||
DeserializeOwned,
|
parse_request_id,
|
||||||
Id,
|
request::{
|
||||||
MethodCall,
|
JsonRpcCallSer,
|
||||||
Notification,
|
JsonRpcInvalidRequest,
|
||||||
Output,
|
JsonRpcNotificationSer,
|
||||||
Request,
|
},
|
||||||
SubscriptionId,
|
response::{
|
||||||
SubscriptionNotif,
|
JsonRpcNotifResponse,
|
||||||
Version,
|
JsonRpcResponse,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
DeserializeOwned,
|
||||||
|
Error as JsonRpseeError,
|
||||||
|
FrontToBack,
|
||||||
|
JsonValue,
|
||||||
|
RequestMessage,
|
||||||
|
Subscription,
|
||||||
|
SubscriptionMessage,
|
||||||
};
|
};
|
||||||
use sc_network::config::TransportConfig;
|
use sc_network::config::TransportConfig;
|
||||||
pub use sc_service::{
|
pub use sc_service::{
|
||||||
@@ -87,6 +95,10 @@ use sc_service::{
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
|
sync::atomic::{
|
||||||
|
AtomicU64,
|
||||||
|
Ordering,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
@@ -107,15 +119,15 @@ pub enum SubxtClientError {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SubxtClient {
|
pub struct SubxtClient {
|
||||||
to_back: mpsc::Sender<FrontToBack>,
|
to_back: mpsc::Sender<FrontToBack>,
|
||||||
|
next_id: Arc<AtomicU64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SubxtClient {
|
impl SubxtClient {
|
||||||
/// Create a new client.
|
/// Create a new client.
|
||||||
pub fn new(mut task_manager: TaskManager, rpc: RpcHandlers) -> Self {
|
pub fn new(mut task_manager: TaskManager, rpc: RpcHandlers) -> Self {
|
||||||
let (to_back, from_front) = mpsc::channel(DEFAULT_CHANNEL_SIZE);
|
let (to_back, from_front) = mpsc::channel(DEFAULT_CHANNEL_SIZE);
|
||||||
|
let subscriptions =
|
||||||
let request_id = Arc::new(RwLock::new(u64::MIN));
|
Arc::new(RwLock::new(HashMap::<SubscriptionId, (String, Id)>::new()));
|
||||||
let subscriptions = Arc::new(RwLock::new(HashMap::<u64, String>::new()));
|
|
||||||
|
|
||||||
task::spawn(
|
task::spawn(
|
||||||
select(
|
select(
|
||||||
@@ -124,118 +136,72 @@ impl SubxtClient {
|
|||||||
let (to_front, from_back) = mpsc01::channel(DEFAULT_CHANNEL_SIZE);
|
let (to_front, from_back) = mpsc01::channel(DEFAULT_CHANNEL_SIZE);
|
||||||
let session = RpcSession::new(to_front.clone());
|
let session = RpcSession::new(to_front.clone());
|
||||||
|
|
||||||
let request_id = request_id.clone();
|
|
||||||
let subscriptions = subscriptions.clone();
|
let subscriptions = subscriptions.clone();
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
let request_id = {
|
|
||||||
let mut request_id = request_id.write().await;
|
|
||||||
*request_id = request_id.wrapping_add(1);
|
|
||||||
*request_id
|
|
||||||
};
|
|
||||||
|
|
||||||
match message {
|
match message {
|
||||||
FrontToBack::Notification(NotificationMessage {
|
FrontToBack::Notification(raw) => {
|
||||||
method,
|
let _ = rpc.rpc_query(&session, &raw).await;
|
||||||
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::Request(RequestMessage {
|
||||||
FrontToBack::StartRequest(RequestMessage {
|
raw,
|
||||||
method,
|
id,
|
||||||
params,
|
|
||||||
send_back,
|
send_back,
|
||||||
}) => {
|
}) => {
|
||||||
let request =
|
let raw_response = rpc.rpc_query(&session, &raw).await;
|
||||||
Request::Single(Call::MethodCall(MethodCall {
|
let to_front = match read_jsonrpc_response(
|
||||||
jsonrpc: Version::V2,
|
raw_response,
|
||||||
method: method.into(),
|
Id::Number(id),
|
||||||
params: params.into(),
|
) {
|
||||||
id: Id::Num(request_id),
|
Some(Err(e)) => Err(e),
|
||||||
}));
|
Some(Ok(rp)) => Ok(rp),
|
||||||
if let Ok(message) = serde_json::to_string(&request) {
|
None => return,
|
||||||
if let Some(response) =
|
};
|
||||||
rpc.rpc_query(&session, &message).await
|
|
||||||
{
|
|
||||||
let result = match serde_json::from_str::<Output>(
|
|
||||||
&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| {
|
send_back
|
||||||
tx.send(result)
|
.expect("request should have send_back")
|
||||||
.expect("failed to send request response")
|
.send(to_front)
|
||||||
});
|
.expect("failed to send request response");
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FrontToBack::Subscribe(SubscriptionMessage {
|
FrontToBack::Subscribe(SubscriptionMessage {
|
||||||
subscribe_method,
|
raw,
|
||||||
params,
|
subscribe_id,
|
||||||
|
unsubscribe_id,
|
||||||
unsubscribe_method,
|
unsubscribe_method,
|
||||||
send_back,
|
send_back,
|
||||||
}) => {
|
}) => {
|
||||||
{
|
let raw_response = rpc.rpc_query(&session, &raw).await;
|
||||||
let mut subscriptions = subscriptions.write().await;
|
let sub_id: SubscriptionId = match read_jsonrpc_response(
|
||||||
subscriptions.insert(request_id, unsubscribe_method);
|
raw_response,
|
||||||
}
|
Id::Number(subscribe_id),
|
||||||
|
) {
|
||||||
let request =
|
Some(Ok(rp)) => {
|
||||||
Request::Single(Call::MethodCall(MethodCall {
|
serde_json::from_value(rp)
|
||||||
jsonrpc: Version::V2,
|
.expect("infalliable; qed")
|
||||||
method: subscribe_method,
|
}
|
||||||
params,
|
Some(Err(e)) => {
|
||||||
id: Id::Num(request_id),
|
send_back
|
||||||
}));
|
.send(Err(e))
|
||||||
|
.expect("failed to send request response");
|
||||||
|
return
|
||||||
|
}
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
let (mut send_front_sub, send_back_sub) =
|
let (mut send_front_sub, send_back_sub) =
|
||||||
mpsc::channel(DEFAULT_CHANNEL_SIZE);
|
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::<Output>(
|
|
||||||
&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(
|
send_back
|
||||||
"failed to send subscription response",
|
.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 {
|
task::spawn(async move {
|
||||||
@@ -245,7 +211,7 @@ impl SubxtClient {
|
|||||||
while let Some(Ok(response)) = from_back.next().await
|
while let Some(Ok(response)) = from_back.next().await
|
||||||
{
|
{
|
||||||
let notif = serde_json::from_str::<
|
let notif = serde_json::from_str::<
|
||||||
SubscriptionNotif,
|
JsonRpcNotifResponse<JsonValue>,
|
||||||
>(
|
>(
|
||||||
&response
|
&response
|
||||||
)
|
)
|
||||||
@@ -258,31 +224,24 @@ impl SubxtClient {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
FrontToBack::SubscriptionClosed(subscription_id) => {
|
FrontToBack::SubscriptionClosed(sub_id) => {
|
||||||
let sub_id =
|
let params: &[JsonValue] = &[sub_id.clone().into()];
|
||||||
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();
|
|
||||||
|
|
||||||
let subscriptions = subscriptions.read().await;
|
let subscriptions = subscriptions.read().await;
|
||||||
if let Some(unsubscribe) = subscriptions.get(&sub_id) {
|
if let Some((unsub_method, unsub_id)) =
|
||||||
let request =
|
subscriptions.get(&sub_id)
|
||||||
Request::Single(Call::MethodCall(MethodCall {
|
{
|
||||||
jsonrpc: Version::V2,
|
let message =
|
||||||
method: unsubscribe.into(),
|
serde_json::to_string(&JsonRpcCallSer::new(
|
||||||
params: jsonrpc::Params::Array(vec![
|
unsub_id.clone(),
|
||||||
json_sub_id,
|
unsub_method,
|
||||||
]),
|
params.into(),
|
||||||
id: Id::Num(request_id),
|
))
|
||||||
}));
|
.unwrap();
|
||||||
if let Ok(message) = serde_json::to_string(&request) {
|
let _ = rpc.rpc_query(&session, &message).await;
|
||||||
rpc.rpc_query(&session, &message).await;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FrontToBack::Batch(_) => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
@@ -293,7 +252,10 @@ impl SubxtClient {
|
|||||||
.map(drop),
|
.map(drop),
|
||||||
);
|
);
|
||||||
|
|
||||||
Self { to_back }
|
Self {
|
||||||
|
to_back,
|
||||||
|
next_id: Arc::new(AtomicU64::new(0)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new client from a config.
|
/// Creates a new client from a config.
|
||||||
@@ -307,43 +269,40 @@ impl SubxtClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Send a JSONRPC notification.
|
/// Send a JSONRPC notification.
|
||||||
pub async fn notification<M, P>(
|
pub async fn notification<'a>(
|
||||||
&self,
|
&self,
|
||||||
method: M,
|
method: &'a str,
|
||||||
params: P,
|
params: JsonRpcParams<'a>,
|
||||||
) -> Result<(), JsonRpseeError>
|
) -> Result<(), JsonRpseeError> {
|
||||||
where
|
let msg = serde_json::to_string(&JsonRpcNotificationSer::new(method, params))
|
||||||
M: Into<String> + Send,
|
.map_err(JsonRpseeError::ParseError)?;
|
||||||
P: Into<jsonrpc::Params> + Send,
|
|
||||||
{
|
|
||||||
self.to_back
|
self.to_back
|
||||||
.clone()
|
.clone()
|
||||||
.send(FrontToBack::Notification(NotificationMessage {
|
.send(FrontToBack::Notification(msg))
|
||||||
method: method.into(),
|
|
||||||
params: params.into(),
|
|
||||||
}))
|
|
||||||
.await
|
.await
|
||||||
.map_err(|e| JsonRpseeError::TransportError(Box::new(e)))
|
.map_err(|e| JsonRpseeError::TransportError(Box::new(e)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a JSONRPC request.
|
/// Send a JSONRPC request.
|
||||||
pub async fn request<T, M, P>(
|
pub async fn request<'a, T>(
|
||||||
&self,
|
&self,
|
||||||
method: M,
|
method: &'a str,
|
||||||
params: P,
|
params: JsonRpcParams<'a>,
|
||||||
) -> Result<T, JsonRpseeError>
|
) -> Result<T, JsonRpseeError>
|
||||||
where
|
where
|
||||||
T: DeserializeOwned,
|
T: DeserializeOwned,
|
||||||
M: Into<String> + Send,
|
|
||||||
P: Into<jsonrpc::Params> + Send,
|
|
||||||
{
|
{
|
||||||
let (send_back_tx, send_back_rx) = oneshot::channel();
|
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
|
self.to_back
|
||||||
.clone()
|
.clone()
|
||||||
.send(FrontToBack::StartRequest(RequestMessage {
|
.send(FrontToBack::Request(RequestMessage {
|
||||||
method: method.into(),
|
raw: msg,
|
||||||
params: params.into(),
|
id,
|
||||||
send_back: Some(send_back_tx),
|
send_back: Some(send_back_tx),
|
||||||
}))
|
}))
|
||||||
.await
|
.await
|
||||||
@@ -354,33 +313,36 @@ impl SubxtClient {
|
|||||||
Ok(Err(err)) => return Err(err),
|
Ok(Err(err)) => return Err(err),
|
||||||
Err(err) => return Err(JsonRpseeError::TransportError(Box::new(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.
|
/// Send a subscription request to the server.
|
||||||
pub async fn subscribe<SM, UM, P, N>(
|
pub async fn subscribe<'a, N>(
|
||||||
&self,
|
&self,
|
||||||
subscribe_method: SM,
|
subscribe_method: &'a str,
|
||||||
params: P,
|
params: JsonRpcParams<'a>,
|
||||||
unsubscribe_method: UM,
|
unsubscribe_method: &'a str,
|
||||||
) -> Result<Subscription<N>, JsonRpseeError>
|
) -> Result<Subscription<N>, JsonRpseeError>
|
||||||
where
|
where
|
||||||
SM: Into<String> + Send,
|
|
||||||
UM: Into<String> + Send,
|
|
||||||
P: Into<jsonrpc::Params> + Send,
|
|
||||||
N: DeserializeOwned,
|
N: DeserializeOwned,
|
||||||
{
|
{
|
||||||
let subscribe_method = subscribe_method.into();
|
let sub_req_id = self.next_id.fetch_add(1, Ordering::Relaxed);
|
||||||
let unsubscribe_method = unsubscribe_method.into();
|
let unsub_req_id = self.next_id.fetch_add(1, Ordering::Relaxed);
|
||||||
let params = params.into();
|
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();
|
let (send_back_tx, send_back_rx) = oneshot::channel();
|
||||||
self.to_back
|
self.to_back
|
||||||
.clone()
|
.clone()
|
||||||
.send(FrontToBack::Subscribe(SubscriptionMessage {
|
.send(FrontToBack::Subscribe(SubscriptionMessage {
|
||||||
subscribe_method,
|
raw: msg,
|
||||||
unsubscribe_method,
|
subscribe_id: sub_req_id,
|
||||||
params,
|
unsubscribe_id: unsub_req_id,
|
||||||
|
unsubscribe_method: unsubscribe_method.to_owned(),
|
||||||
send_back: send_back_tx,
|
send_back: send_back_tx,
|
||||||
}))
|
}))
|
||||||
.await
|
.await
|
||||||
@@ -545,3 +507,31 @@ impl<C: ChainSpec + 'static> SubxtClientConfig<C> {
|
|||||||
service_config
|
service_config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_jsonrpc_response(
|
||||||
|
maybe_msg: Option<String>,
|
||||||
|
id: Id,
|
||||||
|
) -> Option<Result<JsonValue, JsonRpseeError>> {
|
||||||
|
let msg = maybe_msg?;
|
||||||
|
match serde_json::from_str::<JsonRpcResponse<JsonValue>>(&msg) {
|
||||||
|
Ok(rp) => {
|
||||||
|
match parse_request_id::<Id>(rp.id) {
|
||||||
|
Ok(rp_id) if rp_id == id => Some(Ok(rp.result)),
|
||||||
|
_ => Some(Err(JsonRpseeError::InvalidRequestId)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
match serde_json::from_str::<JsonRpcInvalidRequest<'_>>(&msg) {
|
||||||
|
Ok(err) => {
|
||||||
|
let err = JsonRpcErrorAlloc {
|
||||||
|
jsonrpc: TwoPointZero,
|
||||||
|
error: JsonRpcErrorCode::InvalidRequest.into(),
|
||||||
|
id: parse_request_id(err.id).ok()?,
|
||||||
|
};
|
||||||
|
Some(Err(JsonRpseeError::Request(err)))
|
||||||
|
}
|
||||||
|
Err(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with substrate-subxt. If not, see <http://www.gnu.org/licenses/>.
|
// along with substrate-subxt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use jsonrpsee_types::error::Error as RequestError;
|
use jsonrpsee_ws_client::Error as RequestError;
|
||||||
use sp_core::crypto::SecretStringError;
|
use sp_core::crypto::SecretStringError;
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
transaction_validity::TransactionValidityError,
|
transaction_validity::TransactionValidityError,
|
||||||
|
|||||||
+9
-11
@@ -51,14 +51,10 @@ use codec::{
|
|||||||
Decode,
|
Decode,
|
||||||
};
|
};
|
||||||
use futures::future;
|
use futures::future;
|
||||||
use jsonrpsee_http_client::{
|
use jsonrpsee_http_client::HttpClientBuilder;
|
||||||
HttpClient,
|
|
||||||
HttpConfig,
|
|
||||||
};
|
|
||||||
use jsonrpsee_ws_client::{
|
use jsonrpsee_ws_client::{
|
||||||
WsClient,
|
Subscription,
|
||||||
WsConfig,
|
WsClientBuilder,
|
||||||
WsSubscription as Subscription,
|
|
||||||
};
|
};
|
||||||
use sp_core::{
|
use sp_core::{
|
||||||
storage::{
|
storage::{
|
||||||
@@ -212,11 +208,13 @@ impl<T: Runtime> ClientBuilder<T> {
|
|||||||
} else {
|
} else {
|
||||||
let url = self.url.as_deref().unwrap_or("ws://127.0.0.1:9944");
|
let url = self.url.as_deref().unwrap_or("ws://127.0.0.1:9944");
|
||||||
if url.starts_with("ws://") || url.starts_with("wss://") {
|
if url.starts_with("ws://") || url.starts_with("wss://") {
|
||||||
let mut config = WsConfig::with_url(&url);
|
let client = WsClientBuilder::default()
|
||||||
config.max_notifs_per_subscription = 4096;
|
.max_notifs_per_subscription(4096)
|
||||||
RpcClient::WebSocket(Arc::new(WsClient::new(config).await?))
|
.build(&url)
|
||||||
|
.await?;
|
||||||
|
RpcClient::WebSocket(Arc::new(client))
|
||||||
} else {
|
} else {
|
||||||
let client = HttpClient::new(url, HttpConfig::default())?;
|
let client = HttpClientBuilder::default().build(&url)?;
|
||||||
RpcClient::Http(Arc::new(client))
|
RpcClient::Http(Arc::new(client))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+44
-63
@@ -31,22 +31,18 @@ use core::{
|
|||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
};
|
};
|
||||||
use frame_metadata::RuntimeMetadataPrefixed;
|
use frame_metadata::RuntimeMetadataPrefixed;
|
||||||
use jsonrpsee_http_client::HttpClient;
|
use jsonrpsee_http_client::{
|
||||||
use jsonrpsee_types::{
|
to_json_value,
|
||||||
error::Error as RpcError,
|
traits::Client,
|
||||||
jsonrpc::{
|
DeserializeOwned,
|
||||||
to_value as to_json_value,
|
Error as RpcError,
|
||||||
DeserializeOwned,
|
HttpClient,
|
||||||
Params,
|
JsonValue,
|
||||||
},
|
|
||||||
traits::{
|
|
||||||
Client,
|
|
||||||
SubscriptionClient,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use jsonrpsee_ws_client::{
|
use jsonrpsee_ws_client::{
|
||||||
|
traits::SubscriptionClient,
|
||||||
|
Subscription,
|
||||||
WsClient,
|
WsClient,
|
||||||
WsSubscription as Subscription,
|
|
||||||
};
|
};
|
||||||
use serde::{
|
use serde::{
|
||||||
Deserialize,
|
Deserialize,
|
||||||
@@ -176,28 +172,32 @@ pub enum RpcClient {
|
|||||||
|
|
||||||
impl RpcClient {
|
impl RpcClient {
|
||||||
/// Start a JSON-RPC request.
|
/// Start a JSON-RPC request.
|
||||||
pub async fn request<T: DeserializeOwned>(
|
pub async fn request<'a, T: DeserializeOwned + std::fmt::Debug>(
|
||||||
&self,
|
&self,
|
||||||
method: &str,
|
method: &str,
|
||||||
params: Params,
|
params: &[JsonValue],
|
||||||
) -> Result<T, Error> {
|
) -> Result<T, Error> {
|
||||||
match self {
|
let params = params.into();
|
||||||
|
let data = match self {
|
||||||
Self::WebSocket(inner) => {
|
Self::WebSocket(inner) => {
|
||||||
inner.request(method, params).await.map_err(Into::into)
|
inner.request(method, params).await.map_err(Into::into)
|
||||||
}
|
}
|
||||||
Self::Http(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")]
|
#[cfg(feature = "client")]
|
||||||
Self::Subxt(inner) => inner.request(method, params).await.map_err(Into::into),
|
Self::Subxt(inner) => inner.request(method, params).await.map_err(Into::into),
|
||||||
}
|
};
|
||||||
|
log::debug!("{}: {:?}", method, data);
|
||||||
|
data
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start a JSON-RPC Subscription.
|
/// Start a JSON-RPC Subscription.
|
||||||
pub async fn subscribe<T: DeserializeOwned>(
|
pub async fn subscribe<'a, T: DeserializeOwned>(
|
||||||
&self,
|
&self,
|
||||||
subscribe_method: &str,
|
subscribe_method: &str,
|
||||||
params: Params,
|
params: &[JsonValue],
|
||||||
unsubscribe_method: &str,
|
unsubscribe_method: &str,
|
||||||
) -> Result<Subscription<T>, Error> {
|
) -> Result<Subscription<T>, Error> {
|
||||||
|
let params = params.into();
|
||||||
match self {
|
match self {
|
||||||
Self::WebSocket(inner) => {
|
Self::WebSocket(inner) => {
|
||||||
inner
|
inner
|
||||||
@@ -294,9 +294,8 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
key: &StorageKey,
|
key: &StorageKey,
|
||||||
hash: Option<T::Hash>,
|
hash: Option<T::Hash>,
|
||||||
) -> Result<Option<StorageData>, Error> {
|
) -> Result<Option<StorageData>, Error> {
|
||||||
let params = Params::Array(vec![to_json_value(key)?, to_json_value(hash)?]);
|
let params = &[to_json_value(key)?, to_json_value(hash)?];
|
||||||
let data = self.client.request("state_getStorage", params).await?;
|
let data = self.client.request("state_getStorage", params).await?;
|
||||||
log::debug!("state_getStorage {:?}", data);
|
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,14 +309,13 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
start_key: Option<StorageKey>,
|
start_key: Option<StorageKey>,
|
||||||
hash: Option<T::Hash>,
|
hash: Option<T::Hash>,
|
||||||
) -> Result<Vec<StorageKey>, Error> {
|
) -> Result<Vec<StorageKey>, Error> {
|
||||||
let params = Params::Array(vec![
|
let params = &[
|
||||||
to_json_value(prefix)?,
|
to_json_value(prefix)?,
|
||||||
to_json_value(count)?,
|
to_json_value(count)?,
|
||||||
to_json_value(start_key)?,
|
to_json_value(start_key)?,
|
||||||
to_json_value(hash)?,
|
to_json_value(hash)?,
|
||||||
]);
|
];
|
||||||
let data = self.client.request("state_getKeysPaged", params).await?;
|
let data = self.client.request("state_getKeysPaged", params).await?;
|
||||||
log::debug!("state_getKeysPaged {:?}", data);
|
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,11 +326,11 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
from: T::Hash,
|
from: T::Hash,
|
||||||
to: Option<T::Hash>,
|
to: Option<T::Hash>,
|
||||||
) -> Result<Vec<StorageChangeSet<<T as System>::Hash>>, Error> {
|
) -> Result<Vec<StorageChangeSet<<T as System>::Hash>>, Error> {
|
||||||
let params = Params::Array(vec![
|
let params = &[
|
||||||
to_json_value(keys)?,
|
to_json_value(keys)?,
|
||||||
to_json_value(from)?,
|
to_json_value(from)?,
|
||||||
to_json_value(to)?,
|
to_json_value(to)?,
|
||||||
]);
|
];
|
||||||
self.client
|
self.client
|
||||||
.request("state_queryStorage", params)
|
.request("state_queryStorage", params)
|
||||||
.await
|
.await
|
||||||
@@ -345,7 +343,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
keys: &[StorageKey],
|
keys: &[StorageKey],
|
||||||
at: Option<T::Hash>,
|
at: Option<T::Hash>,
|
||||||
) -> Result<Vec<StorageChangeSet<<T as System>::Hash>>, Error> {
|
) -> Result<Vec<StorageChangeSet<<T as System>::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
|
self.client
|
||||||
.request("state_queryStorageAt", params)
|
.request("state_queryStorageAt", params)
|
||||||
.await
|
.await
|
||||||
@@ -355,7 +353,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
/// Fetch the genesis hash
|
/// Fetch the genesis hash
|
||||||
pub async fn genesis_hash(&self) -> Result<T::Hash, Error> {
|
pub async fn genesis_hash(&self) -> Result<T::Hash, Error> {
|
||||||
let block_zero = Some(ListOrValue::Value(NumberOrHex::Number(0)));
|
let block_zero = Some(ListOrValue::Value(NumberOrHex::Number(0)));
|
||||||
let params = Params::Array(vec![to_json_value(block_zero)?]);
|
let params = &[to_json_value(block_zero)?];
|
||||||
let list_or_value: ListOrValue<Option<T::Hash>> =
|
let list_or_value: ListOrValue<Option<T::Hash>> =
|
||||||
self.client.request("chain_getBlockHash", params).await?;
|
self.client.request("chain_getBlockHash", params).await?;
|
||||||
match list_or_value {
|
match list_or_value {
|
||||||
@@ -368,10 +366,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
|
|
||||||
/// Fetch the metadata
|
/// Fetch the metadata
|
||||||
pub async fn metadata(&self) -> Result<Metadata, Error> {
|
pub async fn metadata(&self) -> Result<Metadata, Error> {
|
||||||
let bytes: Bytes = self
|
let bytes: Bytes = self.client.request("state_getMetadata", &[]).await?;
|
||||||
.client
|
|
||||||
.request("state_getMetadata", Params::None)
|
|
||||||
.await?;
|
|
||||||
let meta: RuntimeMetadataPrefixed = Decode::decode(&mut &bytes[..])?;
|
let meta: RuntimeMetadataPrefixed = Decode::decode(&mut &bytes[..])?;
|
||||||
let metadata: Metadata = meta.try_into()?;
|
let metadata: Metadata = meta.try_into()?;
|
||||||
Ok(metadata)
|
Ok(metadata)
|
||||||
@@ -379,10 +374,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
|
|
||||||
/// Fetch system properties
|
/// Fetch system properties
|
||||||
pub async fn system_properties(&self) -> Result<SystemProperties, Error> {
|
pub async fn system_properties(&self) -> Result<SystemProperties, Error> {
|
||||||
Ok(self
|
Ok(self.client.request("system_properties", &[]).await?)
|
||||||
.client
|
|
||||||
.request("system_properties", Params::None)
|
|
||||||
.await?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a header
|
/// Get a header
|
||||||
@@ -390,7 +382,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
&self,
|
&self,
|
||||||
hash: Option<T::Hash>,
|
hash: Option<T::Hash>,
|
||||||
) -> Result<Option<T::Header>, Error> {
|
) -> Result<Option<T::Header>, Error> {
|
||||||
let params = Params::Array(vec![to_json_value(hash)?]);
|
let params = &[to_json_value(hash)?];
|
||||||
let header = self.client.request("chain_getHeader", params).await?;
|
let header = self.client.request("chain_getHeader", params).await?;
|
||||||
Ok(header)
|
Ok(header)
|
||||||
}
|
}
|
||||||
@@ -401,7 +393,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
block_number: Option<BlockNumber>,
|
block_number: Option<BlockNumber>,
|
||||||
) -> Result<Option<T::Hash>, Error> {
|
) -> Result<Option<T::Hash>, Error> {
|
||||||
let block_number = block_number.map(ListOrValue::Value);
|
let block_number = block_number.map(ListOrValue::Value);
|
||||||
let params = Params::Array(vec![to_json_value(block_number)?]);
|
let params = &[to_json_value(block_number)?];
|
||||||
let list_or_value = self.client.request("chain_getBlockHash", params).await?;
|
let list_or_value = self.client.request("chain_getBlockHash", params).await?;
|
||||||
match list_or_value {
|
match list_or_value {
|
||||||
ListOrValue::Value(hash) => Ok(hash),
|
ListOrValue::Value(hash) => Ok(hash),
|
||||||
@@ -411,10 +403,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
|
|
||||||
/// Get a block hash of the latest finalized block
|
/// Get a block hash of the latest finalized block
|
||||||
pub async fn finalized_head(&self) -> Result<T::Hash, Error> {
|
pub async fn finalized_head(&self) -> Result<T::Hash, Error> {
|
||||||
let hash = self
|
let hash = self.client.request("chain_getFinalizedHead", &[]).await?;
|
||||||
.client
|
|
||||||
.request("chain_getFinalizedHead", Params::None)
|
|
||||||
.await?;
|
|
||||||
Ok(hash)
|
Ok(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,7 +412,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
&self,
|
&self,
|
||||||
hash: Option<T::Hash>,
|
hash: Option<T::Hash>,
|
||||||
) -> Result<Option<ChainBlock<T>>, Error> {
|
) -> Result<Option<ChainBlock<T>>, Error> {
|
||||||
let params = Params::Array(vec![to_json_value(hash)?]);
|
let params = &[to_json_value(hash)?];
|
||||||
let block = self.client.request("chain_getBlock", params).await?;
|
let block = self.client.request("chain_getBlock", params).await?;
|
||||||
Ok(block)
|
Ok(block)
|
||||||
}
|
}
|
||||||
@@ -434,7 +423,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
keys: Vec<StorageKey>,
|
keys: Vec<StorageKey>,
|
||||||
hash: Option<T::Hash>,
|
hash: Option<T::Hash>,
|
||||||
) -> Result<ReadProof<T::Hash>, Error> {
|
) -> Result<ReadProof<T::Hash>, Error> {
|
||||||
let params = Params::Array(vec![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).await?;
|
let proof = self.client.request("state_getReadProof", params).await?;
|
||||||
Ok(proof)
|
Ok(proof)
|
||||||
}
|
}
|
||||||
@@ -444,7 +433,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
&self,
|
&self,
|
||||||
at: Option<T::Hash>,
|
at: Option<T::Hash>,
|
||||||
) -> Result<RuntimeVersion, Error> {
|
) -> Result<RuntimeVersion, Error> {
|
||||||
let params = Params::Array(vec![to_json_value(at)?]);
|
let params = &[to_json_value(at)?];
|
||||||
let version = self
|
let version = self
|
||||||
.client
|
.client
|
||||||
.request("state_getRuntimeVersion", params)
|
.request("state_getRuntimeVersion", params)
|
||||||
@@ -458,7 +447,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
/// `subscribe_finalized_events` to ensure events are finalized.
|
/// `subscribe_finalized_events` to ensure events are finalized.
|
||||||
pub async fn subscribe_events(&self) -> Result<EventStorageSubscription<T>, Error> {
|
pub async fn subscribe_events(&self) -> Result<EventStorageSubscription<T>, Error> {
|
||||||
let keys = Some(vec![StorageKey::from(SystemEvents::new())]);
|
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 = self
|
||||||
.client
|
.client
|
||||||
@@ -483,11 +472,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
pub async fn subscribe_blocks(&self) -> Result<Subscription<T::Header>, Error> {
|
pub async fn subscribe_blocks(&self) -> Result<Subscription<T::Header>, Error> {
|
||||||
let subscription = self
|
let subscription = self
|
||||||
.client
|
.client
|
||||||
.subscribe(
|
.subscribe("chain_subscribeNewHeads", &[], "chain_unsubscribeNewHeads")
|
||||||
"chain_subscribeNewHeads",
|
|
||||||
Params::None,
|
|
||||||
"chain_unsubscribeNewHeads",
|
|
||||||
)
|
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(subscription)
|
Ok(subscription)
|
||||||
@@ -501,7 +486,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
.client
|
.client
|
||||||
.subscribe(
|
.subscribe(
|
||||||
"chain_subscribeFinalizedHeads",
|
"chain_subscribeFinalizedHeads",
|
||||||
Params::None,
|
&[],
|
||||||
"chain_unsubscribeFinalizedHeads",
|
"chain_unsubscribeFinalizedHeads",
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -514,7 +499,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
extrinsic: E,
|
extrinsic: E,
|
||||||
) -> Result<T::Hash, Error> {
|
) -> Result<T::Hash, Error> {
|
||||||
let bytes: Bytes = extrinsic.encode().into();
|
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
|
let xt_hash = self
|
||||||
.client
|
.client
|
||||||
.request("author_submitExtrinsic", params)
|
.request("author_submitExtrinsic", params)
|
||||||
@@ -527,7 +512,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
extrinsic: E,
|
extrinsic: E,
|
||||||
) -> Result<Subscription<TransactionStatus<T::Hash, T::Hash>>, Error> {
|
) -> Result<Subscription<TransactionStatus<T::Hash, T::Hash>>, Error> {
|
||||||
let bytes: Bytes = extrinsic.encode().into();
|
let bytes: Bytes = extrinsic.encode().into();
|
||||||
let params = Params::Array(vec![to_json_value(bytes)?]);
|
let params = &[to_json_value(bytes)?];
|
||||||
let subscription = self
|
let subscription = self
|
||||||
.client
|
.client
|
||||||
.subscribe(
|
.subscribe(
|
||||||
@@ -641,21 +626,18 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
suri: String,
|
suri: String,
|
||||||
public: Bytes,
|
public: Bytes,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let params = Params::Array(vec![
|
let params = &[
|
||||||
to_json_value(key_type)?,
|
to_json_value(key_type)?,
|
||||||
to_json_value(suri)?,
|
to_json_value(suri)?,
|
||||||
to_json_value(public)?,
|
to_json_value(public)?,
|
||||||
]);
|
];
|
||||||
self.client.request("author_insertKey", params).await?;
|
self.client.request("author_insertKey", params).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate new session keys and returns the corresponding public keys.
|
/// Generate new session keys and returns the corresponding public keys.
|
||||||
pub async fn rotate_keys(&self) -> Result<Bytes, Error> {
|
pub async fn rotate_keys(&self) -> Result<Bytes, Error> {
|
||||||
Ok(self
|
Ok(self.client.request("author_rotateKeys", &[]).await?)
|
||||||
.client
|
|
||||||
.request("author_rotateKeys", Params::None)
|
|
||||||
.await?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the keystore has private keys for the given session public keys.
|
/// Checks if the keystore has private keys for the given session public keys.
|
||||||
@@ -664,7 +646,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
///
|
///
|
||||||
/// Returns `true` iff all private keys could be found.
|
/// Returns `true` iff all private keys could be found.
|
||||||
pub async fn has_session_keys(&self, session_keys: Bytes) -> Result<bool, Error> {
|
pub async fn has_session_keys(&self, session_keys: Bytes) -> Result<bool, Error> {
|
||||||
let params = Params::Array(vec![to_json_value(session_keys)?]);
|
let params = &[to_json_value(session_keys)?];
|
||||||
Ok(self.client.request("author_hasSessionKeys", params).await?)
|
Ok(self.client.request("author_hasSessionKeys", params).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,8 +658,7 @@ impl<T: Runtime> Rpc<T> {
|
|||||||
public_key: Bytes,
|
public_key: Bytes,
|
||||||
key_type: String,
|
key_type: String,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
let params =
|
let params = &[to_json_value(public_key)?, to_json_value(key_type)?];
|
||||||
Params::Array(vec![to_json_value(public_key)?, to_json_value(key_type)?]);
|
|
||||||
Ok(self.client.request("author_hasKey", params).await?)
|
Ok(self.client.request("author_hasKey", params).await?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with substrate-subxt. If not, see <http://www.gnu.org/licenses/>.
|
// along with substrate-subxt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use jsonrpsee_ws_client::WsSubscription as Subscription;
|
use jsonrpsee_ws_client::Subscription;
|
||||||
use sp_core::{
|
use sp_core::{
|
||||||
storage::{
|
storage::{
|
||||||
StorageChangeSet,
|
StorageChangeSet,
|
||||||
|
|||||||
Reference in New Issue
Block a user