diff --git a/Cargo.toml b/Cargo.toml index 4df8705ac4..dd1d2d0fc0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ tokio02 = ["jsonrpsee-http-client/tokio02"] tokio1 = ["jsonrpsee-http-client/tokio1"] [dependencies] +async-trait = "0.1.49" log = "0.4.14" thiserror = "1.0.24" futures = "0.3.13" diff --git a/proc-macro/Cargo.toml b/proc-macro/Cargo.toml index 8b0d0aa13f..42e64affc4 100644 --- a/proc-macro/Cargo.toml +++ b/proc-macro/Cargo.toml @@ -15,6 +15,7 @@ description = "Derive calls, events, storage and tests for interacting Substrate proc-macro = true [dependencies] +async-trait = "0.1.49" heck = "0.3.2" proc-macro2 = "1.0.24" proc-macro-crate = "0.1.5" diff --git a/proc-macro/src/call.rs b/proc-macro/src/call.rs index 1e7d6dbe0f..c4aebbf8e3 100644 --- a/proc-macro/src/call.rs +++ b/proc-macro/src/call.rs @@ -50,42 +50,44 @@ pub fn call(s: Structure) -> TokenStream { } /// Call extension trait. + #[async_trait::async_trait] pub trait #call_trait { /// Create and submit an extrinsic. - fn #call<'a>( + async fn #call<'a>( &'a self, signer: &'a (dyn #subxt::Signer + Send + Sync), #args - ) -> core::pin::Pin> + Send + 'a>>; + ) -> Result; /// Create, submit and watch an extrinsic. - fn #call_and_watch<'a>( + async fn #call_and_watch<'a>( &'a self, signer: &'a (dyn #subxt::Signer + Send + Sync), #args - ) -> core::pin::Pin, #subxt::Error>> + Send + 'a>>; + ) -> Result<#subxt::ExtrinsicSuccess, #subxt::Error>; } + #[async_trait::async_trait] impl #call_trait for #subxt::Client where <>::Extra as #subxt::SignedExtension>::AdditionalSigned: Send + Sync, { - fn #call<'a>( + async fn #call<'a>( &'a self, signer: &'a (dyn #subxt::Signer + Send + Sync), #args - ) -> core::pin::Pin> + Send + 'a>> { + ) -> Result { let #marker = core::marker::PhantomData::; - Box::pin(self.submit(#build_struct, signer)) + self.submit(#build_struct, signer).await } - fn #call_and_watch<'a>( + async fn #call_and_watch<'a>( &'a self, signer: &'a (dyn #subxt::Signer + Send + Sync), #args - ) -> core::pin::Pin, #subxt::Error>> + Send + 'a>> { + ) -> Result<#subxt::ExtrinsicSuccess, #subxt::Error> { let #marker = core::marker::PhantomData::; - Box::pin(self.watch(#build_struct, signer)) + self.watch(#build_struct, signer).await } } } @@ -112,46 +114,48 @@ mod tests { } /// Call extension trait. + #[async_trait::async_trait] pub trait TransferCallExt { /// Create and submit an extrinsic. - fn transfer<'a>( + async fn transfer<'a>( &'a self, signer: &'a (dyn substrate_subxt::Signer + Send + Sync), to: &'a ::Address, amount: T::Balance, - ) -> core::pin::Pin> + Send + 'a>>; + ) -> Result; /// Create, submit and watch an extrinsic. - fn transfer_and_watch<'a>( + async fn transfer_and_watch<'a>( &'a self, signer: &'a (dyn substrate_subxt::Signer + Send + Sync), to: &'a ::Address, amount: T::Balance, - ) -> core::pin::Pin, substrate_subxt::Error>> + Send + 'a>>; + ) -> Result, substrate_subxt::Error>; } + #[async_trait::async_trait] impl TransferCallExt for substrate_subxt::Client where <>::Extra as substrate_subxt::SignedExtension>::AdditionalSigned: Send + Sync, { - fn transfer<'a>( + async fn transfer<'a>( &'a self, signer: &'a (dyn substrate_subxt::Signer + Send + Sync), to: &'a ::Address, amount: T::Balance, - ) -> core::pin::Pin> + Send + 'a>> { + ) -> Result { let _ = core::marker::PhantomData::; - Box::pin(self.submit(TransferCall { to, amount, }, signer)) + self.submit(TransferCall { to, amount, }, signer).await } - fn transfer_and_watch<'a>( + async fn transfer_and_watch<'a>( &'a self, signer: &'a (dyn substrate_subxt::Signer + Send + Sync), to: &'a ::Address, amount: T::Balance, - ) -> core::pin::Pin, substrate_subxt::Error>> + Send + 'a>> { + ) -> Result, substrate_subxt::Error> { let _ = core::marker::PhantomData::; - Box::pin(self.watch(TransferCall { to, amount, }, signer)) + self.watch(TransferCall { to, amount, }, signer).await } } }; diff --git a/proc-macro/src/store.rs b/proc-macro/src/store.rs index ef2552e331..2a4d0cffb3 100644 --- a/proc-macro/src/store.rs +++ b/proc-macro/src/store.rs @@ -141,36 +141,38 @@ pub fn store(s: Structure) -> TokenStream { } /// Store extension trait. + #[async_trait::async_trait] pub trait #store_trait { /// Retrieve the store element. - fn #store<'a>( + async fn #store<'a>( &'a self, #args hash: Option, - ) -> core::pin::Pin> + Send + 'a>>; + ) -> Result<#ret, #subxt::Error>; /// Iterate over the store element. - fn #store_iter<'a>( + async fn #store_iter<'a>( &'a self, hash: Option, - ) -> core::pin::Pin> + Send + 'a>>; + ) -> Result<#key_iter, #subxt::Error>; } + #[async_trait::async_trait] impl #store_trait for #subxt::Client { - fn #store<'a>( + async fn #store<'a>( &'a self, #args hash: Option, - ) -> core::pin::Pin> + Send + 'a>> { + ) -> Result<#ret, #subxt::Error> { let #marker = core::marker::PhantomData::; - Box::pin(async move { self.#fetch(&#build_struct, hash).await }) + self.#fetch(&#build_struct, hash).await } - fn #store_iter<'a>( + async fn #store_iter<'a>( &'a self, hash: Option, - ) -> core::pin::Pin> + Send + 'a>> { - Box::pin(self.iter(hash)) + ) -> Result<#key_iter, #subxt::Error> { + self.iter(hash).await } } } @@ -217,36 +219,38 @@ mod tests { } /// Store extension trait. + #[async_trait::async_trait] pub trait AccountStoreExt { /// Retrieve the store element. - fn account<'a>( + async fn account<'a>( &'a self, account_id: &'a ::AccountId, hash: Option, - ) -> core::pin::Pin, substrate_subxt::Error>> + Send + 'a>>; + ) -> Result, substrate_subxt::Error>; /// Iterate over the store element. - fn account_iter<'a>( + async fn account_iter<'a>( &'a self, hash: Option, - ) -> core::pin::Pin>, substrate_subxt::Error>> + Send + 'a>>; + ) -> Result>, substrate_subxt::Error>; } + #[async_trait::async_trait] impl AccountStoreExt for substrate_subxt::Client { - fn account<'a>( + async fn account<'a>( &'a self, account_id: &'a ::AccountId, hash: Option, - ) -> core::pin::Pin, substrate_subxt::Error>> + Send + 'a>> + ) -> Result, substrate_subxt::Error> { let _ = core::marker::PhantomData::; - Box::pin(async move { self.fetch_or_default(&AccountStore { account_id, }, hash).await }) + self.fetch_or_default(&AccountStore { account_id, }, hash).await } - fn account_iter<'a>( + async fn account_iter<'a>( &'a self, hash: Option, - ) -> core::pin::Pin>, substrate_subxt::Error>> + Send + 'a>> { - Box::pin(self.iter(hash)) + ) -> Result>, substrate_subxt::Error> { + self.iter(hash).await } } }; diff --git a/src/extrinsic/signer.rs b/src/extrinsic/signer.rs index c015dc1fb3..357ac36042 100644 --- a/src/extrinsic/signer.rs +++ b/src/extrinsic/signer.rs @@ -30,12 +30,9 @@ use sp_runtime::traits::{ SignedExtension, Verify, }; -use std::{ - future::Future, - pin::Pin, -}; /// Extrinsic signer. +#[async_trait::async_trait] pub trait Signer { /// Returns the account id. fn account_id(&self) -> &T::AccountId; @@ -47,10 +44,10 @@ pub trait Signer { /// /// Some signers may fail, for instance because the hardware on which the keys are located has /// refused the operation. - fn sign( + async fn sign( &self, extrinsic: SignedPayload, - ) -> Pin, String>> + Send>>; + ) -> Result, String>; } /// Extrinsic signer using a private key. @@ -96,6 +93,7 @@ where } } +#[async_trait::async_trait] impl Signer for PairSigner where T: Runtime, @@ -112,10 +110,10 @@ where self.nonce } - fn sign( + async fn sign( &self, extrinsic: SignedPayload, - ) -> Pin, String>> + Send>> { + ) -> Result, String> { let signature = extrinsic.using_encoded(|payload| self.signer.sign(payload)); let (call, extra, _) = extrinsic.deconstruct(); let extrinsic = UncheckedExtrinsic::::new_signed( @@ -124,6 +122,6 @@ where signature.into(), extra, ); - Box::pin(async move { Ok(extrinsic) }) + Ok(extrinsic) } }