From ac805e300658c70c5d958532f3c2c02bc2be8e9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Wed, 27 Nov 2024 13:17:34 +0100 Subject: [PATCH 01/22] Add ICRC-106 to supported standards in ICRC ledger --- rs/ledger_suite/icrc1/ledger/src/main.rs | 4 ++++ rs/ledger_suite/tests/sm-tests/src/lib.rs | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/rs/ledger_suite/icrc1/ledger/src/main.rs b/rs/ledger_suite/icrc1/ledger/src/main.rs index 43f23d31c440..147b04bdac78 100644 --- a/rs/ledger_suite/icrc1/ledger/src/main.rs +++ b/rs/ledger_suite/icrc1/ledger/src/main.rs @@ -665,6 +665,10 @@ fn supported_standards() -> Vec { name: "ICRC-21".to_string(), url: "https://github.com/dfinity/wg-identity-authentication/blob/main/topics/ICRC-21/icrc_21_consent_msg.md".to_string(), }, + StandardRecord { + name: "ICRC-106".to_string(), + url: "https://github.com/dfinity/ICRC/pull/106".to_string(), + }, ]; standards } diff --git a/rs/ledger_suite/tests/sm-tests/src/lib.rs b/rs/ledger_suite/tests/sm-tests/src/lib.rs index e8ae80770bfe..863949981ce8 100644 --- a/rs/ledger_suite/tests/sm-tests/src/lib.rs +++ b/rs/ledger_suite/tests/sm-tests/src/lib.rs @@ -1020,7 +1020,10 @@ where standards.push(standard.name); } standards.sort(); - assert_eq!(standards, vec!["ICRC-1", "ICRC-2", "ICRC-21", "ICRC-3"]); + assert_eq!( + standards, + vec!["ICRC-1", "ICRC-106", "ICRC-2", "ICRC-21", "ICRC-3"] + ); } pub fn test_total_supply(ledger_wasm: Vec, encode_init_args: fn(InitArgs) -> T) @@ -3142,7 +3145,10 @@ where standards.push(standard.name); } standards.sort(); - assert_eq!(standards, vec!["ICRC-1", "ICRC-2", "ICRC-21"]); + assert_eq!( + standards, + vec!["ICRC-1", "ICRC-106", "ICRC-2", "ICRC-21", "ICRC-187"] + ); let block_index = send_approval(&env, canister_id, from.0, &approve_args).expect("approval failed"); From 686aad36dc31d61a393fff2131f102ea6985c2d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Wed, 27 Nov 2024 14:49:18 +0100 Subject: [PATCH 02/22] Add new types to icrc-ledger-types --- packages/icrc-ledger-types/src/icrc106/errors.rs | 11 +++++++++++ packages/icrc-ledger-types/src/icrc106/mod.rs | 1 + packages/icrc-ledger-types/src/lib.rs | 1 + 3 files changed, 13 insertions(+) create mode 100644 packages/icrc-ledger-types/src/icrc106/errors.rs create mode 100644 packages/icrc-ledger-types/src/icrc106/mod.rs diff --git a/packages/icrc-ledger-types/src/icrc106/errors.rs b/packages/icrc-ledger-types/src/icrc106/errors.rs new file mode 100644 index 000000000000..d6ad6244ad4b --- /dev/null +++ b/packages/icrc-ledger-types/src/icrc106/errors.rs @@ -0,0 +1,11 @@ +use candid::{CandidType, Deserialize, Nat}; +use serde::Serialize; + +#[derive(Debug, CandidType, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub enum Icrc106Error { + IndexNotSet, + GenericError { + error_code: Nat, + description: String, + }, +} diff --git a/packages/icrc-ledger-types/src/icrc106/mod.rs b/packages/icrc-ledger-types/src/icrc106/mod.rs new file mode 100644 index 000000000000..629e98fbf874 --- /dev/null +++ b/packages/icrc-ledger-types/src/icrc106/mod.rs @@ -0,0 +1 @@ +pub mod errors; diff --git a/packages/icrc-ledger-types/src/lib.rs b/packages/icrc-ledger-types/src/lib.rs index f532acb4880c..d304c1d5a817 100644 --- a/packages/icrc-ledger-types/src/lib.rs +++ b/packages/icrc-ledger-types/src/lib.rs @@ -1,5 +1,6 @@ pub mod icrc; pub mod icrc1; +pub mod icrc106; pub mod icrc2; pub mod icrc21; pub mod icrc3; From 48d81000496a9ad4398db89a496cc18658a3f8d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Wed, 27 Nov 2024 14:54:46 +0100 Subject: [PATCH 03/22] Add index_principal to upgrade args and add new endpoint --- rs/ledger_suite/icrc1/index-ng/tests/tests.rs | 1 + rs/ledger_suite/icrc1/ledger/ledger.did | 13 +++++ rs/ledger_suite/icrc1/ledger/src/lib.rs | 12 +++++ rs/ledger_suite/icrc1/ledger/src/main.rs | 15 +++++- rs/ledger_suite/icrc1/ledger/tests/tests.rs | 28 +++++++++- rs/ledger_suite/tests/sm-tests/src/lib.rs | 53 +++++++++++++++++++ 6 files changed, 119 insertions(+), 3 deletions(-) diff --git a/rs/ledger_suite/icrc1/index-ng/tests/tests.rs b/rs/ledger_suite/icrc1/index-ng/tests/tests.rs index 80369d5d978e..b2b4c362e0e2 100644 --- a/rs/ledger_suite/icrc1/index-ng/tests/tests.rs +++ b/rs/ledger_suite/icrc1/index-ng/tests/tests.rs @@ -57,6 +57,7 @@ fn upgrade_ledger( feature_flags: None, accounts_overflow_trim_quantity: None, change_archive_options: None, + index_principal: None, })); env.upgrade_canister(ledger_id, ledger_wasm(), Encode!(&args).unwrap()) .unwrap() diff --git a/rs/ledger_suite/icrc1/ledger/ledger.did b/rs/ledger_suite/icrc1/ledger/ledger.did index ac3a7bff087f..3b37fe914442 100644 --- a/rs/ledger_suite/icrc1/ledger/ledger.did +++ b/rs/ledger_suite/icrc1/ledger/ledger.did @@ -146,6 +146,7 @@ type UpgradeArgs = record { feature_flags : opt FeatureFlags; accounts_overflow_trim_quantity: opt nat64; change_archive_options : opt ChangeArchiveOptions; + index_principal : opt text; }; type LedgerArg = variant { @@ -481,6 +482,16 @@ type icrc21_consent_message_response = variant { Err: icrc21_error; }; +type GetIndexResult = variant { + Ok : principal; + Err : GetIndexError; +}; + +type GetIndexError = variant { + IndexNotSet; + GenericError : record { error_code : nat; message : text }; +}; + service : (ledger_arg : LedgerArg) -> { archives : () -> (vec ArchiveInfo) query; get_transactions : (GetTransactionsRequest) -> (GetTransactionsResponse) query; @@ -509,4 +520,6 @@ service : (ledger_arg : LedgerArg) -> { icrc21_canister_call_consent_message: (icrc21_consent_message_request) -> (icrc21_consent_message_response); icrc10_supported_standards : () -> (vec record { name : text; url : text }) query; + + icrc106_get_index_principal: () -> (GetIndexResult) query; } diff --git a/rs/ledger_suite/icrc1/ledger/src/lib.rs b/rs/ledger_suite/icrc1/ledger/src/lib.rs index e43676ff9411..5f234ddcbe80 100644 --- a/rs/ledger_suite/icrc1/ledger/src/lib.rs +++ b/rs/ledger_suite/icrc1/ledger/src/lib.rs @@ -335,6 +335,8 @@ pub struct UpgradeArgs { pub accounts_overflow_trim_quantity: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub change_archive_options: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub index_principal: Option, } #[derive(Clone, Eq, PartialEq, Debug, CandidType, Deserialize)] @@ -390,6 +392,8 @@ pub struct Ledger { #[serde(default = "default_ledger_version")] pub ledger_version: u64, + + index_principal: Option, } fn default_maximum_number_of_accounts() -> usize { @@ -487,6 +491,7 @@ impl Ledger { .try_into() .unwrap(), ledger_version: LEDGER_VERSION, + index_principal: None, }; for (account, balance) in initial_balances.into_iter() { @@ -618,6 +623,10 @@ impl Ledger { self.decimals } + pub fn index_principal(&self) -> Option { + self.index_principal.clone() + } + pub fn metadata(&self) -> Vec<(String, Value)> { let mut records: Vec<(String, Value)> = self .metadata @@ -702,6 +711,9 @@ impl Ledger { change_archive_options.apply(archive); } } + if let Some(index_principal) = args.index_principal { + self.index_principal = Some(index_principal); + } } /// Returns the root hash of the certified ledger state. diff --git a/rs/ledger_suite/icrc1/ledger/src/main.rs b/rs/ledger_suite/icrc1/ledger/src/main.rs index 147b04bdac78..28154ed4b45f 100644 --- a/rs/ledger_suite/icrc1/ledger/src/main.rs +++ b/rs/ledger_suite/icrc1/ledger/src/main.rs @@ -1,8 +1,8 @@ #[cfg(feature = "canbench-rs")] mod benches; -use candid::candid_method; use candid::types::number::Nat; +use candid::{candid_method, Principal}; use ic_canister_log::{declare_log_buffer, export}; use ic_canisters_http_types::{HttpRequest, HttpResponse, HttpResponseBuilder}; use ic_cdk::api::stable::StableReader; @@ -26,6 +26,7 @@ use ic_ledger_core::timestamp::TimeStamp; use ic_ledger_core::tokens::Zero; use ic_stable_structures::reader::{BufferedReader, Reader}; use ic_stable_structures::writer::{BufferedWriter, Writer}; +use icrc_ledger_types::icrc106::errors::Icrc106Error; use icrc_ledger_types::icrc2::approve::{ApproveArgs, ApproveError}; use icrc_ledger_types::icrc21::{ errors::Icrc21Error, lib::build_icrc21_consent_info_for_icrc1_and_icrc2_endpoints, @@ -857,6 +858,18 @@ fn icrc10_supported_standards() -> Vec { supported_standards() } +#[query] +#[candid_method(query)] +fn icrc106_get_index_principal() -> Result { + Access::with_ledger(|ledger| { + if let Some(index_principal) = ledger.index_principal() { + Ok(index_principal) + } else { + Err(Icrc106Error::IndexNotSet) + } + }) +} + #[update] #[candid_method(update)] fn icrc21_canister_call_consent_message( diff --git a/rs/ledger_suite/icrc1/ledger/tests/tests.rs b/rs/ledger_suite/icrc1/ledger/tests/tests.rs index 880002ec269e..96b491d72454 100644 --- a/rs/ledger_suite/icrc1/ledger/tests/tests.rs +++ b/rs/ledger_suite/icrc1/ledger/tests/tests.rs @@ -1,10 +1,10 @@ -use candid::{CandidType, Decode, Encode, Nat}; +use candid::{CandidType, Decode, Encode, Nat, Principal}; use ic_agent::identity::Identity; use ic_base_types::{CanisterId, PrincipalId}; use ic_icrc1::{Block, Operation, Transaction}; use ic_icrc1_ledger::{ ChangeFeeCollector, FeatureFlags, InitArgs, InitArgsBuilder as LedgerInitArgsBuilder, - LedgerArgument, + LedgerArgument, UpgradeArgs, }; use ic_icrc1_test_utils::minter_identity; use ic_ledger_canister_core::archive::ArchiveOptions; @@ -428,6 +428,30 @@ fn test_icrc21_standard() { ic_ledger_suite_state_machine_tests::test_icrc21_standard(ledger_wasm(), encode_init_args); } +fn encode_icrc106_upgrade_args(index_principal: Option) -> LedgerArgument { + LedgerArgument::Upgrade(Some(UpgradeArgs { + metadata: None, + token_name: None, + token_symbol: None, + transfer_fee: None, + change_fee_collector: None, + max_memo_length: None, + feature_flags: None, + accounts_overflow_trim_quantity: None, + change_archive_options: None, + index_principal, + })) +} + +#[test] +fn test_icrc106_standard() { + ic_ledger_suite_state_machine_tests::test_icrc106_standard( + ledger_wasm(), + encode_init_args, + encode_icrc106_upgrade_args, + ); +} + // #[test] // fn test_icrc1_test_suite() { // ic_ledger_suite_state_machine_tests::test_icrc1_test_suite(ledger_wasm(), encode_init_args); diff --git a/rs/ledger_suite/tests/sm-tests/src/lib.rs b/rs/ledger_suite/tests/sm-tests/src/lib.rs index 863949981ce8..6c4b7d212ffa 100644 --- a/rs/ledger_suite/tests/sm-tests/src/lib.rs +++ b/rs/ledger_suite/tests/sm-tests/src/lib.rs @@ -25,6 +25,7 @@ use icrc_ledger_types::icrc::generic_metadata_value::MetadataValue as Value; use icrc_ledger_types::icrc::generic_value::Value as GenericValue; use icrc_ledger_types::icrc1::account::{Account, Subaccount}; use icrc_ledger_types::icrc1::transfer::{Memo, TransferArg, TransferError}; +use icrc_ledger_types::icrc106::errors::Icrc106Error; use icrc_ledger_types::icrc2::allowance::{Allowance, AllowanceArgs}; use icrc_ledger_types::icrc2::approve::{ApproveArgs, ApproveError}; use icrc_ledger_types::icrc2::transfer_from::{TransferFromArgs, TransferFromError}; @@ -285,6 +286,19 @@ fn icrc21_consent_message( .expect("failed to decode icrc21_canister_call_consent_message response") } +fn icrc106_get_index_principal( + env: &StateMachine, + ledger: CanisterId, +) -> Result { + Decode!( + &env.query(ledger, "icrc106_get_index_principal", Encode!().unwrap()) + .expect("failed to query icrc106_get_index_principal") + .bytes(), + Result + ) + .expect("failed to decode icrc106_get_index_principal response") +} + pub fn get_all_ledger_and_archive_blocks( state_machine: &StateMachine, ledger_id: CanisterId, @@ -4082,6 +4096,45 @@ where ); } +pub fn test_icrc106_standard( + ledger_wasm: Vec, + encode_init_args: fn(InitArgs) -> T, + encode_upgrade_args: fn(Option) -> U, +) where + T: CandidType, + U: CandidType, +{ + fn assert_icrc106_supported(env: &StateMachine, canister_id: CanisterId) { + let mut found = false; + for standard in supported_standards(&env, canister_id) { + if standard.name == "ICRC-106" { + found = true; + break; + } + } + assert!(found, "ICRC-106 should be supported"); + } + + let (env, canister_id) = setup(ledger_wasm.clone(), encode_init_args, vec![]); + assert_icrc106_supported(&env, canister_id); + assert_eq!( + Err(Icrc106Error::IndexNotSet), + icrc106_get_index_principal(&env, canister_id) + ); + + let index_principal = PrincipalId::new_user_test_id(1).0; + let args = encode_upgrade_args(Some(index_principal)); + let encoded_upgrade_args = Encode!(&args).unwrap(); + env.upgrade_canister(canister_id, ledger_wasm, encoded_upgrade_args.clone()) + .expect("should successfully upgrade ledger canister"); + + assert_icrc106_supported(&env, canister_id); + assert_eq!( + Ok(index_principal), + icrc106_get_index_principal(&env, canister_id) + ); +} + pub struct TransactionGenerationParameters { pub mint_multiplier: u64, pub transfer_multiplier: u64, From 9d6cdb931ada03de015d15ce7284e8a78f805bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Wed, 27 Nov 2024 15:08:59 +0100 Subject: [PATCH 04/22] Add index principal to metadata --- rs/ledger_suite/icrc1/ledger/src/lib.rs | 6 ++++++ rs/ledger_suite/tests/sm-tests/src/lib.rs | 11 ++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/rs/ledger_suite/icrc1/ledger/src/lib.rs b/rs/ledger_suite/icrc1/ledger/src/lib.rs index 5f234ddcbe80..01cf4f5bc6ab 100644 --- a/rs/ledger_suite/icrc1/ledger/src/lib.rs +++ b/rs/ledger_suite/icrc1/ledger/src/lib.rs @@ -642,6 +642,12 @@ impl Ledger { "icrc1:max_memo_length", self.max_memo_length() as u64, )); + if let Some(index_principal) = self.index_principal() { + records.push(Value::entry( + "icrc106:index_principal", + index_principal.to_text(), + )); + } records } diff --git a/rs/ledger_suite/tests/sm-tests/src/lib.rs b/rs/ledger_suite/tests/sm-tests/src/lib.rs index 6c4b7d212ffa..2281da813727 100644 --- a/rs/ledger_suite/tests/sm-tests/src/lib.rs +++ b/rs/ledger_suite/tests/sm-tests/src/lib.rs @@ -21,7 +21,7 @@ use ic_state_machine_tests::{ErrorCode, StateMachine, WasmResult}; use ic_types::Cycles; use ic_universal_canister::{call_args, wasm, UNIVERSAL_CANISTER_WASM}; use icp_ledger::{AccountIdentifier, IcpAllowanceArgs}; -use icrc_ledger_types::icrc::generic_metadata_value::MetadataValue as Value; +use icrc_ledger_types::icrc::generic_metadata_value::{MetadataValue as Value, MetadataValue}; use icrc_ledger_types::icrc::generic_value::Value as GenericValue; use icrc_ledger_types::icrc1::account::{Account, Subaccount}; use icrc_ledger_types::icrc1::transfer::{Memo, TransferArg, TransferError}; @@ -4121,6 +4121,9 @@ pub fn test_icrc106_standard( Err(Icrc106Error::IndexNotSet), icrc106_get_index_principal(&env, canister_id) ); + assert!(metadata(&env, canister_id) + .get("icrc106:index_principal") + .is_none()); let index_principal = PrincipalId::new_user_test_id(1).0; let args = encode_upgrade_args(Some(index_principal)); @@ -4133,6 +4136,12 @@ pub fn test_icrc106_standard( Ok(index_principal), icrc106_get_index_principal(&env, canister_id) ); + assert_eq!( + &MetadataValue::Text(index_principal.to_text()), + metadata(&env, canister_id) + .get("icrc106:index_principal") + .expect("should have index principal metadata") + ); } pub struct TransactionGenerationParameters { From 2308795208fb8aeb8a78ecb63083cddd6556b135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Wed, 27 Nov 2024 16:32:37 +0100 Subject: [PATCH 05/22] Clippy --- rs/ledger_suite/icrc1/ledger/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/ledger_suite/icrc1/ledger/src/lib.rs b/rs/ledger_suite/icrc1/ledger/src/lib.rs index 01cf4f5bc6ab..a93cccc6cf94 100644 --- a/rs/ledger_suite/icrc1/ledger/src/lib.rs +++ b/rs/ledger_suite/icrc1/ledger/src/lib.rs @@ -624,7 +624,7 @@ impl Ledger { } pub fn index_principal(&self) -> Option { - self.index_principal.clone() + self.index_principal } pub fn metadata(&self) -> Vec<(String, Value)> { From 62bfaf6446a09a75b5958393084b745f60c7eb07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Thu, 28 Nov 2024 10:15:50 +0100 Subject: [PATCH 06/22] Candid fixes and renaming --- .../icrc-ledger-types/src/icrc106/errors.rs | 2 +- rs/ledger_suite/icrc1/ledger/ledger.did | 19 ++++++++++++------- rs/ledger_suite/icrc1/ledger/src/main.rs | 2 +- rs/ledger_suite/tests/sm-tests/src/lib.rs | 2 +- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/icrc-ledger-types/src/icrc106/errors.rs b/packages/icrc-ledger-types/src/icrc106/errors.rs index d6ad6244ad4b..81360d1cdf66 100644 --- a/packages/icrc-ledger-types/src/icrc106/errors.rs +++ b/packages/icrc-ledger-types/src/icrc106/errors.rs @@ -3,7 +3,7 @@ use serde::Serialize; #[derive(Debug, CandidType, Clone, Serialize, Deserialize, PartialEq, Eq)] pub enum Icrc106Error { - IndexNotSet, + IndexPrincipalNotSet, GenericError { error_code: Nat, description: String, diff --git a/rs/ledger_suite/icrc1/ledger/ledger.did b/rs/ledger_suite/icrc1/ledger/ledger.did index 3b37fe914442..b7e8d8b81f13 100644 --- a/rs/ledger_suite/icrc1/ledger/ledger.did +++ b/rs/ledger_suite/icrc1/ledger/ledger.did @@ -146,7 +146,7 @@ type UpgradeArgs = record { feature_flags : opt FeatureFlags; accounts_overflow_trim_quantity: opt nat64; change_archive_options : opt ChangeArchiveOptions; - index_principal : opt text; + index_principal : opt principal; }; type LedgerArg = variant { @@ -482,14 +482,19 @@ type icrc21_consent_message_response = variant { Err: icrc21_error; }; -type GetIndexResult = variant { +type GetIndexPrincipalResult = variant { Ok : principal; - Err : GetIndexError; + Err : GetIndexPrincipalError; }; -type GetIndexError = variant { - IndexNotSet; - GenericError : record { error_code : nat; message : text }; +type GetIndexPrincipalError = variant { + IndexPrincipalNotSet; + + // Any error not covered by the above variants. + GenericError: record { + error_code: nat; + description: text; + }; }; service : (ledger_arg : LedgerArg) -> { @@ -521,5 +526,5 @@ service : (ledger_arg : LedgerArg) -> { icrc21_canister_call_consent_message: (icrc21_consent_message_request) -> (icrc21_consent_message_response); icrc10_supported_standards : () -> (vec record { name : text; url : text }) query; - icrc106_get_index_principal: () -> (GetIndexResult) query; + icrc106_get_index_principal: () -> (GetIndexPrincipalResult) query; } diff --git a/rs/ledger_suite/icrc1/ledger/src/main.rs b/rs/ledger_suite/icrc1/ledger/src/main.rs index 28154ed4b45f..ddc3a4708718 100644 --- a/rs/ledger_suite/icrc1/ledger/src/main.rs +++ b/rs/ledger_suite/icrc1/ledger/src/main.rs @@ -865,7 +865,7 @@ fn icrc106_get_index_principal() -> Result { if let Some(index_principal) = ledger.index_principal() { Ok(index_principal) } else { - Err(Icrc106Error::IndexNotSet) + Err(Icrc106Error::IndexPrincipalNotSet) } }) } diff --git a/rs/ledger_suite/tests/sm-tests/src/lib.rs b/rs/ledger_suite/tests/sm-tests/src/lib.rs index 2281da813727..3e70d7636250 100644 --- a/rs/ledger_suite/tests/sm-tests/src/lib.rs +++ b/rs/ledger_suite/tests/sm-tests/src/lib.rs @@ -4118,7 +4118,7 @@ pub fn test_icrc106_standard( let (env, canister_id) = setup(ledger_wasm.clone(), encode_init_args, vec![]); assert_icrc106_supported(&env, canister_id); assert_eq!( - Err(Icrc106Error::IndexNotSet), + Err(Icrc106Error::IndexPrincipalNotSet), icrc106_get_index_principal(&env, canister_id) ); assert!(metadata(&env, canister_id) From a08bb407dd882d2a11817e2d714038a41f7b7a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Thu, 28 Nov 2024 10:34:14 +0100 Subject: [PATCH 07/22] Clippy --- rs/ledger_suite/tests/sm-tests/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/rs/ledger_suite/tests/sm-tests/src/lib.rs b/rs/ledger_suite/tests/sm-tests/src/lib.rs index 3e70d7636250..97ee9cc4e2a3 100644 --- a/rs/ledger_suite/tests/sm-tests/src/lib.rs +++ b/rs/ledger_suite/tests/sm-tests/src/lib.rs @@ -4106,7 +4106,7 @@ pub fn test_icrc106_standard( { fn assert_icrc106_supported(env: &StateMachine, canister_id: CanisterId) { let mut found = false; - for standard in supported_standards(&env, canister_id) { + for standard in supported_standards(env, canister_id) { if standard.name == "ICRC-106" { found = true; break; @@ -4121,9 +4121,7 @@ pub fn test_icrc106_standard( Err(Icrc106Error::IndexPrincipalNotSet), icrc106_get_index_principal(&env, canister_id) ); - assert!(metadata(&env, canister_id) - .get("icrc106:index_principal") - .is_none()); + assert!(!metadata(&env, canister_id).contains_key("icrc106:index_principal")); let index_principal = PrincipalId::new_user_test_id(1).0; let args = encode_upgrade_args(Some(index_principal)); From 23df570c6218f1e2819533634b21abebe17eb81f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Thu, 28 Nov 2024 12:59:35 +0100 Subject: [PATCH 08/22] Cleanup --- rs/ledger_suite/tests/sm-tests/src/lib.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/rs/ledger_suite/tests/sm-tests/src/lib.rs b/rs/ledger_suite/tests/sm-tests/src/lib.rs index 97ee9cc4e2a3..cea7c2eec699 100644 --- a/rs/ledger_suite/tests/sm-tests/src/lib.rs +++ b/rs/ledger_suite/tests/sm-tests/src/lib.rs @@ -3159,10 +3159,7 @@ where standards.push(standard.name); } standards.sort(); - assert_eq!( - standards, - vec!["ICRC-1", "ICRC-106", "ICRC-2", "ICRC-21", "ICRC-187"] - ); + assert_eq!(standards, vec!["ICRC-1", "ICRC-2", "ICRC-21"]); let block_index = send_approval(&env, canister_id, from.0, &approve_args).expect("approval failed"); From ab9c2d0c7c377c44078e7d04ac1fef08a577a7b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Thu, 19 Dec 2024 14:25:20 +0100 Subject: [PATCH 09/22] Support setting index canister ID in ledger init arguments --- rs/ledger_suite/icrc1/ledger/ledger.did | 1 + rs/ledger_suite/icrc1/ledger/src/lib.rs | 5 +- rs/ledger_suite/icrc1/ledger/src/tests.rs | 1 + rs/ledger_suite/icrc1/ledger/tests/tests.rs | 28 +++- rs/ledger_suite/icrc1/tests/tests.rs | 9 ++ .../tests/sm-tests/src/icrc_106.rs | 140 ++++++++++++++++++ rs/ledger_suite/tests/sm-tests/src/lib.rs | 52 +------ 7 files changed, 187 insertions(+), 49 deletions(-) create mode 100644 rs/ledger_suite/tests/sm-tests/src/icrc_106.rs diff --git a/rs/ledger_suite/icrc1/ledger/ledger.did b/rs/ledger_suite/icrc1/ledger/ledger.did index 6448e44bd1cb..16aa04c7eeaf 100644 --- a/rs/ledger_suite/icrc1/ledger/ledger.did +++ b/rs/ledger_suite/icrc1/ledger/ledger.did @@ -119,6 +119,7 @@ type InitArgs = record { controller_id : principal; more_controller_ids : opt vec principal; }; + index_principal : opt principal; }; type ChangeFeeCollector = variant { diff --git a/rs/ledger_suite/icrc1/ledger/src/lib.rs b/rs/ledger_suite/icrc1/ledger/src/lib.rs index 8d5d48c61d2b..4237ef4e5be4 100644 --- a/rs/ledger_suite/icrc1/ledger/src/lib.rs +++ b/rs/ledger_suite/icrc1/ledger/src/lib.rs @@ -181,6 +181,7 @@ impl InitArgsBuilder { feature_flags: None, maximum_number_of_accounts: None, accounts_overflow_trim_quantity: None, + index_principal: None, }) } @@ -265,6 +266,7 @@ pub struct InitArgs { pub feature_flags: Option, pub maximum_number_of_accounts: Option, pub accounts_overflow_trim_quantity: Option, + pub index_principal: Option, } #[derive(Clone, Eq, PartialEq, Debug, CandidType, Deserialize)] @@ -636,6 +638,7 @@ impl Ledger { feature_flags, maximum_number_of_accounts, accounts_overflow_trim_quantity, + index_principal, }: InitArgs, now: TimeStamp, ) -> Self { @@ -678,7 +681,7 @@ impl Ledger { .try_into() .unwrap(), ledger_version: LEDGER_VERSION, - index_principal: None, + index_principal, }; for (account, balance) in initial_balances.into_iter() { diff --git a/rs/ledger_suite/icrc1/ledger/src/tests.rs b/rs/ledger_suite/icrc1/ledger/src/tests.rs index ca5634b81d45..d02675059d6f 100644 --- a/rs/ledger_suite/icrc1/ledger/src/tests.rs +++ b/rs/ledger_suite/icrc1/ledger/src/tests.rs @@ -87,6 +87,7 @@ fn default_init_args() -> InitArgs { feature_flags: None, maximum_number_of_accounts: None, accounts_overflow_trim_quantity: None, + index_principal: None, } } diff --git a/rs/ledger_suite/icrc1/ledger/tests/tests.rs b/rs/ledger_suite/icrc1/ledger/tests/tests.rs index 8479419c5961..1a06bd544e4a 100644 --- a/rs/ledger_suite/icrc1/ledger/tests/tests.rs +++ b/rs/ledger_suite/icrc1/ledger/tests/tests.rs @@ -155,6 +155,7 @@ fn encode_init_args(args: ic_ledger_suite_state_machine_tests::InitArgs) -> Ledg feature_flags: args.feature_flags, maximum_number_of_accounts: args.maximum_number_of_accounts, accounts_overflow_trim_quantity: args.accounts_overflow_trim_quantity, + index_principal: args.index_principal, }) } @@ -431,8 +432,25 @@ fn encode_icrc106_upgrade_args(index_principal: Option) -> LedgerArgu } #[test] -fn test_icrc106_standard() { - ic_ledger_suite_state_machine_tests::test_icrc106_standard( +fn test_icrc106_unsupported_if_index_not_set() { + ic_ledger_suite_state_machine_tests::icrc_106::test_icrc106_unsupported_if_index_not_set( + ledger_wasm(), + encode_init_args, + encode_icrc106_upgrade_args, + ); +} + +#[test] +fn test_icrc106_set_index_in_install() { + ic_ledger_suite_state_machine_tests::icrc_106::test_icrc106_set_index_in_install( + ledger_wasm(), + encode_init_args, + ); +} + +#[test] +fn test_icrc106_set_index_in_upgrade() { + ic_ledger_suite_state_machine_tests::icrc_106::test_icrc106_set_index_in_upgrade( ledger_wasm(), encode_init_args, encode_icrc106_upgrade_args, @@ -664,6 +682,7 @@ fn test_icrc2_feature_flag_doesnt_disable_icrc2_endpoints() { feature_flags: Some(FeatureFlags { icrc2: false }), maximum_number_of_accounts: None, accounts_overflow_trim_quantity: None, + index_principal: None, })) .unwrap(); let ledger_id = env @@ -840,6 +859,7 @@ fn test_icrc3_get_archives() { feature_flags: None, maximum_number_of_accounts: None, accounts_overflow_trim_quantity: None, + index_principal: None, }); let args = Encode!(&args).unwrap(); let ledger_id = env @@ -917,6 +937,7 @@ fn test_icrc3_get_blocks() { feature_flags: None, maximum_number_of_accounts: None, accounts_overflow_trim_quantity: None, + index_principal: None, }); let args = Encode!(&args).unwrap(); let ledger_id = env @@ -1193,6 +1214,7 @@ fn test_icrc3_get_blocks_number_of_blocks_limit() { feature_flags: None, maximum_number_of_accounts: None, accounts_overflow_trim_quantity: None, + index_principal: None, }); let args = Encode!(&args).unwrap(); @@ -1629,6 +1651,7 @@ mod verify_written_blocks { feature_flags: Some(FeatureFlags { icrc2: true }), maximum_number_of_accounts: None, accounts_overflow_trim_quantity: None, + index_principal: None, }); let args = Encode!(&ledger_arg_init).unwrap(); @@ -1847,6 +1870,7 @@ mod incompatible_token_type_upgrade { feature_flags: Some(FeatureFlags { icrc2: false }), maximum_number_of_accounts: None, accounts_overflow_trim_quantity: None, + index_principal: None, })) .unwrap() } diff --git a/rs/ledger_suite/icrc1/tests/tests.rs b/rs/ledger_suite/icrc1/tests/tests.rs index c03889627975..148de80a0fc4 100644 --- a/rs/ledger_suite/icrc1/tests/tests.rs +++ b/rs/ledger_suite/icrc1/tests/tests.rs @@ -156,3 +156,12 @@ fn test_encoding_decoding_block_u254() { prop_assert_eq!(block, decoded); }) } + +#[test] +fn test_icrc106_standard() { + ic_ledger_suite_state_machine_tests::icrc_106::test_icrc106_set_index_in_upgrade( + ledger_wasm(), + encode_init_args, + encode_icrc106_upgrade_args, + ); +} diff --git a/rs/ledger_suite/tests/sm-tests/src/icrc_106.rs b/rs/ledger_suite/tests/sm-tests/src/icrc_106.rs new file mode 100644 index 000000000000..ae0a59f096ff --- /dev/null +++ b/rs/ledger_suite/tests/sm-tests/src/icrc_106.rs @@ -0,0 +1,140 @@ +use super::*; + +pub fn test_icrc106_unsupported_if_index_not_set( + ledger_wasm: Vec, + encode_ledger_init_args: fn(InitArgs) -> T, + encode_upgrade_args: fn(Option) -> U, +) where + T: CandidType, + U: CandidType, +{ + fn assert_index_not_set(env: &StateMachine, ledger_canister_id: CanisterId) { + assert_icrc106_supported(env, ledger_canister_id); + assert_eq!( + Err(Icrc106Error::IndexPrincipalNotSet), + icrc106_get_index_principal(env, ledger_canister_id) + ); + assert_eq!( + None, + metadata(env, ledger_canister_id).get("icrc106:index_principal") + ); + } + + let env = StateMachine::new(); + let ledger_canister_id = env.create_canister(None); + let ledger_init_args = encode_ledger_init_args(init_args(vec![])); + env.install_existing_canister( + ledger_canister_id, + ledger_wasm.clone(), + Encode!(&ledger_init_args).unwrap(), + ) + .expect("should successfully install ledger canister"); + + assert_index_not_set(&env, ledger_canister_id); + + let args = encode_upgrade_args(None); + let encoded_upgrade_args = Encode!(&args).unwrap(); + env.upgrade_canister( + ledger_canister_id, + ledger_wasm, + encoded_upgrade_args.clone(), + ) + .expect("should successfully upgrade ledger canister"); + + assert_index_not_set(&env, ledger_canister_id); +} + +pub fn test_icrc106_set_index_in_install( + ledger_wasm: Vec, + encode_ledger_init_args: fn(InitArgs) -> T, +) where + T: CandidType, +{ + let env = StateMachine::new(); + let ledger_canister_id = env.create_canister(None); + let index_canister_id = env.create_canister(None); + let index_principal = Principal::from(index_canister_id.get()); + let ledger_init_args = encode_ledger_init_args(InitArgs { + index_principal: Some(index_principal), + ..init_args(vec![]) + }); + env.install_existing_canister( + ledger_canister_id, + ledger_wasm.clone(), + Encode!(&ledger_init_args).unwrap(), + ) + .expect("should successfully install ledger canister"); + + assert_icrc106_supported(&env, ledger_canister_id); + assert_eq!( + Ok(index_principal), + icrc106_get_index_principal(&env, ledger_canister_id) + ); + assert_eq!( + &Value::Text(index_principal.to_text()), + metadata(&env, ledger_canister_id) + .get("icrc106:index_principal") + .expect("should have index principal metadata") + ); +} + +pub fn test_icrc106_set_index_in_upgrade( + ledger_wasm: Vec, + encode_init_args: fn(InitArgs) -> T, + encode_upgrade_args: fn(Option) -> U, +) where + T: CandidType, + U: CandidType, +{ + fn assert_index_set( + env: &StateMachine, + ledger_canister_id: CanisterId, + index_principal: Principal, + ) { + assert_icrc106_supported(&env, ledger_canister_id); + assert_eq!( + Ok(index_principal), + icrc106_get_index_principal(&env, ledger_canister_id) + ); + assert_eq!( + &Value::Text(index_principal.to_text()), + metadata(&env, ledger_canister_id) + .get("icrc106:index_principal") + .expect("should have index principal metadata") + ); + } + + let (env, canister_id) = setup(ledger_wasm.clone(), encode_init_args, vec![]); + assert_icrc106_supported(&env, canister_id); + assert_eq!( + Err(Icrc106Error::IndexPrincipalNotSet), + icrc106_get_index_principal(&env, canister_id) + ); + assert!(!metadata(&env, canister_id).contains_key("icrc106:index_principal")); + + let index_principal = PrincipalId::new_user_test_id(1).0; + let args = encode_upgrade_args(Some(index_principal)); + let encoded_upgrade_args = Encode!(&args).unwrap(); + env.upgrade_canister(canister_id, ledger_wasm.clone(), encoded_upgrade_args) + .expect("should successfully upgrade ledger canister"); + // The index should now be set + assert_index_set(&env, canister_id, index_principal); + + let args = encode_upgrade_args(None); + let encoded_upgrade_args = Encode!(&args).unwrap(); + env.upgrade_canister(canister_id, ledger_wasm, encoded_upgrade_args) + .expect("should successfully upgrade ledger canister"); + // Passing `None` should not change the previously set index + assert_index_set(&env, canister_id, index_principal); +} + +fn assert_icrc106_supported(env: &StateMachine, canister_id: CanisterId) { + let mut found = false; + for standard in supported_standards(env, canister_id) { + if standard.name == "ICRC-106" { + found = true; + break; + } + } + assert!(found, "ICRC-106 should be supported"); +} diff --git a/rs/ledger_suite/tests/sm-tests/src/lib.rs b/rs/ledger_suite/tests/sm-tests/src/lib.rs index d010735069cc..d2792c501e21 100644 --- a/rs/ledger_suite/tests/sm-tests/src/lib.rs +++ b/rs/ledger_suite/tests/sm-tests/src/lib.rs @@ -63,6 +63,7 @@ use std::{ }; pub mod fee_collector; +pub mod icrc_106; pub mod in_memory_ledger; pub mod metrics; @@ -104,6 +105,7 @@ pub struct InitArgs { pub feature_flags: Option, pub maximum_number_of_accounts: Option, pub accounts_overflow_trim_quantity: Option, + pub index_principal: Option, } #[derive(Clone, Eq, PartialEq, Debug, CandidType)] @@ -910,6 +912,7 @@ fn init_args(initial_balances: Vec<(Account, u64)>) -> InitArgs { feature_flags: Some(FeatureFlags { icrc2: true }), maximum_number_of_accounts: None, accounts_overflow_trim_quantity: None, + index_principal: None, } } @@ -1685,6 +1688,7 @@ pub fn test_archive_controllers(ledger_wasm: Vec) { feature_flags: args.feature_flags, maximum_number_of_accounts: args.maximum_number_of_accounts, accounts_overflow_trim_quantity: args.accounts_overflow_trim_quantity, + index_principal: None, }) } @@ -1715,6 +1719,7 @@ pub fn test_archive_no_additional_controllers(ledger_wasm: Vec) { feature_flags: args.feature_flags, maximum_number_of_accounts: args.maximum_number_of_accounts, accounts_overflow_trim_quantity: args.accounts_overflow_trim_quantity, + index_principal: None, }) } @@ -1750,6 +1755,7 @@ pub fn test_archive_duplicate_controllers(ledger_wasm: Vec) { feature_flags: args.feature_flags, maximum_number_of_accounts: args.maximum_number_of_accounts, accounts_overflow_trim_quantity: args.accounts_overflow_trim_quantity, + index_principal: None, }) } let p100 = PrincipalId::new_user_test_id(100); @@ -4528,52 +4534,6 @@ where ); } -pub fn test_icrc106_standard( - ledger_wasm: Vec, - encode_init_args: fn(InitArgs) -> T, - encode_upgrade_args: fn(Option) -> U, -) where - T: CandidType, - U: CandidType, -{ - fn assert_icrc106_supported(env: &StateMachine, canister_id: CanisterId) { - let mut found = false; - for standard in supported_standards(env, canister_id) { - if standard.name == "ICRC-106" { - found = true; - break; - } - } - assert!(found, "ICRC-106 should be supported"); - } - - let (env, canister_id) = setup(ledger_wasm.clone(), encode_init_args, vec![]); - assert_icrc106_supported(&env, canister_id); - assert_eq!( - Err(Icrc106Error::IndexPrincipalNotSet), - icrc106_get_index_principal(&env, canister_id) - ); - assert!(!metadata(&env, canister_id).contains_key("icrc106:index_principal")); - - let index_principal = PrincipalId::new_user_test_id(1).0; - let args = encode_upgrade_args(Some(index_principal)); - let encoded_upgrade_args = Encode!(&args).unwrap(); - env.upgrade_canister(canister_id, ledger_wasm, encoded_upgrade_args.clone()) - .expect("should successfully upgrade ledger canister"); - - assert_icrc106_supported(&env, canister_id); - assert_eq!( - Ok(index_principal), - icrc106_get_index_principal(&env, canister_id) - ); - assert_eq!( - &Value::Text(index_principal.to_text()), - metadata(&env, canister_id) - .get("icrc106:index_principal") - .expect("should have index principal metadata") - ); -} - pub struct TransactionGenerationParameters { pub mint_multiplier: u64, pub transfer_multiplier: u64, From d59a44c6efcd40ee641b3ff0e29f59b2c84d5521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Thu, 19 Dec 2024 14:55:39 +0100 Subject: [PATCH 10/22] Fixes --- .../ledger-suite-orchestrator/src/scheduler/mod.rs | 1 + rs/ledger_suite/icrc1/tests/tests.rs | 9 --------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs b/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs index 8848c70062a6..656758134c08 100644 --- a/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs +++ b/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs @@ -934,6 +934,7 @@ fn icrc1_ledger_init_arg( feature_flags: Some(ICRC2_FEATURE), maximum_number_of_accounts: None, accounts_overflow_trim_quantity: None, + index_principal: None, } } diff --git a/rs/ledger_suite/icrc1/tests/tests.rs b/rs/ledger_suite/icrc1/tests/tests.rs index 148de80a0fc4..c03889627975 100644 --- a/rs/ledger_suite/icrc1/tests/tests.rs +++ b/rs/ledger_suite/icrc1/tests/tests.rs @@ -156,12 +156,3 @@ fn test_encoding_decoding_block_u254() { prop_assert_eq!(block, decoded); }) } - -#[test] -fn test_icrc106_standard() { - ic_ledger_suite_state_machine_tests::icrc_106::test_icrc106_set_index_in_upgrade( - ledger_wasm(), - encode_init_args, - encode_icrc106_upgrade_args, - ); -} From 509ab756087d090b8cd691ef4ffcc1794c626994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Thu, 19 Dec 2024 15:03:18 +0100 Subject: [PATCH 11/22] Clippy --- rs/ledger_suite/tests/sm-tests/src/icrc_106.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rs/ledger_suite/tests/sm-tests/src/icrc_106.rs b/rs/ledger_suite/tests/sm-tests/src/icrc_106.rs index ae0a59f096ff..f3da22908e57 100644 --- a/rs/ledger_suite/tests/sm-tests/src/icrc_106.rs +++ b/rs/ledger_suite/tests/sm-tests/src/icrc_106.rs @@ -91,14 +91,14 @@ pub fn test_icrc106_set_index_in_upgrade( ledger_canister_id: CanisterId, index_principal: Principal, ) { - assert_icrc106_supported(&env, ledger_canister_id); + assert_icrc106_supported(env, ledger_canister_id); assert_eq!( Ok(index_principal), - icrc106_get_index_principal(&env, ledger_canister_id) + icrc106_get_index_principal(env, ledger_canister_id) ); assert_eq!( &Value::Text(index_principal.to_text()), - metadata(&env, ledger_canister_id) + metadata(env, ledger_canister_id) .get("icrc106:index_principal") .expect("should have index principal metadata") ); From 3b4cc30736d9ff7f3c0cda40d84a841b2aa97c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Wed, 26 Mar 2025 13:15:02 +0100 Subject: [PATCH 12/22] Missing field --- rs/sns/governance/src/types/tests.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rs/sns/governance/src/types/tests.rs b/rs/sns/governance/src/types/tests.rs index 19a831d377f0..31fcd85602ef 100644 --- a/rs/sns/governance/src/types/tests.rs +++ b/rs/sns/governance/src/types/tests.rs @@ -1533,6 +1533,7 @@ fn test_from_manage_ledger_parameters_into_ledger_upgrade_args() { max_memo_length: None, feature_flags: None, change_archive_options: None, + index_principal: None, } ); } @@ -1559,6 +1560,7 @@ fn test_from_manage_ledger_parameters_into_ledger_upgrade_args_no_logo() { max_memo_length: None, feature_flags: None, change_archive_options: None, + index_principal: None, } ); } From 59c27ed5dde37262cc7a024c9cb8844c07c3ab2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Thu, 17 Apr 2025 09:44:27 +0200 Subject: [PATCH 13/22] Set index principal for new chain fusion ledgers --- .../ledger-suite-orchestrator/src/scheduler/mod.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs b/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs index 5eded3f2d54c..08c27fd9df28 100644 --- a/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs +++ b/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs @@ -834,6 +834,9 @@ async fn install_ledger_suite( let ledger_canister_id = create_canister_once::(&args.contract, runtime, cycles_for_ledger_creation) .await?; + let index_principal = + create_canister_once::(&args.contract, runtime, cycles_for_index_creation) + .await?; let more_controllers = read_state(|s| s.more_controller_ids().to_vec()) .into_iter() @@ -848,14 +851,12 @@ async fn install_ledger_suite( runtime.id().into(), more_controllers, cycles_for_archive_creation, + Some(index_principal), )), runtime, ) .await?; - let _index_principal = - create_canister_once::(&args.contract, runtime, cycles_for_index_creation) - .await?; let index_arg = Some(IndexArg::Init(IndexInitArg { ledger_id: ledger_canister_id, retrieve_blocks_from_ledger_interval_seconds: None, @@ -898,6 +899,7 @@ fn icrc1_ledger_init_arg( archive_controller_id: PrincipalId, archive_more_controller_ids: Vec, cycles_for_archive_creation: Nat, + index_principal: Option, ) -> LedgerInitArgs { use ic_icrc1_ledger::FeatureFlags as LedgerFeatureFlags; use icrc_ledger_types::icrc::generic_metadata_value::MetadataValue as LedgerMetadataValue; @@ -932,7 +934,7 @@ fn icrc1_ledger_init_arg( ), max_memo_length: Some(MAX_MEMO_LENGTH), feature_flags: Some(ICRC2_FEATURE), - index_principal: None, + index_principal, } } From f794544321491144367ad1a2e4d4ed4c0c412cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Thu, 17 Apr 2025 09:44:42 +0200 Subject: [PATCH 14/22] Set index principal for new SNS ledgers --- rs/ledger_suite/icrc1/ledger/src/lib.rs | 5 +++++ rs/sns/init/src/lib.rs | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/rs/ledger_suite/icrc1/ledger/src/lib.rs b/rs/ledger_suite/icrc1/ledger/src/lib.rs index 4741cbd199d0..c06d15139acf 100644 --- a/rs/ledger_suite/icrc1/ledger/src/lib.rs +++ b/rs/ledger_suite/icrc1/ledger/src/lib.rs @@ -242,6 +242,11 @@ impl InitArgsBuilder { self } + pub fn with_index_principal(mut self, index_principal: Principal) -> Self { + self.0.index_principal = Some(index_principal); + self + } + pub fn with_feature_flags(mut self, flags: FeatureFlags) -> Self { self.0.feature_flags = Some(flags); self diff --git a/rs/sns/init/src/lib.rs b/rs/sns/init/src/lib.rs index 78e0389ee855..d2d97d01ed03 100644 --- a/rs/sns/init/src/lib.rs +++ b/rs/sns/init/src/lib.rs @@ -610,7 +610,8 @@ impl SnsInitPayload { // 10 Trillion cycles cycles_for_archive_creation: Some(10_000_000_000_000), max_transactions_per_response: None, - }); + }) + .with_index_principal(Principal::from(sns_canister_ids.index)); if let Some(token_logo) = &self.token_logo { payload_builder = payload_builder.with_metadata_entry( From 56e4d71d178776ff4822ff253e5711e9efcc43a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Thu, 17 Apr 2025 13:44:54 +0200 Subject: [PATCH 15/22] Fix ledger suite orchestrator tests --- .../src/scheduler/tests.rs | 87 ++++++++++++++----- .../ledger-suite-orchestrator/tests/tests.rs | 4 + 2 files changed, 71 insertions(+), 20 deletions(-) diff --git a/rs/ethereum/ledger-suite-orchestrator/src/scheduler/tests.rs b/rs/ethereum/ledger-suite-orchestrator/src/scheduler/tests.rs index c155d2e8167d..b4a6ed769b3c 100644 --- a/rs/ethereum/ledger-suite-orchestrator/src/scheduler/tests.rs +++ b/rs/ethereum/ledger-suite-orchestrator/src/scheduler/tests.rs @@ -189,19 +189,15 @@ async fn should_not_retry_successful_operation_after_failing_one() { let mut runtime = MockCanisterRuntime::new(); runtime.expect_id().return_const(ORCHESTRATOR_PRINCIPAL); + let expected_error = CallError { + method: "create_canister".to_string(), + reason: Reason::OutOfCycles, + }; expect_create_canister_returning( &mut runtime, vec![ORCHESTRATOR_PRINCIPAL], - vec![Ok(LEDGER_PRINCIPAL)], + vec![Err(expected_error.clone())], ); - let expected_error = CallError { - method: "install_code".to_string(), - reason: Reason::OutOfCycles, - }; - runtime - .expect_install_code() - .times(1) - .return_const(Err(expected_error.clone())); let task = TaskExecution { task_type: Task::InstallLedgerSuite(usdc_install_args()), @@ -209,14 +205,12 @@ async fn should_not_retry_successful_operation_after_failing_one() { }; assert_eq!( task.execute(&runtime).await, - Err(TaskError::InstallCodeError(expected_error)) + Err(TaskError::CanisterCreationError(expected_error)) ); assert_eq!( read_state(|s| s.managed_canisters(&usdc_token_id()).cloned()), Some(Canisters { - ledger: Some(LedgerCanister::new(ManagedCanisterStatus::Created { - canister_id: LEDGER_PRINCIPAL - })), + ledger: None, index: None, archives: vec![], metadata: usdc_metadata(), @@ -229,13 +223,16 @@ async fn should_not_retry_successful_operation_after_failing_one() { method: "create_canister".to_string(), reason: Reason::OutOfCycles, }; - runtime.expect_install_code().times(1).return_const(Ok(())); expect_create_canister_returning( &mut runtime, vec![ORCHESTRATOR_PRINCIPAL], - vec![Err(expected_error.clone())], + vec![Ok(LEDGER_PRINCIPAL), Err(expected_error.clone())], ); + let task = TaskExecution { + task_type: Task::InstallLedgerSuite(usdc_install_args()), + execute_at_ns: 0, + }; assert_eq!( task.execute(&runtime).await, Err(TaskError::CanisterCreationError(expected_error)) @@ -243,9 +240,8 @@ async fn should_not_retry_successful_operation_after_failing_one() { assert_eq!( read_state(|s| s.managed_canisters(&usdc_token_id()).cloned()), Some(Canisters { - ledger: Some(LedgerCanister::new(ManagedCanisterStatus::Installed { - canister_id: LEDGER_PRINCIPAL, - installed_wasm_hash: read_ledger_wasm_hash(), + ledger: Some(LedgerCanister::new(ManagedCanisterStatus::Created { + canister_id: LEDGER_PRINCIPAL })), index: None, archives: vec![], @@ -269,6 +265,36 @@ async fn should_not_retry_successful_operation_after_failing_one() { .times(1) .return_const(Err(expected_error.clone())); + let task = TaskExecution { + task_type: Task::InstallLedgerSuite(usdc_install_args()), + execute_at_ns: 0, + }; + assert_eq!( + task.execute(&runtime).await, + Err(TaskError::InstallCodeError(expected_error)) + ); + assert_eq!( + read_state(|s| s.managed_canisters(&usdc_token_id()).cloned()), + Some(Canisters { + ledger: Some(LedgerCanister::new(ManagedCanisterStatus::Created { + canister_id: LEDGER_PRINCIPAL + })), + index: Some(IndexCanister::new(ManagedCanisterStatus::Created { + canister_id: INDEX_PRINCIPAL + })), + archives: vec![], + metadata: usdc_metadata(), + }) + ); + + runtime.checkpoint(); + runtime.expect_id().return_const(ORCHESTRATOR_PRINCIPAL); + let expected_error = CallError { + method: "install_code".to_string(), + reason: Reason::OutOfCycles, + }; + expect_install_code_returning(&mut runtime, vec![Ok(()), Err(expected_error.clone())]); + assert_eq!( task.execute(&runtime).await, Err(TaskError::InstallCodeError(expected_error)) @@ -325,7 +351,7 @@ async fn should_discard_add_erc20_task_when_ledger_wasm_not_found() { expect_create_canister_returning( &mut runtime, vec![ORCHESTRATOR_PRINCIPAL], - vec![Ok(LEDGER_PRINCIPAL)], + vec![Ok(LEDGER_PRINCIPAL), Ok(INDEX_PRINCIPAL)], ); assert_eq!( @@ -340,7 +366,9 @@ async fn should_discard_add_erc20_task_when_ledger_wasm_not_found() { ledger: Some(LedgerCanister::new(ManagedCanisterStatus::Created { canister_id: LEDGER_PRINCIPAL })), - index: None, + index: Some(IndexCanister::new(ManagedCanisterStatus::Created { + canister_id: INDEX_PRINCIPAL + })), archives: vec![], metadata: usdc_metadata(), }) @@ -1488,6 +1516,25 @@ fn expect_create_canister_returning( }); } +fn expect_install_code_returning( + runtime: &mut MockCanisterRuntime, + results: Vec>, +) { + assert!(!results.is_empty(), "must return at least one result"); + let mut install_code_call_counter = 0_usize; + runtime + .expect_install_code() + .times(results.len()) + .returning(move |_canister_id, _wasm, _args| { + if install_code_call_counter >= results.len() { + panic!("install_code called too many times!"); + } + let result = results[install_code_call_counter].clone(); + install_code_call_counter += 1; + result + }); +} + fn expect_call_canister_add_ckerc20_token( runtime: &mut MockCanisterRuntime, expected_canister_id: Principal, diff --git a/rs/ethereum/ledger-suite-orchestrator/tests/tests.rs b/rs/ethereum/ledger-suite-orchestrator/tests/tests.rs index 74c8837363cc..f57add7d5dd4 100644 --- a/rs/ethereum/ledger-suite-orchestrator/tests/tests.rs +++ b/rs/ethereum/ledger-suite-orchestrator/tests/tests.rs @@ -76,6 +76,10 @@ fn should_spawn_ledger_with_correct_init_args() { "icrc1:max_memo_length".to_string(), LedgerMetadataValue::from(80_u64), ), + ( + "icrc106:index_principal".to_string(), + LedgerMetadataValue::from("ryjl3-tyaaa-aaaaa-aaaba-cai"), + ), ]); } From 3ea51bc9a59f97eef9e4fb612241726270074643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Thu, 17 Apr 2025 17:13:11 +0200 Subject: [PATCH 16/22] Address review comments --- rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs | 6 +++--- rs/ethereum/ledger-suite-orchestrator/tests/tests.rs | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs b/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs index 08c27fd9df28..400d4e9763e5 100644 --- a/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs +++ b/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs @@ -851,7 +851,7 @@ async fn install_ledger_suite( runtime.id().into(), more_controllers, cycles_for_archive_creation, - Some(index_principal), + index_principal, )), runtime, ) @@ -899,7 +899,7 @@ fn icrc1_ledger_init_arg( archive_controller_id: PrincipalId, archive_more_controller_ids: Vec, cycles_for_archive_creation: Nat, - index_principal: Option, + index_principal: Principal, ) -> LedgerInitArgs { use ic_icrc1_ledger::FeatureFlags as LedgerFeatureFlags; use icrc_ledger_types::icrc::generic_metadata_value::MetadataValue as LedgerMetadataValue; @@ -934,7 +934,7 @@ fn icrc1_ledger_init_arg( ), max_memo_length: Some(MAX_MEMO_LENGTH), feature_flags: Some(ICRC2_FEATURE), - index_principal, + index_principal: Some(index_principal), } } diff --git a/rs/ethereum/ledger-suite-orchestrator/tests/tests.rs b/rs/ethereum/ledger-suite-orchestrator/tests/tests.rs index f57add7d5dd4..6a8029f85071 100644 --- a/rs/ethereum/ledger-suite-orchestrator/tests/tests.rs +++ b/rs/ethereum/ledger-suite-orchestrator/tests/tests.rs @@ -36,12 +36,15 @@ fn should_spawn_ledger_with_correct_init_args() { }; let orchestrator = LedgerSuiteOrchestrator::default(); - orchestrator + let managed_canisters_assert = orchestrator .add_erc20_token(AddErc20Arg { contract: usdc_erc20_contract(), ledger_init_arg: realistic_usdc_ledger_init_arg, }) - .expect_new_ledger_and_index_canisters() + .expect_new_ledger_and_index_canisters(); + let index_id = managed_canisters_assert.canister_ids.index.unwrap(); + assert_eq!(index_id, "ryjl3-tyaaa-aaaaa-aaaba-cai".parse().unwrap()); + managed_canisters_assert .assert_ledger_icrc1_fee(2_000_000_000_000_u64) .assert_ledger_icrc1_decimals(6_u8) .assert_ledger_icrc1_name("USD Coin") From 5f5fcd57932919939b23d093ffa68f1df27fd0a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 16 May 2025 10:59:32 +0200 Subject: [PATCH 17/22] Add serde_default to new index_principal field in Ledger struct --- rs/ledger_suite/icrc1/ledger/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rs/ledger_suite/icrc1/ledger/src/lib.rs b/rs/ledger_suite/icrc1/ledger/src/lib.rs index 6ad80df364e5..6ebd637323ea 100644 --- a/rs/ledger_suite/icrc1/ledger/src/lib.rs +++ b/rs/ledger_suite/icrc1/ledger/src/lib.rs @@ -601,6 +601,7 @@ pub struct Ledger { #[serde(default)] pub ledger_version: u64, + // #[serde(default)] index_principal: Option, } From f78f6fd52f94c3d0389ffadc450a3aa2f00fd619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 16 May 2025 11:04:36 +0200 Subject: [PATCH 18/22] Beautify code --- rs/ledger_suite/icrc1/ledger/src/main.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/rs/ledger_suite/icrc1/ledger/src/main.rs b/rs/ledger_suite/icrc1/ledger/src/main.rs index 6bf7e5036aa0..787b1f9c4633 100644 --- a/rs/ledger_suite/icrc1/ledger/src/main.rs +++ b/rs/ledger_suite/icrc1/ledger/src/main.rs @@ -1081,12 +1081,9 @@ fn icrc10_supported_standards() -> Vec { #[query] #[candid_method(query)] fn icrc106_get_index_principal() -> Result { - Access::with_ledger(|ledger| { - if let Some(index_principal) = ledger.index_principal() { - Ok(index_principal) - } else { - Err(Icrc106Error::IndexPrincipalNotSet) - } + Access::with_ledger(|ledger| match ledger.index_principal() { + None => Err(Icrc106Error::IndexPrincipalNotSet), + Some(index_principal) => Ok(index_principal), }) } From b3ec415bea61659c208e4a85a4887b25d729a2b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 16 May 2025 11:04:57 +0200 Subject: [PATCH 19/22] Clean up and improve tests --- rs/ledger_suite/icrc1/ledger/tests/tests.rs | 13 +- .../tests/sm-tests/src/icrc_106.rs | 169 ++++++++++++------ rs/ledger_suite/tests/sm-tests/src/lib.rs | 13 -- 3 files changed, 129 insertions(+), 66 deletions(-) diff --git a/rs/ledger_suite/icrc1/ledger/tests/tests.rs b/rs/ledger_suite/icrc1/ledger/tests/tests.rs index 98bfdc9edb61..97adf6407d20 100644 --- a/rs/ledger_suite/icrc1/ledger/tests/tests.rs +++ b/rs/ledger_suite/icrc1/ledger/tests/tests.rs @@ -549,7 +549,7 @@ fn encode_icrc106_upgrade_args(index_principal: Option) -> LedgerArgu #[test] fn test_icrc106_unsupported_if_index_not_set() { - ic_ledger_suite_state_machine_tests::icrc_106::test_icrc106_unsupported_if_index_not_set( + ic_ledger_suite_state_machine_tests::icrc_106::test_icrc106_supported_even_if_index_not_set( ledger_wasm(), encode_init_args, encode_icrc106_upgrade_args, @@ -573,6 +573,17 @@ fn test_icrc106_set_index_in_upgrade() { ); } +#[test] +fn test_upgrade_from_mainnet_ledger_version() { + ic_ledger_suite_state_machine_tests::icrc_106::test_upgrade_downgrade_with_mainnet_ledger( + ledger_mainnet_wasm(), + ledger_wasm(), + encode_init_args, + encode_upgrade_args, + encode_icrc106_upgrade_args, + ); +} + // #[test] // fn test_icrc1_test_suite() { // ic_ledger_suite_state_machine_tests::test_icrc1_test_suite(ledger_wasm(), encode_init_args); diff --git a/rs/ledger_suite/tests/sm-tests/src/icrc_106.rs b/rs/ledger_suite/tests/sm-tests/src/icrc_106.rs index f3da22908e57..9f4bbd267d42 100644 --- a/rs/ledger_suite/tests/sm-tests/src/icrc_106.rs +++ b/rs/ledger_suite/tests/sm-tests/src/icrc_106.rs @@ -1,6 +1,6 @@ use super::*; -pub fn test_icrc106_unsupported_if_index_not_set( +pub fn test_icrc106_supported_even_if_index_not_set( ledger_wasm: Vec, encode_ledger_init_args: fn(InitArgs) -> T, encode_upgrade_args: fn(Option) -> U, @@ -8,18 +8,6 @@ pub fn test_icrc106_unsupported_if_index_not_set( T: CandidType, U: CandidType, { - fn assert_index_not_set(env: &StateMachine, ledger_canister_id: CanisterId) { - assert_icrc106_supported(env, ledger_canister_id); - assert_eq!( - Err(Icrc106Error::IndexPrincipalNotSet), - icrc106_get_index_principal(env, ledger_canister_id) - ); - assert_eq!( - None, - metadata(env, ledger_canister_id).get("icrc106:index_principal") - ); - } - let env = StateMachine::new(); let ledger_canister_id = env.create_canister(None); let ledger_init_args = encode_ledger_init_args(init_args(vec![])); @@ -30,7 +18,7 @@ pub fn test_icrc106_unsupported_if_index_not_set( ) .expect("should successfully install ledger canister"); - assert_index_not_set(&env, ledger_canister_id); + assert_index_not_set(&env, ledger_canister_id, true); let args = encode_upgrade_args(None); let encoded_upgrade_args = Encode!(&args).unwrap(); @@ -41,7 +29,7 @@ pub fn test_icrc106_unsupported_if_index_not_set( ) .expect("should successfully upgrade ledger canister"); - assert_index_not_set(&env, ledger_canister_id); + assert_index_not_set(&env, ledger_canister_id, true); } pub fn test_icrc106_set_index_in_install( @@ -65,17 +53,7 @@ pub fn test_icrc106_set_index_in_install( ) .expect("should successfully install ledger canister"); - assert_icrc106_supported(&env, ledger_canister_id); - assert_eq!( - Ok(index_principal), - icrc106_get_index_principal(&env, ledger_canister_id) - ); - assert_eq!( - &Value::Text(index_principal.to_text()), - metadata(&env, ledger_canister_id) - .get("icrc106:index_principal") - .expect("should have index principal metadata") - ); + assert_index_set(&env, ledger_canister_id, index_principal); } pub fn test_icrc106_set_index_in_upgrade( @@ -86,31 +64,8 @@ pub fn test_icrc106_set_index_in_upgrade( T: CandidType, U: CandidType, { - fn assert_index_set( - env: &StateMachine, - ledger_canister_id: CanisterId, - index_principal: Principal, - ) { - assert_icrc106_supported(env, ledger_canister_id); - assert_eq!( - Ok(index_principal), - icrc106_get_index_principal(env, ledger_canister_id) - ); - assert_eq!( - &Value::Text(index_principal.to_text()), - metadata(env, ledger_canister_id) - .get("icrc106:index_principal") - .expect("should have index principal metadata") - ); - } - let (env, canister_id) = setup(ledger_wasm.clone(), encode_init_args, vec![]); - assert_icrc106_supported(&env, canister_id); - assert_eq!( - Err(Icrc106Error::IndexPrincipalNotSet), - icrc106_get_index_principal(&env, canister_id) - ); - assert!(!metadata(&env, canister_id).contains_key("icrc106:index_principal")); + assert_index_not_set(&env, canister_id, true); let index_principal = PrincipalId::new_user_test_id(1).0; let args = encode_upgrade_args(Some(index_principal)); @@ -128,7 +83,101 @@ pub fn test_icrc106_set_index_in_upgrade( assert_index_set(&env, canister_id, index_principal); } -fn assert_icrc106_supported(env: &StateMachine, canister_id: CanisterId) { +pub fn test_upgrade_downgrade_with_mainnet_ledger( + mainnet_ledger_wasm: Vec, + ledger_wasm: Vec, + encode_init_args: fn(InitArgs) -> T, + encode_empty_upgrade_args: fn() -> U, + encode_upgrade_args: fn(Option) -> U, +) where + T: CandidType, + U: CandidType, +{ + // Install the mainnet ledger canister that does not support ICRC-106 + let (env, canister_id) = setup(mainnet_ledger_wasm.clone(), encode_init_args, vec![]); + assert_index_not_set(&env, canister_id, false); + + // Upgrade to a ledger version that supports ICRC-106, but does not set the index principal + let encoded_empty_upgrade_args = Encode!(&encode_empty_upgrade_args()).unwrap(); + env.upgrade_canister( + canister_id, + ledger_wasm.clone(), + encoded_empty_upgrade_args.clone(), + ) + .expect("should successfully upgrade ledger canister"); + assert_index_not_set(&env, canister_id, true); + + // Self-upgrade to a ledger version and set the index principal + let index_principal = PrincipalId::new_user_test_id(1).0; + let args = encode_upgrade_args(Some(index_principal)); + let encoded_upgrade_args = Encode!(&args).unwrap(); + env.upgrade_canister(canister_id, ledger_wasm.clone(), encoded_upgrade_args) + .expect("should successfully upgrade ledger canister"); + assert_index_set(&env, canister_id, index_principal); + + // Self-upgrade the ledger with empty upgrade args. The index principal should stay set. + let encoded_empty_upgrade_args = Encode!(&encode_empty_upgrade_args()).unwrap(); + env.upgrade_canister( + canister_id, + ledger_wasm.clone(), + encoded_empty_upgrade_args.clone(), + ) + .expect("should successfully self-upgrade ledger canister"); + assert_index_set(&env, canister_id, index_principal); + + // Downgrade the ledger to the mainnet version that does not support ICRC-106 + env.upgrade_canister(canister_id, mainnet_ledger_wasm, encoded_empty_upgrade_args) + .expect("should successfully downgrade ledger canister"); + assert_index_not_set(&env, canister_id, false); + + // Upgrade to a ledger version that supports ICRC-106, but do not set the index principal + let encoded_empty_upgrade_args = Encode!(&encode_empty_upgrade_args()).unwrap(); + env.upgrade_canister(canister_id, ledger_wasm, encoded_empty_upgrade_args) + .expect("should successfully upgrade ledger canister"); + assert_index_not_set(&env, canister_id, true); +} + +fn assert_index_not_set( + env: &StateMachine, + ledger_canister_id: CanisterId, + expect_icrc106_supported: bool, +) { + check_icrc106_support(env, ledger_canister_id, expect_icrc106_supported); + if expect_icrc106_supported { + assert_eq!( + Err(Icrc106Error::IndexPrincipalNotSet), + icrc106_get_index_principal(env, ledger_canister_id) + ); + } + assert_eq!( + None, + metadata(env, ledger_canister_id).get("icrc106:index_principal") + ); +} + +fn assert_index_set( + env: &StateMachine, + ledger_canister_id: CanisterId, + index_principal: Principal, +) { + check_icrc106_support(env, ledger_canister_id, true); + assert_eq!( + Ok(index_principal), + icrc106_get_index_principal(env, ledger_canister_id) + ); + assert_eq!( + &Value::Text(index_principal.to_text()), + metadata(env, ledger_canister_id) + .get("icrc106:index_principal") + .expect("should have index principal metadata") + ); +} + +fn check_icrc106_support( + env: &StateMachine, + canister_id: CanisterId, + expect_icrc106_supported: bool, +) { let mut found = false; for standard in supported_standards(env, canister_id) { if standard.name == "ICRC-106" { @@ -136,5 +185,21 @@ fn assert_icrc106_supported(env: &StateMachine, canister_id: CanisterId) { break; } } - assert!(found, "ICRC-106 should be supported"); + assert_eq!( + found, expect_icrc106_supported, + "ICRC-106 should be supported" + ); +} + +fn icrc106_get_index_principal( + env: &StateMachine, + ledger: CanisterId, +) -> Result { + Decode!( + &env.query(ledger, "icrc106_get_index_principal", Encode!().unwrap()) + .expect("failed to query icrc106_get_index_principal") + .bytes(), + Result + ) + .expect("failed to decode icrc106_get_index_principal response") } diff --git a/rs/ledger_suite/tests/sm-tests/src/lib.rs b/rs/ledger_suite/tests/sm-tests/src/lib.rs index 3a5d1de76160..1b156d55b923 100644 --- a/rs/ledger_suite/tests/sm-tests/src/lib.rs +++ b/rs/ledger_suite/tests/sm-tests/src/lib.rs @@ -290,19 +290,6 @@ fn icrc21_consent_message( .expect("failed to decode icrc21_canister_call_consent_message response") } -fn icrc106_get_index_principal( - env: &StateMachine, - ledger: CanisterId, -) -> Result { - Decode!( - &env.query(ledger, "icrc106_get_index_principal", Encode!().unwrap()) - .expect("failed to query icrc106_get_index_principal") - .bytes(), - Result - ) - .expect("failed to decode icrc106_get_index_principal response") -} - pub fn get_all_ledger_and_archive_blocks( state_machine: &StateMachine, ledger_id: CanisterId, From a981f60acac0b238f5d0acf1fa6d5b1f3ad264de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Wed, 21 May 2025 12:00:50 +0200 Subject: [PATCH 20/22] Uncomment annotation --- rs/ledger_suite/icrc1/ledger/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/ledger_suite/icrc1/ledger/src/lib.rs b/rs/ledger_suite/icrc1/ledger/src/lib.rs index 23fe84c12b83..f24f1554fe99 100644 --- a/rs/ledger_suite/icrc1/ledger/src/lib.rs +++ b/rs/ledger_suite/icrc1/ledger/src/lib.rs @@ -609,7 +609,7 @@ pub struct Ledger { #[serde(default)] pub ledger_version: u64, - // #[serde(default)] + #[serde(default)] index_principal: Option, } From 58460e921482a31abb22ccaf1b46b9afa20d6e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 6 Jun 2025 06:20:02 +0200 Subject: [PATCH 21/22] Added SNS governance unreleased_changelog.md entry --- rs/sns/governance/unreleased_changelog.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rs/sns/governance/unreleased_changelog.md b/rs/sns/governance/unreleased_changelog.md index 94126a0ff421..805c60d55680 100644 --- a/rs/sns/governance/unreleased_changelog.md +++ b/rs/sns/governance/unreleased_changelog.md @@ -4,11 +4,16 @@ In general, upcoming/unreleased behavior changes are described here. For details on the process that this file is part of, see `rs/nervous_system/changelog_process.md`. - # Next Upgrade Proposal ## Added +### Set the principal of the index canister when installing the ledger ([ICRC-106](https://github.com/dfinity/ICRC-1/pull/196/files/7f9b4739d9b3ec2cf549bf468e3a1731c31eecbf)) + +When installing the ledger canister for a new SNS, the index canister's principal is now set in the ledger. +This allows a ledger client to query the ledger using the `icrc106_get_index_principal` endpoint to figure out where the +ledger index canister is running. + ## Changed ## Deprecated From 413b9c6f2af19bcef49c6379a34bb0befbc97d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 6 Jun 2025 08:47:12 +0200 Subject: [PATCH 22/22] Bump ICRC ledger size limit --- publish/canisters/BUILD.bazel | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/publish/canisters/BUILD.bazel b/publish/canisters/BUILD.bazel index 767d97231642..e1bf0313e417 100644 --- a/publish/canisters/BUILD.bazel +++ b/publish/canisters/BUILD.bazel @@ -65,10 +65,11 @@ DEFAULT_CANISTERS_MAX_SIZE_E5_BYTES = 21 CANISTERS_MAX_SIZE_COMPRESSED_E5_BYTES = { # -- FI team -- - # The compressed version of these two canisters should be ~600kb, - # we are setting the check to 7 to leave some space for growth + # The compressed version of these two canisters should be ~700kb, + # we are setting the check to 8 to leave some space for growth # but enough to get an alert in case of a spike in size. - "ic-icrc1-ledger.wasm.gz": 7, + # The size is currently at 701737 bytes. + "ic-icrc1-ledger.wasm.gz": 8, # The size is currently at 704585 bytes. "ic-icrc1-ledger-u256.wasm.gz": 8, # Size when constraint addded: 841_234 bytes