Skip to content

Commit e5e0d13

Browse files
authored
test(ICRC_Index): DEFI-2527: index-ng u256 token testing (#7788)
Not all `index-ng` tests were also being run with `u256` tokens - in particular, the integration tests under `tests/`, with the bazel target `name = "index_ng_test" + conf["test_suffix"],`, were only using the `u256` feature for one config, and not e.g., for the `"get_blocks_disabled"` and `"icrc3_disabled"` features. This PR proposes to add the `u256-tokens` feature flag where it was missing, and also proposes to add a test that explicitly verifies that `Tokens::MAX` returns the expected value, and verifies that the ledger and index handle large transfer and approve amounts correctly.
1 parent 00d5a4c commit e5e0d13

File tree

3 files changed

+116
-11
lines changed

3 files changed

+116
-11
lines changed

rs/ledger_suite/icrc1/index-ng/BUILD.bazel

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ rust_test(
123123
"//rs/ledger_suite/icrc1/ledger",
124124
"//rs/ledger_suite/icrc1/test_utils",
125125
"//rs/ledger_suite/icrc1/test_utils/icrc3_test_ledger",
126+
"//rs/ledger_suite/icrc1/tokens_u256",
126127
"//rs/ledger_suite/icrc1/tokens_u64",
127128
"//rs/ledger_suite/test_utils/state_machine_helpers:ic-ledger-suite-state-machine-helpers",
128129
"//rs/ledger_suite/tests/sm-tests:ic-ledger-suite-state-machine-tests",
@@ -153,7 +154,7 @@ rust_test(
153154
"test_suffix": "",
154155
},
155156
{
156-
"crate_features": [],
157+
"crate_features": ["u256-tokens"],
157158
"index_wasm": ":index_ng_canister_u256.wasm.gz",
158159
"ledger_wasm": "//rs/ledger_suite/icrc1/ledger:ledger_canister_u256.wasm.gz",
159160
"test_suffix": "_u256",
@@ -166,7 +167,10 @@ rust_test(
166167
"test_suffix": "_wo_getblocks",
167168
},
168169
{
169-
"crate_features": ["get_blocks_disabled"],
170+
"crate_features": [
171+
"get_blocks_disabled",
172+
"u256-tokens",
173+
],
170174
"index_wasm": ":index_ng_canister_u256.wasm.gz",
171175
"ledger_wasm": "//rs/ledger_suite/icrc1/ledger:ledger_canister_u256_getblocksdisabled.wasm.gz",
172176
"test_suffix": "_u256_wo_getblocks",
@@ -179,7 +183,10 @@ rust_test(
179183
"test_suffix": "_wo_icrc3",
180184
},
181185
{
182-
"crate_features": ["icrc3_disabled"],
186+
"crate_features": [
187+
"icrc3_disabled",
188+
"u256-tokens",
189+
],
183190
"index_wasm": ":index_ng_canister_u256.wasm.gz",
184191
"ledger_wasm": "@ic-icrc1-ledger-wo-icrc-3-u256.wasm.gz//file",
185192
"test_suffix": "_wo_icrc3_u256",

rs/ledger_suite/icrc1/index-ng/tests/common/mod.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,15 @@ pub fn default_archive_options() -> ArchiveOptions {
5959

6060
#[allow(dead_code)]
6161
pub fn index_ng_wasm() -> Vec<u8> {
62-
ic_test_utilities_load_wasm::load_wasm(
63-
std::env::var("CARGO_MANIFEST_DIR").unwrap(),
64-
"ic-icrc1-index-ng",
65-
&[],
66-
)
62+
let index_ng_wasm_path = std::env::var("IC_ICRC1_INDEX_NG_WASM_PATH").expect(
63+
"The Index-ng wasm path must be set using the env variable IC_ICRC1_INDEX_NG_WASM_PATH",
64+
);
65+
std::fs::read(&index_ng_wasm_path).unwrap_or_else(|e| {
66+
panic!(
67+
"failed to load Wasm file from path {} (env var IC_ICRC1_INDEX_NG_WASM_PATH): {}",
68+
index_ng_wasm_path, e
69+
)
70+
})
6771
}
6872

6973
pub fn install_ledger(

rs/ledger_suite/icrc1/index-ng/tests/tests.rs

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@ use crate::common::{
66
use candid::{Decode, Encode, Nat, Principal};
77
use ic_agent::identity::Identity;
88
use ic_base_types::{CanisterId, PrincipalId};
9+
use ic_icrc1::blocks::generic_block_to_encoded_block;
10+
use ic_icrc1::{Block, Operation};
911
use ic_icrc1_index_ng::{
1012
DEFAULT_MAX_BLOCKS_PER_RESPONSE, FeeCollectorRanges, GetAccountTransactionsArgs,
1113
GetAccountTransactionsResponse, GetAccountTransactionsResult, GetBlocksResponse, IndexArg,
1214
InitArg as IndexInitArg, ListSubaccountsArgs, TransactionWithId,
1315
};
14-
use ic_icrc1_ledger::{
15-
ChangeFeeCollector, LedgerArgument, Tokens, UpgradeArgs as LedgerUpgradeArgs,
16-
};
16+
use ic_icrc1_ledger::{ChangeFeeCollector, LedgerArgument, UpgradeArgs as LedgerUpgradeArgs};
1717
use ic_icrc1_test_utils::{
1818
ArgWithCaller, LedgerEndpointArg, icrc3::BlockBuilder, minter_identity,
1919
valid_transactions_strategy,
2020
};
21+
use ic_ledger_core::block::BlockType;
2122
use ic_ledger_suite_state_machine_helpers::{
2223
add_block, archive_blocks, get_logs, set_icrc3_enabled,
2324
};
@@ -26,6 +27,7 @@ use ic_state_machine_tests::StateMachine;
2627
use icrc_ledger_types::icrc::generic_value::ICRC3Value;
2728
use icrc_ledger_types::icrc1::account::{Account, Subaccount};
2829
use icrc_ledger_types::icrc1::transfer::{BlockIndex, TransferArg, TransferError};
30+
use icrc_ledger_types::icrc2::allowance::{Allowance, AllowanceArgs};
2931
use icrc_ledger_types::icrc2::approve::{ApproveArgs, ApproveError};
3032
use icrc_ledger_types::icrc2::transfer_from::{TransferFromArgs, TransferFromError};
3133
use icrc_ledger_types::icrc3::blocks::GetBlocksRequest;
@@ -40,6 +42,12 @@ use std::time::{Duration, SystemTime};
4042

4143
mod common;
4244

45+
#[cfg(not(feature = "u256-tokens"))]
46+
type Tokens = ic_icrc1_tokens_u64::U64;
47+
48+
#[cfg(feature = "u256-tokens")]
49+
type Tokens = ic_icrc1_tokens_u256::U256;
50+
4351
fn index_wasm() -> Vec<u8> {
4452
ic_test_utilities_load_wasm::load_wasm(
4553
std::env::var("CARGO_MANIFEST_DIR").unwrap(),
@@ -1536,6 +1544,92 @@ fn test_principal_subaccounts() {
15361544
assert!(subaccounts.contains(&account(2, 1).subaccount.unwrap()));
15371545
}
15381546

1547+
#[test]
1548+
fn test_large_transfers_and_approvals() {
1549+
let env = &StateMachine::new();
1550+
let minter = minter_identity().sender().unwrap();
1551+
let ledger_id = install_ledger(env, vec![], default_archive_options(), None, minter);
1552+
let index_id = install_index_ng(env, index_init_arg_without_interval(ledger_id));
1553+
let account1 = account(1, 0);
1554+
let account2 = account(2, 0);
1555+
let max_amount = Nat::from(Tokens::MAX);
1556+
1557+
// Make sure we are using the correct token type.
1558+
#[cfg(not(feature = "u256-tokens"))]
1559+
assert_eq!(max_amount, Nat::from(u64::MAX));
1560+
#[cfg(feature = "u256-tokens")]
1561+
assert_ne!(max_amount, Nat::from(u64::MAX));
1562+
1563+
// Mint a huge amount
1564+
let req = TransferArg {
1565+
from_subaccount: None,
1566+
to: account1,
1567+
amount: max_amount.clone(),
1568+
created_at_time: None,
1569+
fee: None,
1570+
memo: None,
1571+
};
1572+
let mint_index = icrc1_transfer(env, ledger_id, minter.into(), req);
1573+
assert_eq!(mint_index, Nat::from(0u64));
1574+
1575+
// Test initial mint block.
1576+
wait_until_sync_is_completed(env, index_id, ledger_id);
1577+
assert_ledger_index_parity(env, ledger_id, index_id);
1578+
let balance = Decode!(
1579+
&env.execute_ingress(index_id, "icrc1_balance_of", Encode!(&account1).unwrap())
1580+
.expect("Failed to send icrc1_balance_of")
1581+
.bytes(),
1582+
Nat
1583+
)
1584+
.expect("Failed to decode icrc1_balance_of response");
1585+
assert_eq!(balance, max_amount);
1586+
1587+
// Approve a huge amount
1588+
let req = ApproveArgs {
1589+
from_subaccount: None,
1590+
spender: account2,
1591+
amount: max_amount.clone(),
1592+
expected_allowance: None,
1593+
expires_at: None,
1594+
fee: None,
1595+
memo: None,
1596+
created_at_time: None,
1597+
};
1598+
let approve_index = icrc2_approve(env, ledger_id, PrincipalId(account1.owner), req);
1599+
assert_eq!(approve_index, Nat::from(1u64));
1600+
1601+
wait_until_sync_is_completed(env, index_id, ledger_id);
1602+
assert_ledger_index_parity(env, ledger_id, index_id);
1603+
1604+
let arg = AllowanceArgs {
1605+
account: account1,
1606+
spender: account2,
1607+
};
1608+
let allowance = Decode!(
1609+
&env.query(ledger_id, "icrc2_allowance", Encode!(&arg).unwrap())
1610+
.expect("failed to guery the allowance")
1611+
.bytes(),
1612+
Allowance
1613+
)
1614+
.expect("failed to decode allowance response");
1615+
assert_eq!(allowance.allowance, max_amount);
1616+
1617+
let res = index_get_blocks(env, index_id, 1, 1);
1618+
let index_approval_block = res.blocks.first().expect("expected at least one block");
1619+
let encoded_block = generic_block_to_encoded_block(index_approval_block.clone())
1620+
.expect("should convert generic block to encoded block");
1621+
let block: Block<Tokens> = Block::decode(encoded_block).expect("should decode encoded block");
1622+
match block.transaction.operation {
1623+
Operation::Approve { amount, .. } => {
1624+
assert_eq!(
1625+
amount,
1626+
Tokens::try_from(max_amount).expect("should convert max amount to Tokens")
1627+
);
1628+
}
1629+
_ => panic!("expected Approve operation"),
1630+
}
1631+
}
1632+
15391633
#[test]
15401634
fn test_index_http_request_decoding_quota() {
15411635
let env = &StateMachine::new();

0 commit comments

Comments
 (0)