From 432ff1d80b7a8e46d78a683cba70920ecf76e548 Mon Sep 17 00:00:00 2001 From: Adam Spofford <93943719+adamspofford-dfinity@users.noreply.github.com> Date: Thu, 3 Aug 2023 14:24:18 -0700 Subject: [PATCH] feat: Disable arc_type requirement in candid for ic-utils (#454) --- ic-utils/Cargo.toml | 2 +- ic-utils/src/call.rs | 23 +++++++++----- .../management_canister/builders.rs | 24 +++++++++----- ic-utils/src/interfaces/wallet.rs | 31 +++++++++++-------- rust-toolchain.toml | 1 + 5 files changed, 51 insertions(+), 30 deletions(-) diff --git a/ic-utils/Cargo.toml b/ic-utils/Cargo.toml index e23a2b79..a94cd2d3 100644 --- a/ic-utils/Cargo.toml +++ b/ic-utils/Cargo.toml @@ -18,7 +18,7 @@ include = ["src", "Cargo.toml", "../LICENSE", "README.md"] [dependencies] async-trait = "0.1.68" -candid = { workspace = true, features = ["arc_type"] } +candid = { workspace = true } ic-agent = { workspace = true, default-features = false } serde = { workspace = true } serde_bytes = { workspace = true } diff --git a/ic-utils/src/call.rs b/ic-utils/src/call.rs index 8476d0e4..a4a03bd3 100644 --- a/ic-utils/src/call.rs +++ b/ic-utils/src/call.rs @@ -4,10 +4,16 @@ use ic_agent::{agent::UpdateBuilder, export::Principal, Agent, AgentError, Reque use serde::de::DeserializeOwned; use std::fmt; use std::future::Future; +use std::pin::Pin; mod expiry; pub use expiry::Expiry; +#[cfg(target_family = "wasm")] +pub(crate) type BoxFuture<'a, T> = Pin + 'a>>; +#[cfg(not(target_family = "wasm"))] +pub(crate) type BoxFuture<'a, T> = Pin + 'a + Send>>; + /// A type that implements synchronous calls (ie. 'query' calls). #[cfg_attr(target_family = "wasm", async_trait(?Send))] #[cfg_attr(not(target_family = "wasm"), async_trait)] @@ -96,14 +102,15 @@ where /// .create_canister() /// .as_provisional_create_with_amount(None) /// .with_effective_canister_id(effective_id) - /// .and_then(|(canister_id,)| async move { - /// management_canister - /// .install_code(&canister_id, canister_wasm) - /// .build() - /// .unwrap() - /// .call_and_wait() - /// .await?; - /// Ok((canister_id,)) + /// .and_then(|(canister_id,)| { + /// let call = management_canister + /// .install_code(&canister_id, canister_wasm) + /// .build() + /// .unwrap(); + /// async move { + /// call.call_and_wait().await?; + /// Ok((canister_id,)) + /// } /// }) /// .call_and_wait() /// .await?; diff --git a/ic-utils/src/interfaces/management_canister/builders.rs b/ic-utils/src/interfaces/management_canister/builders.rs index 759282cf..f1f125ba 100644 --- a/ic-utils/src/interfaces/management_canister/builders.rs +++ b/ic-utils/src/interfaces/management_canister/builders.rs @@ -1,7 +1,10 @@ //! Builder interfaces for some method calls of the management canister. use crate::{ - call::AsyncCall, canister::Argument, interfaces::management_canister::MgmtMethod, Canister, + call::{AsyncCall, BoxFuture}, + canister::Argument, + interfaces::management_canister::MgmtMethod, + Canister, }; use async_trait::async_trait; use candid::{CandidType, Deserialize, Nat}; @@ -437,15 +440,20 @@ impl<'agent, 'canister: 'agent> InstallCodeBuilder<'agent, 'canister> { } } -#[cfg_attr(target_family = "wasm", async_trait(?Send))] -#[cfg_attr(not(target_family = "wasm"), async_trait)] impl<'agent, 'canister: 'agent> AsyncCall<()> for InstallCodeBuilder<'agent, 'canister> { - async fn call(self) -> Result { - self.build()?.call().await + fn call<'async_trait>(self) -> BoxFuture<'async_trait, Result> + where + Self: 'async_trait, + { + let call_res = self.build(); + Box::pin(async move { call_res?.call().await }) } - - async fn call_and_wait(self) -> Result<(), AgentError> { - self.build()?.call_and_wait().await + fn call_and_wait<'async_trait>(self) -> BoxFuture<'async_trait, Result<(), AgentError>> + where + Self: 'async_trait, + { + let call_res = self.build(); + Box::pin(async move { call_res?.call_and_wait().await }) } } diff --git a/ic-utils/src/interfaces/wallet.rs b/ic-utils/src/interfaces/wallet.rs index 431f230c..6ee3e5ef 100644 --- a/ic-utils/src/interfaces/wallet.rs +++ b/ic-utils/src/interfaces/wallet.rs @@ -2,10 +2,10 @@ //! //! [cycles wallet]: https://github.com/dfinity/cycles-wallet -use std::ops::Deref; +use std::{future::Future, ops::Deref}; use crate::{ - call::{AsyncCall, SyncCall}, + call::{AsyncCall, BoxFuture, SyncCall}, canister::Argument, interfaces::management_canister::{ attributes::{ComputeAllocation, FreezingThreshold, MemoryAllocation}, @@ -13,7 +13,6 @@ use crate::{ }, Canister, }; -use async_trait::async_trait; use candid::{decode_args, utils::ArgumentDecoder, CandidType, Deserialize, Nat}; use ic_agent::{agent::RejectCode, export::Principal, Agent, AgentError, RequestId}; use once_cell::sync::Lazy; @@ -111,28 +110,34 @@ where } /// Calls the forwarded canister call on the wallet canister. Equivalent to `.build().call()`. - pub async fn call(self) -> Result { - self.build()?.call().await + pub fn call(self) -> impl Future> + 'agent { + let call_res = self.build(); + async move { call_res?.call().await } } /// Calls the forwarded canister call on the wallet canister, and waits for the result. Equivalent to `.build().call_and_wait()`. - pub async fn call_and_wait(self) -> Result { - self.build()?.call_and_wait().await + pub fn call_and_wait(self) -> impl Future> + 'agent { + let call_res = self.build(); + async move { call_res?.call_and_wait().await } } } -#[cfg_attr(target_family = "wasm", async_trait(?Send))] -#[cfg_attr(not(target_family = "wasm"), async_trait)] impl<'agent, 'canister: 'agent, Out> AsyncCall for CallForwarder<'agent, 'canister, Out> where Out: for<'de> ArgumentDecoder<'de> + Send + Sync, { - async fn call(self) -> Result { - self.call().await + fn call<'async_trait>(self) -> BoxFuture<'async_trait, Result> + where + Self: 'async_trait, + { + Box::pin(self.call()) } - async fn call_and_wait(self) -> Result { - self.call_and_wait().await + fn call_and_wait<'async_trait>(self) -> BoxFuture<'async_trait, Result> + where + Self: 'async_trait, + { + Box::pin(self.call_and_wait()) } } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index c032b573..b314ae52 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,4 @@ [toolchain] channel = "1.65.0" components = ["rustfmt", "clippy"] +targets = ["wasm32-unknown-unknown"]