mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +00:00
Convert to std futures (#58)
* WIP * Begin converting rpc layer to use std futures and jsonrpsee * Convert metadata to async/await * Convert block_hash to async/await * Convert more methods to async/await * Remove sp_rpc * Fix more compilation errors * Remove connect * Starting to convert subscription functions * Use jsonrpsee branch from PR for public client types * Implement subscribe events with jsonrpsee subscription * Converting subscriptions and wait_for_block_events * WIP converting lib methods to async * Use shared client reference directly for rpc call `rpc_api!` macro currently only supports RawClient (which cannot be shared). Also supports named params only which is not currently compatible with substrate rpd which accepts only positional params. * Use &self instead of &mut self for shared Client * Convert submit_and_watch to async/await * Convert more Client fns to async * Pin some trait futures * Add serde error * Fix client creation * Fix client request compiler errors * Unify metadata errors * Add WS handshake error variant * Fix some more compiler errors * Fix more compiler errors * Convert submit_extrinsic to async * Convert submit and submit_and_watch * Add Send + Sync constraints * Clone clients * Fix EventArg conversion error * Fix remaining warnings/errors * Replace deny warnings with specific lints * Infallable subscription loops * Use jsonrpsee wss branch * Fix example * Start to fix up tests * Make contracts tests compile * Make some more tests pass * Fix up remaining tests * Fmt * Use correct event storage key type * Fix finding events * Use master jsonrpsee
This commit is contained in:
+24
-7
@@ -16,7 +16,10 @@
|
||||
|
||||
//! Implements support for the pallet_balances module.
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::{
|
||||
fmt::Debug,
|
||||
pin::Pin,
|
||||
};
|
||||
|
||||
use futures::future::{
|
||||
self,
|
||||
@@ -74,17 +77,26 @@ pub trait BalancesStore {
|
||||
fn free_balance(
|
||||
&self,
|
||||
account_id: <Self::Balances as System>::AccountId,
|
||||
) -> Box<dyn Future<Item = <Self::Balances as Balances>::Balance, Error = Error> + Send>;
|
||||
) -> Pin<
|
||||
Box<
|
||||
dyn Future<Output = Result<<Self::Balances as Balances>::Balance, Error>>
|
||||
+ Send,
|
||||
>,
|
||||
>;
|
||||
}
|
||||
|
||||
impl<T: Balances + 'static, S: 'static> BalancesStore for Client<T, S> {
|
||||
impl<T: Balances + Sync + Send + 'static, S: 'static> BalancesStore for Client<T, S> {
|
||||
type Balances = T;
|
||||
|
||||
fn free_balance(
|
||||
&self,
|
||||
account_id: <Self::Balances as System>::AccountId,
|
||||
) -> Box<dyn Future<Item = <Self::Balances as Balances>::Balance, Error = Error> + Send>
|
||||
{
|
||||
) -> Pin<
|
||||
Box<
|
||||
dyn Future<Output = Result<<Self::Balances as Balances>::Balance, Error>>
|
||||
+ Send,
|
||||
>,
|
||||
> {
|
||||
let free_balance_map = || {
|
||||
Ok(self
|
||||
.metadata()
|
||||
@@ -96,9 +108,14 @@ impl<T: Balances + 'static, S: 'static> BalancesStore for Client<T, S> {
|
||||
};
|
||||
let map = match free_balance_map() {
|
||||
Ok(map) => map,
|
||||
Err(err) => return Box::new(future::err(err)),
|
||||
Err(err) => return Box::pin(future::err(err)),
|
||||
};
|
||||
Box::new(self.fetch_or(map.key(account_id), None, map.default()))
|
||||
let client = self.clone();
|
||||
Box::pin(async move {
|
||||
client
|
||||
.fetch_or(map.key(account_id), None, map.default())
|
||||
.await
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+38
-49
@@ -139,11 +139,7 @@ pub fn call<T: Contracts>(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use codec::{
|
||||
Codec,
|
||||
Error as CodecError,
|
||||
};
|
||||
use futures::Future;
|
||||
use codec::Codec;
|
||||
use sp_core::Pair;
|
||||
use sp_keyring::AccountKeyring;
|
||||
use sp_runtime::traits::{
|
||||
@@ -154,7 +150,7 @@ mod tests {
|
||||
use super::events;
|
||||
use crate::{
|
||||
frame::contracts::MODULE,
|
||||
tests::test_setup,
|
||||
tests::test_client,
|
||||
Balances,
|
||||
Client,
|
||||
DefaultNodeRuntime as Runtime,
|
||||
@@ -164,17 +160,16 @@ mod tests {
|
||||
|
||||
type AccountId = <Runtime as System>::AccountId;
|
||||
|
||||
fn put_code<T, P, S>(
|
||||
async fn put_code<T, P, S>(
|
||||
client: &Client<T, S>,
|
||||
signer: P,
|
||||
) -> impl Future<Item = Option<Result<T::Hash, CodecError>>, Error = Error>
|
||||
) -> Result<T::Hash, Error>
|
||||
where
|
||||
T: System + Balances + Send + Sync,
|
||||
T::Address: From<T::AccountId>,
|
||||
P: Pair,
|
||||
P::Signature: Codec,
|
||||
S: 'static,
|
||||
S: Verify + Codec + From<P::Signature>,
|
||||
S: Verify + Codec + From<P::Signature> + 'static,
|
||||
S::Signer: From<P::Public> + IdentifyAccount<AccountId = T::AccountId>,
|
||||
{
|
||||
const CONTRACT: &str = r#"
|
||||
@@ -185,70 +180,64 @@ mod tests {
|
||||
"#;
|
||||
let wasm = wabt::wat2wasm(CONTRACT).expect("invalid wabt");
|
||||
|
||||
client.xt(signer, None).and_then(|xt| {
|
||||
xt.watch()
|
||||
.submit(super::put_code(500_000, wasm))
|
||||
.map(|result| result.find_event::<T::Hash>(MODULE, events::CODE_STORED))
|
||||
})
|
||||
let xt = client.xt(signer, None).await?;
|
||||
|
||||
let result = xt.watch().submit(super::put_code(500_000, wasm)).await?;
|
||||
let code_hash = result
|
||||
.find_event::<T::Hash>(MODULE, events::CODE_STORED)
|
||||
.ok_or(Error::Other("Failed to find CodeStored event".into()))??;
|
||||
|
||||
Ok(code_hash)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // requires locally running substrate node
|
||||
fn tx_put_code() {
|
||||
let (mut rt, client) = test_setup();
|
||||
|
||||
let signer = AccountKeyring::Alice.pair();
|
||||
let code_hash = rt.block_on(put_code(&client, signer)).unwrap();
|
||||
env_logger::try_init().ok();
|
||||
let code_hash: Result<_, Error> = async_std::task::block_on(async move {
|
||||
let signer = AccountKeyring::Alice.pair();
|
||||
let client = test_client().await;
|
||||
let code_hash = put_code(&client, signer).await?;
|
||||
Ok(code_hash)
|
||||
});
|
||||
|
||||
assert!(
|
||||
code_hash.is_some(),
|
||||
"Contracts CodeStored event should be present"
|
||||
);
|
||||
assert!(
|
||||
code_hash.unwrap().is_ok(),
|
||||
"CodeStored Hash should decode successfully"
|
||||
code_hash.is_ok(),
|
||||
"Contracts CodeStored event should be received and decoded"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // requires locally running substrate node
|
||||
fn tx_instantiate() {
|
||||
let (mut rt, client) = test_setup();
|
||||
env_logger::try_init().ok();
|
||||
let result: Result<_, Error> = async_std::task::block_on(async move {
|
||||
let signer = AccountKeyring::Alice.pair();
|
||||
let client = test_client().await;
|
||||
|
||||
let signer = AccountKeyring::Alice.pair();
|
||||
let code_hash = rt
|
||||
.block_on(put_code(&client, signer.clone()))
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let code_hash = put_code(&client, signer.clone()).await?;
|
||||
|
||||
println!("{:?}", code_hash);
|
||||
println!("{:?}", code_hash);
|
||||
|
||||
let instantiate = client.xt(signer, None).and_then(move |xt| {
|
||||
xt.watch()
|
||||
let xt = client.xt(signer, None).await?;
|
||||
let result = xt
|
||||
.watch()
|
||||
.submit(super::instantiate::<Runtime>(
|
||||
100_000_000_000_000,
|
||||
500_000,
|
||||
code_hash,
|
||||
Vec::new(),
|
||||
))
|
||||
.map(|result| {
|
||||
result.find_event::<(AccountId, AccountId)>(
|
||||
MODULE,
|
||||
events::INSTANTIATED,
|
||||
)
|
||||
})
|
||||
.await?;
|
||||
let event = result
|
||||
.find_event::<(AccountId, AccountId)>(MODULE, events::INSTANTIATED)
|
||||
.ok_or(Error::Other("Failed to find Instantiated event".into()))??;
|
||||
Ok(event)
|
||||
});
|
||||
|
||||
let result = rt.block_on(instantiate).unwrap();
|
||||
|
||||
assert!(
|
||||
result.is_some(),
|
||||
"Contracts Instantiated event should be present"
|
||||
);
|
||||
assert!(
|
||||
result.unwrap().is_ok(),
|
||||
"Instantiated Event should decode successfully"
|
||||
result.is_ok(),
|
||||
"Contracts CodeStored event should be received and decoded"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-10
@@ -16,16 +16,13 @@
|
||||
|
||||
//! Implements support for the frame_system module.
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
use codec::Codec;
|
||||
use frame_support::Parameter;
|
||||
use futures::future::{
|
||||
self,
|
||||
Future,
|
||||
};
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
use frame_support::Parameter;
|
||||
use sp_runtime::traits::{
|
||||
Bounded,
|
||||
CheckEqual,
|
||||
@@ -39,6 +36,10 @@ use sp_runtime::traits::{
|
||||
SimpleArithmetic,
|
||||
SimpleBitOps,
|
||||
};
|
||||
use std::{
|
||||
fmt::Debug,
|
||||
pin::Pin,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
error::Error,
|
||||
@@ -123,17 +124,22 @@ pub trait SystemStore {
|
||||
fn account_nonce(
|
||||
&self,
|
||||
account_id: <Self::System as System>::AccountId,
|
||||
) -> Box<dyn Future<Item = <Self::System as System>::Index, Error = Error> + Send>;
|
||||
) -> Pin<
|
||||
Box<dyn Future<Output = Result<<Self::System as System>::Index, Error>> + Send>,
|
||||
>;
|
||||
}
|
||||
|
||||
impl<T: System + Balances + 'static, S: 'static> SystemStore for Client<T, S> {
|
||||
impl<T: System + Balances + Sync + Send + 'static, S: 'static> SystemStore
|
||||
for Client<T, S>
|
||||
{
|
||||
type System = T;
|
||||
|
||||
fn account_nonce(
|
||||
&self,
|
||||
account_id: <Self::System as System>::AccountId,
|
||||
) -> Box<dyn Future<Item = <Self::System as System>::Index, Error = Error> + Send>
|
||||
{
|
||||
) -> Pin<
|
||||
Box<dyn Future<Output = Result<<Self::System as System>::Index, Error>> + Send>,
|
||||
> {
|
||||
let account_nonce_map = || {
|
||||
Ok(self
|
||||
.metadata
|
||||
@@ -143,9 +149,14 @@ impl<T: System + Balances + 'static, S: 'static> SystemStore for Client<T, S> {
|
||||
};
|
||||
let map = match account_nonce_map() {
|
||||
Ok(map) => map,
|
||||
Err(err) => return Box::new(future::err(err)),
|
||||
Err(err) => return Box::pin(future::err(err)),
|
||||
};
|
||||
Box::new(self.fetch_or(map.key(account_id), None, map.default()))
|
||||
let client = self.clone();
|
||||
Box::pin(async move {
|
||||
client
|
||||
.fetch_or(map.key(account_id), None, map.default())
|
||||
.await
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user