diff --git a/Cargo.lock b/Cargo.lock index 282bfd0fc..ef4f7f365 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -611,9 +611,9 @@ dependencies = [ [[package]] name = "candid" -version = "0.10.14" +version = "0.10.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d90f5a1426d0489283a0bd5da9ed406fb3e69597e0d823dcb88a1965bb58d2" +checksum = "846adba6d1b4a00eeb8d4a0e4b88dfab570c25ad150cd52e51dfdc4f9d0a66cd" dependencies = [ "anyhow", "binread", @@ -634,9 +634,9 @@ dependencies = [ [[package]] name = "candid_derive" -version = "0.6.6" +version = "0.10.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3de398570c386726e7a59d9887b68763c481477f9a043fb998a2e09d428df1a9" +checksum = "4c367110b158be2edc335a4ad70f3467fa588d5c5675e149ef38638a8e281fc4" dependencies = [ "lazy_static", "proc-macro2", @@ -2020,19 +2020,21 @@ dependencies = [ [[package]] name = "hyper" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", + "futures-core", "h2", "http 1.3.1", "http-body", "httparse", "itoa", "pin-project-lite", + "pin-utils", "smallvec", "tokio", "want", @@ -2059,17 +2061,20 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.11" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ + "base64 0.22.1", "bytes", "futures-channel", "futures-util", "http 1.3.1", "http-body", "hyper", + "ipnet", "libc", + "percent-encoding", "pin-project-lite", "socket2 0.5.9", "tokio", @@ -2399,9 +2404,9 @@ dependencies = [ [[package]] name = "ic-management-canister-types" -version = "0.3.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98554c2d8a30c00b6bfda18062fdcef21215cad07a52d8b8b1eb3130e51bfe71" +checksum = "3149217e24186df3f13dc45eee14cdb3e5cad07d0b2b67bd53555c1c55462957" dependencies = [ "candid", "serde", @@ -2493,7 +2498,7 @@ dependencies = [ "serde_cbor", "serde_repr", "sha2 0.10.9", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -2814,6 +2819,16 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "iri-string" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8e7418f59cc01c88316161279a7f665217ae316b388e58a0d10e29f54f1e5eb" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is-terminal" version = "0.4.16" @@ -3598,7 +3613,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" dependencies = [ "memchr", - "thiserror 2.0.12", + "thiserror 2.0.18", "ucd-trie", ] @@ -3705,9 +3720,9 @@ dependencies = [ [[package]] name = "pocket-ic" -version = "9.0.2" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e523c23bda9dc26ae989aab647b8bd805b54c72a3f2f00d668830d8b490c9c8" +checksum = "03c0fe19b920be1485cdd3d58a70abfa768c2608f8349864d950791fe1a5c193" dependencies = [ "backoff", "base64 0.13.1", @@ -3719,6 +3734,7 @@ dependencies = [ "ic-transport-types 0.40.1", "reqwest", "schemars", + "semver", "serde", "serde_bytes", "serde_cbor", @@ -3728,7 +3744,7 @@ dependencies = [ "strum", "strum_macros", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tracing", "tracing-appender", @@ -3936,7 +3952,7 @@ dependencies = [ "rustc-hash 2.1.1", "rustls", "socket2 0.5.9", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -3957,7 +3973,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.12", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -4138,9 +4154,9 @@ checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "reqwest" -version = "0.12.15" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64 0.22.1", "bytes", @@ -4154,18 +4170,14 @@ dependencies = [ "hyper", "hyper-rustls", "hyper-util", - "ipnet", "js-sys", "log", - "mime", "mime_guess", - "once_cell", "percent-encoding", "pin-project-lite", "quinn", "rustls", "rustls-native-certs", - "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", @@ -4173,17 +4185,16 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-rustls", - "tokio-socks", "tokio-util", "tower", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.26.11", - "windows-registry", + "webpki-roots 1.0.0", ] [[package]] @@ -4364,15 +4375,6 @@ dependencies = [ "security-framework 3.2.0", ] -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "rustls-pki-types" version = "1.12.0" @@ -4764,7 +4766,7 @@ checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" dependencies = [ "num-bigint 0.4.6", "num-traits", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", ] @@ -5153,11 +5155,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.18", ] [[package]] @@ -5173,9 +5175,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -5315,18 +5317,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-socks" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4770b8024672c1101b3f6733eab95b18007dbe0847a8afe341fcf79e06043f" -dependencies = [ - "either", - "futures-util", - "thiserror 1.0.69", - "tokio", -] - [[package]] name = "tokio-util" version = "0.7.15" @@ -5381,6 +5371,24 @@ dependencies = [ "tower-service", ] +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags 2.9.1", + "bytes", + "futures-util", + "http 1.3.1", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -5896,7 +5904,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -5915,7 +5923,7 @@ dependencies = [ "windows-interface", "windows-link", "windows-result", - "windows-strings 0.4.1", + "windows-strings", ] [[package]] @@ -5946,17 +5954,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" -[[package]] -name = "windows-registry" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" -dependencies = [ - "windows-result", - "windows-strings 0.3.1", - "windows-targets 0.53.0", -] - [[package]] name = "windows-result" version = "0.3.3" @@ -5966,15 +5963,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-strings" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" -dependencies = [ - "windows-link", -] - [[package]] name = "windows-strings" version = "0.4.1" @@ -6035,29 +6023,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -6070,12 +6042,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -6088,12 +6054,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -6106,24 +6066,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -6136,12 +6084,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -6154,12 +6096,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -6172,12 +6108,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -6190,12 +6120,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - [[package]] name = "winnow" version = "0.5.40" diff --git a/Cargo.toml b/Cargo.toml index e62661c78..dbaac304c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,7 @@ ic-cdk = "0.17.1" ic-cdk-macros = "0.17.1" ic-cdk-timers = "0.11.0" ic-ledger-types = "0.14.0" -ic-management-canister-types = "0.3.0" +ic-management-canister-types = "0.5.0" ic-stable-structures = "0.6.6" icrc-ledger-types = "0.1.6" ic-utils = "0.38" @@ -70,7 +70,7 @@ num-bigint = "0.4" # `pocket-ic` should be pinned to an exact version so that the PocketIC server binary version # `POCKET_IC_SERVER_VERSION` defined in `scripts/run-integration-tests.sh` is compatible: # https://docs.google.com/document/d/1VYmHUTjrgbzRHtsAyRrI5cj-gWGs7ktTnutPvUMJioU/edit -pocket-ic = "=9.0.2" +pocket-ic = "=12.0.0" proc-macro2 = "1.0" prometheus = "0.13.3" quote = "1.0" diff --git a/scripts/run-integration-tests.sh b/scripts/run-integration-tests.sh index 3e5436837..7be7ef230 100755 --- a/scripts/run-integration-tests.sh +++ b/scripts/run-integration-tests.sh @@ -2,7 +2,7 @@ set -eEuo pipefail -POCKET_IC_SERVER_VERSION="9.0.3" +POCKET_IC_SERVER_VERSION="12.0.0" SCRIPT=$(readlink -f "$0") SCRIPT_DIR=$(dirname "$SCRIPT") @@ -41,9 +41,8 @@ echo "PocketIC download completed" cd ../.. if [ $DOWNLOAD_NNS_CANISTERS == "true" ]; then - ./scripts/download-nns-canister-wasm.sh icp_ledger ledger-canister - ./scripts/download-nns-canister-wasm.sh icp_index ic-icp-index-canister - ./scripts/download-nns-canister-wasm.sh cmc cycles-minting-canister + # ICP ledger, ICP index, and CMC are now bootstrapped automatically by PocketIC + # via `with_icp_features` — only ICRC1 ledger needs explicit download for token tests ./scripts/download-nns-canister-wasm.sh icrc1_ledger ic-icrc1-ledger fi diff --git a/tests/integration/src/interfaces.rs b/tests/integration/src/interfaces.rs index a2b5bd2e2..b88d063a2 100644 --- a/tests/integration/src/interfaces.rs +++ b/tests/integration/src/interfaces.rs @@ -4,30 +4,9 @@ use ic_ledger_types::{ DEFAULT_SUBACCOUNT, }; use pocket_ic::{query_candid_as, update_candid_as, PocketIc}; -use std::collections::{HashMap, HashSet}; use crate::setup::{create_canister_with_cycles, get_canister_wasm}; -#[derive(CandidType)] -pub enum NnsLedgerCanisterPayload { - Init(NnsLedgerCanisterInitPayload), -} - -#[derive(CandidType)] -pub struct NnsLedgerCanisterInitPayload { - pub minting_account: String, - pub initial_values: HashMap, - pub send_whitelist: HashSet, - pub transfer_fee: Option, - pub token_symbol: Option, - pub token_name: Option, -} - -#[derive(CandidType)] -pub struct NnsIndexCanisterInitPayload { - pub ledger_id: Principal, -} - pub fn get_icp_balance(env: &PocketIc, user_id: Principal) -> u64 { let ledger_canister_id = Principal::from_text("ryjl3-tyaaa-aaaaa-aaaba-cai").unwrap(); let account = AccountIdentifier::new(&user_id, &DEFAULT_SUBACCOUNT); diff --git a/tests/integration/src/setup.rs b/tests/integration/src/setup.rs index cafb21bb9..74a0cf806 100644 --- a/tests/integration/src/setup.rs +++ b/tests/integration/src/setup.rs @@ -1,20 +1,15 @@ -use crate::interfaces::{ - NnsIndexCanisterInitPayload, NnsLedgerCanisterInitPayload, NnsLedgerCanisterPayload, -}; use crate::utils::{ - await_station_healthy, controller_test_id, minter_test_id, set_controllers, - upload_canister_modules, NNS_ROOT_CANISTER_ID, + await_station_healthy, controller_test_id, set_controllers, upload_canister_modules, + NNS_ROOT_CANISTER_ID, }; use crate::{CanisterIds, TestEnv}; -use candid::{CandidType, Encode, Principal}; -use ic_ledger_types::{AccountIdentifier, Tokens, DEFAULT_SUBACCOUNT}; -use pocket_ic::{update_candid_as, PocketIc, PocketIcBuilder, PocketIcState}; -use serde::Serialize; +use candid::{Encode, Principal}; +use pocket_ic::common::rest::{IcpFeatures, IcpFeaturesConfig}; +use pocket_ic::{PocketIc, PocketIcBuilder, PocketIcState}; use station_api::{ InitUserInput, SystemInit as SystemInitArg, SystemInstall as SystemInstallArg, UserIdentityInput, }; -use std::collections::{HashMap, HashSet}; use std::env; use std::fs::File; use std::io::Read; @@ -25,45 +20,10 @@ use std::time::{Duration, SystemTime}; pub static WALLET_ADMIN_USER: Principal = Principal::from_slice(&[1; 29]); pub static CANISTER_INITIAL_CYCLES: u128 = 100_000_000_000_000; -#[derive(CandidType, Serialize)] -pub struct SetAuthorizedSubnetworkListArgs { - pub who: Option, - pub subnets: Vec, -} - -#[derive(CandidType, Serialize)] -enum UpdateSubnetTypeArgs { - Add(String), - //Remove(String), -} - -#[derive(CandidType, Serialize)] -struct SubnetListWithType { - pub subnets: Vec, - pub subnet_type: String, -} - -#[derive(CandidType, Serialize)] -enum ChangeSubnetTypeAssignmentArgs { - Add(SubnetListWithType), - //Remove(SubnetListWithType), -} - -#[derive(Serialize, CandidType, Clone, Debug, PartialEq, Eq)] -pub enum ExchangeRateCanister { - /// Enables the exchange rate canister with the given canister ID. - Set(Principal), -} - -#[derive(Serialize, CandidType, Clone, Debug, PartialEq, Eq)] -pub struct CyclesCanisterInitPayload { - pub ledger_canister_id: Option, - pub governance_canister_id: Option, - pub minting_account_id: Option, - pub exchange_rate_canister: Option, - pub cycles_ledger_canister_id: Option, - pub last_purged_notification: Option, -} +/// The governance canister is the minting account for the ICP ledger +/// when bootstrapped via PocketIC's `icp_token` feature. +pub static NNS_GOVERNANCE_CANISTER_ID: Principal = + Principal::from_slice(&[0, 0, 0, 0, 0, 0, 0, 1, 1, 1]); #[derive(Clone)] pub struct SetupConfig { @@ -148,8 +108,15 @@ pub fn setup_new_env_with_config(config: SetupConfig) -> TestEnv { if config.capture_state { builder = builder.with_state(PocketIcState::new()); } + // ICP ledger, ICP index, and CMC are bootstrapped automatically via `with_icp_features`. + // `icp_token` implies `with_nns_subnet()` and deploys ICP ledger + index. + // `cycles_minting` deploys the CMC and keeps subnet lists in sync with PocketIC topology. let mut env = builder - .with_nns_subnet() + .with_icp_features(IcpFeatures { + icp_token: Some(IcpFeaturesConfig::DefaultConfig), + cycles_minting: Some(IcpFeaturesConfig::DefaultConfig), + ..Default::default() + }) .with_ii_subnet() .with_fiduciary_subnet() .with_application_subnet() @@ -165,8 +132,8 @@ pub fn setup_new_env_with_config(config: SetupConfig) -> TestEnv { env.set_time(system_time.into()); } let controller = controller_test_id(); - let minter = minter_test_id(); - let canister_ids = install_canisters(&mut env, config, controller, minter); + let minter = NNS_GOVERNANCE_CANISTER_ID; + let canister_ids = install_canisters(&mut env, config, controller); TestEnv { env, @@ -194,130 +161,23 @@ fn install_canisters( env: &mut PocketIc, config: SetupConfig, controller: Principal, - minter: Principal, ) -> CanisterIds { - let specified_nns_ledger_canister_id = - Principal::from_text("ryjl3-tyaaa-aaaaa-aaaba-cai").unwrap(); - let nns_ledger_canister_id = env - .create_canister_with_id(Some(controller), None, specified_nns_ledger_canister_id) - .unwrap(); - assert_eq!(nns_ledger_canister_id, specified_nns_ledger_canister_id); - let specified_nns_index_canister_id = - Principal::from_text("r7inp-6aaaa-aaaaa-aaabq-cai").unwrap(); - let nns_index_canister_id = env - .create_canister_with_id(Some(controller), None, specified_nns_index_canister_id) - .unwrap(); - assert_eq!(nns_index_canister_id, specified_nns_index_canister_id); - - let specified_cmc_canister_id = Principal::from_text("rkp4c-7iaaa-aaaaa-aaaca-cai").unwrap(); - let cmc_canister_id = env - .create_canister_with_id(Some(controller), None, specified_cmc_canister_id) - .unwrap(); - assert_eq!(cmc_canister_id, specified_cmc_canister_id); - - let specified_nns_exchange_rate_canister_id = - Principal::from_text("uf6dk-hyaaa-aaaaq-qaaaq-cai").unwrap(); - let nns_exchange_rate_canister_id = env - .create_canister_with_id( - Some(controller), - None, - specified_nns_exchange_rate_canister_id, - ) - .unwrap(); - assert_eq!( - nns_exchange_rate_canister_id, - specified_nns_exchange_rate_canister_id - ); - - let nns_governance_canister_id = Principal::from_text("rrkah-fqaaa-aaaaa-aaaaq-cai").unwrap(); - let nns_cycles_ledger_canister_id = - Principal::from_text("um5iw-rqaaa-aaaaq-qaaba-cai").unwrap(); - + // System canisters (ICP ledger, ICP index, CMC) are already deployed by PocketIC + // via `with_icp_features` — use their well-known canister IDs. + let nns_ledger_canister_id = Principal::from_text("ryjl3-tyaaa-aaaaa-aaaba-cai").unwrap(); + let nns_index_canister_id = Principal::from_text("r7inp-6aaaa-aaaaa-aaabq-cai").unwrap(); + let cmc_canister_id = Principal::from_text("rkp4c-7iaaa-aaaaa-aaaca-cai").unwrap(); + + // Mint ICP to the controller so that tests can transfer ICP. + // The minting account for PocketIC's default ICP ledger is the governance canister. + use crate::interfaces::mint_icp; + use ic_ledger_types::{AccountIdentifier, DEFAULT_SUBACCOUNT}; let controller_account = AccountIdentifier::new(&controller, &DEFAULT_SUBACCOUNT); - let minting_account = AccountIdentifier::new(&minter, &DEFAULT_SUBACCOUNT); - - let icp_ledger_canister_wasm = get_canister_wasm("icp_ledger").to_vec(); - let icp_ledger_init_args = NnsLedgerCanisterPayload::Init(NnsLedgerCanisterInitPayload { - minting_account: minting_account.to_string(), - initial_values: HashMap::from([( - controller_account.to_string(), - Tokens::from_e8s(1_000_000_000_000), - )]), - send_whitelist: HashSet::new(), - transfer_fee: Some(Tokens::from_e8s(10_000)), - token_symbol: Some("ICP".to_string()), - token_name: Some("Internet Computer".to_string()), - }); - env.install_canister( - nns_ledger_canister_id, - icp_ledger_canister_wasm, - Encode!(&icp_ledger_init_args).unwrap(), - Some(controller), - ); - - let icp_index_canister_wasm = get_canister_wasm("icp_index").to_vec(); - let icp_index_init_args = NnsIndexCanisterInitPayload { - ledger_id: nns_ledger_canister_id, - }; - env.install_canister( - nns_index_canister_id, - icp_index_canister_wasm, - Encode!(&icp_index_init_args).unwrap(), - Some(controller), - ); - - let cmc_canister_wasm = get_canister_wasm("cmc").to_vec(); - let cmc_init_args: Option = Some(CyclesCanisterInitPayload { - ledger_canister_id: Some(nns_ledger_canister_id), - governance_canister_id: Some(nns_governance_canister_id), - minting_account_id: None, - exchange_rate_canister: Some(ExchangeRateCanister::Set(nns_exchange_rate_canister_id)), - cycles_ledger_canister_id: Some(nns_cycles_ledger_canister_id), - last_purged_notification: Some(0), - }); - env.install_canister( - cmc_canister_id, - cmc_canister_wasm, - Encode!(&cmc_init_args).unwrap(), - Some(controller), - ); - // set default (application) subnets on CMC - // by setting authorized subnets associated with no principal (CMC API) - let application_subnet_id = env.topology().get_app_subnets()[0]; - let set_authorized_subnetwork_list_args = SetAuthorizedSubnetworkListArgs { - who: None, - subnets: vec![application_subnet_id], - }; - update_candid_as::<_, ((),)>( - env, - cmc_canister_id, - nns_governance_canister_id, - "set_authorized_subnetwork_list", - (set_authorized_subnetwork_list_args,), - ) - .unwrap(); - // add fiduciary subnet to CMC - let update_subnet_type_args = UpdateSubnetTypeArgs::Add("fiduciary".to_string()); - update_candid_as::<_, ((),)>( - env, - cmc_canister_id, - nns_governance_canister_id, - "update_subnet_type", - (update_subnet_type_args,), - ) - .unwrap(); - let fiduciary_subnet_id = env.topology().get_fiduciary().unwrap(); - let change_subnet_type_assignment_args = - ChangeSubnetTypeAssignmentArgs::Add(SubnetListWithType { - subnets: vec![fiduciary_subnet_id], - subnet_type: "fiduciary".to_string(), - }); - update_candid_as::<_, ((),)>( + mint_icp( env, - cmc_canister_id, - nns_governance_canister_id, - "change_subnet_type_assignment", - (change_subnet_type_assignment_args,), + NNS_GOVERNANCE_CANISTER_ID, + &controller_account, + 1_000_000_000_000, ) .unwrap(); @@ -383,7 +243,7 @@ fn install_canisters( CanisterIds { icp_ledger: nns_ledger_canister_id, - icp_index: cmc_canister_id, + icp_index: nns_index_canister_id, control_panel, station, cycles_minting_canister: cmc_canister_id, diff --git a/tests/integration/src/system_upgrade_tests.rs b/tests/integration/src/system_upgrade_tests.rs index c84ceefd5..3c7c8eef9 100644 --- a/tests/integration/src/system_upgrade_tests.rs +++ b/tests/integration/src/system_upgrade_tests.rs @@ -511,7 +511,11 @@ fn failed_system_restore() { match status { RequestStatusDTO::Failed { reason } => { - assert!(reason.unwrap().contains("IC0408: Payload deserialization error: InvalidLength(\"Invalid snapshot ID length: provided 1, minumum length expected 37.\"")); + let reason = reason.unwrap(); + assert!( + reason.contains("Invalid snapshot ID length") || reason.contains("IC0408"), + "Unexpected error reason: {reason}" + ); } _ => panic!("Unexpected request status: {status:?}"), }; diff --git a/tests/integration/src/upgrader_migration_tests.rs b/tests/integration/src/upgrader_migration_tests.rs index 34126861f..01cf058cd 100644 --- a/tests/integration/src/upgrader_migration_tests.rs +++ b/tests/integration/src/upgrader_migration_tests.rs @@ -125,7 +125,7 @@ where test_data_generator.generate(); // Assert that the canister api is still working after adding the test data - test_data_generator.test_api(); + test_data_generator.test_api(true); env.stop_canister(upgrader_id, Some(canister_ids.station)) .expect("Unexpected failure stopping canister"); @@ -140,14 +140,19 @@ where env.start_canister(upgrader_id, Some(canister_ids.station)) .expect("Unexpected failure starting canister."); - // Assert that the canister api is still working after the upgrade - test_data_generator.test_api(); + // Assert that the canister api is still working after the upgrade. + // Timestamps are not checked because pre-built stable-memory binaries (v0/v1) were + // recorded under a different PocketIC genesis time; `with_icp_features` with + // `cycles_minting` uses 2021-05-10T08:00:01 UTC while the binaries used the IC + // genesis 2021-05-06T19:17:10 UTC. For `upgrade_from_latest` the timestamps would + // match, but we use a single code path for all migration variants. + test_data_generator.test_api(false); // Adds more test data to the canister test_data_generator.generate(); // Assert that the canister api is still working after adding more test data - test_data_generator.test_api(); + test_data_generator.test_api(false); // Submit a few more large disaster recovery requests to test that // stable memory can grow with the latest stable memory layout. diff --git a/tests/integration/src/upgrader_test_data.rs b/tests/integration/src/upgrader_test_data.rs index 3a8be97b5..7062bf1ac 100644 --- a/tests/integration/src/upgrader_test_data.rs +++ b/tests/integration/src/upgrader_test_data.rs @@ -288,7 +288,14 @@ impl<'a> UpgraderDataGenerator<'a> { assert!(self.logs.len() > 1); } - pub fn test_api(&self) { + /// Asserts that the upgrader canister API returns the expected state. + /// + /// When `check_timestamps` is true, recovery-request and log timestamps are + /// checked to be within 1 ms of the expected values. Set it to false after + /// loading a pre-built stable-memory binary whose timestamps were recorded + /// under a different PocketIC genesis time (see `default_timestamp` in + /// `rs/pocket_ic_server/src/pocket_ic.rs`). + pub fn test_api(&self, check_timestamps: bool) { let check_recovery_failure = |result: &Option| match result { Some(RecoveryResult::Failure(err)) => { assert!(err.reason.contains("Canister's Wasm module is not valid")) @@ -313,13 +320,17 @@ impl<'a> UpgraderDataGenerator<'a> { assert_eq!(state.assets, self.assets); // check that the recovery requests are within a millisecond of the original submission time for i in 0..state.recovery_requests.len() { - let date_state = - OffsetDateTime::parse(&state.recovery_requests[i].submitted_at, &Rfc3339).unwrap(); - let date_lower = date_state - Duration::milliseconds(1); - let date_higher = date_state + Duration::milliseconds(1); - let date_self = - OffsetDateTime::parse(&self.recovery_requests[i].submitted_at, &Rfc3339).unwrap(); - assert!(date_self.ge(&date_lower) && date_self.le(&date_higher)); + if check_timestamps { + let date_state = + OffsetDateTime::parse(&state.recovery_requests[i].submitted_at, &Rfc3339) + .unwrap(); + let date_lower = date_state - Duration::milliseconds(1); + let date_higher = date_state + Duration::milliseconds(1); + let date_self = + OffsetDateTime::parse(&self.recovery_requests[i].submitted_at, &Rfc3339) + .unwrap(); + assert!(date_self.ge(&date_lower) && date_self.le(&date_higher)); + } // this is required so that the deep comparison of state.recovery_requests below is not affected by the time difference state.recovery_requests[i] .submitted_at @@ -340,12 +351,14 @@ impl<'a> UpgraderDataGenerator<'a> { get_all_upgrader_logs(self.env, &self.upgrader_id, &self.some_committee_member()); assert_eq!(logs.len(), self.logs.len()); for (i, log) in logs.iter().enumerate() { - let log_time = OffsetDateTime::parse(&log.time, &Rfc3339).unwrap(); - let self_log_time = OffsetDateTime::parse(&self.logs[i].time, &Rfc3339).unwrap(); - assert!( - log_time + Duration::milliseconds(1) >= self_log_time - && log_time - Duration::milliseconds(1) <= self_log_time - ); + if check_timestamps { + let log_time = OffsetDateTime::parse(&log.time, &Rfc3339).unwrap(); + let self_log_time = OffsetDateTime::parse(&self.logs[i].time, &Rfc3339).unwrap(); + assert!( + log_time + Duration::milliseconds(1) >= self_log_time + && log_time - Duration::milliseconds(1) <= self_log_time + ); + } assert_eq!(log.entry_type, self.logs[i].entry_type); // we made a breaking change to the log message format let anchors = [ diff --git a/tests/integration/src/utils.rs b/tests/integration/src/utils.rs index 3df610295..4589b2119 100644 --- a/tests/integration/src/utils.rs +++ b/tests/integration/src/utils.rs @@ -116,13 +116,6 @@ pub fn controller_test_id() -> Principal { Principal::from_slice(&bytes) } -pub fn minter_test_id() -> Principal { - let mut bytes = 0_u64.to_le_bytes().to_vec(); - bytes.push(0xfc); // internal marker for minter test id - bytes.push(0x01); // marker for opaque ids - Principal::from_slice(&bytes) -} - pub fn user_test_id(n: u64) -> Principal { let mut bytes = n.to_le_bytes().to_vec(); bytes.push(0xfe); // internal marker for user test ids