Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions rs/ledger_suite/icrc1/index-ng/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,11 @@ fn process_balance_changes(block_index: BlockIndex64, block: &Block<Tokens>) {
}
| Operation::Pause { .. }
| Operation::Unpause { .. }
| Operation::Deactivate { .. } => {
| Operation::Deactivate { .. }
| Operation::FreezeAccount { .. }
| Operation::UnfreezeAccount { .. }
| Operation::FreezePrincipal { .. }
| Operation::UnfreezePrincipal { .. } => {
// Does not affect the balance
}
},
Expand Down Expand Up @@ -1161,7 +1165,11 @@ fn get_accounts(block: &Block<Tokens>) -> Vec<Account> {
Operation::FeeCollector { .. }
| Operation::Pause { .. }
| Operation::Unpause { .. }
| Operation::Deactivate { .. } => vec![],
| Operation::Deactivate { .. }
| Operation::FreezeAccount { .. }
| Operation::UnfreezeAccount { .. }
| Operation::FreezePrincipal { .. }
| Operation::UnfreezePrincipal { .. } => vec![],
}
}

Expand Down
69 changes: 66 additions & 3 deletions rs/ledger_suite/icrc1/src/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ use icrc_ledger_types::icrc1::transfer::TransferError;
use icrc_ledger_types::icrc2::approve::ApproveError;
use icrc_ledger_types::icrc2::transfer_from::TransferFromError;
use icrc_ledger_types::icrc3::transactions::{
Approve, Burn, FeeCollector, ManagementAction, Mint, TRANSACTION_124_DEACTIVATE,
TRANSACTION_124_PAUSE, TRANSACTION_124_UNPAUSE, TRANSACTION_APPROVE, TRANSACTION_BURN,
TRANSACTION_FEE_COLLECTOR, TRANSACTION_MINT, TRANSACTION_TRANSFER, Transaction, Transfer,
Approve, Burn, FeeCollector, FreezeAccountAction, FreezePrincipalAction, ManagementAction,
Mint, TRANSACTION_123_FREEZE_ACCOUNT, TRANSACTION_123_FREEZE_PRINCIPAL,
TRANSACTION_123_UNFREEZE_ACCOUNT, TRANSACTION_123_UNFREEZE_PRINCIPAL,
TRANSACTION_124_DEACTIVATE, TRANSACTION_124_PAUSE, TRANSACTION_124_UNPAUSE,
TRANSACTION_APPROVE, TRANSACTION_BURN, TRANSACTION_FEE_COLLECTOR, TRANSACTION_MINT,
TRANSACTION_TRANSFER, Transaction, Transfer,
};
use serde::Deserialize;

Expand Down Expand Up @@ -295,6 +298,66 @@ impl<Tokens: TokensType> From<Block<Tokens>> for Transaction {
mthd,
});
}
Operation::FreezeAccount {
account,
caller,
mthd,
reason,
} => {
tx.kind = TRANSACTION_123_FREEZE_ACCOUNT.to_string();
tx.freeze_account = Some(FreezeAccountAction {
account,
caller,
reason,
ts: created_at_time,
mthd,
});
}
Operation::UnfreezeAccount {
account,
caller,
mthd,
reason,
} => {
tx.kind = TRANSACTION_123_UNFREEZE_ACCOUNT.to_string();
tx.unfreeze_account = Some(FreezeAccountAction {
account,
caller,
reason,
ts: created_at_time,
mthd,
});
}
Operation::FreezePrincipal {
principal,
caller,
mthd,
reason,
} => {
tx.kind = TRANSACTION_123_FREEZE_PRINCIPAL.to_string();
tx.freeze_principal = Some(FreezePrincipalAction {
principal,
caller,
reason,
ts: created_at_time,
mthd,
});
}
Operation::UnfreezePrincipal {
principal,
caller,
mthd,
reason,
} => {
tx.kind = TRANSACTION_123_UNFREEZE_PRINCIPAL.to_string();
tx.unfreeze_principal = Some(FreezePrincipalAction {
principal,
caller,
reason,
ts: created_at_time,
mthd,
});
}
}

tx
Expand Down
140 changes: 130 additions & 10 deletions rs/ledger_suite/icrc1/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use icrc_ledger_types::icrc1::account::Account;
use icrc_ledger_types::{
icrc1::transfer::Memo,
icrc3::transactions::{
TRANSACTION_123_FREEZE_ACCOUNT, TRANSACTION_123_FREEZE_PRINCIPAL,
TRANSACTION_123_UNFREEZE_ACCOUNT, TRANSACTION_123_UNFREEZE_PRINCIPAL,
TRANSACTION_124_DEACTIVATE, TRANSACTION_124_PAUSE, TRANSACTION_124_UNPAUSE,
TRANSACTION_FEE_COLLECTOR,
},
Expand Down Expand Up @@ -75,6 +77,30 @@ pub enum Operation<Tokens: TokensType> {
mthd: Option<String>,
reason: Option<String>,
},
FreezeAccount {
account: Account,
caller: Option<Principal>,
mthd: Option<String>,
reason: Option<String>,
},
UnfreezeAccount {
account: Account,
caller: Option<Principal>,
mthd: Option<String>,
reason: Option<String>,
},
FreezePrincipal {
principal: Principal,
caller: Option<Principal>,
mthd: Option<String>,
reason: Option<String>,
},
UnfreezePrincipal {
principal: Principal,
caller: Option<Principal>,
mthd: Option<String>,
reason: Option<String>,
},
}

// A [Transaction] but flattened meaning that [Operation]
Expand Down Expand Up @@ -147,6 +173,15 @@ struct FlattenedTransaction<Tokens: TokensType> {
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,

#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(with = "compact_account::opt")]
pub account: Option<Account>,

#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub principal: Option<Principal>,
}

impl<Tokens: TokensType> TryFrom<FlattenedTransaction<Tokens>> for Transaction<Tokens> {
Expand Down Expand Up @@ -202,6 +237,38 @@ impl<Tokens: TokensType> TryFrom<(Option<String>, FlattenedTransaction<Tokens>)>
mthd: value.mthd,
reason: value.reason,
},
Some(TRANSACTION_123_FREEZE_ACCOUNT) => Operation::FreezeAccount {
account: value
.account
.ok_or("`account` field required for freeze_account operation")?,
caller: value.caller,
mthd: value.mthd,
reason: value.reason,
},
Some(TRANSACTION_123_UNFREEZE_ACCOUNT) => Operation::UnfreezeAccount {
account: value
.account
.ok_or("`account` field required for unfreeze_account operation")?,
caller: value.caller,
mthd: value.mthd,
reason: value.reason,
},
Some(TRANSACTION_123_FREEZE_PRINCIPAL) => Operation::FreezePrincipal {
principal: value
.principal
.ok_or("`principal` field required for freeze_principal operation")?,
caller: value.caller,
mthd: value.mthd,
reason: value.reason,
},
Some(TRANSACTION_123_UNFREEZE_PRINCIPAL) => Operation::UnfreezePrincipal {
principal: value
.principal
.ok_or("`principal` field required for unfreeze_principal operation")?,
caller: value.caller,
mthd: value.mthd,
reason: value.reason,
},
_ => Operation::try_from(value)
.map_err(|e| format!("{} and/or unknown btype {:?}", e, btype_str))?,
};
Expand Down Expand Up @@ -281,7 +348,14 @@ impl<Tokens: TokensType> From<Transaction<Tokens>> for FlattenedTransaction<Toke
Mint { .. } => Some("mint".to_string()),
Transfer { .. } => Some("xfer".to_string()),
Approve { .. } => Some("approve".to_string()),
FeeCollector { .. } | Pause { .. } | Unpause { .. } | Deactivate { .. } => None,
FeeCollector { .. }
| Pause { .. }
| Unpause { .. }
| Deactivate { .. }
| FreezeAccount { .. }
| UnfreezeAccount { .. }
| FreezePrincipal { .. }
| UnfreezePrincipal { .. } => None,
},
from: match &t.operation {
Transfer { from, .. } | Burn { from, .. } | Approve { from, .. } => Some(*from),
Expand All @@ -301,14 +375,28 @@ impl<Tokens: TokensType> From<Transaction<Tokens>> for FlattenedTransaction<Toke
| Mint { amount, .. }
| Transfer { amount, .. }
| Approve { amount, .. } => Some(amount.clone()),
FeeCollector { .. } | Pause { .. } | Unpause { .. } | Deactivate { .. } => None,
FeeCollector { .. }
| Pause { .. }
| Unpause { .. }
| Deactivate { .. }
| FreezeAccount { .. }
| UnfreezeAccount { .. }
| FreezePrincipal { .. }
| UnfreezePrincipal { .. } => None,
},
fee: match &t.operation {
Transfer { fee, .. }
| Approve { fee, .. }
| Mint { fee, .. }
| Burn { fee, .. } => fee.to_owned(),
FeeCollector { .. } | Pause { .. } | Unpause { .. } | Deactivate { .. } => None,
FeeCollector { .. }
| Pause { .. }
| Unpause { .. }
| Deactivate { .. }
| FreezeAccount { .. }
| UnfreezeAccount { .. }
| FreezePrincipal { .. }
| UnfreezePrincipal { .. } => None,
},
expected_allowance: match &t.operation {
Approve {
Expand All @@ -328,19 +416,41 @@ impl<Tokens: TokensType> From<Transaction<Tokens>> for FlattenedTransaction<Toke
FeeCollector { caller, .. }
| Pause { caller, .. }
| Unpause { caller, .. }
| Deactivate { caller, .. } => caller.to_owned(),
| Deactivate { caller, .. }
| FreezeAccount { caller, .. }
| UnfreezeAccount { caller, .. }
| FreezePrincipal { caller, .. }
| UnfreezePrincipal { caller, .. } => caller.to_owned(),
_ => None,
},
mthd: match &t.operation {
FeeCollector { mthd, .. }
| Pause { mthd, .. }
| Unpause { mthd, .. }
| Deactivate { mthd, .. } => mthd.to_owned(),
| Deactivate { mthd, .. }
| FreezeAccount { mthd, .. }
| UnfreezeAccount { mthd, .. }
| FreezePrincipal { mthd, .. }
| UnfreezePrincipal { mthd, .. } => mthd.to_owned(),
_ => None,
},
reason: match &t.operation {
Pause { reason, .. } | Unpause { reason, .. } | Deactivate { reason, .. } => {
reason.to_owned()
Pause { reason, .. }
| Unpause { reason, .. }
| Deactivate { reason, .. }
| FreezeAccount { reason, .. }
| UnfreezeAccount { reason, .. }
| FreezePrincipal { reason, .. }
| UnfreezePrincipal { reason, .. } => reason.to_owned(),
_ => None,
},
account: match &t.operation {
FreezeAccount { account, .. } | UnfreezeAccount { account, .. } => Some(*account),
_ => None,
},
principal: match &t.operation {
FreezePrincipal { principal, .. } | UnfreezePrincipal { principal, .. } => {
Some(*principal)
}
_ => None,
},
Expand Down Expand Up @@ -537,8 +647,14 @@ impl<Tokens: TokensType> LedgerTransaction for Transaction<Tokens> {
Operation::FeeCollector { .. } => {
panic!("FeeCollector107 not implemented")
}
Operation::Pause { .. } | Operation::Unpause { .. } | Operation::Deactivate { .. } => {
// ICRC-124 management operations do not affect balances or approvals.
Operation::Pause { .. }
| Operation::Unpause { .. }
| Operation::Deactivate { .. }
| Operation::FreezeAccount { .. }
| Operation::UnfreezeAccount { .. }
| Operation::FreezePrincipal { .. }
| Operation::UnfreezePrincipal { .. } => {
// ICRC-124/123 management operations do not affect balances or approvals.
// Treat them as no-ops when applying historical blocks so replay/upgrade
// does not crash the canister.
}
Expand Down Expand Up @@ -732,7 +848,11 @@ impl<Tokens: TokensType> BlockType for Block<Tokens> {
Operation::FeeCollector { .. }
| Operation::Pause { .. }
| Operation::Unpause { .. }
| Operation::Deactivate { .. } => None,
| Operation::Deactivate { .. }
| Operation::FreezeAccount { .. }
| Operation::UnfreezeAccount { .. }
| Operation::FreezePrincipal { .. }
| Operation::UnfreezePrincipal { .. } => None,
_ => None,
};
let (fee_collector, fee_collector_block_index) = match fee_collector {
Expand Down
22 changes: 19 additions & 3 deletions rs/ledger_suite/icrc1/test_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,11 @@ pub fn blocks_strategy<Tokens: TokensType>(
Operation::FeeCollector { .. }
| Operation::Pause { .. }
| Operation::Unpause { .. }
| Operation::Deactivate { .. } => None,
| Operation::Deactivate { .. }
| Operation::FreezeAccount { .. }
| Operation::UnfreezeAccount { .. }
| Operation::FreezePrincipal { .. }
| Operation::UnfreezePrincipal { .. } => None,
};
let btype = match transaction.operation {
Operation::FeeCollector { .. } => Some(BTYPE_107.to_string()),
Expand Down Expand Up @@ -610,7 +614,13 @@ impl TransactionsAndBalances {
Operation::FeeCollector { .. } => {
panic!("FeeCollector107 not implemented")
}
Operation::Pause { .. } | Operation::Unpause { .. } | Operation::Deactivate { .. } => {
Operation::Pause { .. }
| Operation::Unpause { .. }
| Operation::Deactivate { .. }
| Operation::FreezeAccount { .. }
| Operation::UnfreezeAccount { .. }
| Operation::FreezePrincipal { .. }
| Operation::UnfreezePrincipal { .. } => {
// No balance changes
}
};
Expand Down Expand Up @@ -643,7 +653,13 @@ impl TransactionsAndBalances {
Operation::FeeCollector { .. } => {
panic!("FeeCollector107 not implemented")
}
Operation::Pause { .. } | Operation::Unpause { .. } | Operation::Deactivate { .. } => {
Operation::Pause { .. }
| Operation::Unpause { .. }
| Operation::Deactivate { .. }
| Operation::FreezeAccount { .. }
| Operation::UnfreezeAccount { .. }
| Operation::FreezePrincipal { .. }
| Operation::UnfreezePrincipal { .. } => {
// No balance changes
}
}
Expand Down
6 changes: 5 additions & 1 deletion rs/ledger_suite/test_utils/in_memory_ledger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,11 @@ where
}
Operation::Pause { .. }
| Operation::Unpause { .. }
| Operation::Deactivate { .. } => {
| Operation::Deactivate { .. }
| Operation::FreezeAccount { .. }
| Operation::UnfreezeAccount { .. }
| Operation::FreezePrincipal { .. }
| Operation::UnfreezePrincipal { .. } => {
// No balance changes
}
}
Expand Down
8 changes: 8 additions & 0 deletions rs/rosetta-api/icrc1/src/common/storage/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,14 @@ where
mthd,
reason,
},
Op::FreezeAccount { .. }
| Op::UnfreezeAccount { .. }
| Op::FreezePrincipal { .. }
| Op::UnfreezePrincipal { .. } => {
// ICRC-123 freeze operations are not yet supported in Rosetta.
// Full support will be added in a follow-up PR.
unimplemented!("ICRC-123 freeze operations are not yet supported in Rosetta")
}
}
}
}
Expand Down
Loading
Loading