From 58faf92083add2f7821e7511f468d98897542233 Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Mon, 6 May 2024 14:37:56 -0400 Subject: [PATCH] feat: add API `in_replicated_execution()` (#489) * update ic0.txt * auto-gen files * add the safe wrapper * e2e * Changelog --- Cargo.lock | 2 +- Cargo.toml | 2 +- e2e-tests/canisters/api_call.rs | 10 ++++++++++ e2e-tests/tests/e2e.rs | 8 ++++++++ ic0.txt | 10 ++++++---- src/candid-extractor/CHANGELOG.md | 5 +++++ src/candid-extractor/ic_mock.wat | 1 + src/ic-cdk/CHANGELOG.md | 9 +++++++-- src/ic-cdk/src/api/mod.rs | 12 ++++++++++++ src/ic0/Cargo.toml | 2 +- src/ic0/src/ic0.rs | 4 ++++ 11 files changed, 56 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f9a1be963..049f28038 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1032,7 +1032,7 @@ dependencies = [ [[package]] name = "ic0" -version = "0.21.1" +version = "0.23.0" dependencies = [ "quote", "syn 2.0.60", diff --git a/Cargo.toml b/Cargo.toml index 2893e369a..cff29a409 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ lto = true opt-level = 'z' [workspace.dependencies] -ic0 = { path = "src/ic0", version = "0.21.1" } +ic0 = { path = "src/ic0", version = "0.23.0" } ic-cdk = { path = "src/ic-cdk", version = "0.13.2"} ic-cdk-timers = { path = "src/ic-cdk-timers", version = "0.7.0" } diff --git a/e2e-tests/canisters/api_call.rs b/e2e-tests/canisters/api_call.rs index 2f8f90002..06fe45c0c 100644 --- a/e2e-tests/canisters/api_call.rs +++ b/e2e-tests/canisters/api_call.rs @@ -15,4 +15,14 @@ fn cycles_burn(amount: u128) -> u128 { ic_cdk::api::cycles_burn(amount) } +#[update] +fn update_is_replicated() -> bool { + ic_cdk::api::in_replicated_execution() +} + +#[query] +fn query_is_not_replicated() -> bool { + ic_cdk::api::in_replicated_execution() +} + fn main() {} diff --git a/e2e-tests/tests/e2e.rs b/e2e-tests/tests/e2e.rs index bf9541df6..879d4598c 100644 --- a/e2e-tests/tests/e2e.rs +++ b/e2e-tests/tests/e2e.rs @@ -182,6 +182,14 @@ fn test_api_call() { ) .unwrap(); assert_eq!(result, WasmResult::Reject("manual reject".to_string())); + + let (result,): (bool,) = call_candid(&env, canister_id, "update_is_replicated", ()) + .expect("Failed to call update_is_replicated"); + assert!(result); + + let (result,): (bool,) = query_candid(&env, canister_id, "query_is_not_replicated", ()) + .expect("Failed to call query_is_not_replicated"); + assert!(!result); } #[test] diff --git a/ic0.txt b/ic0.txt index 29955e510..c842e930d 100644 --- a/ic0.txt +++ b/ic0.txt @@ -17,7 +17,8 @@ ic0.msg_cycles_refunded128 : (dst : i32) -> (); // R ic0.msg_cycles_accept : (max_amount : i64) -> (amount : i64); // U Rt Ry ic0.msg_cycles_accept128 : (max_amount_high : i64, max_amount_low: i64, dst : i32) -> (); // U Rt Ry -ic0.cycles_burn128 : (amount_high : i64, amount_low : i64, dst : i32) -> ();// I G U Ry Rt C T + +ic0.cycles_burn128 : (amount_high : i64, amount_low : i64, dst : i32) -> (); // I G U Ry Rt C T ic0.canister_self_size : () -> i32; // * ic0.canister_self_copy : (dst : i32, offset : i32, size : i32) -> (); // * @@ -57,13 +58,14 @@ ic0.stable64_read : (dst : i64, offset : i64, size : i64) -> (); // * ic0.certified_data_set : (src: i32, size: i32) -> (); // I G U Ry Rt T ic0.data_certificate_present : () -> i32; // * -ic0.data_certificate_size : () -> i32; // * -ic0.data_certificate_copy : (dst: i32, offset: i32, size: i32) -> (); // * +ic0.data_certificate_size : () -> i32; // Q CQ +ic0.data_certificate_copy : (dst: i32, offset: i32, size: i32) -> (); // Q CQ ic0.time : () -> (timestamp : i64); // * ic0.global_timer_set : (timestamp : i64) -> i64; // I G U Ry Rt C T ic0.performance_counter : (counter_type : i32) -> (counter : i64); // * s ic0.is_controller: (src: i32, size: i32) -> ( result: i32); // * s +ic0.in_replicated_execution: () -> (result: i32); // * s ic0.debug_print : (src : i32, size : i32) -> (); // * s -ic0.trap : (src : i32, size : i32) -> (); // * s \ No newline at end of file +ic0.trap : (src : i32, size : i32) -> (); // * s diff --git a/src/candid-extractor/CHANGELOG.md b/src/candid-extractor/CHANGELOG.md index 859cf8751..c8d023468 100644 --- a/src/candid-extractor/CHANGELOG.md +++ b/src/candid-extractor/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] +### Added + +- Upgrade `ic0` to 0.23.0 which includes the new system API `in_replicated_execution`. + ## [0.1.3] - 2024-04-22 ### Added @@ -17,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Includes new system API `cycles_burn128`. (#434) + ## [0.1.1] - 2023-09-19 ### Added diff --git a/src/candid-extractor/ic_mock.wat b/src/candid-extractor/ic_mock.wat index 17e1f5d41..2886218a5 100644 --- a/src/candid-extractor/ic_mock.wat +++ b/src/candid-extractor/ic_mock.wat @@ -49,6 +49,7 @@ (func (export "global_timer_set") (param i64) (result i64) i64.const 0) (func (export "performance_counter") (param i32) (result i64) i64.const 0) (func (export "is_controller") (param i32 i32) (result i32) i32.const 0) + (func (export "in_replicated_execution") (result i32) i32.const 0) (func (export "debug_print") (param i32 i32) ) (func (export "trap") (param i32 i32) ) ) diff --git a/src/ic-cdk/CHANGELOG.md b/src/ic-cdk/CHANGELOG.md index 014688e6c..79e86f809 100644 --- a/src/ic-cdk/CHANGELOG.md +++ b/src/ic-cdk/CHANGELOG.md @@ -8,16 +8,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Add `wasm_memory_limit` to the management canister API types: (#483) +- Add `wasm_memory_limit` to the management canister API types: (#483) * `CanisterSettings` * `DefiniteCanisterSettings`. +- Provide safe wrapper of `in_replicated_execution` in ic-cdk. (#489) + +### Changed + +- Upgrade `ic0` to v0.23.0. (#489) ## [0.13.2] - 2024-04-08 ### Added - Management canister methods for interacting with the chunk store. (#461) -- Provide safe wrapper of global_timer_set in ic-cdk. (#475) +- Provide safe wrapper of `global_timer_set` in ic-cdk. (#475) ## [0.13.1] - 2024-03-01 diff --git a/src/ic-cdk/src/api/mod.rs b/src/ic-cdk/src/api/mod.rs index 5a2d5fcf2..5663b46fe 100644 --- a/src/ic-cdk/src/api/mod.rs +++ b/src/ic-cdk/src/api/mod.rs @@ -193,3 +193,15 @@ pub fn set_global_timer(timestamp: u64) -> u64 { // SAFETY: ic0.global_timer_set is always safe to call. unsafe { ic0::global_timer_set(timestamp as i64) as u64 } } + +/// Checks if in replicated execution. +/// +/// The canister can check whether it is currently running in replicated or non replicated execution. +pub fn in_replicated_execution() -> bool { + // SAFETY: ic0.in_replicated_execution is always safe to call. + match unsafe { ic0::in_replicated_execution() } { + 0 => false, + 1 => true, + _ => unreachable!(), + } +} diff --git a/src/ic0/Cargo.toml b/src/ic0/Cargo.toml index 540cb3d99..266013dcf 100644 --- a/src/ic0/Cargo.toml +++ b/src/ic0/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ic0" -version = "0.21.1" +version = "0.23.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/src/ic0/src/ic0.rs b/src/ic0/src/ic0.rs index bac51bf5f..9a2ed93ed 100644 --- a/src/ic0/src/ic0.rs +++ b/src/ic0/src/ic0.rs @@ -60,6 +60,7 @@ extern "C" { pub fn global_timer_set(timestamp: i64) -> i64; pub fn performance_counter(counter_type: i32) -> i64; pub fn is_controller(src: i32, size: i32) -> i32; + pub fn in_replicated_execution() -> i32; pub fn debug_print(src: i32, size: i32); pub fn trap(src: i32, size: i32); } @@ -222,6 +223,9 @@ mod non_wasm { pub unsafe fn is_controller(src: i32, size: i32) -> i32 { panic!("is_controller should only be called inside canisters."); } + pub unsafe fn in_replicated_execution() -> i32 { + panic!("in_replicated_execution should only be called inside canisters."); + } pub unsafe fn debug_print(src: i32, size: i32) { panic!("debug_print should only be called inside canisters."); }