diff --git a/Cargo.Bazel.json.lock b/Cargo.Bazel.json.lock index ae3a6e269f4..da588ed0203 100644 --- a/Cargo.Bazel.json.lock +++ b/Cargo.Bazel.json.lock @@ -1,5 +1,5 @@ { - "checksum": "c940ed0c71e779f38de47e366662d71cd883022d89016936e1952a55719fe089", + "checksum": "5eb904c0c07c6b91be340371eabc73c69bb12f120fa709cc3b1d8488b1a5de6b", "crates": { "abnf 0.12.0": { "name": "abnf", @@ -10027,7 +10027,7 @@ "target": "canbench_rs" }, { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -10122,7 +10122,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -10209,14 +10209,14 @@ ], "license_file": null }, - "candid 0.10.10": { + "candid 0.10.12": { "name": "candid", - "version": "0.10.10", + "version": "0.10.12", "package_url": "https://github.com/dfinity/candid", "repository": { "Http": { - "url": "https://static.crates.io/crates/candid/0.10.10/download", - "sha256": "6c30ee7f886f296b6422c0ff017e89dd4f831521dfdcc76f3f71aae1ce817222" + "url": "https://static.crates.io/crates/candid/0.10.12/download", + "sha256": "51e129c4051c57daf943586e01ef72faae48b04a8f692d5f646febf17a264c38" } }, "targets": [ @@ -10323,7 +10323,7 @@ ], "selects": {} }, - "version": "0.10.10" + "version": "0.10.12" }, "license": "Apache-2.0", "license_ids": [ @@ -10438,7 +10438,7 @@ "target": "anyhow" }, { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -18346,7 +18346,7 @@ "target": "canbench_rs" }, { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -18609,6 +18609,11 @@ "id": "ic-cdk 0.16.0", "target": "ic_cdk" }, + { + "id": "ic-cdk 0.18.0-alpha.1", + "target": "ic_cdk", + "alias": "ic_cdk_next" + }, { "id": "ic-cdk-timers 0.11.0", "target": "ic_cdk_timers" @@ -19505,6 +19510,11 @@ "id": "ic-cdk-macros 0.9.0", "target": "ic_cdk_macros" }, + { + "id": "ic-cdk-macros 0.18.0-alpha.1", + "target": "ic_cdk_macros", + "alias": "ic_cdk_macros_next" + }, { "id": "indoc 1.0.9", "target": "indoc" @@ -23076,7 +23086,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -29827,7 +29837,7 @@ "target": "cached" }, { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -30298,7 +30308,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -30402,7 +30412,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -30489,7 +30499,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -30552,7 +30562,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -30620,7 +30630,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -30688,7 +30698,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -30724,6 +30734,81 @@ ], "license_file": "LICENSE" }, + "ic-cdk 0.18.0-alpha.1": { + "name": "ic-cdk", + "version": "0.18.0-alpha.1", + "package_url": "https://github.com/dfinity/cdk-rs", + "repository": { + "Git": { + "remote": "https://github.com/dfinity/cdk-rs.git", + "commitish": { + "Rev": "4e287ce51636b0e70768c193da38d2fc5324ea15" + }, + "strip_prefix": "ic-cdk" + } + }, + "targets": [ + { + "Library": { + "crate_name": "ic_cdk", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "ic_cdk", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "candid 0.10.12", + "target": "candid" + }, + { + "id": "ic0 0.24.0-alpha.1", + "target": "ic0" + }, + { + "id": "serde 1.0.217", + "target": "serde" + }, + { + "id": "serde_bytes 0.11.15", + "target": "serde_bytes" + }, + { + "id": "thiserror 2.0.3", + "target": "thiserror" + } + ], + "selects": {} + }, + "edition": "2021", + "proc_macro_deps": { + "common": [ + { + "id": "ic-cdk-macros 0.18.0-alpha.1", + "target": "ic_cdk_macros" + } + ], + "selects": {} + }, + "version": "0.18.0-alpha.1" + }, + "license": "Apache-2.0", + "license_ids": [ + "Apache-2.0" + ], + "license_file": "LICENSE" + }, "ic-cdk-macros 0.8.4": { "name": "ic-cdk-macros", "version": "0.8.4", @@ -30756,7 +30841,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -30823,7 +30908,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -30890,7 +30975,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -30957,7 +31042,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -30992,6 +31077,76 @@ ], "license_file": "LICENSE" }, + "ic-cdk-macros 0.18.0-alpha.1": { + "name": "ic-cdk-macros", + "version": "0.18.0-alpha.1", + "package_url": "https://github.com/dfinity/cdk-rs", + "repository": { + "Git": { + "remote": "https://github.com/dfinity/cdk-rs.git", + "commitish": { + "Rev": "4e287ce51636b0e70768c193da38d2fc5324ea15" + }, + "strip_prefix": "ic-cdk-macros" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "ic_cdk_macros", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "ic_cdk_macros", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "candid 0.10.12", + "target": "candid" + }, + { + "id": "proc-macro2 1.0.89", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.37", + "target": "quote" + }, + { + "id": "serde 1.0.217", + "target": "serde" + }, + { + "id": "serde_tokenstream 0.2.1", + "target": "serde_tokenstream" + }, + { + "id": "syn 2.0.87", + "target": "syn" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.18.0-alpha.1" + }, + "license": "Apache-2.0", + "license_ids": [ + "Apache-2.0" + ], + "license_file": "LICENSE" + }, "ic-cdk-timers 0.11.0": { "name": "ic-cdk-timers", "version": "0.11.0", @@ -31095,7 +31250,7 @@ "target": "cached" }, { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -31370,7 +31525,7 @@ "target": "base64" }, { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -31449,7 +31604,7 @@ "target": "bytes" }, { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -31625,7 +31780,7 @@ "target": "base64" }, { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -31822,7 +31977,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -31881,7 +32036,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -31965,7 +32120,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -32059,7 +32214,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -32337,7 +32492,7 @@ "target": "anyhow" }, { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -32412,7 +32567,7 @@ "deps": { "common": [ { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -32545,6 +32700,47 @@ ], "license_file": "LICENSE" }, + "ic0 0.24.0-alpha.1": { + "name": "ic0", + "version": "0.24.0-alpha.1", + "package_url": "https://github.com/dfinity/cdk-rs", + "repository": { + "Git": { + "remote": "https://github.com/dfinity/cdk-rs.git", + "commitish": { + "Rev": "4e287ce51636b0e70768c193da38d2fc5324ea15" + }, + "strip_prefix": "ic0" + } + }, + "targets": [ + { + "Library": { + "crate_name": "ic0", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "ic0", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2021", + "version": "0.24.0-alpha.1" + }, + "license": "Apache-2.0", + "license_ids": [ + "Apache-2.0" + ], + "license_file": "LICENSE" + }, "ic_bls12_381 0.10.0": { "name": "ic_bls12_381", "version": "0.10.0", @@ -32753,7 +32949,7 @@ "target": "anyhow" }, { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -32824,7 +33020,7 @@ "target": "anyhow" }, { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -49217,7 +49413,7 @@ "target": "base64" }, { - "id": "candid 0.10.10", + "id": "candid 0.10.12", "target": "candid" }, { @@ -87297,7 +87493,7 @@ "cached 0.49.2", "canbench 0.1.8", "canbench-rs 0.1.8", - "candid 0.10.10", + "candid 0.10.12", "candid_parser 0.1.2", "cargo_metadata 0.14.2", "cc 1.1.37", @@ -87364,7 +87560,9 @@ "ic-canister-sig-creation 1.1.0", "ic-cbor 3.0.2", "ic-cdk 0.16.0", + "ic-cdk 0.18.0-alpha.1", "ic-cdk-macros 0.9.0", + "ic-cdk-macros 0.18.0-alpha.1", "ic-cdk-timers 0.11.0", "ic-certificate-verification 3.0.2", "ic-certification 3.0.2", diff --git a/Cargo.Bazel.toml.lock b/Cargo.Bazel.toml.lock index a81cc6d2d52..fc8871c416f 100644 --- a/Cargo.Bazel.toml.lock +++ b/Cargo.Bazel.toml.lock @@ -1746,9 +1746,9 @@ dependencies = [ [[package]] name = "candid" -version = "0.10.10" +version = "0.10.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c30ee7f886f296b6422c0ff017e89dd4f831521dfdcc76f3f71aae1ce817222" +checksum = "51e129c4051c57daf943586e01ef72faae48b04a8f692d5f646febf17a264c38" dependencies = [ "anyhow", "binread", @@ -3069,6 +3069,8 @@ dependencies = [ "ic-canister-sig-creation", "ic-cbor", "ic-cdk 0.16.0", + "ic-cdk 0.18.0-alpha.1", + "ic-cdk-macros 0.18.0-alpha.1", "ic-cdk-macros 0.9.0", "ic-cdk-timers", "ic-certificate-verification", @@ -5113,6 +5115,19 @@ dependencies = [ "serde_bytes", ] +[[package]] +name = "ic-cdk" +version = "0.18.0-alpha.1" +source = "git+https://github.com/dfinity/cdk-rs.git?branch=next#4e287ce51636b0e70768c193da38d2fc5324ea15" +dependencies = [ + "candid", + "ic-cdk-macros 0.18.0-alpha.1", + "ic0 0.24.0-alpha.1", + "serde", + "serde_bytes", + "thiserror 2.0.3", +] + [[package]] name = "ic-cdk-macros" version = "0.8.4" @@ -5169,6 +5184,19 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "ic-cdk-macros" +version = "0.18.0-alpha.1" +source = "git+https://github.com/dfinity/cdk-rs.git?branch=next#4e287ce51636b0e70768c193da38d2fc5324ea15" +dependencies = [ + "candid", + "proc-macro2", + "quote", + "serde", + "serde_tokenstream 0.2.1", + "syn 2.0.87", +] + [[package]] name = "ic-cdk-timers" version = "0.11.0" @@ -5472,6 +5500,11 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de254dd67bbd58073e23dc1c8553ba12fa1dc610a19de94ad2bbcd0460c067f" +[[package]] +name = "ic0" +version = "0.24.0-alpha.1" +source = "git+https://github.com/dfinity/cdk-rs.git?branch=next#4e287ce51636b0e70768c193da38d2fc5324ea15" + [[package]] name = "ic_bls12_381" version = "0.10.0" diff --git a/Cargo.lock b/Cargo.lock index da683f8ccbc..967ae2e10bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6344,6 +6344,19 @@ dependencies = [ "serde_bytes", ] +[[package]] +name = "ic-cdk" +version = "0.18.0-alpha.1" +source = "git+https://github.com/dfinity/cdk-rs?branch=next#4e287ce51636b0e70768c193da38d2fc5324ea15" +dependencies = [ + "candid", + "ic-cdk-macros 0.18.0-alpha.1", + "ic0 0.24.0-alpha.1", + "serde", + "serde_bytes", + "thiserror 2.0.11", +] + [[package]] name = "ic-cdk-macros" version = "0.8.4" @@ -6414,6 +6427,19 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "ic-cdk-macros" +version = "0.18.0-alpha.1" +source = "git+https://github.com/dfinity/cdk-rs?branch=next#4e287ce51636b0e70768c193da38d2fc5324ea15" +dependencies = [ + "candid", + "proc-macro2", + "quote", + "serde", + "serde_tokenstream 0.2.2", + "syn 2.0.96", +] + [[package]] name = "ic-cdk-timers" version = "0.7.0" @@ -13714,6 +13740,11 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de254dd67bbd58073e23dc1c8553ba12fa1dc610a19de94ad2bbcd0460c067f" +[[package]] +name = "ic0" +version = "0.24.0-alpha.1" +source = "git+https://github.com/dfinity/cdk-rs?branch=next#4e287ce51636b0e70768c193da38d2fc5324ea15" + [[package]] name = "ic_bls12_381" version = "0.10.0" @@ -15589,7 +15620,7 @@ dependencies = [ "dfn_candid", "ic-agent", "ic-base-types", - "ic-cdk 0.16.0", + "ic-cdk 0.18.0-alpha.1", "ic-registry-subnet-type", "ic-system-test-driver", "ic-types", @@ -22996,8 +23027,8 @@ version = "0.9.0" dependencies = [ "candid", "futures", - "ic-cdk 0.16.0", - "ic-cdk-macros 0.9.0", + "ic-cdk 0.18.0-alpha.1", + "ic-cdk-macros 0.18.0-alpha.1", "rand 0.8.5", "rand_pcg 0.3.1", "serde", diff --git a/bazel/external_crates.bzl b/bazel/external_crates.bzl index f25afadc154..0da3fafe937 100644 --- a/bazel/external_crates.bzl +++ b/bazel/external_crates.bzl @@ -592,6 +592,18 @@ def external_crates_repository(name, cargo_lockfile, lockfile, sanitizers_enable "ic-cdk-macros": crate.spec( version = "^0.9.0", ), + "ic-cdk-macros-next": crate.spec( + package = "ic-cdk-macros", + git = "https://github.com/dfinity/cdk-rs.git", + branch = "next", + # rev = "4e287ce51636b0e70768c193da38d2fc5324ea15", + ), + "ic-cdk-next": crate.spec( + package = "ic-cdk", + git = "https://github.com/dfinity/cdk-rs.git", + branch = "next", + # rev = "4e287ce51636b0e70768c193da38d2fc5324ea15", + ), "ic-certified-map": crate.spec( version = "^0.3.1", ), diff --git a/rs/config/src/embedders.rs b/rs/config/src/embedders.rs index 9c6ef4db9d7..4e599ea4c5a 100644 --- a/rs/config/src/embedders.rs +++ b/rs/config/src/embedders.rs @@ -121,7 +121,7 @@ impl FeatureFlags { write_barrier: FlagStatus::Disabled, wasm_native_stable_memory: FlagStatus::Enabled, wasm64: FlagStatus::Enabled, - best_effort_responses: FlagStatus::Disabled, + best_effort_responses: FlagStatus::Enabled, canister_backtrace: FlagStatus::Enabled, } } diff --git a/rs/messaging/tests/queue_tests.rs b/rs/messaging/tests/queue_tests.rs index 2107d111210..33adfbedcbb 100644 --- a/rs/messaging/tests/queue_tests.rs +++ b/rs/messaging/tests/queue_tests.rs @@ -102,7 +102,9 @@ impl SubnetPairProxy { Encode!(&StartArgs { network_topology, canister_to_subnet_rate, - payload_size_bytes, + request_payload_size_bytes: payload_size_bytes, + request_timeout_seconds: 0, + response_payload_size_bytes: payload_size_bytes, }) } diff --git a/rs/rust_canisters/xnet_test/BUILD.bazel b/rs/rust_canisters/xnet_test/BUILD.bazel index 4382e3ffc46..38a68d9ef14 100644 --- a/rs/rust_canisters/xnet_test/BUILD.bazel +++ b/rs/rust_canisters/xnet_test/BUILD.bazel @@ -7,7 +7,7 @@ DEPENDENCIES = [ # Keep sorted. "@crate_index//:candid", "@crate_index//:futures", - "@crate_index//:ic-cdk", + "@crate_index//:ic_cdk_next", "@crate_index//:rand", "@crate_index//:rand_pcg", "@crate_index//:serde", @@ -16,7 +16,7 @@ DEPENDENCIES = [ MACRO_DEPENDENCIES = [ # Keep sorted. - "@crate_index//:ic-cdk-macros", + "@crate_index//:ic_cdk_macros_next", ] rust_library( diff --git a/rs/rust_canisters/xnet_test/Cargo.toml b/rs/rust_canisters/xnet_test/Cargo.toml index 48384c1838b..92285baf255 100644 --- a/rs/rust_canisters/xnet_test/Cargo.toml +++ b/rs/rust_canisters/xnet_test/Cargo.toml @@ -13,8 +13,8 @@ path = "src/main.rs" [dependencies] candid = { workspace = true } futures = { workspace = true } -ic-cdk = { workspace = true } -ic-cdk-macros = { workspace = true } +ic-cdk = { git = "https://github.com/dfinity/cdk-rs", branch = "next" } +ic-cdk-macros = { git = "https://github.com/dfinity/cdk-rs", branch = "next" } rand = { workspace = true } rand_pcg = "0.3" serde = { workspace = true } diff --git a/rs/rust_canisters/xnet_test/src/lib.rs b/rs/rust_canisters/xnet_test/src/lib.rs index 0ab8122568f..19b52556f8a 100644 --- a/rs/rust_canisters/xnet_test/src/lib.rs +++ b/rs/rust_canisters/xnet_test/src/lib.rs @@ -14,7 +14,9 @@ pub type NetworkTopology = Vec>; pub struct StartArgs { pub network_topology: NetworkTopology, pub canister_to_subnet_rate: u64, - pub payload_size_bytes: u64, + pub request_payload_size_bytes: u64, + pub request_timeout_seconds: u32, + pub response_payload_size_bytes: u64, } /// Metrics observed by this canister. diff --git a/rs/rust_canisters/xnet_test/src/main.rs b/rs/rust_canisters/xnet_test/src/main.rs index 6b2767f689f..81a5c97d02d 100644 --- a/rs/rust_canisters/xnet_test/src/main.rs +++ b/rs/rust_canisters/xnet_test/src/main.rs @@ -8,19 +8,14 @@ use candid::{CandidType, Deserialize, Principal}; use futures::future::join_all; use ic_cdk::api::management_canister::provisional::CanisterId; -use ic_cdk::{ - api::{ - call::{call, call_with_payment}, - caller, canister_balance, id, time, - }, - setup, -}; +use ic_cdk::api::{canister_cycle_balance, canister_self, msg_caller, time}; +use ic_cdk::call::{Call, CallError, ConfigurableCall, SendableCall}; +use ic_cdk::setup; use ic_cdk_macros::{heartbeat, query, update}; use rand::Rng; use rand_pcg::Lcg64Xsh32; use std::cell::RefCell; use std::collections::BTreeMap; -use std::str::FromStr; use std::time::Duration; use xnet_test::{Metrics, NetworkTopology, StartArgs}; @@ -38,8 +33,14 @@ thread_local! { /// Number of requests to send to each subnet (other than ours) every round. static PER_SUBNET_RATE: RefCell = const { RefCell::new(1) }; - /// Pad requests AND responses to this size (in bytes) if smaller. - static PAYLOAD_SIZE: RefCell = const { RefCell::new(1024) }; + /// Pad requests to this size (in bytes) if smaller. + static REQUEST_PAYLOAD_SIZE: RefCell = const { RefCell::new(1024) }; + + /// Timeout to set on requests. Zero for guaranteed response calls. + static REQUEST_TIMEOUT_SECONDS: RefCell = const { RefCell::new(0) }; + + /// Pad responses to this size (in bytes) if smaller. + static RESPONSE_PAYLOAD_SIZE: RefCell = const { RefCell::new(1024) }; /// State of the messaging that we use to check invariants (e.g., sequence /// numbers). @@ -151,7 +152,9 @@ fn start(start_args: StartArgs) -> String { *canisters.borrow_mut() = start_args.network_topology; }); PER_SUBNET_RATE.with(|r| *r.borrow_mut() = start_args.canister_to_subnet_rate); - PAYLOAD_SIZE.with(|r| *r.borrow_mut() = start_args.payload_size_bytes); + REQUEST_PAYLOAD_SIZE.with(|r| *r.borrow_mut() = start_args.request_payload_size_bytes); + REQUEST_TIMEOUT_SECONDS.with(|r| *r.borrow_mut() = start_args.request_timeout_seconds); + RESPONSE_PAYLOAD_SIZE.with(|r| *r.borrow_mut() = start_args.response_payload_size_bytes); RUNNING.with(|r| *r.borrow_mut() = true); @@ -169,10 +172,12 @@ fn stop() -> String { /// Invoked by the canister heartbeat handler as long as `RUNNING` is `true` /// (`start()` was and `stop()` was not yet called). async fn fanout() { - let self_id = id(); + let self_id = canister_self(); let network_topology = NETWORK_TOPOLOGY.with(|network_topology| network_topology.borrow().clone()); + let timeout_seconds = REQUEST_TIMEOUT_SECONDS.with(|p| *p.borrow()); + let payload_size = REQUEST_PAYLOAD_SIZE.with(|p| *p.borrow()) as usize; let mut futures = vec![]; for canisters in network_topology { @@ -191,15 +196,19 @@ async fn fanout() { let seq_no = STATE.with(|s| s.borrow_mut().next_out_seq_no(canister)); - let payload_size = PAYLOAD_SIZE.with(|p| *p.borrow()) as usize; let payload = Request { seq_no, time_nanos: time(), padding: vec![0; payload_size.saturating_sub(16)], }; - let res = call::<(Request,), (Reply,)>(canister, "handle_request", (payload,)); - futures.push(res); + let call = Call::new(canister, "handle_request").with_args((payload,)); + let call = if timeout_seconds == 0 { + call.with_guaranteed_response() + } else { + call.change_timeout(timeout_seconds) + }; + futures.push(call.call::()); METRICS.with(move |m| m.borrow_mut().calls_attempted += 1); } } @@ -208,25 +217,32 @@ async fn fanout() { for res in results { match res { - Ok((reply,)) => { + Ok(reply) => { let elapsed = Duration::from_nanos(time() - reply.time_nanos); METRICS.with(|m| m.borrow_mut().latency_distribution.observe(elapsed)); } - Err((err_code, err_message)) => { - // Catch whether the call failed due to a synchronous or - // asynchronous error. Based on the current implementation of - // the Rust CDK, a synchronous error will contain a specific - // error message. - if err_message.contains("Couldn't send message") { - log(&format!( - "{} call failed with {:?}", - time() / 1_000_000, - err_code - )); - METRICS.with(|m| m.borrow_mut().call_errors += 1); - } else { - METRICS.with(|m| m.borrow_mut().reject_responses += 1); - } + Err(CallError::CallRejected(rejection)) if rejection.is_sync() => { + // Call failed due to a synchronous error. + log(&format!( + "{} sync failure {:?} {}", + time() / 1_000_000, + rejection.reject_code(), + rejection.reject_message() + )); + METRICS.with(|m| m.borrow_mut().call_errors += 1); + } + Err(CallError::CallRejected(rejection)) => { + log(&format!( + "{} rejected {:?} {}", + time() / 1_000_000, + rejection.reject_code(), + rejection.reject_message() + )); + METRICS.with(|m| m.borrow_mut().reject_responses += 1); + } + Err(CallError::CandidDecodeFailed(err)) => { + log(&format!("{} call failed: {}", time() / 1_000_000, err)); + METRICS.with(|m| m.borrow_mut().call_errors += 1); } } } @@ -235,14 +251,14 @@ async fn fanout() { /// Endpoint that handles requests from canisters located on remote subnets. #[update] fn handle_request(req: Request) -> Reply { - let caller = caller(); + let caller = msg_caller(); let in_seq_no = STATE.with(|s| s.borrow_mut().set_in_seq_no(caller, req.seq_no)); if req.seq_no <= in_seq_no { METRICS.with(|m| m.borrow_mut().seq_errors += 1); } - let payload_size = PAYLOAD_SIZE.with(|p| *p.borrow()) as usize; + let payload_size = RESPONSE_PAYLOAD_SIZE.with(|p| *p.borrow()) as usize; Reply { time_nanos: req.time_nanos, padding: vec![0; payload_size.saturating_sub(8)], @@ -252,14 +268,14 @@ fn handle_request(req: Request) -> Reply { /// Deposits the cycles this canister has minus 1T at the given destination. #[update] async fn return_cycles(canister_id_record: CanisterIdRecord) -> String { - let cycle_refund = canister_balance().saturating_sub(1_000_000_000_000); - let _ = call_with_payment::<(CanisterIdRecord,), ()>( - Principal::from_str("aaaaa-aa").unwrap(), - "deposit_cycles", - (canister_id_record,), - cycle_refund, - ) - .await; + let cycle_refund = canister_cycle_balance().saturating_sub(1_000_000_000_000); + Call::new(Principal::from_text("aaaaa-aa").unwrap(), "deposit_cycles") + .with_arg(canister_id_record) + .with_guaranteed_response() + .with_cycles(cycle_refund) + .call::<()>() + .await + .unwrap(); "ok".to_string() } diff --git a/rs/tests/message_routing/BUILD.bazel b/rs/tests/message_routing/BUILD.bazel index ba42cad9e36..541505b545c 100644 --- a/rs/tests/message_routing/BUILD.bazel +++ b/rs/tests/message_routing/BUILD.bazel @@ -26,7 +26,7 @@ system_test_nns( "//rs/tests/driver:ic-system-test-driver", "@crate_index//:anyhow", "@crate_index//:candid", - "@crate_index//:ic-cdk", + "@crate_index//:ic_cdk_next", "@crate_index//:itertools", "@crate_index//:slog", "@crate_index//:tokio", diff --git a/rs/tests/message_routing/Cargo.toml b/rs/tests/message_routing/Cargo.toml index bbba932178f..5e3c54769a3 100644 --- a/rs/tests/message_routing/Cargo.toml +++ b/rs/tests/message_routing/Cargo.toml @@ -11,7 +11,7 @@ anyhow = { workspace = true } candid = { workspace = true } canister-test = { path = "../../rust_canisters/canister_test" } dfn_candid = { path = "../../rust_canisters/dfn_candid" } -ic-cdk = { workspace = true } +ic-cdk = { git = "https://github.com/dfinity/cdk-rs", branch = "next" } ic-registry-subnet-type = { path = "../../registry/subnet_type" } ic-system-test-driver = { path = "../driver" } itertools = { workspace = true } diff --git a/rs/tests/message_routing/common/common.rs b/rs/tests/message_routing/common/common.rs index 2a1d826616e..3516e6c714b 100644 --- a/rs/tests/message_routing/common/common.rs +++ b/rs/tests/message_routing/common/common.rs @@ -13,7 +13,9 @@ use xnet_test::StartArgs; /// given parameters. pub async fn start_all_canisters( canisters: &[Vec>], - payload_size_bytes: u64, + request_payload_size_bytes: u64, + request_timeout_seconds: u32, + response_payload_size_bytes: u64, canister_to_subnet_rate: u64, ) { let topology: Vec> = canisters @@ -33,7 +35,9 @@ pub async fn start_all_canisters( let input = StartArgs { network_topology: topology.clone(), canister_to_subnet_rate, - payload_size_bytes, + request_payload_size_bytes, + request_timeout_seconds, + response_payload_size_bytes, }; futures.push(async move { let _: String = canister diff --git a/rs/tests/message_routing/global_reboot_test.rs b/rs/tests/message_routing/global_reboot_test.rs index b1060cb2580..bf9a8fcfe94 100644 --- a/rs/tests/message_routing/global_reboot_test.rs +++ b/rs/tests/message_routing/global_reboot_test.rs @@ -189,7 +189,9 @@ pub fn start_all_canisters( let input = StartArgs { network_topology: topology.clone(), canister_to_subnet_rate, - payload_size_bytes, + request_payload_size_bytes: payload_size_bytes, + request_timeout_seconds: 0, + response_payload_size_bytes: payload_size_bytes, }; let _: String = canister .update_("start", candid, (input,)) diff --git a/rs/tests/message_routing/xnet/BUILD.bazel b/rs/tests/message_routing/xnet/BUILD.bazel index 8b77eea3cda..7cf39ffc0c6 100644 --- a/rs/tests/message_routing/xnet/BUILD.bazel +++ b/rs/tests/message_routing/xnet/BUILD.bazel @@ -25,6 +25,27 @@ system_test_nns( ], ) +system_test_nns( + name = "xnet_slo_3_subnets_best_effort_test", + env = { + "XNET_TEST_CANISTER_WASM_PATH": "$(rootpath //rs/rust_canisters/xnet_test:xnet-test-canister)", + }, + extra_head_nns_tags = ["manual"], # only run this test with the mainnet NNS canisters. + flaky = False, + tags = [ + "k8s", + "system_test_nightly", + ], + target_compatible_with = ["@platforms//os:linux"], # requires libssh that does not build on Mac OS + test_timeout = "long", + runtime_deps = GUESTOS_RUNTIME_DEPS + XNET_TEST_CANISTER_RUNTIME_DEPS + GRAFANA_RUNTIME_DEPS, + deps = [ + "//rs/tests/driver:ic-system-test-driver", + "//rs/tests/message_routing/xnet/slo_test_lib:xnet_slo_test_lib", + "@crate_index//:anyhow", + ], +) + system_test_nns( name = "xnet_slo_3_subnets_hotfix_test", env = { diff --git a/rs/tests/message_routing/xnet/Cargo.toml b/rs/tests/message_routing/xnet/Cargo.toml index 4cdb5ff722e..400b76a4ac0 100644 --- a/rs/tests/message_routing/xnet/Cargo.toml +++ b/rs/tests/message_routing/xnet/Cargo.toml @@ -26,6 +26,10 @@ path = "xnet_compatibility.rs" name = "xnet_malicious_slices" path = "xnet_malicious_slices.rs" +[[bin]] +name = "xnet_slo_3_subnets_best_effort_test" +path = "xnet_slo_3_subnets_best_effort_test.rs" + [[bin]] name = "xnet_slo_3_subnets_hotfix_test" path = "xnet_slo_3_subnets_hotfix_test.rs" diff --git a/rs/tests/message_routing/xnet/slo_test_lib/xnet_slo_test_lib.rs b/rs/tests/message_routing/xnet/slo_test_lib/xnet_slo_test_lib.rs index 102a82a8caa..808922a3c0e 100644 --- a/rs/tests/message_routing/xnet/slo_test_lib/xnet_slo_test_lib.rs +++ b/rs/tests/message_routing/xnet/slo_test_lib/xnet_slo_test_lib.rs @@ -28,7 +28,7 @@ use canister_test::{Canister, Runtime}; use dfn_candid::candid; use futures::future::join_all; use ic_registry_subnet_type::SubnetType; -use ic_system_test_driver::driver::ic::{InternetComputer, Subnet}; +use ic_system_test_driver::driver::ic::{InternetComputer, Subnet, VmResources}; use ic_system_test_driver::driver::pot_dsl::{PotSetupFn, SysTestFn}; use ic_system_test_driver::driver::prometheus_vm::{HasPrometheus, PrometheusVm}; use ic_system_test_driver::driver::test_env::TestEnv; @@ -48,7 +48,7 @@ const PAYLOAD_SIZE_BYTES: u64 = 1024; /// filling up its output queue). This should be estimated as: /// /// `queue_capacity / 10 /* max_rounds roundtrip */` -const MAX_CANISTER_TO_CANISTER_RATE: usize = 30; +const MAX_CANISTER_TO_CANISTER_RATE: usize = 5; const SEND_RATE_THRESHOLD: f64 = 0.3; const ERROR_PERCENTAGE_THRESHOLD: f64 = 5.0; const TARGETED_LATENCY_SECONDS: u64 = 20; @@ -58,13 +58,16 @@ pub struct Config { subnets: usize, nodes_per_subnet: usize, runtime: Duration, - payload_size_bytes: u64, + request_payload_size_bytes: u64, + request_timeout_seconds: u32, + response_payload_size_bytes: u64, send_rate_threshold: f64, error_percentage_threshold: f64, targeted_latency_seconds: u64, subnet_to_subnet_rate: usize, canisters_per_subnet: usize, canister_to_subnet_rate: usize, + vm_resources: Option, with_prometheus: bool, } @@ -106,23 +109,56 @@ impl Config { subnets, nodes_per_subnet, runtime, - payload_size_bytes: PAYLOAD_SIZE_BYTES, + request_payload_size_bytes: PAYLOAD_SIZE_BYTES, + request_timeout_seconds: 0, + response_payload_size_bytes: PAYLOAD_SIZE_BYTES, send_rate_threshold, error_percentage_threshold, targeted_latency_seconds, subnet_to_subnet_rate, canisters_per_subnet, canister_to_subnet_rate, + vm_resources: None, with_prometheus: false, } } + pub fn with_vm_resources(mut self, resources: VmResources) -> Self { + self.vm_resources = Some(resources); + self + } + pub fn with_prometheus(self) -> Self { let mut config = self.clone(); config.with_prometheus = true; config } + pub fn with_best_effort_response(self, timeout_seconds: u32) -> Self { + let mut config = self.clone(); + config.request_timeout_seconds = timeout_seconds; + config + } + + pub fn with_payload_bytes(self, payload_size_bytes: u64) -> Self { + let mut config = self.clone(); + config.request_payload_size_bytes = payload_size_bytes; + config.response_payload_size_bytes = payload_size_bytes; + config + } + + pub fn with_request_payload_size_bytes(self, request_payload_size_bytes: u64) -> Self { + let mut config = self.clone(); + config.request_payload_size_bytes = request_payload_size_bytes; + config + } + + pub fn with_response_payload_size_bytes(self, response_payload_size_bytes: u64) -> Self { + let mut config = self.clone(); + config.response_payload_size_bytes = response_payload_size_bytes; + config + } + /// Builds the IC instance. pub fn build(self) -> impl PotSetupFn { move |env: TestEnv| setup(env, self) @@ -136,8 +172,12 @@ impl Config { // Generic setup fn setup(env: TestEnv, config: Config) { + let mut ic = InternetComputer::new(); + if let Some(resources) = config.vm_resources { + ic = ic.with_default_vm_resources(resources); + } (0..config.subnets) - .fold(InternetComputer::new(), |ic, _idx| { + .fold(ic, |ic, _idx| { ic.add_subnet(Subnet::new(SubnetType::Application).add_nodes(config.nodes_per_subnet)) }) .setup_and_start(&env) @@ -226,7 +266,9 @@ pub async fn deploy_and_start<'a, 'b>( start_all_canisters( &canisters, - config.payload_size_bytes, + config.request_payload_size_bytes, + config.request_timeout_seconds, + config.response_payload_size_bytes, config.canister_to_subnet_rate as u64, ) .await; @@ -234,10 +276,12 @@ pub async fn deploy_and_start<'a, 'b>( config.canister_to_subnet_rate * config.canisters_per_subnet * (config.subnets - 1); info!( logger, - "Starting chatter: {} messages/round * {} bytes = {} bytes/round", + "Starting chatter: {} messages/round * {}/{} bytes = {} bytes/round", msgs_per_round, - config.payload_size_bytes, - msgs_per_round * config.payload_size_bytes as usize + config.request_payload_size_bytes, + config.response_payload_size_bytes, + msgs_per_round + * (config.request_payload_size_bytes + config.response_payload_size_bytes) as usize ); canisters diff --git a/rs/tests/message_routing/xnet/xnet_malicious_slices.rs b/rs/tests/message_routing/xnet/xnet_malicious_slices.rs index 74bb2195973..acc5e2d97db 100644 --- a/rs/tests/message_routing/xnet/xnet_malicious_slices.rs +++ b/rs/tests/message_routing/xnet/xnet_malicious_slices.rs @@ -154,6 +154,8 @@ pub async fn test_async(env: TestEnv, config: Config) { info!(logger, "Calling start() on all canisters..."); start_all_canisters( &canisters, 1024, // send messages with 1024 byte payloads + 0, // guaranteed response calls + 1024, // same response size 10, // each canister sends 10 RPS ) .await; diff --git a/rs/tests/message_routing/xnet/xnet_slo_3_subnets_best_effort_test.rs b/rs/tests/message_routing/xnet/xnet_slo_3_subnets_best_effort_test.rs new file mode 100644 index 00000000000..92e1358fd90 --- /dev/null +++ b/rs/tests/message_routing/xnet/xnet_slo_3_subnets_best_effort_test.rs @@ -0,0 +1,27 @@ +use anyhow::Result; +use ic_system_test_driver::driver::group::SystemTestGroup; +use ic_system_test_driver::systest; +use std::time::Duration; +use xnet_slo_test_lib::Config; + +const SUBNETS: usize = 3; +const NODES_PER_SUBNET: usize = 4; +const RUNTIME: Duration = Duration::from_secs(60); +const REQUEST_RATE: usize = 100; +const RESPONSE_TIMEOUT_SECONDS: u32 = 300; + +const PER_TASK_TIMEOUT: Duration = Duration::from_secs(15 * 60); +const OVERALL_TIMEOUT: Duration = Duration::from_secs(25 * 60); + +fn main() -> Result<()> { + let config = Config::new(SUBNETS, NODES_PER_SUBNET, RUNTIME, REQUEST_RATE) + .with_best_effort_response(RESPONSE_TIMEOUT_SECONDS); + let test = config.clone().test(); + SystemTestGroup::new() + .with_setup(config.build()) + .add_test(systest!(test)) + .with_timeout_per_test(PER_TASK_TIMEOUT) // each task (including the setup function) may take up to `per_task_timeout`. + .with_overall_timeout(OVERALL_TIMEOUT) // the entire group may take up to `overall_timeout`. + .execute_from_args()?; + Ok(()) +}