From d70076ad88de14e92e85e1e7d2646f67cac2ad1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 30 Aug 2024 14:03:24 +0200 Subject: [PATCH 01/11] Initial attempt at adding transactions --- rs/rosetta-api/icrc1/BUILD.bazel | 3 + .../ledger/sm-tests/src/in_memory_ledger.rs | 151 +++++++------ .../icrc1/ledger/sm-tests/src/lib.rs | 26 ++- .../tests/golden_state_upgrade_downgrade.rs | 213 +++++++++++++++++- 4 files changed, 305 insertions(+), 88 deletions(-) diff --git a/rs/rosetta-api/icrc1/BUILD.bazel b/rs/rosetta-api/icrc1/BUILD.bazel index be0d9a9a63c..c54f02c36f3 100644 --- a/rs/rosetta-api/icrc1/BUILD.bazel +++ b/rs/rosetta-api/icrc1/BUILD.bazel @@ -134,9 +134,12 @@ rust_test( "//packages/icrc-ledger-types:icrc_ledger_types", "//rs/nns/test_utils", "//rs/nns/test_utils/golden_nns_state", + "//rs/rosetta-api/ledger_core", "//rs/rosetta-api/icrc1/ledger", "//rs/rosetta-api/icrc1/ledger/sm-tests:sm-tests" + name_suffix, "//rs/rosetta-api/icrc1/test_utils", + "//rs/rosetta-api/icrc1/tokens_u256", + "//rs/rosetta-api/icrc1/tokens_u64", "//rs/rust_canisters/canister_test", "//rs/state_machine_tests", "//rs/test_utilities/load_wasm", diff --git a/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs b/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs index f5a31cda716..5d65e4d58c1 100644 --- a/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs +++ b/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs @@ -29,7 +29,7 @@ impl From for (Account, Account) { } } -trait InMemoryLedgerState { +pub trait InMemoryLedgerState { type AccountId; type Tokens; @@ -319,30 +319,29 @@ where } impl InMemoryLedger { - fn new_from_icrc1_ledger_blocks( - blocks: &[ic_icrc1::Block], - ) -> InMemoryLedger { - let mut state = InMemoryLedger::default(); + pub fn new() -> Self { + InMemoryLedger::default() + } + + pub fn ingest_icrc1_ledger_blocks(&mut self, blocks: &[ic_icrc1::Block]) { for block in blocks { if let Some(fee_collector) = block.fee_collector { - state.fee_collector = Some(fee_collector); + self.fee_collector = Some(fee_collector); } match &block.transaction.operation { - Operation::Mint { to, amount } => state.process_mint(to, amount), + Operation::Mint { to, amount } => self.process_mint(to, amount), Operation::Transfer { from, to, spender, amount, fee, - } => { - state.process_transfer(from, to, spender, amount, &fee.or(block.effective_fee)) - } + } => self.process_transfer(from, to, spender, amount, &fee.or(block.effective_fee)), Operation::Burn { from, spender, amount, - } => state.process_burn(from, spender, amount), + } => self.process_burn(from, spender, amount), Operation::Approve { from, spender, @@ -350,7 +349,7 @@ impl InMemoryLedger { expected_allowance, expires_at, fee, - } => state.process_approve( + } => self.process_approve( from, spender, amount, @@ -360,12 +359,72 @@ impl InMemoryLedger { TimeStamp::from_nanos_since_unix_epoch(block.timestamp), ), } - state.validate_invariants(); + self.validate_invariants(); } - state.prune_expired_allowances(TimeStamp::from_nanos_since_unix_epoch( + self.prune_expired_allowances(TimeStamp::from_nanos_since_unix_epoch( blocks.last().unwrap().timestamp, )); - state + } + + pub fn verify_balances_and_allowances(&self, env: &StateMachine, ledger_id: CanisterId) { + let actual_num_approvals = parse_metric(env, ledger_id, "ledger_num_approvals"); + let actual_num_balances = parse_metric(env, ledger_id, "ledger_balance_store_entries"); + assert_eq!( + self.balances.len() as u64, + actual_num_balances, + "Mismatch in number of balances ({} vs {})", + self.balances.len(), + actual_num_balances + ); + assert_eq!( + self.allowances.len() as u64, + actual_num_approvals, + "Mismatch in number of approvals ({} vs {})", + self.allowances.len(), + actual_num_approvals + ); + println!( + "Checking {} balances and {} allowances", + actual_num_balances, actual_num_approvals + ); + for (account, balance) in self.balances.iter() { + let actual_balance = Decode!( + &env.query(ledger_id, "icrc1_balance_of", Encode!(account).unwrap()) + .expect("failed to query balance") + .bytes(), + Nat + ) + .expect("failed to decode balance_of response"); + + assert_eq!( + &Tokens::try_from(actual_balance.clone()).unwrap(), + balance, + "Mismatch in balance for account {:?} ({} vs {})", + account, + balance, + actual_balance + ); + } + for (approval, allowance) in self.allowances.iter() { + let (from, spender): (Account, Account) = approval.clone().into(); + assert!( + !allowance.amount.is_zero(), + "Expected allowance is zero! Should not happen... from: {:?}, spender: {:?}", + &from, + &spender + ); + let actual_allowance = get_allowance(env, ledger_id, from, spender); + assert_eq!( + allowance.amount, + Tokens::try_from(actual_allowance.allowance.clone()).unwrap(), + "Mismatch in allowance for approval from {:?} spender {:?}: {:?} ({:?} vs {:?})", + &from, + &spender, + approval, + allowance, + actual_allowance + ); + } } } @@ -373,65 +432,9 @@ pub fn verify_ledger_state(env: &StateMachine, ledger_id: CanisterId) { println!("verifying state of ledger {}", ledger_id); let blocks = get_all_ledger_and_archive_blocks(env, ledger_id); println!("retrieved all ledger and archive blocks"); - let expected_ledger_state = InMemoryLedger::new_from_icrc1_ledger_blocks(&blocks); + let mut expected_ledger_state = InMemoryLedger::new(); + expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); println!("recreated expected ledger state"); - let actual_num_approvals = parse_metric(env, ledger_id, "ledger_num_approvals"); - let actual_num_balances = parse_metric(env, ledger_id, "ledger_balance_store_entries"); - assert_eq!( - expected_ledger_state.balances.len() as u64, - actual_num_balances, - "Mismatch in number of balances ({} vs {})", - expected_ledger_state.balances.len(), - actual_num_balances - ); - assert_eq!( - expected_ledger_state.allowances.len() as u64, - actual_num_approvals, - "Mismatch in number of approvals ({} vs {})", - expected_ledger_state.allowances.len(), - actual_num_approvals - ); - println!( - "Checking {} balances and {} allowances", - actual_num_balances, actual_num_approvals - ); - for (account, balance) in expected_ledger_state.balances.iter() { - let actual_balance = Decode!( - &env.query(ledger_id, "icrc1_balance_of", Encode!(account).unwrap()) - .expect("failed to query balance") - .bytes(), - Nat - ) - .expect("failed to decode balance_of response"); - - assert_eq!( - &Tokens::try_from(actual_balance.clone()).unwrap(), - balance, - "Mismatch in balance for account {:?} ({} vs {})", - account, - balance, - actual_balance - ); - } - for (approval, allowance) in expected_ledger_state.allowances.iter() { - let (from, spender): (Account, Account) = approval.clone().into(); - assert!( - !allowance.amount.is_zero(), - "Expected allowance is zero! Should not happen... from: {:?}, spender: {:?}", - &from, - &spender - ); - let actual_allowance = get_allowance(env, ledger_id, from, spender); - assert_eq!( - allowance.amount, - Tokens::try_from(actual_allowance.allowance.clone()).unwrap(), - "Mismatch in allowance for approval from {:?} spender {:?}: {:?} ({:?} vs {:?})", - &from, - &spender, - approval, - allowance, - actual_allowance - ); - } + expected_ledger_state.verify_balances_and_allowances(env, ledger_id); println!("ledger state verified successfully"); } diff --git a/rs/rosetta-api/icrc1/ledger/sm-tests/src/lib.rs b/rs/rosetta-api/icrc1/ledger/sm-tests/src/lib.rs index e06707441ee..6bb17b31e7f 100644 --- a/rs/rosetta-api/icrc1/ledger/sm-tests/src/lib.rs +++ b/rs/rosetta-api/icrc1/ledger/sm-tests/src/lib.rs @@ -205,7 +205,7 @@ fn model_transfer( ((from_balance, to_balance), None) } -fn send_transfer( +pub fn send_transfer( env: &StateMachine, ledger: CanisterId, from: Principal, @@ -534,6 +534,19 @@ pub fn balance_of(env: &StateMachine, ledger: CanisterId, acc: impl Into u64 { + Decode!( + &env.query(ledger, "icrc1_fee", Encode!().unwrap()) + .expect("failed to query fee") + .bytes(), + Nat + ) + .expect("failed to decode icrc1_fee response") + .0 + .to_u64() + .unwrap() +} + pub fn metadata(env: &StateMachine, ledger: CanisterId) -> BTreeMap { Decode!( &env.query(ledger, "icrc1_metadata", Encode!().unwrap()) @@ -1943,16 +1956,7 @@ where .expect("failed to decode balance_of response"); assert_eq!(token_name_after_upgrade, OTHER_TOKEN_NAME); - let token_fee_after_upgrade: u64 = Decode!( - &env.query(canister_id, "icrc1_fee", Encode!().unwrap()) - .expect("failed to query fee") - .bytes(), - Nat - ) - .expect("failed to decode balance_of response") - .0 - .to_u64() - .unwrap(); + let token_fee_after_upgrade = fee(&env, canister_id); assert_eq!(token_fee_after_upgrade, NEW_FEE); } diff --git a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs index 446e5e45240..f298a91a021 100644 --- a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs +++ b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs @@ -1,13 +1,36 @@ use crate::common::ledger_wasm; -use candid::Encode; +use candid::{Encode, Nat}; use canister_test::Wasm; use ic_base_types::{CanisterId, PrincipalId}; +use ic_icrc1_ledger_sm_tests::in_memory_ledger::{ + ApprovalKey, InMemoryLedger, InMemoryLedgerState, +}; +use ic_icrc1_ledger_sm_tests::{get_all_ledger_and_archive_blocks, send_transfer}; +use ic_ledger_core::approvals::Allowance; +use ic_ledger_core::timestamp::TimeStamp; use ic_nns_test_utils::governance::bump_gzip_timestamp; use ic_state_machine_tests::StateMachine; +use icrc_ledger_types::icrc1::account::Account; +use icrc_ledger_types::icrc1::transfer::{Memo, TransferArg}; +use icrc_ledger_types::icrc2::approve::ApproveArgs; +use icrc_ledger_types::icrc2::transfer_from::TransferFromArgs; use std::str::FromStr; +use std::time::UNIX_EPOCH; mod common; +const NUM_TRANSACTIONS_PER_TYPE: usize = 1; +const MINT_AMOUNT: u64 = 100_000_000; +const TRANSFER_AMOUNT: u64 = 10_000_000; +const APPROVE_AMOUNT: u64 = 1_000_000; +const TRANSFER_FROM_AMOUNT: u64 = 100_000; + +#[cfg(not(feature = "u256-tokens"))] +type Tokens = ic_icrc1_tokens_u64::U64; + +#[cfg(feature = "u256-tokens")] +type Tokens = ic_icrc1_tokens_u256::U256; + #[cfg(not(feature = "u256-tokens"))] #[test] fn should_upgrade_icrc_ck_btc_canister_with_golden_state() { @@ -149,8 +172,20 @@ fn should_upgrade_icrc_sns_canisters_with_golden_state() { for (canister_id_str, canister_name) in canister_id_and_names { let canister_id = CanisterId::unchecked_from_principal(PrincipalId::from_str(canister_id_str).unwrap()); - // TODO: Uncomment once mainnet ledgers have been upgraded to include `ledger_num_approvals` metric - // ic_icrc1_ledger_sm_tests::in_memory_ledger::verify_ledger_state(&state_machine, canister_id, None); + let blocks = get_all_ledger_and_archive_blocks(&state_machine, canister_id); + println!("retrieved all ledger and archive blocks"); + let mut initial_expected_ledger_state = + ic_icrc1_ledger_sm_tests::in_memory_ledger::InMemoryLedger::new(); + initial_expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); + ic_icrc1_ledger_sm_tests::in_memory_ledger::verify_ledger_state( + &state_machine, + canister_id, + ); + generate_transactions( + &state_machine, + canister_id, + &mut initial_expected_ledger_state, + ); upgrade_canister( &state_machine, (canister_id_str, canister_name), @@ -172,6 +207,178 @@ fn should_upgrade_icrc_sns_canisters_with_golden_state() { (canister_id_str, canister_name), mainnet_ledger_wasm.clone(), ); + assert_eq!(1, 64); + } +} + +fn generate_transactions( + state_machine: &StateMachine, + canister_id: CanisterId, + in_memory_ledger: &mut InMemoryLedger, +) { + let minter_account = ic_icrc1_ledger_sm_tests::minting_account(&state_machine, canister_id) + .unwrap_or_else(|| panic!("minter account should be set for {:?}", canister_id)); + let fee = Tokens::from(ic_icrc1_ledger_sm_tests::fee(&state_machine, canister_id)); + let mut accounts = vec![]; + for i in 0..NUM_TRANSACTIONS_PER_TYPE { + let subaccount = match i { + 0 => None, + _ => Some([i as u8; 32]), + }; + accounts.push(Account { + owner: PrincipalId::new_user_test_id(i as u64).0, + subaccount, + }); + } + // Mint + let mut minted = 0usize; + for to in &accounts { + send_transfer( + &state_machine, + canister_id, + minter_account.owner, + &TransferArg { + from_subaccount: minter_account.subaccount, + to: to.copy(), + fee: Some(Nat::from(fee)), + created_at_time: Some( + state_machine + .time() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_millis() as u64, + ), + memo: Some(Memo::from(minted as u64)), + amount: Nat::from(MINT_AMOUNT), + }, + ) + .expect("should be able to mint"); + in_memory_ledger.process_mint(&to, &Tokens::from(MINT_AMOUNT)); + minted += 1; + if minted >= NUM_TRANSACTIONS_PER_TYPE { + break; + } + } + // Transfer + for i in 0..NUM_TRANSACTIONS_PER_TYPE { + let from = accounts[i]; + let to = accounts[(i + 1) % NUM_TRANSACTIONS_PER_TYPE]; + ic_icrc1_ledger_sm_tests::send_transfer( + &state_machine, + canister_id, + from.owner, + &TransferArg { + from_subaccount: from.subaccount, + to, + fee: Some(Nat::from(fee)), + created_at_time: Some( + state_machine + .time() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_millis() as u64, + ), + memo: Some(Memo::from(i as u64)), + amount: Nat::from(TRANSFER_AMOUNT), + }, + ) + .expect("should be able to transfer"); + in_memory_ledger.process_transfer( + &from, + &to, + &None, + &Tokens::from(TRANSFER_AMOUNT), + &Some(fee), + ); + } + // Approve + for i in 0..NUM_TRANSACTIONS_PER_TYPE { + let from = accounts[i]; + let spender = accounts[(i + 1) % NUM_TRANSACTIONS_PER_TYPE]; + let approval_key = ApprovalKey::from((&from, &spender)); + let default_allowance = Allowance::default(); + let current_allowance = in_memory_ledger + .allowances + .get(&approval_key) + .unwrap_or(&default_allowance); + let expires_at = state_machine + .time() + .checked_add(std::time::Duration::from_secs(3600)) + .unwrap() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_millis() as u64; + ic_icrc1_ledger_sm_tests::send_approval( + &state_machine, + canister_id, + from.owner, + &ApproveArgs { + from_subaccount: from.subaccount, + spender, + amount: Nat::from(APPROVE_AMOUNT), + expected_allowance: Some(Nat::from(current_allowance.amount)), + expires_at: Some(expires_at), + fee: Some(Nat::from(fee)), + memo: Some(Memo::from(i as u64)), + created_at_time: Some( + state_machine + .time() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_millis() as u64, + ), + }, + ) + .expect("should be able to transfer"); + in_memory_ledger.process_approve( + &from, + &spender, + &Tokens::from(APPROVE_AMOUNT), + &Some(current_allowance.amount), + &Some(expires_at), + &Some(fee), + TimeStamp::from_nanos_since_unix_epoch( + state_machine + .time() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos() as u64, + ), + ); + } + // Transfer From + for i in 0..NUM_TRANSACTIONS_PER_TYPE { + let from = accounts[i]; + let spender = accounts[(i + 1) % NUM_TRANSACTIONS_PER_TYPE]; + let to = accounts[(i + 2) % NUM_TRANSACTIONS_PER_TYPE]; + ic_icrc1_ledger_sm_tests::send_transfer_from( + &state_machine, + canister_id, + spender.owner, + &TransferFromArgs { + spender_subaccount: spender.subaccount, + from, + to, + amount: Nat::from(TRANSFER_FROM_AMOUNT), + fee: Some(Nat::from(fee)), + memo: Some(Memo::from(i as u64)), + created_at_time: Some( + state_machine + .time() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_millis() as u64, + ), + }, + ) + .expect("should be able to transfer from"); + in_memory_ledger.process_transfer( + &from, + &to, + &Some(spender), + &Tokens::from(TRANSFER_FROM_AMOUNT), + &Some(fee), + ); } } From 1b5b2a35ba6caf1e44c28f2868b809111f4bb7ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 6 Sep 2024 11:45:42 +0200 Subject: [PATCH 02/11] Printing out elapsed time, adjusting number of tx generated --- .../ledger/sm-tests/src/in_memory_ledger.rs | 33 +++++-- .../tests/golden_state_upgrade_downgrade.rs | 94 +++++++++++++++---- 2 files changed, 104 insertions(+), 23 deletions(-) diff --git a/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs b/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs index 5d65e4d58c1..e141ee425c6 100644 --- a/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs +++ b/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs @@ -10,6 +10,7 @@ use ic_state_machine_tests::StateMachine; use icrc_ledger_types::icrc1::account::Account; use std::collections::HashMap; use std::hash::Hash; +use std::time::Instant; #[cfg(test)] mod tests; @@ -240,12 +241,16 @@ where ) { let key = K::from((from, spender)); if let Some(expected_allowance) = expected_allowance { - let current_allowance = self + let current_allowance_amount = self .allowances .get(&key) - .unwrap_or_else(|| panic!("No current allowance but expected allowance set")); - if current_allowance.amount != *expected_allowance { - panic!("Expected allowance does not match current allowance"); + .map(|allowance| allowance.amount.clone()) + .unwrap_or(Tokens::zero()); + if current_allowance_amount != *expected_allowance { + panic!( + "Expected allowance ({:?}) does not match current allowance ({:?})", + expected_allowance, current_allowance_amount + ); } } if amount == &Tokens::zero() { @@ -324,6 +329,7 @@ impl InMemoryLedger { } pub fn ingest_icrc1_ledger_blocks(&mut self, blocks: &[ic_icrc1::Block]) { + let start = Instant::now(); for block in blocks { if let Some(fee_collector) = block.fee_collector { self.fee_collector = Some(fee_collector); @@ -364,6 +370,11 @@ impl InMemoryLedger { self.prune_expired_allowances(TimeStamp::from_nanos_since_unix_epoch( blocks.last().unwrap().timestamp, )); + println!( + "initialized InMemoryLedger with {} blocks in {:?}", + blocks.len(), + start.elapsed() + ); } pub fn verify_balances_and_allowances(&self, env: &StateMachine, ledger_id: CanisterId) { @@ -429,12 +440,20 @@ impl InMemoryLedger { } pub fn verify_ledger_state(env: &StateMachine, ledger_id: CanisterId) { + let start = Instant::now(); println!("verifying state of ledger {}", ledger_id); let blocks = get_all_ledger_and_archive_blocks(env, ledger_id); - println!("retrieved all ledger and archive blocks"); + println!( + "retrieved all ledger and archive blocks in {:?}", + start.elapsed() + ); let mut expected_ledger_state = InMemoryLedger::new(); expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); - println!("recreated expected ledger state"); + println!("recreated expected ledger state in {:?}", start.elapsed()); + let start = Instant::now(); expected_ledger_state.verify_balances_and_allowances(env, ledger_id); - println!("ledger state verified successfully"); + println!( + "ledger state verified successfully in {:?}", + start.elapsed() + ); } diff --git a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs index f298a91a021..dda762867e1 100644 --- a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs +++ b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs @@ -15,15 +15,16 @@ use icrc_ledger_types::icrc1::transfer::{Memo, TransferArg}; use icrc_ledger_types::icrc2::approve::ApproveArgs; use icrc_ledger_types::icrc2::transfer_from::TransferFromArgs; use std::str::FromStr; -use std::time::UNIX_EPOCH; +use std::time::{Instant, UNIX_EPOCH}; mod common; -const NUM_TRANSACTIONS_PER_TYPE: usize = 1; -const MINT_AMOUNT: u64 = 100_000_000; -const TRANSFER_AMOUNT: u64 = 10_000_000; -const APPROVE_AMOUNT: u64 = 1_000_000; -const TRANSFER_FROM_AMOUNT: u64 = 100_000; +const NUM_TRANSACTIONS_PER_TYPE: usize = 20; +const MINT_AMOUNT: u64 = 1_000_000_000; +const TRANSFER_AMOUNT: u64 = 100_000_000; +const APPROVE_AMOUNT: u64 = 10_000_000; +const TRANSFER_FROM_AMOUNT: u64 = 1_000_000; +const BURN_AMOUNT: u64 = 100_000; #[cfg(not(feature = "u256-tokens"))] type Tokens = ic_icrc1_tokens_u64::U64; @@ -172,8 +173,12 @@ fn should_upgrade_icrc_sns_canisters_with_golden_state() { for (canister_id_str, canister_name) in canister_id_and_names { let canister_id = CanisterId::unchecked_from_principal(PrincipalId::from_str(canister_id_str).unwrap()); + let start = Instant::now(); let blocks = get_all_ledger_and_archive_blocks(&state_machine, canister_id); - println!("retrieved all ledger and archive blocks"); + println!( + "retrieved all ledger and archive blocks in {:?}", + start.elapsed() + ); let mut initial_expected_ledger_state = ic_icrc1_ledger_sm_tests::in_memory_ledger::InMemoryLedger::new(); initial_expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); @@ -197,6 +202,11 @@ fn should_upgrade_icrc_sns_canisters_with_golden_state() { (canister_id_str, canister_name), bump_gzip_timestamp(&ledger_wasm), ); + generate_transactions( + &state_machine, + canister_id, + &mut initial_expected_ledger_state, + ); ic_icrc1_ledger_sm_tests::in_memory_ledger::verify_ledger_state( &state_machine, canister_id, @@ -207,7 +217,11 @@ fn should_upgrade_icrc_sns_canisters_with_golden_state() { (canister_id_str, canister_name), mainnet_ledger_wasm.clone(), ); - assert_eq!(1, 64); + generate_transactions( + &state_machine, + canister_id, + &mut initial_expected_ledger_state, + ); } } @@ -216,6 +230,7 @@ fn generate_transactions( canister_id: CanisterId, in_memory_ledger: &mut InMemoryLedger, ) { + let start = Instant::now(); let minter_account = ic_icrc1_ledger_sm_tests::minting_account(&state_machine, canister_id) .unwrap_or_else(|| panic!("minter account should be set for {:?}", canister_id)); let fee = Tokens::from(ic_icrc1_ledger_sm_tests::fee(&state_machine, canister_id)); @@ -232,6 +247,7 @@ fn generate_transactions( } // Mint let mut minted = 0usize; + println!("minting"); for to in &accounts { send_transfer( &state_machine, @@ -239,14 +255,14 @@ fn generate_transactions( minter_account.owner, &TransferArg { from_subaccount: minter_account.subaccount, - to: to.copy(), - fee: Some(Nat::from(fee)), + to: *to, + fee: None, created_at_time: Some( state_machine .time() .duration_since(UNIX_EPOCH) .unwrap() - .as_millis() as u64, + .as_nanos() as u64, ), memo: Some(Memo::from(minted as u64)), amount: Nat::from(MINT_AMOUNT), @@ -260,6 +276,7 @@ fn generate_transactions( } } // Transfer + println!("transferring"); for i in 0..NUM_TRANSACTIONS_PER_TYPE { let from = accounts[i]; let to = accounts[(i + 1) % NUM_TRANSACTIONS_PER_TYPE]; @@ -276,7 +293,7 @@ fn generate_transactions( .time() .duration_since(UNIX_EPOCH) .unwrap() - .as_millis() as u64, + .as_nanos() as u64, ), memo: Some(Memo::from(i as u64)), amount: Nat::from(TRANSFER_AMOUNT), @@ -292,6 +309,7 @@ fn generate_transactions( ); } // Approve + println!("approving"); for i in 0..NUM_TRANSACTIONS_PER_TYPE { let from = accounts[i]; let spender = accounts[(i + 1) % NUM_TRANSACTIONS_PER_TYPE]; @@ -307,7 +325,7 @@ fn generate_transactions( .unwrap() .duration_since(UNIX_EPOCH) .unwrap() - .as_millis() as u64; + .as_nanos() as u64; ic_icrc1_ledger_sm_tests::send_approval( &state_machine, canister_id, @@ -325,7 +343,7 @@ fn generate_transactions( .time() .duration_since(UNIX_EPOCH) .unwrap() - .as_millis() as u64, + .as_nanos() as u64, ), }, ) @@ -347,6 +365,7 @@ fn generate_transactions( ); } // Transfer From + println!("transferring from"); for i in 0..NUM_TRANSACTIONS_PER_TYPE { let from = accounts[i]; let spender = accounts[(i + 1) % NUM_TRANSACTIONS_PER_TYPE]; @@ -367,7 +386,7 @@ fn generate_transactions( .time() .duration_since(UNIX_EPOCH) .unwrap() - .as_millis() as u64, + .as_nanos() as u64, ), }, ) @@ -380,6 +399,43 @@ fn generate_transactions( &Some(fee), ); } + // Burn + println!("burning"); + for i in 0..NUM_TRANSACTIONS_PER_TYPE { + let from = accounts[i]; + send_transfer( + &state_machine, + canister_id, + from.owner, + &TransferArg { + from_subaccount: from.subaccount, + to: minter_account, + fee: None, + created_at_time: Some( + state_machine + .time() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos() as u64, + ), + memo: Some(Memo::from(i as u64)), + amount: Nat::from(BURN_AMOUNT), + }, + ) + .expect("should be able to transfer"); + in_memory_ledger.process_transfer( + &from, + &minter_account, + &None, + &Tokens::from(BURN_AMOUNT), + &None, + ); + } + println!( + "generated {} transactions in {:?}", + NUM_TRANSACTIONS_PER_TYPE * 5, + start.elapsed() + ); } fn upgrade_canister( @@ -387,10 +443,16 @@ fn upgrade_canister( (canister_id_str, canister_name): (&str, &str), ledger_wasm: Wasm, ) { + let start = Instant::now(); let canister_id = CanisterId::unchecked_from_principal(PrincipalId::from_str(canister_id_str).unwrap()); upgrade_ledger(state_machine, ledger_wasm, canister_id); - println!("Upgraded {} '{}'", canister_name, canister_id_str); + println!( + "Upgraded {} '{}' in {:?}", + canister_name, + canister_id_str, + start.elapsed() + ); } fn upgrade_ledger(state_machine: &StateMachine, wasm: Wasm, canister_id: CanisterId) { From ca03d20391082e6b201f43aa389c73b4585c4f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 6 Sep 2024 14:03:18 +0200 Subject: [PATCH 03/11] Merge conflicts and amount multipliers --- .../ledger/sm-tests/src/in_memory_ledger.rs | 62 ++++++---- .../tests/golden_state_upgrade_downgrade.rs | 106 +++++++++++++----- 2 files changed, 116 insertions(+), 52 deletions(-) diff --git a/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs b/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs index 26cedeac249..0cfa35d4430 100644 --- a/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs +++ b/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs @@ -31,10 +31,16 @@ impl From for (Account, Account) { } } -trait InMemoryLedgerState { +pub trait InMemoryLedgerState { type AccountId; type Tokens; + fn get_allowance_if_set( + &self, + from: &Self::AccountId, + spender: &Self::AccountId, + ) -> Option>; + fn process_approve( &mut self, from: &Self::AccountId, @@ -85,6 +91,15 @@ where type AccountId = AccountId; type Tokens = Tokens; + fn get_allowance_if_set( + &self, + from: &Self::AccountId, + spender: &Self::AccountId, + ) -> Option> { + let key = K::from((from, spender)); + self.allowances.get(&key).map(|allowance| allowance.clone()) + } + fn process_approve( &mut self, from: &Self::AccountId, @@ -257,12 +272,16 @@ where ) { let key = K::from((from, spender)); if let Some(expected_allowance) = expected_allowance { - let current_allowance = self + let current_allowance_amount = self .allowances .get(&key) - .unwrap_or_else(|| panic!("No current allowance but expected allowance set")); - if current_allowance.amount != *expected_allowance { - panic!("Expected allowance does not match current allowance"); + .map(|allowance| allowance.amount.clone()) + .unwrap_or(Tokens::zero()); + if current_allowance_amount != *expected_allowance { + panic!( + "Expected allowance ({:?}) does not match current allowance ({:?})", + expected_allowance, current_allowance_amount + ); } } if amount == &Tokens::zero() { @@ -336,34 +355,32 @@ where } impl InMemoryLedger { - fn new_from_icrc1_ledger_blocks( - blocks: &[ic_icrc1::Block], - burns_without_spender: Option>, - ) -> InMemoryLedger { - let mut state = InMemoryLedger { + pub fn new(burns_without_spender: Option>) -> Self { + InMemoryLedger { burns_without_spender, ..Default::default() - }; + } + } + + pub fn ingest_icrc1_ledger_blocks(&mut self, blocks: &[ic_icrc1::Block]) { for (index, block) in blocks.iter().enumerate() { if let Some(fee_collector) = block.fee_collector { - state.fee_collector = Some(fee_collector); + self.fee_collector = Some(fee_collector); } match &block.transaction.operation { - Operation::Mint { to, amount } => state.process_mint(to, amount), + Operation::Mint { to, amount } => self.process_mint(to, amount), Operation::Transfer { from, to, spender, amount, fee, - } => { - state.process_transfer(from, to, spender, amount, &fee.or(block.effective_fee)) - } + } => self.process_transfer(from, to, spender, amount, &fee.or(block.effective_fee)), Operation::Burn { from, spender, amount, - } => state.process_burn(from, spender, amount, index), + } => self.process_burn(from, spender, amount, index), Operation::Approve { from, spender, @@ -371,7 +388,7 @@ impl InMemoryLedger { expected_allowance, expires_at, fee, - } => state.process_approve( + } => self.process_approve( from, spender, amount, @@ -381,12 +398,11 @@ impl InMemoryLedger { TimeStamp::from_nanos_since_unix_epoch(block.timestamp), ), } - state.validate_invariants(); + self.validate_invariants(); } - state.prune_expired_allowances(TimeStamp::from_nanos_since_unix_epoch( + self.prune_expired_allowances(TimeStamp::from_nanos_since_unix_epoch( blocks.last().unwrap().timestamp, )); - state } pub fn apply_arg_with_caller( @@ -522,8 +538,8 @@ pub fn verify_ledger_state( println!("verifying state of ledger {}", ledger_id); let blocks = get_all_ledger_and_archive_blocks(env, ledger_id); println!("retrieved all ledger and archive blocks"); - let expected_ledger_state = - InMemoryLedger::new_from_icrc1_ledger_blocks(&blocks, burns_without_spender); + let mut expected_ledger_state = InMemoryLedger::new(burns_without_spender); + expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); println!("recreated expected ledger state"); expected_ledger_state.verify_balances_and_allowances(env, ledger_id); println!("ledger state verified successfully"); diff --git a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs index e5e726c7a68..3652da6e734 100644 --- a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs +++ b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs @@ -2,7 +2,9 @@ use crate::common::{ledger_wasm, load_wasm_using_env_var}; use candid::{Encode, Nat}; use canister_test::Wasm; use ic_base_types::{CanisterId, PrincipalId}; -use ic_icrc1_ledger_sm_tests::in_memory_ledger::{verify_ledger_state, ApprovalKey, InMemoryLedger, InMemoryLedgerState,}; +use ic_icrc1_ledger_sm_tests::in_memory_ledger::{ + verify_ledger_state, ApprovalKey, InMemoryLedger, InMemoryLedgerState, +}; use ic_icrc1_ledger_sm_tests::{get_all_ledger_and_archive_blocks, send_transfer}; use ic_ledger_core::approvals::Allowance; use ic_ledger_core::timestamp::TimeStamp; @@ -18,11 +20,11 @@ use std::time::{Instant, UNIX_EPOCH}; mod common; const NUM_TRANSACTIONS_PER_TYPE: usize = 20; -const MINT_AMOUNT: u64 = 1_000_000_000; -const TRANSFER_AMOUNT: u64 = 100_000_000; -const APPROVE_AMOUNT: u64 = 10_000_000; -const TRANSFER_FROM_AMOUNT: u64 = 1_000_000; -const BURN_AMOUNT: u64 = 100_000; +const MINT_MULTIPLIER: u64 = 10_000; +const TRANSFER_MULTIPLIER: u64 = 1000; +const APPROVE_MULTIPLIER: u64 = 100; +const TRANSFER_FROM_MULTIPLIER: u64 = 10; +const BURN_MULTIPLIER: u64 = 1; #[cfg(not(feature = "u256-tokens"))] type Tokens = ic_icrc1_tokens_u64::U64; @@ -77,6 +79,11 @@ fn should_upgrade_icrc_ck_btc_canister_with_golden_state() { (CK_BTC_LEDGER_CANISTER_ID, CK_BTC_LEDGER_CANISTER_NAME), bump_gzip_timestamp(&ledger_wasm), ); + let blocks = get_all_ledger_and_archive_blocks(&state_machine, canister_id); + let mut expected_ledger_state = + ic_icrc1_ledger_sm_tests::in_memory_ledger::InMemoryLedger::new(None); + expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); + generate_transactions(&state_machine, canister_id, &mut expected_ledger_state); verify_ledger_state(&state_machine, canister_id, Some(burns_without_spender)); // Downgrade back to the mainnet ledger version upgrade_canister( @@ -151,6 +158,11 @@ fn should_upgrade_icrc_ck_u256_canisters_with_golden_state() { (canister_id_str, canister_name), bump_gzip_timestamp(&ledger_wasm_u256), ); + let blocks = get_all_ledger_and_archive_blocks(&state_machine, canister_id); + let mut expected_ledger_state = + ic_icrc1_ledger_sm_tests::in_memory_ledger::InMemoryLedger::new(None); + expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); + generate_transactions(&state_machine, canister_id, &mut expected_ledger_state); // Downgrade back to the mainnet ledger version upgrade_canister( &state_machine, @@ -232,8 +244,12 @@ fn should_upgrade_icrc_sns_canisters_with_golden_state() { for (canister_id_str, canister_name) in canister_id_and_names { let canister_id = CanisterId::unchecked_from_principal(PrincipalId::from_str(canister_id_str).unwrap()); - // TODO: Uncomment once mainnet ledgers have been upgraded to include `ledger_num_approvals` metric - // verify_ledger_state(&state_machine, canister_id, None); + // TODO: Verify the ledger state here already once mainnet ledgers have been upgraded to include `ledger_num_approvals` metric + let blocks = get_all_ledger_and_archive_blocks(&state_machine, canister_id); + let mut expected_ledger_state = + ic_icrc1_ledger_sm_tests::in_memory_ledger::InMemoryLedger::new(None); + expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); + generate_transactions(&state_machine, canister_id, &mut expected_ledger_state); upgrade_canister( &state_machine, (canister_id_str, canister_name), @@ -245,6 +261,11 @@ fn should_upgrade_icrc_sns_canisters_with_golden_state() { (canister_id_str, canister_name), bump_gzip_timestamp(&ledger_wasm), ); + let blocks = get_all_ledger_and_archive_blocks(&state_machine, canister_id); + let mut expected_ledger_state = + ic_icrc1_ledger_sm_tests::in_memory_ledger::InMemoryLedger::new(None); + expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); + generate_transactions(&state_machine, canister_id, &mut expected_ledger_state); verify_ledger_state(&state_machine, canister_id, None); // Downgrade back to the mainnet ledger version upgrade_canister( @@ -263,7 +284,37 @@ fn generate_transactions( let start = Instant::now(); let minter_account = ic_icrc1_ledger_sm_tests::minting_account(&state_machine, canister_id) .unwrap_or_else(|| panic!("minter account should be set for {:?}", canister_id)); - let fee = Tokens::from(ic_icrc1_ledger_sm_tests::fee(&state_machine, canister_id)); + let u64_fee = ic_icrc1_ledger_sm_tests::fee(&state_machine, canister_id); + let fee = Tokens::from(u64_fee); + let burn_amount = Tokens::from( + u64_fee + .checked_mul(BURN_MULTIPLIER) + .unwrap_or_else(|| panic!("burn amount overflowed for canister {:?}", canister_id)), + ); + let transfer_amount = + Tokens::from(u64_fee.checked_mul(TRANSFER_MULTIPLIER).unwrap_or_else(|| { + panic!("transfer amount overflowed for canister {:?}", canister_id) + })); + let mint_amount = Tokens::from( + u64_fee + .checked_mul(MINT_MULTIPLIER) + .unwrap_or_else(|| panic!("mint amount overflowed for canister {:?}", canister_id)), + ); + let transfer_from_amount = Tokens::from( + u64_fee + .checked_mul(TRANSFER_FROM_MULTIPLIER) + .unwrap_or_else(|| { + panic!( + "transfer_from amount overflowed for canister {:?}", + canister_id + ) + }), + ); + let approve_amount = Tokens::from( + u64_fee + .checked_mul(APPROVE_MULTIPLIER) + .unwrap_or_else(|| panic!("approve amount overflowed for canister {:?}", canister_id)), + ); let mut accounts = vec![]; for i in 0..NUM_TRANSACTIONS_PER_TYPE { let subaccount = match i { @@ -295,11 +346,11 @@ fn generate_transactions( .as_nanos() as u64, ), memo: Some(Memo::from(minted as u64)), - amount: Nat::from(MINT_AMOUNT), + amount: Nat::from(mint_amount), }, ) - .expect("should be able to mint"); - in_memory_ledger.process_mint(&to, &Tokens::from(MINT_AMOUNT)); + .expect("should be able to mint"); + in_memory_ledger.process_mint(&to, &Tokens::from(mint_amount)); minted += 1; if minted >= NUM_TRANSACTIONS_PER_TYPE { break; @@ -326,15 +377,15 @@ fn generate_transactions( .as_nanos() as u64, ), memo: Some(Memo::from(i as u64)), - amount: Nat::from(TRANSFER_AMOUNT), + amount: Nat::from(transfer_amount), }, ) - .expect("should be able to transfer"); + .expect("should be able to transfer"); in_memory_ledger.process_transfer( &from, &to, &None, - &Tokens::from(TRANSFER_AMOUNT), + &Tokens::from(transfer_amount), &Some(fee), ); } @@ -343,12 +394,9 @@ fn generate_transactions( for i in 0..NUM_TRANSACTIONS_PER_TYPE { let from = accounts[i]; let spender = accounts[(i + 1) % NUM_TRANSACTIONS_PER_TYPE]; - let approval_key = ApprovalKey::from((&from, &spender)); - let default_allowance = Allowance::default(); let current_allowance = in_memory_ledger - .allowances - .get(&approval_key) - .unwrap_or(&default_allowance); + .get_allowance_if_set(&from, &spender) + .unwrap_or(Allowance::default()); let expires_at = state_machine .time() .checked_add(std::time::Duration::from_secs(3600)) @@ -363,7 +411,7 @@ fn generate_transactions( &ApproveArgs { from_subaccount: from.subaccount, spender, - amount: Nat::from(APPROVE_AMOUNT), + amount: Nat::from(approve_amount), expected_allowance: Some(Nat::from(current_allowance.amount)), expires_at: Some(expires_at), fee: Some(Nat::from(fee)), @@ -377,11 +425,11 @@ fn generate_transactions( ), }, ) - .expect("should be able to transfer"); + .expect("should be able to transfer"); in_memory_ledger.process_approve( &from, &spender, - &Tokens::from(APPROVE_AMOUNT), + &Tokens::from(approve_amount), &Some(current_allowance.amount), &Some(expires_at), &Some(fee), @@ -408,7 +456,7 @@ fn generate_transactions( spender_subaccount: spender.subaccount, from, to, - amount: Nat::from(TRANSFER_FROM_AMOUNT), + amount: Nat::from(transfer_from_amount), fee: Some(Nat::from(fee)), memo: Some(Memo::from(i as u64)), created_at_time: Some( @@ -420,12 +468,12 @@ fn generate_transactions( ), }, ) - .expect("should be able to transfer from"); + .expect("should be able to transfer from"); in_memory_ledger.process_transfer( &from, &to, &Some(spender), - &Tokens::from(TRANSFER_FROM_AMOUNT), + &Tokens::from(transfer_from_amount), &Some(fee), ); } @@ -449,15 +497,15 @@ fn generate_transactions( .as_nanos() as u64, ), memo: Some(Memo::from(i as u64)), - amount: Nat::from(BURN_AMOUNT), + amount: Nat::from(burn_amount), }, ) - .expect("should be able to transfer"); + .expect("should be able to transfer"); in_memory_ledger.process_transfer( &from, &minter_account, &None, - &Tokens::from(BURN_AMOUNT), + &Tokens::from(burn_amount), &None, ); } From 0374c1e0e956f86c7f2b183ca6e982ee04449b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 13 Sep 2024 14:39:36 +0200 Subject: [PATCH 04/11] Bump the timeout in the instructions --- rs/rosetta-api/icrc1/BUILD.bazel | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/rs/rosetta-api/icrc1/BUILD.bazel b/rs/rosetta-api/icrc1/BUILD.bazel index 6c6e3851ea6..58b374d9fa1 100644 --- a/rs/rosetta-api/icrc1/BUILD.bazel +++ b/rs/rosetta-api/icrc1/BUILD.bazel @@ -85,15 +85,17 @@ rust_test( # bazel \ # test \ # --test_env=SSH_AUTH_SOCK \ + # --test_timeout=43200 \ # //rs/rosetta-api/icrc1:icrc_ledger_suite_integration_golden_state_upgrade_downgrade_test # # To run the U256 token version of the test (for ckETH and ckERC20 tokens), use: # # //rs/rosetta-api/icrc1:icrc_ledger_suite_integration_golden_state_upgrade_downgrade_test_u256 # - # The only unusual thing in this command is `--test_env=SSH_AUTH_SOCK`. That causes the - # SSH_AUTH_SOCK environment variable to be "forwarded" from your shell to the sandbox where the test - # is run. This authorizes the test to download the test data. + # The unusual things in this command are: + # - `--test_env=SSH_AUTH_SOCK`: This causes the SSH_AUTH_SOCK environment variable to be "forwarded" from + # your shell to the sandbox where the test is run. This authorizes the test to download the test data. + # - `--test_timeout=43200`: This sets the test timeout to 12 hours (more than currently required). # # Additionally, the following flags are recommended (but not required): # From c882d69fcabc9529011f7fd0d03fddcbf35d0f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 13 Sep 2024 18:06:08 +0200 Subject: [PATCH 05/11] Buildifier --- rs/rosetta-api/icrc1/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/rosetta-api/icrc1/BUILD.bazel b/rs/rosetta-api/icrc1/BUILD.bazel index 58b374d9fa1..6de700a770b 100644 --- a/rs/rosetta-api/icrc1/BUILD.bazel +++ b/rs/rosetta-api/icrc1/BUILD.bazel @@ -140,12 +140,12 @@ rust_test( "//packages/icrc-ledger-types:icrc_ledger_types", "//rs/nns/test_utils", "//rs/nns/test_utils/golden_nns_state", - "//rs/rosetta-api/ledger_core", "//rs/rosetta-api/icrc1/ledger", "//rs/rosetta-api/icrc1/ledger/sm-tests:sm-tests" + name_suffix, "//rs/rosetta-api/icrc1/test_utils", "//rs/rosetta-api/icrc1/tokens_u256", "//rs/rosetta-api/icrc1/tokens_u64", + "//rs/rosetta-api/ledger_core", "//rs/rust_canisters/canister_test", "//rs/state_machine_tests", "//rs/test_utilities/load_wasm", From 49eed4989255fd84d58b55461b2493e1a0359c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 13 Sep 2024 18:46:53 +0200 Subject: [PATCH 06/11] Clippy --- rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs b/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs index 0cfa35d4430..5759dde7e9d 100644 --- a/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs +++ b/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs @@ -97,7 +97,7 @@ where spender: &Self::AccountId, ) -> Option> { let key = K::from((from, spender)); - self.allowances.get(&key).map(|allowance| allowance.clone()) + self.allowances.get(&key).cloned() } fn process_approve( From 2812d45d3f12f5691957dac8f4afcca855ef450f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 13 Sep 2024 19:09:30 +0200 Subject: [PATCH 07/11] More clippy --- .../tests/golden_state_upgrade_downgrade.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs index e8131498084..ca108576c66 100644 --- a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs +++ b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs @@ -308,9 +308,9 @@ fn generate_transactions( in_memory_ledger: &mut InMemoryLedger, ) { let start = Instant::now(); - let minter_account = ic_icrc1_ledger_sm_tests::minting_account(&state_machine, canister_id) + let minter_account = ic_icrc1_ledger_sm_tests::minting_account(state_machine, canister_id) .unwrap_or_else(|| panic!("minter account should be set for {:?}", canister_id)); - let u64_fee = ic_icrc1_ledger_sm_tests::fee(&state_machine, canister_id); + let u64_fee = ic_icrc1_ledger_sm_tests::fee(state_machine, canister_id); let fee = Tokens::from(u64_fee); let burn_amount = Tokens::from( u64_fee @@ -357,7 +357,7 @@ fn generate_transactions( println!("minting"); for to in &accounts { send_transfer( - &state_machine, + state_machine, canister_id, minter_account.owner, &TransferArg { @@ -376,7 +376,7 @@ fn generate_transactions( }, ) .expect("should be able to mint"); - in_memory_ledger.process_mint(&to, &Tokens::from(mint_amount)); + in_memory_ledger.process_mint(to, &Tokens::from(mint_amount)); minted += 1; if minted >= NUM_TRANSACTIONS_PER_TYPE { break; @@ -431,7 +431,7 @@ fn generate_transactions( .unwrap() .as_nanos() as u64; ic_icrc1_ledger_sm_tests::send_approval( - &state_machine, + state_machine, canister_id, from.owner, &ApproveArgs { @@ -475,7 +475,7 @@ fn generate_transactions( let spender = accounts[(i + 1) % NUM_TRANSACTIONS_PER_TYPE]; let to = accounts[(i + 2) % NUM_TRANSACTIONS_PER_TYPE]; ic_icrc1_ledger_sm_tests::send_transfer_from( - &state_machine, + state_machine, canister_id, spender.owner, &TransferFromArgs { @@ -505,10 +505,9 @@ fn generate_transactions( } // Burn println!("burning"); - for i in 0..NUM_TRANSACTIONS_PER_TYPE { - let from = accounts[i]; + for (i, from) in accounts.iter().enumerate().take(NUM_TRANSACTIONS_PER_TYPE) { send_transfer( - &state_machine, + state_machine, canister_id, from.owner, &TransferArg { From 9b9ce5354c477d15de33323430dfaa5ff04bfa2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 13 Sep 2024 19:20:02 +0200 Subject: [PATCH 08/11] Clippy revisited --- .../icrc1/tests/golden_state_upgrade_downgrade.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs index ca108576c66..a6599144088 100644 --- a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs +++ b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs @@ -5,7 +5,9 @@ use ic_base_types::{CanisterId, PrincipalId}; use ic_icrc1_ledger_sm_tests::in_memory_ledger::{ verify_ledger_state, ApprovalKey, InMemoryLedger, InMemoryLedgerState, }; -use ic_icrc1_ledger_sm_tests::{get_all_ledger_and_archive_blocks, send_transfer}; +use ic_icrc1_ledger_sm_tests::{ + get_all_ledger_and_archive_blocks, send_approval, send_transfer, send_transfer_from, +}; use ic_ledger_core::approvals::Allowance; use ic_ledger_core::timestamp::TimeStamp; use ic_nns_test_utils::governance::bump_gzip_timestamp; @@ -387,8 +389,8 @@ fn generate_transactions( for i in 0..NUM_TRANSACTIONS_PER_TYPE { let from = accounts[i]; let to = accounts[(i + 1) % NUM_TRANSACTIONS_PER_TYPE]; - ic_icrc1_ledger_sm_tests::send_transfer( - &state_machine, + send_transfer( + state_machine, canister_id, from.owner, &TransferArg { @@ -430,7 +432,7 @@ fn generate_transactions( .duration_since(UNIX_EPOCH) .unwrap() .as_nanos() as u64; - ic_icrc1_ledger_sm_tests::send_approval( + send_approval( state_machine, canister_id, from.owner, @@ -474,7 +476,7 @@ fn generate_transactions( let from = accounts[i]; let spender = accounts[(i + 1) % NUM_TRANSACTIONS_PER_TYPE]; let to = accounts[(i + 2) % NUM_TRANSACTIONS_PER_TYPE]; - ic_icrc1_ledger_sm_tests::send_transfer_from( + send_transfer_from( state_machine, canister_id, spender.owner, @@ -527,7 +529,7 @@ fn generate_transactions( ) .expect("should be able to transfer"); in_memory_ledger.process_transfer( - &from, + from, &minter_account, &None, &Tokens::from(burn_amount), From 07baa209027646d1053786e5a713e39cf2d4c738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Wed, 18 Sep 2024 15:23:52 +0200 Subject: [PATCH 09/11] Refactoring; only run extensive tests for a subset of ledgers --- .../tests/golden_state_upgrade_downgrade.rs | 310 +++++++++--------- 1 file changed, 160 insertions(+), 150 deletions(-) diff --git a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs index a6599144088..5d1623196e7 100644 --- a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs +++ b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs @@ -3,7 +3,7 @@ use candid::{Encode, Nat}; use canister_test::Wasm; use ic_base_types::{CanisterId, PrincipalId}; use ic_icrc1_ledger_sm_tests::in_memory_ledger::{ - verify_ledger_state, ApprovalKey, InMemoryLedger, InMemoryLedgerState, + verify_ledger_state, ApprovalKey, BurnsWithoutSpender, InMemoryLedger, InMemoryLedgerState, }; use ic_icrc1_ledger_sm_tests::{ get_all_ledger_and_archive_blocks, send_approval, send_transfer, send_transfer_from, @@ -34,6 +34,40 @@ type Tokens = ic_icrc1_tokens_u64::U64; #[cfg(feature = "u256-tokens")] type Tokens = ic_icrc1_tokens_u256::U256; +struct CanisterConfig { + canister_id: &'static str, + canister_name: &'static str, + burns_without_spender: Option>, + extended_testing: bool, +} + +impl CanisterConfig { + #[cfg(feature = "u256-tokens")] + fn new(canister_id_and_name: (&'static str, &'static str)) -> Self { + let (canister_id, canister_name) = canister_id_and_name; + Self { + canister_id, + canister_name, + burns_without_spender: None, + extended_testing: false, + } + } + + fn new_with_params( + canister_id_and_name: (&'static str, &'static str), + burns_without_spender: Option>, + extended_testing: bool, + ) -> Self { + let (canister_id, canister_name) = canister_id_and_name; + Self { + canister_id, + canister_name, + burns_without_spender, + extended_testing, + } + } +} + #[cfg(not(feature = "u256-tokens"))] #[test] fn should_upgrade_icrc_ck_btc_canister_with_golden_state() { @@ -62,35 +96,14 @@ fn should_upgrade_icrc_ck_btc_canister_with_golden_state() { ], }; - let canister_id = CanisterId::unchecked_from_principal( - PrincipalId::from_str(CK_BTC_LEDGER_CANISTER_ID).unwrap(), - ); - verify_ledger_state( + perform_upgrade_downgrade_testing( &state_machine, - canister_id, - Some(burns_without_spender.clone()), - ); - upgrade_canister( - &state_machine, - (CK_BTC_LEDGER_CANISTER_ID, CK_BTC_LEDGER_CANISTER_NAME), - ledger_wasm.clone(), - ); - // Upgrade again with bumped wasm timestamp to test pre_upgrade - upgrade_canister( - &state_machine, - (CK_BTC_LEDGER_CANISTER_ID, CK_BTC_LEDGER_CANISTER_NAME), - bump_gzip_timestamp(&ledger_wasm), - ); - let blocks = get_all_ledger_and_archive_blocks(&state_machine, canister_id); - let mut expected_ledger_state = - ic_icrc1_ledger_sm_tests::in_memory_ledger::InMemoryLedger::new(None); - expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); - generate_transactions(&state_machine, canister_id, &mut expected_ledger_state); - verify_ledger_state(&state_machine, canister_id, Some(burns_without_spender)); - // Downgrade back to the mainnet ledger version - upgrade_canister( - &state_machine, - (CK_BTC_LEDGER_CANISTER_ID, CK_BTC_LEDGER_CANISTER_NAME), + vec![CanisterConfig::new_with_params( + (CK_BTC_LEDGER_CANISTER_ID, CK_BTC_LEDGER_CANISTER_NAME), + Some(burns_without_spender), + true, + )], + ledger_wasm, mainnet_ledger_wasm, ); } @@ -125,73 +138,45 @@ fn should_upgrade_icrc_ck_u256_canisters_with_golden_state() { .0, subaccount: None, }; - let ck_eth_burns_without_spender = - ic_icrc1_ledger_sm_tests::in_memory_ledger::BurnsWithoutSpender { - minter: ck_eth_minter, - burn_indexes: vec![ - 1051, 1094, 1276, 1759, 1803, 1929, 2449, 2574, 2218, 2219, 2231, 1777, 4, 9, 31, - 1540, 1576, 1579, 1595, 1607, 1617, 1626, 1752, 1869, 1894, 2013, 2555, - ], - }; + let ck_eth_burns_without_spender = BurnsWithoutSpender { + minter: ck_eth_minter, + burn_indexes: vec![ + 1051, 1094, 1276, 1759, 1803, 1929, 2449, 2574, 2218, 2219, 2231, 1777, 4, 9, 31, 1540, + 1576, 1579, 1595, 1607, 1617, 1626, 1752, 1869, 1894, 2013, 2555, + ], + }; let ledger_wasm_u256 = Wasm::from_bytes(ledger_wasm()); - let canister_ids_names_and_burns_without_spender = vec![ - (CK_SEPOLIA_LINK_LEDGER, None), - (CK_SEPOLIA_PEPE_LEDGER, None), - (CK_SEPOLIA_USDC_LEDGER, None), - (CK_ETH_LEDGER, Some(ck_eth_burns_without_spender)), - (CK_EURC_LEDGER, None), - (CK_USDC_LEDGER, None), - (CK_LINK_LEDGER, None), - (CK_OCT_LEDGER, None), - (CK_PEPE_LEDGER, None), - (CK_SHIB_LEDGER, None), - (CK_UNI_LEDGER, None), - (CK_USDT_LEDGER, None), - (CK_WBTC_LEDGER, None), - (CK_WSTETH_LEDGER, None), - (CK_XAUT_LEDGER, None), + let canister_configs = vec![ + CanisterConfig::new_with_params(CK_ETH_LEDGER, Some(ck_eth_burns_without_spender), true), + CanisterConfig::new(CK_SEPOLIA_LINK_LEDGER), + CanisterConfig::new(CK_SEPOLIA_LINK_LEDGER), + CanisterConfig::new(CK_SEPOLIA_PEPE_LEDGER), + CanisterConfig::new(CK_SEPOLIA_USDC_LEDGER), + CanisterConfig::new(CK_EURC_LEDGER), + CanisterConfig::new(CK_USDC_LEDGER), + CanisterConfig::new(CK_LINK_LEDGER), + CanisterConfig::new(CK_OCT_LEDGER), + CanisterConfig::new(CK_PEPE_LEDGER), + CanisterConfig::new(CK_SHIB_LEDGER), + CanisterConfig::new(CK_UNI_LEDGER), + CanisterConfig::new(CK_USDT_LEDGER), + CanisterConfig::new(CK_WBTC_LEDGER), + CanisterConfig::new(CK_WSTETH_LEDGER), + CanisterConfig::new(CK_XAUT_LEDGER), ]; let state_machine = ic_nns_test_utils_golden_nns_state::new_state_machine_with_golden_fiduciary_state_or_panic( ); - for ((canister_id_str, canister_name), burns_without_spender) in - canister_ids_names_and_burns_without_spender - { - println!( - "Processing {} ledger, id {}", - canister_id_str, canister_name - ); - let canister_id = - CanisterId::unchecked_from_principal(PrincipalId::from_str(canister_id_str).unwrap()); - verify_ledger_state(&state_machine, canister_id, burns_without_spender.clone()); - upgrade_canister( - &state_machine, - (canister_id_str, canister_name), - ledger_wasm_u256.clone(), - ); - // Upgrade again with bumped wasm timestamp to test pre_upgrade - upgrade_canister( - &state_machine, - (canister_id_str, canister_name), - bump_gzip_timestamp(&ledger_wasm_u256), - ); - let blocks = get_all_ledger_and_archive_blocks(&state_machine, canister_id); - let mut expected_ledger_state = - ic_icrc1_ledger_sm_tests::in_memory_ledger::InMemoryLedger::new(None); - expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); - generate_transactions(&state_machine, canister_id, &mut expected_ledger_state); - // Downgrade back to the mainnet ledger version - upgrade_canister( - &state_machine, - (canister_id_str, canister_name), - mainnet_ledger_wasm_u256.clone(), - ); - verify_ledger_state(&state_machine, canister_id, burns_without_spender); - } + perform_upgrade_downgrade_testing( + &state_machine, + canister_configs, + ledger_wasm_u256, + mainnet_ledger_wasm_u256, + ); } #[cfg(feature = "u256-tokens")] @@ -234,74 +219,47 @@ fn should_upgrade_icrc_sns_canisters_with_golden_state() { "IC_ICRC1_LEDGER_DEPLOYED_VERSION_WASM_PATH", )); - let canister_id_and_names = vec![ - BOOMDAO, - CATALYZE, - CYCLES_TRANSFER_STATION, - DECIDEAI, - DOGMI, - DRAGGINZ, - ELNAAI, - ESTATEDAO, - GOLDDAO, - ICGHOST, - ICLIGHTHOUSE, - ICPANDA, - ICPCC, - ICPSWAP, - ICVC, - KINIC, - MOTOKO, - NEUTRINITE, - NUANCE, - OPENCHAT, - OPENFPL, - ORIGYN, - SEERS, - SNEED, - SONIC, - TRAX, - WATERNEURON, - YRAL, - YUKU, + let canister_configs = vec![ + CanisterConfig::new_with_params(OPENCHAT, None, true), + CanisterConfig::new(BOOMDAO), + CanisterConfig::new(CATALYZE), + CanisterConfig::new(CYCLES_TRANSFER_STATION), + CanisterConfig::new(DECIDEAI), + CanisterConfig::new(DOGMI), + CanisterConfig::new(DRAGGINZ), + CanisterConfig::new(ELNAAI), + CanisterConfig::new(ESTATEDAO), + CanisterConfig::new(GOLDDAO), + CanisterConfig::new(ICGHOST), + CanisterConfig::new(ICLIGHTHOUSE), + CanisterConfig::new(ICPANDA), + CanisterConfig::new(ICPCC), + CanisterConfig::new(ICPSWAP), + CanisterConfig::new(ICVC), + CanisterConfig::new(KINIC), + CanisterConfig::new(MOTOKO), + CanisterConfig::new(NEUTRINITE), + CanisterConfig::new(NUANCE), + CanisterConfig::new(OPENFPL), + CanisterConfig::new(ORIGYN), + CanisterConfig::new(SEERS), + CanisterConfig::new(SNEED), + CanisterConfig::new(SONIC), + CanisterConfig::new(TRAX), + CanisterConfig::new(WATERNEURON), + CanisterConfig::new(YRAL), + CanisterConfig::new(YUKU), ]; let state_machine = ic_nns_test_utils_golden_nns_state::new_state_machine_with_golden_sns_state_or_panic(); - for (canister_id_str, canister_name) in canister_id_and_names { - let canister_id = - CanisterId::unchecked_from_principal(PrincipalId::from_str(canister_id_str).unwrap()); - // TODO: Verify the ledger state here already once mainnet ledgers have been upgraded to include `ledger_num_approvals` metric - let blocks = get_all_ledger_and_archive_blocks(&state_machine, canister_id); - let mut expected_ledger_state = - ic_icrc1_ledger_sm_tests::in_memory_ledger::InMemoryLedger::new(None); - expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); - generate_transactions(&state_machine, canister_id, &mut expected_ledger_state); - upgrade_canister( - &state_machine, - (canister_id_str, canister_name), - ledger_wasm.clone(), - ); - // Upgrade again with bumped wasm timestamp to test pre_upgrade - upgrade_canister( - &state_machine, - (canister_id_str, canister_name), - bump_gzip_timestamp(&ledger_wasm), - ); - let blocks = get_all_ledger_and_archive_blocks(&state_machine, canister_id); - let mut expected_ledger_state = - ic_icrc1_ledger_sm_tests::in_memory_ledger::InMemoryLedger::new(None); - expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); - generate_transactions(&state_machine, canister_id, &mut expected_ledger_state); - verify_ledger_state(&state_machine, canister_id, None); - // Downgrade back to the mainnet ledger version - upgrade_canister( - &state_machine, - (canister_id_str, canister_name), - mainnet_ledger_wasm.clone(), - ); - } + perform_upgrade_downgrade_testing( + &state_machine, + canister_configs, + ledger_wasm, + mainnet_ledger_wasm, + ); } fn generate_transactions( @@ -543,6 +501,58 @@ fn generate_transactions( ); } +fn perform_upgrade_downgrade_testing( + state_machine: &StateMachine, + canister_configs: Vec, + master_canister_wasm: Wasm, + mainnet_canister_wasm: Wasm, +) { + for canister_config in canister_configs { + let CanisterConfig { + canister_id: canister_id_str, + canister_name, + burns_without_spender, + extended_testing, + } = canister_config; + println!( + "Processing {} ledger, id {}", + canister_id_str, canister_name + ); + let canister_id = + CanisterId::unchecked_from_principal(PrincipalId::from_str(canister_id_str).unwrap()); + if extended_testing { + verify_ledger_state(&state_machine, canister_id, burns_without_spender.clone()); + } + upgrade_canister( + &state_machine, + (canister_id_str, canister_name), + master_canister_wasm.clone(), + ); + // Upgrade again with bumped wasm timestamp to test pre_upgrade + upgrade_canister( + &state_machine, + (canister_id_str, canister_name), + bump_gzip_timestamp(&master_canister_wasm), + ); + if extended_testing { + let blocks = get_all_ledger_and_archive_blocks(&state_machine, canister_id); + let mut expected_ledger_state = + ic_icrc1_ledger_sm_tests::in_memory_ledger::InMemoryLedger::new(None); + expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); + generate_transactions(&state_machine, canister_id, &mut expected_ledger_state); + } + // Downgrade back to the mainnet ledger version + upgrade_canister( + &state_machine, + (canister_id_str, canister_name), + mainnet_canister_wasm.clone(), + ); + if extended_testing { + verify_ledger_state(&state_machine, canister_id, burns_without_spender); + } + } +} + fn upgrade_canister( state_machine: &StateMachine, (canister_id_str, canister_name): (&str, &str), From f4b0cb0e50042bfbe420974524dbfb70ab6c07c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 20 Sep 2024 08:46:23 +0200 Subject: [PATCH 10/11] Rename --- rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs | 4 ++-- rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs b/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs index 5759dde7e9d..71eb30ad6e0 100644 --- a/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs +++ b/rs/rosetta-api/icrc1/ledger/sm-tests/src/in_memory_ledger.rs @@ -35,7 +35,7 @@ pub trait InMemoryLedgerState { type AccountId; type Tokens; - fn get_allowance_if_set( + fn get_allowance( &self, from: &Self::AccountId, spender: &Self::AccountId, @@ -91,7 +91,7 @@ where type AccountId = AccountId; type Tokens = Tokens; - fn get_allowance_if_set( + fn get_allowance( &self, from: &Self::AccountId, spender: &Self::AccountId, diff --git a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs index 5d1623196e7..70cc321a303 100644 --- a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs +++ b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs @@ -381,7 +381,7 @@ fn generate_transactions( let from = accounts[i]; let spender = accounts[(i + 1) % NUM_TRANSACTIONS_PER_TYPE]; let current_allowance = in_memory_ledger - .get_allowance_if_set(&from, &spender) + .get_allowance(&from, &spender) .unwrap_or(Allowance::default()); let expires_at = state_machine .time() From e913a2237fa3b5976cec080a7f30a6d2ed25de45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 20 Sep 2024 09:26:19 +0200 Subject: [PATCH 11/11] Clippy --- .../icrc1/tests/golden_state_upgrade_downgrade.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs index 70cc321a303..78bdd577b1e 100644 --- a/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs +++ b/rs/rosetta-api/icrc1/tests/golden_state_upgrade_downgrade.rs @@ -521,34 +521,34 @@ fn perform_upgrade_downgrade_testing( let canister_id = CanisterId::unchecked_from_principal(PrincipalId::from_str(canister_id_str).unwrap()); if extended_testing { - verify_ledger_state(&state_machine, canister_id, burns_without_spender.clone()); + verify_ledger_state(state_machine, canister_id, burns_without_spender.clone()); } upgrade_canister( - &state_machine, + state_machine, (canister_id_str, canister_name), master_canister_wasm.clone(), ); // Upgrade again with bumped wasm timestamp to test pre_upgrade upgrade_canister( - &state_machine, + state_machine, (canister_id_str, canister_name), bump_gzip_timestamp(&master_canister_wasm), ); if extended_testing { - let blocks = get_all_ledger_and_archive_blocks(&state_machine, canister_id); + let blocks = get_all_ledger_and_archive_blocks(state_machine, canister_id); let mut expected_ledger_state = ic_icrc1_ledger_sm_tests::in_memory_ledger::InMemoryLedger::new(None); expected_ledger_state.ingest_icrc1_ledger_blocks(&blocks); - generate_transactions(&state_machine, canister_id, &mut expected_ledger_state); + generate_transactions(state_machine, canister_id, &mut expected_ledger_state); } // Downgrade back to the mainnet ledger version upgrade_canister( - &state_machine, + state_machine, (canister_id_str, canister_name), mainnet_canister_wasm.clone(), ); if extended_testing { - verify_ledger_state(&state_machine, canister_id, burns_without_spender); + verify_ledger_state(state_machine, canister_id, burns_without_spender); } } }