From 2fd26498c53dec124f798c0c83f22fa484919594 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Fri, 11 Aug 2023 11:18:30 +0000 Subject: [PATCH 1/2] add created at time --- cycles-ledger/src/endpoints.rs | 2 ++ cycles-ledger/src/main.rs | 13 +++++++++---- cycles-ledger/src/storage.rs | 27 ++++++++++++++++++++++++++- depositor/src/main.rs | 1 + 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/cycles-ledger/src/endpoints.rs b/cycles-ledger/src/endpoints.rs index 6feb402..bf7e11b 100644 --- a/cycles-ledger/src/endpoints.rs +++ b/cycles-ledger/src/endpoints.rs @@ -11,6 +11,8 @@ pub type NumCycles = Nat; pub struct DepositArg { pub to: Account, pub memo: Option, + #[serde(default)] + pub created_at_time: Option, } #[derive(CandidType, Deserialize, Clone, Debug, PartialEq, Eq)] diff --git a/cycles-ledger/src/main.rs b/cycles-ledger/src/main.rs index ac574c9..9d90ade 100644 --- a/cycles-ledger/src/main.rs +++ b/cycles-ledger/src/main.rs @@ -113,8 +113,13 @@ fn deposit(arg: endpoints::DepositArg) -> endpoints::DepositResult { ic_cdk::trap("deposit amount is insufficient"); } let memo = validate_memo(arg.memo); - let (txid, balance, _phash) = - storage::record_deposit(&arg.to, amount, memo, ic_cdk::api::time()); + let (txid, balance, _phash) = storage::record_deposit( + &arg.to, + amount, + memo, + ic_cdk::api::time(), + arg.created_at_time, + ); // TODO(FI-766): set the certified variable. @@ -175,7 +180,7 @@ fn icrc1_transfer(args: TransferArg) -> Result { } } - let (txid, _hash) = storage::transfer(&from, &args.to, amount, memo, now); + let (txid, _hash) = storage::transfer(&from, &args.to, amount, memo, now, args.created_at_time); Ok(Nat::from(txid)) } @@ -289,7 +294,7 @@ async fn send(args: endpoints::SendArg) -> Result { ) } else { let now = ic_cdk::api::time(); - let (send, _send_hash) = storage::send(&from, amount, memo, now); + let (send, _send_hash) = storage::send(&from, amount, memo, now, args.created_at_time); Ok(send) } } diff --git a/cycles-ledger/src/storage.rs b/cycles-ledger/src/storage.rs index 2089e19..88aa344 100644 --- a/cycles-ledger/src/storage.rs +++ b/cycles-ledger/src/storage.rs @@ -40,6 +40,10 @@ pub enum Operation { fee: u128, #[serde(skip_serializing_if = "Option::is_none")] memo: Option, + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "ts")] + created_at_time: Option, }, Transfer { #[serde(with = "compact_account")] @@ -51,6 +55,10 @@ pub enum Operation { fee: u128, #[serde(skip_serializing_if = "Option::is_none")] memo: Option, + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "ts")] + created_at_time: Option, }, Burn { #[serde(with = "compact_account")] @@ -60,6 +68,10 @@ pub enum Operation { fee: u128, #[serde(skip_serializing_if = "Option::is_none")] memo: Option, + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "ts")] + created_at_time: Option, }, } @@ -197,6 +209,7 @@ pub fn record_deposit( amount: u128, memo: Option, now: u64, + created_at_time: Option, ) -> (u64, u128, Hash) { assert!(amount >= crate::config::FEE); @@ -212,6 +225,7 @@ pub fn record_deposit( amount, memo, fee: crate::config::FEE, + created_at_time, }, timestamp: now, phash, @@ -226,6 +240,7 @@ pub fn transfer( amount: u128, memo: Option, now: u64, + created_at_time: Option, ) -> (u64, Hash) { let from_key = to_account_key(from); let to_key = to_account_key(to); @@ -253,6 +268,7 @@ pub fn transfer( amount, memo, fee: crate::config::FEE, + created_at_time, }, timestamp: now, phash, @@ -281,6 +297,7 @@ pub fn penalize(from: &Account, now: u64) -> (BlockIndex, Hash) { amount: 0, memo: None, fee: crate::config::FEE, + created_at_time: None, }, timestamp: now, phash, @@ -289,7 +306,13 @@ pub fn penalize(from: &Account, now: u64) -> (BlockIndex, Hash) { }) } -pub fn send(from: &Account, amount: u128, memo: Option, now: u64) -> (BlockIndex, Hash) { +pub fn send( + from: &Account, + amount: u128, + memo: Option, + now: u64, + created_at_time: Option, +) -> (BlockIndex, Hash) { let from_key = to_account_key(from); mutate_state(|s| { @@ -311,6 +334,7 @@ pub fn send(from: &Account, amount: u128, memo: Option, now: u64) -> (Bloc amount, memo, fee: crate::config::FEE, + created_at_time, }, timestamp: now, phash, @@ -343,6 +367,7 @@ mod tests { amount: u128::MAX, fee: 10_000, memo: Some(Memo::default()), + created_at_time: None, }, timestamp: 1691065957, phash: None, diff --git a/depositor/src/main.rs b/depositor/src/main.rs index 366c008..081b29c 100644 --- a/depositor/src/main.rs +++ b/depositor/src/main.rs @@ -35,6 +35,7 @@ async fn deposit(arg: DepositArg) -> DepositResult { let arg = cycles_ledger::endpoints::DepositArg { to: arg.to, memo: arg.memo, + created_at_time: Some(ic_cdk::api::time()), }; let (result,): (DepositResult,) = call_with_payment128(ledger_id, "deposit", (arg,), cycles) .await From 420b8a7f76d4370db2f7f0c927b4973696ae8113 Mon Sep 17 00:00:00 2001 From: Nikolas Haimerl Date: Mon, 14 Aug 2023 15:54:02 +0000 Subject: [PATCH 2/2] add: transaction struct --- cycles-ledger/src/storage.rs | 91 +++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/cycles-ledger/src/storage.rs b/cycles-ledger/src/storage.rs index 88aa344..27f99eb 100644 --- a/cycles-ledger/src/storage.rs +++ b/cycles-ledger/src/storage.rs @@ -30,6 +30,18 @@ pub struct Cache { pub phash: Option, } +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Transaction { + pub operation: Operation, + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "ts")] + pub created_at_time: Option, + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + pub memo: Option, +} + #[derive(Serialize, Deserialize, Clone, Debug)] pub enum Operation { Mint { @@ -38,12 +50,6 @@ pub enum Operation { #[serde(rename = "amt")] amount: u128, fee: u128, - #[serde(skip_serializing_if = "Option::is_none")] - memo: Option, - #[serde(default)] - #[serde(skip_serializing_if = "Option::is_none")] - #[serde(rename = "ts")] - created_at_time: Option, }, Transfer { #[serde(with = "compact_account")] @@ -53,12 +59,6 @@ pub enum Operation { #[serde(rename = "amt")] amount: u128, fee: u128, - #[serde(skip_serializing_if = "Option::is_none")] - memo: Option, - #[serde(default)] - #[serde(skip_serializing_if = "Option::is_none")] - #[serde(rename = "ts")] - created_at_time: Option, }, Burn { #[serde(with = "compact_account")] @@ -66,18 +66,12 @@ pub enum Operation { #[serde(rename = "amt")] amount: u128, fee: u128, - #[serde(skip_serializing_if = "Option::is_none")] - memo: Option, - #[serde(default)] - #[serde(skip_serializing_if = "Option::is_none")] - #[serde(rename = "ts")] - created_at_time: Option, }, } #[derive(Serialize, Deserialize, Clone, Debug)] pub struct Block { - op: Operation, + transaction: Transaction, #[serde(rename = "ts")] pub timestamp: u64, #[serde(skip_serializing_if = "Option::is_none")] @@ -220,11 +214,13 @@ pub fn record_deposit( s.balances.insert(key, new_balance); let phash = s.last_block_hash(); let block_hash = s.emit_block(Block { - op: Operation::Mint { - to: *account, - amount, + transaction: Transaction { + operation: Operation::Mint { + to: *account, + amount, + fee: crate::config::FEE, + }, memo, - fee: crate::config::FEE, created_at_time, }, timestamp: now, @@ -262,12 +258,14 @@ pub fn transfer( let phash = s.last_block_hash(); let block_hash = s.emit_block(Block { - op: Operation::Transfer { - from: *from, - to: *to, - amount, + transaction: Transaction { + operation: Operation::Transfer { + from: *from, + to: *to, + amount, + fee: crate::config::FEE, + }, memo, - fee: crate::config::FEE, created_at_time, }, timestamp: now, @@ -292,11 +290,13 @@ pub fn penalize(from: &Account, now: u64) -> (BlockIndex, Hash) { } let phash = s.last_block_hash(); let block_hash = s.emit_block(Block { - op: Operation::Burn { - from: *from, - amount: 0, + transaction: Transaction { + operation: Operation::Burn { + from: *from, + amount: 0, + fee: crate::config::FEE, + }, memo: None, - fee: crate::config::FEE, created_at_time: None, }, timestamp: now, @@ -329,11 +329,13 @@ pub fn send( .expect("failed to update balance"); let phash = s.last_block_hash(); let block_hash = s.emit_block(Block { - op: Operation::Burn { - from: *from, - amount, + transaction: Transaction { + operation: Operation::Burn { + from: *from, + amount, + fee: crate::config::FEE, + }, memo, - fee: crate::config::FEE, created_at_time, }, timestamp: now, @@ -354,18 +356,23 @@ mod tests { }; use num_bigint::BigUint; - use crate::ciborium_to_generic_value; + use crate::{ + ciborium_to_generic_value, + storage::{Operation, Transaction}, + }; use super::Block; #[test] fn test_block_hash() { let block = Block { - op: super::Operation::Transfer { - from: Account::from(Principal::anonymous()), - to: Account::from(Principal::anonymous()), - amount: u128::MAX, - fee: 10_000, + transaction: Transaction { + operation: Operation::Transfer { + from: Account::from(Principal::anonymous()), + to: Account::from(Principal::anonymous()), + amount: u128::MAX, + fee: 10_000, + }, memo: Some(Memo::default()), created_at_time: None, },