diff --git a/CHANGELOG.md b/CHANGELOG.md index d5be8214..007f0cd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased * The `Unknown` lookup of a request_status path in a certificate results in an `AgentError` (the IC returns `Absent` for non-existing paths). +* For `Canister` type, added methods with no trailing underscore: update(), query(), canister_id(), clone_with() ## [0.27.0] - 2023-08-30 diff --git a/ic-utils/src/canister.rs b/ic-utils/src/canister.rs index 5ea716af..8160f4bd 100644 --- a/ic-utils/src/canister.rs +++ b/ic-utils/src/canister.rs @@ -87,10 +87,16 @@ pub struct Canister<'agent> { impl<'agent> Canister<'agent> { /// Get the canister ID of this canister. + /// Prefer using [`canister_id`](Canister::canister_id) instead. pub fn canister_id_<'canister: 'agent>(&'canister self) -> &Principal { &self.canister_id } + /// Get the canister ID of this canister. + pub fn canister_id<'canister: 'agent>(&'canister self) -> &Principal { + &self.canister_id + } + /// Create an AsyncCallBuilder to do an update call. pub fn update_<'canister: 'agent>( &'canister self, @@ -99,7 +105,17 @@ impl<'agent> Canister<'agent> { AsyncCallBuilder::new(self, method_name) } + /// Create an AsyncCallBuilder to do an update call. + /// Prefer using [`update`](Canister::update) instead. + pub fn update<'canister: 'agent>( + &'canister self, + method_name: &str, + ) -> AsyncCallBuilder<'agent, 'canister> { + AsyncCallBuilder::new(self, method_name) + } + /// Create a SyncCallBuilder to do a query call. + /// Prefer using [`query`](Canister::query) instead. pub fn query_<'canister: 'agent>( &'canister self, method_name: &str, @@ -107,6 +123,14 @@ impl<'agent> Canister<'agent> { SyncCallBuilder::new(self, method_name) } + /// Create a SyncCallBuilder to do a query call. + pub fn query<'canister: 'agent>( + &'canister self, + method_name: &str, + ) -> SyncCallBuilder<'agent, 'canister> { + SyncCallBuilder::new(self, method_name) + } + /// Call request_status on the RequestId in a loop and return the response as a byte vector. pub async fn wait<'canister: 'agent>( &'canister self, @@ -116,12 +140,20 @@ impl<'agent> Canister<'agent> { } /// Creates a copy of this canister, changing the canister ID to the provided principal. + /// Prefer using [`clone_with`](Canister::clone_with) instead. pub fn clone_with_(&self, id: Principal) -> Self { Self { agent: self.agent, canister_id: id, } } + /// Creates a copy of this canister, changing the canister ID to the provided principal. + pub fn clone_with(&self, id: Principal) -> Self { + Self { + agent: self.agent, + canister_id: id, + } + } /// Create a CanisterBuilder instance to build a canister abstraction. pub fn builder() -> CanisterBuilder<'agent> { @@ -216,7 +248,7 @@ impl<'agent, 'canister: 'agent> SyncCallBuilder<'agent, 'canister> { Self { canister, method_name: method_name.into(), - effective_canister_id: canister.canister_id_().to_owned(), + effective_canister_id: canister.canister_id().to_owned(), arg: Default::default(), } } @@ -301,7 +333,7 @@ impl<'agent, 'canister: 'agent> AsyncCallBuilder<'agent, 'canister> { Self { canister, method_name: method_name.to_string(), - effective_canister_id: canister.canister_id_().to_owned(), + effective_canister_id: canister.canister_id().to_owned(), arg: Default::default(), } } @@ -431,7 +463,7 @@ mod tests { .unwrap(); assert!(canister - .update_("hello") + .update("hello") .build::<()>() .call_and_wait() .await diff --git a/ic-utils/src/interfaces/http_request.rs b/ic-utils/src/interfaces/http_request.rs index 9ca8d145..b40fa534 100644 --- a/ic-utils/src/interfaces/http_request.rs +++ b/ic-utils/src/interfaces/http_request.rs @@ -434,7 +434,7 @@ impl<'agent> HttpRequestCanister<'agent> { T: 'agent + Send + Sync + CandidType + for<'de> Deserialize<'de>, C: 'agent + Send + Sync + CandidType + for<'de> Deserialize<'de>, { - self.query_("http_request") + self.query("http_request") .with_arg(HttpRequest { method, url, @@ -472,7 +472,7 @@ impl<'agent> HttpRequestCanister<'agent> { T: 'agent + Send + Sync + CandidType + for<'de> Deserialize<'de>, C: 'agent + Send + Sync + CandidType + for<'de> Deserialize<'de>, { - self.update_("http_request_update") + self.update("http_request_update") .with_arg(HttpUpdateRequest { method, url, @@ -488,7 +488,7 @@ impl<'agent> HttpRequestCanister<'agent> { method: impl AsRef, token: Token, ) -> impl 'agent + SyncCall<(StreamingCallbackHttpResponse,)> { - self.query_(method.as_ref()).with_value_arg(token.0).build() + self.query(method.as_ref()).with_value_arg(token.0).build() } /// Retrieves the next chunk of a stream from a streaming callback, using the method from [`CallbackStrategy`]. @@ -501,7 +501,7 @@ impl<'agent> HttpRequestCanister<'agent> { where T: 'agent + Send + Sync + CandidType + for<'de> Deserialize<'de>, { - self.query_(method.as_ref()).with_arg(token).build() + self.query(method.as_ref()).with_arg(token).build() } } diff --git a/ic-utils/src/interfaces/management_canister.rs b/ic-utils/src/interfaces/management_canister.rs index 559e20f1..f56d2e8c 100644 --- a/ic-utils/src/interfaces/management_canister.rs +++ b/ic-utils/src/interfaces/management_canister.rs @@ -140,7 +140,7 @@ impl<'agent> ManagementCanister<'agent> { canister_id: Principal, } - self.update_(MgmtMethod::CanisterStatus.as_ref()) + self.update(MgmtMethod::CanisterStatus.as_ref()) .with_arg(In { canister_id: *canister_id, }) @@ -167,7 +167,7 @@ impl<'agent> ManagementCanister<'agent> { canister_id: Principal, } - self.update_(MgmtMethod::DepositCycles.as_ref()) + self.update(MgmtMethod::DepositCycles.as_ref()) .with_arg(Argument { canister_id: *canister_id, }) @@ -185,7 +185,7 @@ impl<'agent> ManagementCanister<'agent> { canister_id: Principal, } - self.update_(MgmtMethod::DeleteCanister.as_ref()) + self.update(MgmtMethod::DeleteCanister.as_ref()) .with_arg(Argument { canister_id: *canister_id, }) @@ -208,7 +208,7 @@ impl<'agent> ManagementCanister<'agent> { amount: u64, } - self.update_(MgmtMethod::ProvisionalTopUpCanister.as_ref()) + self.update(MgmtMethod::ProvisionalTopUpCanister.as_ref()) .with_arg(Argument { canister_id: *canister_id, amount, @@ -221,7 +221,7 @@ impl<'agent> ManagementCanister<'agent> { /// The return value is unknown to any part of the IC at time of the submission of this call. /// A new return value is generated for each call to this method. pub fn raw_rand<'canister: 'agent>(&'canister self) -> impl 'agent + AsyncCall<(Vec,)> { - self.update_(MgmtMethod::RawRand.as_ref()) + self.update(MgmtMethod::RawRand.as_ref()) .build() .map(|result: (Vec,)| (result.0,)) } @@ -236,7 +236,7 @@ impl<'agent> ManagementCanister<'agent> { canister_id: Principal, } - self.update_(MgmtMethod::StartCanister.as_ref()) + self.update(MgmtMethod::StartCanister.as_ref()) .with_arg(Argument { canister_id: *canister_id, }) @@ -254,7 +254,7 @@ impl<'agent> ManagementCanister<'agent> { canister_id: Principal, } - self.update_(MgmtMethod::StopCanister.as_ref()) + self.update(MgmtMethod::StopCanister.as_ref()) .with_arg(Argument { canister_id: *canister_id, }) @@ -278,7 +278,7 @@ impl<'agent> ManagementCanister<'agent> { canister_id: Principal, } - self.update_(MgmtMethod::UninstallCode.as_ref()) + self.update(MgmtMethod::UninstallCode.as_ref()) .with_arg(Argument { canister_id: *canister_id, }) diff --git a/ic-utils/src/interfaces/management_canister/builders.rs b/ic-utils/src/interfaces/management_canister/builders.rs index a6ae3a7d..62438ce5 100644 --- a/ic-utils/src/interfaces/management_canister/builders.rs +++ b/ic-utils/src/interfaces/management_canister/builders.rs @@ -271,12 +271,12 @@ impl<'agent, 'canister: 'agent> CreateCanisterBuilder<'agent, 'canister> { specified_id: self.specified_id, }; self.canister - .update_(MgmtMethod::ProvisionalCreateCanisterWithCycles.as_ref()) + .update(MgmtMethod::ProvisionalCreateCanisterWithCycles.as_ref()) .with_arg(in_arg) .with_effective_canister_id(self.effective_canister_id) } else { self.canister - .update_(MgmtMethod::CreateCanister.as_ref()) + .update(MgmtMethod::CreateCanister.as_ref()) .with_arg(CanisterSettings { controllers, compute_allocation, @@ -423,7 +423,7 @@ impl<'agent, 'canister: 'agent> InstallCodeBuilder<'agent, 'canister> { pub fn build(self) -> Result, AgentError> { Ok(self .canister - .update_(MgmtMethod::InstallCode.as_ref()) + .update(MgmtMethod::InstallCode.as_ref()) .with_arg(CanisterInstall { mode: self.mode.unwrap_or(InstallMode::Install), canister_id: self.canister_id, @@ -627,7 +627,7 @@ impl<'agent, 'canister: 'agent> UpdateCanisterBuilder<'agent, 'canister> { Ok(self .canister - .update_(MgmtMethod::UpdateSettings.as_ref()) + .update(MgmtMethod::UpdateSettings.as_ref()) .with_arg(In { canister_id: self.canister_id, settings: CanisterSettings { diff --git a/ic-utils/src/interfaces/wallet.rs b/ic-utils/src/interfaces/wallet.rs index f15ee909..87b5cbb6 100644 --- a/ic-utils/src/interfaces/wallet.rs +++ b/ic-utils/src/interfaces/wallet.rs @@ -90,14 +90,14 @@ where cycles: TCycles, } Ok(if self.u128 { - self.wallet.update_("wallet_call128").with_arg(In { + self.wallet.update("wallet_call128").with_arg(In { canister: self.destination, method_name: self.method_name, args: self.arg.serialize()?.to_vec(), cycles: self.amount, }) } else { - self.wallet.update_("wallet_call").with_arg(In { + self.wallet.update("wallet_call").with_arg(In { canister: self.destination, method_name: self.method_name, args: self.arg.serialize()?.to_vec(), @@ -431,7 +431,7 @@ impl<'agent> WalletCanister<'agent> { ) -> Result, AgentError> { static DEFAULT_VERSION: Lazy = Lazy::new(|| Version::parse("0.1.0").unwrap()); let version: Result<(String,), _> = - canister.query_("wallet_api_version").build().call().await; + canister.query("wallet_api_version").build().call().await; let version = match version { Err(AgentError::ReplicaError(replica_error)) if replica_error.reject_code == RejectCode::DestinationInvalid @@ -462,7 +462,7 @@ impl<'agent> WalletCanister<'agent> { pub fn fetch_wallet_api_version<'canister: 'agent>( &'canister self, ) -> impl 'agent + SyncCall<(Option,)> { - self.query_("wallet_api_version").build() + self.query("wallet_api_version").build() } /// Get the (cached) API version of the wallet. @@ -472,7 +472,7 @@ impl<'agent> WalletCanister<'agent> { /// Get the friendly name of the wallet (if one exists). pub fn name<'canister: 'agent>(&'canister self) -> impl 'agent + SyncCall<(Option,)> { - self.query_("name").build() + self.query("name").build() } /// Set the friendly name of the wallet. @@ -480,14 +480,14 @@ impl<'agent> WalletCanister<'agent> { &'canister self, name: String, ) -> impl 'agent + AsyncCall<()> { - self.update_("set_name").with_arg(name).build() + self.update("set_name").with_arg(name).build() } /// Get the current controller's principal ID. pub fn get_controllers<'canister: 'agent>( &'canister self, ) -> impl 'agent + SyncCall<(Vec,)> { - self.query_("get_controllers").build() + self.query("get_controllers").build() } /// Transfer controller to another principal ID. @@ -495,7 +495,7 @@ impl<'agent> WalletCanister<'agent> { &'canister self, principal: Principal, ) -> impl 'agent + AsyncCall<()> { - self.update_("add_controller").with_arg(principal).build() + self.update("add_controller").with_arg(principal).build() } /// Remove a user as a wallet controller. @@ -503,16 +503,14 @@ impl<'agent> WalletCanister<'agent> { &'canister self, principal: Principal, ) -> impl 'agent + AsyncCall<()> { - self.update_("remove_controller") - .with_arg(principal) - .build() + self.update("remove_controller").with_arg(principal).build() } /// Get the list of custodians. pub fn get_custodians<'canister: 'agent>( &'canister self, ) -> impl 'agent + SyncCall<(Vec,)> { - self.query_("get_custodians").build() + self.query("get_custodians").build() } /// Authorize a new custodian. @@ -520,7 +518,7 @@ impl<'agent> WalletCanister<'agent> { &'canister self, custodian: Principal, ) -> impl 'agent + AsyncCall<()> { - self.update_("authorize").with_arg(custodian).build() + self.update("authorize").with_arg(custodian).build() } /// Deauthorize a custodian. @@ -528,21 +526,21 @@ impl<'agent> WalletCanister<'agent> { &'canister self, custodian: Principal, ) -> impl 'agent + AsyncCall<()> { - self.update_("deauthorize").with_arg(custodian).build() + self.update("deauthorize").with_arg(custodian).build() } /// Get the balance with the 64-bit API. pub fn wallet_balance64<'canister: 'agent>( &'canister self, ) -> impl 'agent + SyncCall<(BalanceResult,)> { - self.query_("wallet_balance").build() + self.query("wallet_balance").build() } /// Get the balance with the 128-bit API. pub fn wallet_balance128<'canister: 'agent>( &'canister self, ) -> impl 'agent + SyncCall<(BalanceResult,)> { - self.query_("wallet_balance128").build() + self.query("wallet_balance128").build() } /// Get the balance. @@ -573,7 +571,7 @@ impl<'agent> WalletCanister<'agent> { amount: u64, } - self.update_("wallet_send") + self.update("wallet_send") .with_arg(In { canister: destination, amount, @@ -593,7 +591,7 @@ impl<'agent> WalletCanister<'agent> { amount: u128, } - self.update_("wallet_send128") + self.update("wallet_send128") .with_arg(In { canister: destination, amount, @@ -634,7 +632,7 @@ impl<'agent> WalletCanister<'agent> { struct In { memo: Option, } - self.update_("wallet_receive") + self.update("wallet_receive") .with_arg(memo.map(|memo| In { memo: Some(memo) })) .build() } @@ -661,7 +659,7 @@ impl<'agent> WalletCanister<'agent> { freezing_threshold: freezing_threshold.map(u64::from).map(Nat::from), }; - self.update_("wallet_create_canister") + self.update("wallet_create_canister") .with_arg(In { cycles, settings }) .build() .map(|result: (Result,)| (result.0,)) @@ -689,7 +687,7 @@ impl<'agent> WalletCanister<'agent> { freezing_threshold: freezing_threshold.map(u64::from).map(Nat::from), }; - self.update_("wallet_create_canister") + self.update("wallet_create_canister") .with_arg(In { cycles, settings }) .build() .map(|result: (Result,)| (result.0,)) @@ -717,7 +715,7 @@ impl<'agent> WalletCanister<'agent> { freezing_threshold: freezing_threshold.map(u64::from).map(Nat::from), }; - self.update_("wallet_create_canister128") + self.update("wallet_create_canister128") .with_arg(In { cycles, settings }) .build() .map(|result: (Result,)| (result.0,)) @@ -807,7 +805,7 @@ impl<'agent> WalletCanister<'agent> { freezing_threshold: freezing_threshold.map(u64::from).map(Nat::from), }; - self.update_("wallet_create_wallet") + self.update("wallet_create_wallet") .with_arg(In { cycles, settings }) .build() .map(|result: (Result,)| (result.0,)) @@ -835,7 +833,7 @@ impl<'agent> WalletCanister<'agent> { freezing_threshold: freezing_threshold.map(u64::from).map(Nat::from), }; - self.update_("wallet_create_wallet") + self.update("wallet_create_wallet") .with_arg(In { cycles, settings }) .build() .map(|result: (Result,)| (result.0,)) @@ -863,7 +861,7 @@ impl<'agent> WalletCanister<'agent> { freezing_threshold: freezing_threshold.map(u64::from).map(Nat::from), }; - self.update_("wallet_create_wallet128") + self.update("wallet_create_wallet128") .with_arg(In { cycles, settings }) .build() .map(|result: (Result,)| (result.0,)) @@ -938,7 +936,7 @@ impl<'agent> WalletCanister<'agent> { #[serde(with = "serde_bytes")] wasm_module: Vec, } - self.update_("wallet_store_wallet_wasm") + self.update("wallet_store_wallet_wasm") .with_arg(In { wasm_module }) .build() } @@ -948,14 +946,14 @@ impl<'agent> WalletCanister<'agent> { &'canister self, address: AddressEntry, ) -> impl 'agent + AsyncCall<()> { - self.update_("add_address").with_arg(address).build() + self.update("add_address").with_arg(address).build() } /// List the entries in the address book. pub fn list_addresses<'canister: 'agent>( &'canister self, ) -> impl 'agent + SyncCall<(Vec,)> { - self.query_("list_addresses").build() + self.query("list_addresses").build() } /// Remove a principal from the address book. @@ -963,7 +961,7 @@ impl<'agent> WalletCanister<'agent> { &'canister self, principal: Principal, ) -> impl 'agent + AsyncCall<()> { - self.update_("remove_address").with_arg(principal).build() + self.update("remove_address").with_arg(principal).build() } /// Get a list of all transaction events this wallet remembers, using the 64-bit API. Fails if any events are 128-bit. @@ -984,7 +982,7 @@ impl<'agent> WalletCanister<'agent> { Some(In { from, to }) }; - self.query_("get_events").with_arg(arg).build() + self.query("get_events").with_arg(arg).build() } /// Get a list of all transaction events this wallet remembers, using the 128-bit API. @@ -1003,7 +1001,7 @@ impl<'agent> WalletCanister<'agent> { } else { Some(In { from, to }) }; - self.query_("get_events128").with_arg(arg).build() + self.query("get_events128").with_arg(arg).build() } /// Get a list of all transaction events this wallet remembers. @@ -1105,7 +1103,7 @@ impl<'agent> WalletCanister<'agent> { from: Option, to: Option, } - self.query_("list_managed_canisters") + self.query("list_managed_canisters") .with_arg((In { from, to },)) .build() } @@ -1123,7 +1121,7 @@ impl<'agent> WalletCanister<'agent> { from: Option, to: Option, } - self.query_("get_managed_canister_events") + self.query("get_managed_canister_events") .with_arg((In { canister, from, to },)) .build() } @@ -1141,7 +1139,7 @@ impl<'agent> WalletCanister<'agent> { from: Option, to: Option, } - self.query_("get_managed_canister_events128") + self.query("get_managed_canister_events128") .with_arg((In { canister, from, to },)) .build() } diff --git a/ref-tests/tests/integration.rs b/ref-tests/tests/integration.rs index aecc7071..55837b12 100644 --- a/ref-tests/tests/integration.rs +++ b/ref-tests/tests/integration.rs @@ -76,7 +76,7 @@ fn canister_query() { let arg = payload().reply_data(b"hello").build(); let out = universal - .query_("query") + .query("query") .with_arg_raw(arg) .build::<()>() .call_raw() @@ -98,7 +98,7 @@ fn canister_reject_call() { let bob = WalletCanister::create(&agent, create_wallet_canister(&agent, None).await?).await?; - let result = alice.wallet_send(*bob.canister_id_(), 1_000_000).await; + let result = alice.wallet_send(*bob.canister_id(), 1_000_000).await; assert_eq!( result, @@ -377,7 +377,7 @@ fn wallet_canister_funds() { let alice_previous_balance = alice.wallet_balance().await?; let bob_previous_balance = bob.wallet_balance().await?; - alice.wallet_send(*bob.canister_id_(), 1_000_000).await?; + alice.wallet_send(*bob.canister_id(), 1_000_000).await?; let bob_balance = bob.wallet_balance().await?;