feat(ICRC-Ledger): DEFI-1687: implement ICRC-107 fee collector#8217
feat(ICRC-Ledger): DEFI-1687: implement ICRC-107 fee collector#8217maciejdfinity wants to merge 103 commits intomasterfrom
Conversation
| withdrawal_id: cketh_block_index.clone(), | ||
| burn_in_block: ckerc20_block_index.clone(), | ||
| reimbursed_in_block: Nat::from(3_u8), | ||
| reimbursed_in_block: Nat::from(4_u8), |
There was a problem hiding this comment.
If the ICRC ledger is installed with a 107 fee collector, the first block is the fee collector setting block and therefore all block indexes that are tested need to be increased by 1.
| index_status, | ||
| ic_icrc1_index_ng::Status { | ||
| num_blocks_synced: Nat::from(0_u8) | ||
| num_blocks_synced: Nat::from(1_u8) |
There was a problem hiding this comment.
If the ICRC ledger is installed with a 107 fee collector, the first block is the fee collector setting block and therefore even a ledger with no transactions will contain one block.
This reverts commit fe7d54f.
| calls: 1 | ||
| instructions: 54416296904 | ||
| heap_increase: 264 | ||
| instructions: 54937060262 |
There was a problem hiding this comment.
u64 diffs:
Only significant changes:
| status | name | calls | ins | ins Δ% | HI | HI Δ% | SMI | SMI Δ% |
|---|---|---|---|---|---|---|---|---|
| +/- | bench_icrc1_transfers::icrc2_approve | 1 | 19.65B | +6.57% | 24 | -4.00% | 128 | 0.00% |
| - | bench_icrc1_transfers::icrc3_get_blocks | 1 | 7.84M | -7.01% | 0 | 0.00% | 0 | 0.00% |
u256 diffs:
Only significant changes:
| status | name | calls | ins | ins Δ% | HI | HI Δ% | SMI | SMI Δ% |
|---|---|---|---|---|---|---|---|---|
| +/- | bench_icrc1_transfers::icrc2_approve | 1 | 20.55B | +6.23% | 25 | -13.79% | 128 | 0.00% |
| + | bench_icrc1_transfers::icrc2_transfer_from | 1 | 21.03B | -1.86% | 4 | +33.33% | 0 | 0.00% |
| +/- | bench_icrc1_transfers::icrc1_transfer | 1 | 12.64B | -2.20% | 34 | +6.25% | 0 | 0.00% |
| - | bench_icrc1_transfers::icrc3_get_blocks | 1 | 8.22M | -7.89% | 0 | 0.00% | 0 | 0.00% |
There was a problem hiding this comment.
The u64 diffs make some sense, icrc2_approve now also collects fees, so it uses a bit more instructions. The created blocks don't contain the fee collector or fee collector block index, which results in less heap usage for icrc2_approve and less instructions for decoding the blocks in case of icrc3_get_blocks.
There was a problem hiding this comment.
For u256, the instruction diffs are similar for icrc2_approve and icrc3_get_blocks. We also see improvements for icrc1_transfer and icrc2_transfer_from (in case of u64 they were significant but below threshold). The latter might be caused by the fact that the fee collector is stored directly as Option<Account> and previously it was stored in Option<FeeCollector<Account>>. The heap diffs are less consistent, though.
mbjorkqvist
left a comment
There was a problem hiding this comment.
Thanks @maciejdfinity! I have a few comments and questions, but overall this looks very good!
| "ck_btc_ledger": "ic-icrc1-ledger.wasm.gz", | ||
| "ck_btc_ledger_v1": "ic-icrc1-ledger.wasm.gz", | ||
| "ck_btc_ledger_v3": "ic-icrc1-ledger.wasm.gz", | ||
| "ck_btc_ledger_v5": "ic-icrc1-ledger.wasm.gz", |
There was a problem hiding this comment.
Would it make sense to rename this to something more descriptive, and/or perhaps add a comment somewhere (I think comments don't work in mainnet-canister-revisions.json, but here would be ok?)? Especially since the v5 doesn't correspond to the LEDGER_VERSION, so it can be confusing.
There was a problem hiding this comment.
Good point! Maybe we could change it to correspond to the ledger versions, i.e.:
v1 -> no_mem_mgr
v3 -> v1
v5 -> v3
WDYT?
| "ck_btc_ledger_v5": { | ||
| "rev": "512cf412f33d430b79f42330518166d14fc6884e", | ||
| "sha256": "901bc548f901145bd15a1156487eed703705794ad6a23787eaa04b1c7bbdcf48" | ||
| }, |
There was a problem hiding this comment.
This points to ledger-suite-icrc-2025-04-14. Is there a particular reason for this specific version, or could we use ledger-suite-icrc-2025-10-27, which is the minimum version we point to from the currently most recent version ledger-suite-icrc-2026-02-02?
There was a problem hiding this comment.
No reason, I just used the same version as current mainnet ledger :) Changed!
There was a problem hiding this comment.
Would it make sense to move all the fee collector-related tests to a separate file? rs/ledger_suite/icrc1/index-ng/tests/tests.rs is already over 2000 lines.
Also, would it make sense to add tests for the following (unless they already exist and I missed them):
- Trying to set the fee collector account to the minting account, the anonymous account, and an invalid account (e.g., an account with an invalid principal). For the init, upgrade, and endpoint fee collector setting paths. IIUC, there's a check for the minting account in the init and upgrade paths, but not for the endpoint?
| // Downgrade to mainnet is currently not possible. The rest of the test can | ||
| // be uncommented again, once the PR that introduced this line is on mainnet. | ||
|
|
||
| // // 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); |
There was a problem hiding this comment.
Would it help to have a ticket in the ICRC-107 epic to remember to uncomment this, and the other snippet in rs/ledger_suite/icrc1/tests/upgrade_downgrade.rs, once this has been released and deployed to mainnet? Or will the tests fail anyway once that happens, and uncommenting cannot be forgotten?
Co-authored-by: Mathias Björkqvist <mathias.bjorkqvist@dfinity.org>
With this change the ICRC ledger now implements the ICRC-107 fee collector standard as described in https://github.com/dfinity/ICRC/blob/main/ICRCs/ICRC-107/ICRC-107.md. The legacy fee collector is not longer supported by the ledger. This results in the following notable changes:
The fee collector can be configured using the existing
fee_collector_accountinit argument andchange_fee_collectorupgrade argument.Since the ICRC-107 fee collector change is not backwards compatible, the ledger upgraded to this version cannot be downgraded to an earlier version.