diff --git a/Cargo.lock b/Cargo.lock index 72d0eee780a0..c59c54a860fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10103,6 +10103,7 @@ dependencies = [ "ic-stable-structures 0.6.8", "ic-state-machine-tests", "ic-test-utilities-load-wasm", + "ic-types", "icp-ledger", "icrc-ledger-types", "num-traits", diff --git a/rs/cross-chain/proposal-cli/src/candid/tests.rs b/rs/cross-chain/proposal-cli/src/candid/tests.rs index 06045c9e1358..ff4bd09bf652 100644 --- a/rs/cross-chain/proposal-cli/src/candid/tests.rs +++ b/rs/cross-chain/proposal-cli/src/candid/tests.rs @@ -75,7 +75,7 @@ fn should_parse_constructor_parameters() { | (TargetCanister::CkEthLedger, "(LedgerArg)") | (TargetCanister::CkEthMinter, "(MinterArg)") | (TargetCanister::CyclesIndex, "(opt IndexArg)") - | (TargetCanister::IcpIndex, "(InitArg)") + | (TargetCanister::IcpIndex, "(opt IndexArg)") | (TargetCanister::IcpLedger, "(LedgerCanisterPayload)") | (TargetCanister::LedgerSuiteOrchestrator, "(OrchestratorArg)") ); diff --git a/rs/ledger_suite/icp/index/BUILD.bazel b/rs/ledger_suite/icp/index/BUILD.bazel index 92b682ebbc20..a1e2a2a074b8 100644 --- a/rs/ledger_suite/icp/index/BUILD.bazel +++ b/rs/ledger_suite/icp/index/BUILD.bazel @@ -33,6 +33,7 @@ DEV_DEPENDENCIES = [ "//rs/ledger_suite/tests/sm-tests:ic-ledger-suite-state-machine-tests", "//rs/state_machine_tests", "//rs/test_utilities/load_wasm", + "//rs/types/types", "@crate_index//:candid_parser", "@crate_index//:proptest", ] diff --git a/rs/ledger_suite/icp/index/Cargo.toml b/rs/ledger_suite/icp/index/Cargo.toml index a0504be6feba..4f26756a18d8 100644 --- a/rs/ledger_suite/icp/index/Cargo.toml +++ b/rs/ledger_suite/icp/index/Cargo.toml @@ -37,4 +37,5 @@ ic-ledger-suite-state-machine-tests = { path = "../../tests/sm-tests" } ic-ledger-test-utils = { path = "../test_utils" } ic-state-machine-tests = { path = "../../../state_machine_tests" } ic-test-utilities-load-wasm = { path = "../../../test_utilities/load_wasm" } +ic-types = { path = "../../../types/types" } proptest = { workspace = true } diff --git a/rs/ledger_suite/icp/index/index.did b/rs/ledger_suite/icp/index/index.did index 7148ed9a3464..a1d887ae72b5 100644 --- a/rs/ledger_suite/icp/index/index.did +++ b/rs/ledger_suite/icp/index/index.did @@ -33,14 +33,28 @@ type HttpResponse = record { headers : vec record { text; text }; status_code : nat16 }; -type InitArg = record { ledger_id : principal }; + +type InitArg = record { + ledger_id : principal; + // The interval in seconds in which to retrieve blocks from the ledger. A lower value makes the index more + // responsive in showing new blocks, but increases the consumption of cycles of both the index and ledger canisters. + // A higher values means that it takes longer for new blocks to show up in the index. + retrieve_blocks_from_ledger_interval_seconds : opt nat64 +}; type UpgradeArg = record { + ledger_id : opt principal; // The interval in seconds in which to retrieve blocks from the ledger. A lower value makes the index more // responsive in showing new blocks, but increases the consumption of cycles of both the index and ledger canisters. // A higher values means that it takes longer for new blocks to show up in the index. retrieve_blocks_from_ledger_interval_seconds : opt nat64 }; + +type IndexArg = variant { + Init : InitArg; + Upgrade : UpgradeArg +}; + type Operation = variant { Approve : record { fee : Tokens; @@ -75,7 +89,7 @@ type Transaction = record { timestamp : opt TimeStamp }; type TransactionWithId = record { id : nat64; transaction : Transaction }; -service : (InitArg) -> { +service : (index_arg : opt IndexArg) -> { get_account_identifier_balance : (text) -> (nat64) query; get_account_identifier_transactions : ( GetAccountIdentifierTransactionsArgs diff --git a/rs/ledger_suite/icp/index/src/lib.rs b/rs/ledger_suite/icp/index/src/lib.rs index 43407e05af27..e621bb384b85 100644 --- a/rs/ledger_suite/icp/index/src/lib.rs +++ b/rs/ledger_suite/icp/index/src/lib.rs @@ -6,13 +6,21 @@ use serde_bytes::ByteBuf; pub mod logs; +#[derive(Clone, Debug, CandidType, Deserialize)] +pub enum IndexArg { + Init(InitArg), + Upgrade(UpgradeArg), +} + #[derive(Clone, Debug, CandidType, Deserialize)] pub struct InitArg { pub ledger_id: Principal, + pub retrieve_blocks_from_ledger_interval_seconds: Option, } #[derive(Clone, Debug, CandidType, Deserialize)] pub struct UpgradeArg { + pub ledger_id: Option, pub retrieve_blocks_from_ledger_interval_seconds: Option, } diff --git a/rs/ledger_suite/icp/index/src/main.rs b/rs/ledger_suite/icp/index/src/main.rs index bbcf19bcabba..0748de33f65c 100644 --- a/rs/ledger_suite/icp/index/src/main.rs +++ b/rs/ledger_suite/icp/index/src/main.rs @@ -3,14 +3,14 @@ use candid::Principal; use ic_base_types::PrincipalId; use ic_canister_log::{export as export_logs, log}; use ic_cdk::api::caller; -use ic_cdk::{init, post_upgrade, query}; +use ic_cdk::{init, post_upgrade, query, trap}; use ic_cdk_timers::TimerId; use ic_http_types::{HttpRequest, HttpResponse, HttpResponseBuilder}; use ic_icp_index::logs::{P0, P1}; use ic_icp_index::{ GetAccountIdentifierTransactionsArgs, GetAccountIdentifierTransactionsResponse, - GetAccountIdentifierTransactionsResult, GetAccountTransactionsResult, InitArg, Log, LogEntry, - Priority, SettledTransaction, SettledTransactionWithId, Status, UpgradeArg, + GetAccountIdentifierTransactionsResult, GetAccountTransactionsResult, IndexArg, InitArg, Log, + LogEntry, Priority, SettledTransaction, SettledTransactionWithId, Status, UpgradeArg, }; use ic_icrc1_index_ng::GetAccountTransactionsArgs; use ic_ledger_canister_core::runtime::heap_memory_size_bytes; @@ -256,10 +256,19 @@ fn balance_key(account_identifier: AccountIdentifier) -> (AccountIdentifierDataT } #[init] -fn init(init_arg: InitArg) { +fn init(index_arg: Option) { + let InitArg { + ledger_id, + retrieve_blocks_from_ledger_interval_seconds, + } = match index_arg { + Some(IndexArg::Init(arg)) => arg, + _ => trap("Index initialization must take in input an InitArg argument"), + }; // stable memory initialization mutate_state(|state| { - state.ledger_id = init_arg.ledger_id; + state.ledger_id = ledger_id; + state.retrieve_blocks_from_ledger_interval = + retrieve_blocks_from_ledger_interval_seconds.map(Duration::from_secs); }); // set the first build_index to be called after init @@ -269,20 +278,30 @@ fn init(init_arg: InitArg) { } #[post_upgrade] -fn post_upgrade(upgrade_arg: Option) { - if let Some(upgrade) = upgrade_arg { - log!(P1, "Possible upgrade configuration changes: {:#?}", upgrade); - - let UpgradeArg { - retrieve_blocks_from_ledger_interval_seconds, - } = upgrade; +fn post_upgrade(index_arg: Option) { + match index_arg { + Some(IndexArg::Upgrade(upgrade)) => { + log!(P1, "Possible upgrade configuration changes: {:#?}", upgrade,); + + let UpgradeArg { + ledger_id, + retrieve_blocks_from_ledger_interval_seconds, + } = upgrade; + + mutate_state(|state| { + if let Some(new_value) = ledger_id { + state.ledger_id = new_value; + } - mutate_state(|state| { - if let Some(new_value) = retrieve_blocks_from_ledger_interval_seconds { - state.retrieve_blocks_from_ledger_interval = Some(Duration::from_secs(new_value)); - } - }); - } + if let Some(new_value) = retrieve_blocks_from_ledger_interval_seconds { + state.retrieve_blocks_from_ledger_interval = + Some(Duration::from_secs(new_value)); + } + }); + } + Some(IndexArg::Init(..)) => trap("Index upgrade argument cannot be of variant Init"), + _ => (), + }; // set the first build_index to be called after upgrade set_build_index_timer(with_state(|state| { diff --git a/rs/ledger_suite/icp/index/tests/retrieve_blocks_from_ledger_interval.rs b/rs/ledger_suite/icp/index/tests/retrieve_blocks_from_ledger_interval.rs index 33d19c1c4c72..b4817eb09059 100644 --- a/rs/ledger_suite/icp/index/tests/retrieve_blocks_from_ledger_interval.rs +++ b/rs/ledger_suite/icp/index/tests/retrieve_blocks_from_ledger_interval.rs @@ -1,9 +1,11 @@ use candid::{Decode, Encode}; use ic_base_types::{CanisterId, PrincipalId}; -use ic_icp_index::{InitArg, Status, UpgradeArg}; +use ic_icp_index::{IndexArg, InitArg, Status, UpgradeArg}; use ic_ledger_canister_core::archive::ArchiveOptions; use ic_ledger_core::Tokens; +use ic_ledger_test_utils::state_machine_helpers::index::wait_until_sync_is_completed; use ic_state_machine_tests::{ErrorCode, StateMachine, UserError}; +use ic_types::Time; use icp_ledger::{AccountIdentifier, FeatureFlags, LedgerCanisterInitPayload, Memo, Subaccount}; use icrc_ledger_types::icrc1::account::Account; use proptest::prelude::Strategy; @@ -12,10 +14,8 @@ use std::collections::HashMap; use std::path::PathBuf; use std::time::Duration; -/// Corresponds to ic_icp_index::DEFAULT_RETRIEVE_BLOCKS_FROM_LEDGER_INTERVAL -const DEFAULT_RETRIEVE_BLOCKS_FROM_LEDGER_INTERVAL_SECS: u64 = 1; -const GENESIS_NANOS: u64 = 1_620_328_630_000_000_000; -const INDEX_SYNC_TIME_TO_ADVANCE: Duration = Duration::from_secs(60); +const GENESIS_NANOS: Time = Time::from_nanos_since_unix_epoch(1_620_328_630_000_000_000); +const INDEX_SYNC_TIME_TO_ADVANCE: Duration = Duration::from_secs(2); const MAX_ATTEMPTS_FOR_INDEX_SYNC_WAIT: u8 = 100; const FEE: u64 = 10_000; @@ -87,14 +87,6 @@ fn install_ledger( .unwrap() } -fn install_index(env: &StateMachine, ledger_id: CanisterId) -> CanisterId { - let args = InitArg { - ledger_id: ledger_id.into(), - }; - env.install_canister(index_wasm(), Encode!(&args).unwrap(), None) - .unwrap() -} - fn status(env: &StateMachine, index_id: CanisterId) -> Status { let res = env .query(index_id, "status", Encode!(&()).unwrap()) @@ -103,22 +95,47 @@ fn status(env: &StateMachine, index_id: CanisterId) -> Status { candid::Decode!(&res, Status).expect("Failed to decode status response") } -fn install_and_upgrade(upgrade_interval: Option) -> Result<(), UserError> { +fn install_index( + env: &StateMachine, + ledger_id: CanisterId, + interval: Option, +) -> Result { + let args = IndexArg::Init(InitArg { + ledger_id: ledger_id.into(), + retrieve_blocks_from_ledger_interval_seconds: interval, + }); + env.install_canister(index_wasm(), Encode!(&args).unwrap(), None) +} + +fn install_and_upgrade( + install_interval: Option, + upgrade_interval: Option, +) -> Result<(), UserError> { let env = &StateMachine::new(); - let ledger_id = install_ledger(env, vec![], default_archive_options()); + // Provide an initial balance so the ledger has at least one block + let ledger_id = install_ledger( + env, + vec![(account(1, 0), 1_000_000)], + default_archive_options(), + ); - let index_id = install_index(env, ledger_id); + let index_id = install_index(env, ledger_id, install_interval)?; - let upgrade_arg = UpgradeArg { + wait_until_sync_is_completed(env, index_id, ledger_id); + + let upgrade_arg = IndexArg::Upgrade(UpgradeArg { + ledger_id: None, retrieve_blocks_from_ledger_interval_seconds: upgrade_interval, - }; + }); env.upgrade_canister(index_id, index_wasm(), Encode!(&Some(upgrade_arg)).unwrap())?; + wait_until_sync_is_completed(env, index_id, ledger_id); + Ok(()) } fn max_value_for_interval() -> u64 { - (u64::MAX - GENESIS_NANOS) / 1_000_000_000 + (u64::MAX - GENESIS_NANOS.as_nanos_since_unix_epoch()) / 1_000_000_000 } fn max_index_sync_time() -> u64 { @@ -128,33 +145,50 @@ fn max_index_sync_time() -> u64 { } #[test] -fn should_fail_to_upgrade_with_invalid_value() { - let minimum_invalid_value_for_interval = Some(max_value_for_interval() + 1); - - let err = install_and_upgrade(minimum_invalid_value_for_interval) - .expect_err("should fail to install with invalid interval"); - let code = err.code(); - assert_eq!(code, ErrorCode::CanisterCalledTrap); - let description = err.description(); - assert!(description.contains("delay out of bounds")); +fn should_fail_to_install_and_upgrade_with_invalid_value() { + let minimum_invalid_value_for_interval = max_value_for_interval() + 1; + let invalid_install_and_upgrade_combinations = [ + (Some(minimum_invalid_value_for_interval), Some(1)), + (Some(1), Some(minimum_invalid_value_for_interval)), + ]; + + for (install_interval, upgrade_interval) in &invalid_install_and_upgrade_combinations { + let err = install_and_upgrade(*install_interval, *upgrade_interval) + .expect_err("should fail to install with invalid interval"); + let code = err.code(); + assert_eq!(code, ErrorCode::CanisterCalledTrap); + let description = err.description(); + assert!(description.contains("delay out of bounds")); + } } #[test] -fn should_upgrade_with_valid_values() { +fn should_install_and_upgrade_with_valid_values() { let max_seconds_for_timer = max_value_for_interval() - max_index_sync_time(); let build_index_interval_values = [ - None, - Some(0u64), - Some(1u64), - Some(10u64), - Some(max_seconds_for_timer), + (None, None), + (None, Some(0u64)), + (None, Some(1u64)), + (None, Some(10u64)), + (None, Some(max_seconds_for_timer)), + (Some(1u64), None), + (Some(1u64), Some(0u64)), + (Some(1u64), Some(1u64)), + (Some(1u64), Some(10u64)), + (Some(1u64), Some(max_seconds_for_timer)), + (Some(10u64), None), + (Some(10u64), Some(0u64)), + (Some(10u64), Some(1u64)), + (Some(10u64), Some(10u64)), + (Some(10u64), Some(max_seconds_for_timer)), ]; - for upgrade_interval in &build_index_interval_values { + // Installing and upgrading with valid values should succeed + for (install_interval, upgrade_interval) in &build_index_interval_values { assert_eq!( - install_and_upgrade(*upgrade_interval), + install_and_upgrade(*install_interval, *upgrade_interval), Ok(()), - "upgrade_interval: {upgrade_interval:?}" + "install_interval: {install_interval:?}, upgrade_interval: {upgrade_interval:?}" ); } } @@ -163,6 +197,7 @@ fn should_upgrade_with_valid_values() { fn should_sync_according_to_interval() { const INITIAL_BALANCE: u64 = 1_000_000_000; const TRANSFER_AMOUNT: u64 = 1_000_000; + const DEFAULT_RETRIEVE_BLOCKS_FROM_LEDGER_INTERVAL: u64 = 1; fn send_transaction_and_verify_index_sync( env: &StateMachine, @@ -170,6 +205,7 @@ fn should_sync_according_to_interval() { index_id: CanisterId, a1: Account, a2: Account, + install_interval: Option, upgrade_interval: Option, ) { let transfer_args = icp_ledger::TransferArgs { @@ -197,8 +233,9 @@ fn should_sync_according_to_interval() { .expect("should be able to add 1 to block index"); let mut index_num_blocks_synced = status(env, index_id).num_blocks_synced; if index_num_blocks_synced != ledger_chain_length { - let time_to_advance = - upgrade_interval.unwrap_or(DEFAULT_RETRIEVE_BLOCKS_FROM_LEDGER_INTERVAL_SECS); + let time_to_advance = upgrade_interval + .or(install_interval) + .unwrap_or(DEFAULT_RETRIEVE_BLOCKS_FROM_LEDGER_INTERVAL); if time_to_advance > 0 { env.advance_time(Duration::from_secs(time_to_advance)); env.tick(); @@ -217,13 +254,14 @@ fn should_sync_according_to_interval() { runner .run( &( + proptest::option::of(0..(max_value_for_interval() / 2)), proptest::option::of(0..(max_value_for_interval() / 2)), arb_account(), arb_account(), ) - .prop_filter("The accounts must be different", |(_, a1, a2)| a1 != a2) + .prop_filter("The accounts must be different", |(_, _, a1, a2)| a1 != a2) .no_shrink(), - |(upgrade_interval, a1, a2)| { + |(install_interval, upgrade_interval, a1, a2)| { // Create a new environment let env = &StateMachine::new(); @@ -231,22 +269,39 @@ fn should_sync_according_to_interval() { let ledger_id = install_ledger(env, vec![(a1, INITIAL_BALANCE)], default_archive_options()); - let index_id = install_index(env, ledger_id); + let index_id = install_index(env, ledger_id, install_interval).unwrap(); + + // Send a transaction and verify that the index is synced after the interval + // specified during the install, or the default value if the interval specified + // during the install was None. + send_transaction_and_verify_index_sync( + env, + ledger_id, + index_id, + a1, // from + a2, // to + install_interval, + None, + ); - let upgrade_arg = UpgradeArg { + // Upgrade the index with a specific interval + let upgrade_arg = IndexArg::Upgrade(UpgradeArg { + ledger_id: None, retrieve_blocks_from_ledger_interval_seconds: upgrade_interval, - }; + }); env.upgrade_canister(index_id, index_wasm(), Encode!(&Some(upgrade_arg)).unwrap())?; // Send a transaction and verify that the index is synced after the interval - // specified during the upgrade, or the default value if the interval specified - // during the upgrade was None. + // specified during the upgrade, or if it is None, the interval specified during + // the install, or the default value if the interval specified during the install + // was None. send_transaction_and_verify_index_sync( env, ledger_id, index_id, a1, // from a2, // to + install_interval, upgrade_interval, ); diff --git a/rs/ledger_suite/icp/index/tests/tests.rs b/rs/ledger_suite/icp/index/tests/tests.rs index 1a2d32f203bb..856e338ca872 100644 --- a/rs/ledger_suite/icp/index/tests/tests.rs +++ b/rs/ledger_suite/icp/index/tests/tests.rs @@ -2,7 +2,8 @@ use candid::{Decode, Encode, Nat, Principal}; use ic_base_types::{CanisterId, PrincipalId}; use ic_icp_index::{ GetAccountIdentifierTransactionsArgs, GetAccountIdentifierTransactionsResponse, - GetAccountIdentifierTransactionsResult, SettledTransaction, SettledTransactionWithId, + GetAccountIdentifierTransactionsResult, IndexArg, InitArg, SettledTransaction, + SettledTransactionWithId, }; use ic_icrc1_index_ng::GetAccountTransactionsArgs; use ic_ledger_canister_core::archive::ArchiveOptions; @@ -142,9 +143,10 @@ fn install_ledger( } fn install_index(env: &StateMachine, ledger_id: CanisterId) -> CanisterId { - let args = ic_icp_index::InitArg { + let args = IndexArg::Init(InitArg { ledger_id: ledger_id.into(), - }; + retrieve_blocks_from_ledger_interval_seconds: None, + }); env.install_canister(index_wasm(), Encode!(&args).unwrap(), None) .unwrap() } @@ -2044,7 +2046,7 @@ fn test_index_sync_with_invalid_block() { mod metrics { use crate::index_wasm; use candid::Principal; - use ic_icp_index::InitArg; + use ic_icp_index::{IndexArg, InitArg}; #[test] fn should_export_heap_memory_usage_bytes_metrics() { @@ -2054,7 +2056,10 @@ mod metrics { ); } - fn encode_init_args(ledger_id: Principal) -> InitArg { - InitArg { ledger_id } + fn encode_init_args(ledger_id: Principal) -> IndexArg { + IndexArg::Init(InitArg { + ledger_id, + retrieve_blocks_from_ledger_interval_seconds: None, + }) } } diff --git a/rs/ledger_suite/icp/tests/upgrade_downgrade.rs b/rs/ledger_suite/icp/tests/upgrade_downgrade.rs index 90c5e8b03154..9eca4067755a 100644 --- a/rs/ledger_suite/icp/tests/upgrade_downgrade.rs +++ b/rs/ledger_suite/icp/tests/upgrade_downgrade.rs @@ -388,6 +388,7 @@ impl SetupBuilder { .unwrap(); let index_canister_init_args = ic_icp_index::InitArg { ledger_id: candid::Principal::from(LEDGER_CANISTER_ID), + retrieve_blocks_from_ledger_interval_seconds: None, }; let pocket_ic = PocketIcBuilder::new().with_nns_subnet().build(); diff --git a/rs/nns/test_utils/src/common.rs b/rs/nns/test_utils/src/common.rs index 80686f3c795b..c913c399124d 100644 --- a/rs/nns/test_utils/src/common.rs +++ b/rs/nns/test_utils/src/common.rs @@ -83,6 +83,7 @@ impl NnsInitPayloadsBuilder { sns_wasms: SnsWasmCanisterInitPayloadBuilder::new(), index: ic_icp_index::InitArg { ledger_id: LEDGER_CANISTER_ID.get().into(), + retrieve_blocks_from_ledger_interval_seconds: None, }, subnet_rental: SubnetRentalCanisterInitPayloadBuilder::new(), } diff --git a/rs/pocket_ic_server/BUILD.bazel b/rs/pocket_ic_server/BUILD.bazel index 312b3de903bc..1d695890f0ad 100644 --- a/rs/pocket_ic_server/BUILD.bazel +++ b/rs/pocket_ic_server/BUILD.bazel @@ -184,6 +184,9 @@ HEAD_NNS_CANISTER_DATA = [ ] HEAD_NNS_CANISTER_ENV = { + # Head build uses current canister interfaces (e.g. unified ICP Index init/upgrade args). + # TODO(DEFI-2655): remove once release of Mainnet PocketIC embeds new ICP Index arg. + "POCKET_IC_USE_LEGACY_ICP_INDEX_INIT_ARGS": "0", "REGISTRY_CANISTER_WASM_PATH": "$(location //rs/registry/canister:registry-canister)", "CYCLES_MINTING_CANISTER_WASM_PATH": "$(location //rs/nns/cmc:cycles-minting-canister)", "ICP_LEDGER_CANISTER_WASM_PATH": "$(location //rs/ledger_suite/icp/ledger:ledger-canister-wasm)", @@ -220,6 +223,9 @@ MAINNET_NNS_CANISTER_DATA = [ ] MAINNET_NNS_CANISTER_ENV = { + # Mainnet embeds older canister WASMs; use legacy ICP Index init args until mainnet is updated (see DEFI-2617). + # TODO(DEFI-2655): remove once release of Mainnet PocketIC embeds new ICP Index arg. + "POCKET_IC_USE_LEGACY_ICP_INDEX_INIT_ARGS": "1", "REGISTRY_CANISTER_WASM_PATH": "$(location @mainnet_canisters//:registry.wasm.gz)", "CYCLES_MINTING_CANISTER_WASM_PATH": "$(location @mainnet_canisters//:cycles-minting.wasm.gz)", "ICP_LEDGER_CANISTER_WASM_PATH": "$(location @mainnet_canisters//:ledger.wasm.gz)", diff --git a/rs/pocket_ic_server/src/pocket_ic.rs b/rs/pocket_ic_server/src/pocket_ic.rs index a55be784a4b6..eeb924ca2081 100644 --- a/rs/pocket_ic_server/src/pocket_ic.rs +++ b/rs/pocket_ic_server/src/pocket_ic.rs @@ -56,7 +56,7 @@ use ic_https_outcalls_service::HttpsOutcallResponse; use ic_https_outcalls_service::HttpsOutcallResult; use ic_https_outcalls_service::https_outcalls_service_server::HttpsOutcallsService; use ic_https_outcalls_service::https_outcalls_service_server::HttpsOutcallsServiceServer; -use ic_icp_index::InitArg as IcpIndexInitArg; +use ic_icp_index::{IndexArg as IcpIndexArg, InitArg as IcpIndexInitArg}; use ic_icrc1_index_ng::{IndexArg as CyclesLedgerIndexArg, InitArg as CyclesLedgerIndexInitArg}; use ic_interfaces::{crypto::BasicSigner, ingress_pool::IngressPoolThrottler}; use ic_interfaces_adapter_client::NonBlockingChannel; @@ -1463,16 +1463,30 @@ impl PocketIcSubnets { assert_eq!(canister_id, LEDGER_INDEX_CANISTER_ID); // Install the ICP index. - let icp_index_init_arg = IcpIndexInitArg { - ledger_id: LEDGER_CANISTER_ID.get().0, - }; + // Mainnet PocketIC embeds an older ICP Index WASM that expects the pre-DEFI-2617 init + // format (InitArg with ledger_id only). Head build uses the unified IndexArg::Init(InitArg) format. + // TODO(DEFI-2655): remove once release of Mainnet PocketIC embeds new ICP Index arg. + let icp_index_init_payload: Vec = + if option_env!("POCKET_IC_USE_LEGACY_ICP_INDEX_INIT_ARGS").unwrap_or("0") == "1" { + let legacy_arg = IcpIndexInitArg { + ledger_id: LEDGER_CANISTER_ID.get().0, + retrieve_blocks_from_ledger_interval_seconds: None, + }; + Encode!(&legacy_arg).unwrap() + } else { + let arg = IcpIndexArg::Init(IcpIndexInitArg { + ledger_id: LEDGER_CANISTER_ID.get().0, + retrieve_blocks_from_ledger_interval_seconds: None, + }); + Encode!(&arg).unwrap() + }; nns_subnet .state_machine .install_wasm_in_mode( canister_id, CanisterInstallMode::Install, ICP_INDEX_CANISTER_WASM.to_vec(), - Encode!(&icp_index_init_arg).unwrap(), + icp_index_init_payload, ) .unwrap(); }