Skip to content

Commit

Permalink
Merge pull request #27 from dfinity/FI-885-add-created-at-time-to-cyc…
Browse files Browse the repository at this point in the history
…les-ledger

feat(FI-885) add created at time
  • Loading branch information
NikolasHaimerl authored Aug 15, 2023
2 parents df63e9d + 420b8a7 commit 55d24c5
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 35 deletions.
2 changes: 2 additions & 0 deletions cycles-ledger/src/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub type NumCycles = Nat;
pub struct DepositArg {
pub to: Account,
pub memo: Option<Memo>,
#[serde(default)]
pub created_at_time: Option<u64>,
}

#[derive(CandidType, Deserialize, Clone, Debug, PartialEq, Eq)]
Expand Down
13 changes: 9 additions & 4 deletions cycles-ledger/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -175,7 +180,7 @@ fn icrc1_transfer(args: TransferArg) -> Result<Nat, TransferError> {
}
}

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))
}
Expand Down Expand Up @@ -289,7 +294,7 @@ async fn send(args: endpoints::SendArg) -> Result<Nat, SendError> {
)
} 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)
}
}
Expand Down
94 changes: 63 additions & 31 deletions cycles-ledger/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ pub struct Cache {
pub phash: Option<Hash>,
}

#[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<u64>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub memo: Option<Memo>,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum Operation {
Mint {
Expand All @@ -38,8 +50,6 @@ pub enum Operation {
#[serde(rename = "amt")]
amount: u128,
fee: u128,
#[serde(skip_serializing_if = "Option::is_none")]
memo: Option<Memo>,
},
Transfer {
#[serde(with = "compact_account")]
Expand All @@ -49,23 +59,19 @@ pub enum Operation {
#[serde(rename = "amt")]
amount: u128,
fee: u128,
#[serde(skip_serializing_if = "Option::is_none")]
memo: Option<Memo>,
},
Burn {
#[serde(with = "compact_account")]
from: Account,
#[serde(rename = "amt")]
amount: u128,
fee: u128,
#[serde(skip_serializing_if = "Option::is_none")]
memo: Option<Memo>,
},
}

#[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")]
Expand Down Expand Up @@ -197,6 +203,7 @@ pub fn record_deposit(
amount: u128,
memo: Option<Memo>,
now: u64,
created_at_time: Option<u64>,
) -> (u64, u128, Hash) {
assert!(amount >= crate::config::FEE);

Expand All @@ -207,11 +214,14 @@ 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,
phash,
Expand All @@ -226,6 +236,7 @@ pub fn transfer(
amount: u128,
memo: Option<Memo>,
now: u64,
created_at_time: Option<u64>,
) -> (u64, Hash) {
let from_key = to_account_key(from);
let to_key = to_account_key(to);
Expand All @@ -247,12 +258,15 @@ 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,
phash,
Expand All @@ -276,11 +290,14 @@ 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,
phash,
Expand All @@ -289,7 +306,13 @@ pub fn penalize(from: &Account, now: u64) -> (BlockIndex, Hash) {
})
}

pub fn send(from: &Account, amount: u128, memo: Option<Memo>, now: u64) -> (BlockIndex, Hash) {
pub fn send(
from: &Account,
amount: u128,
memo: Option<Memo>,
now: u64,
created_at_time: Option<u64>,
) -> (BlockIndex, Hash) {
let from_key = to_account_key(from);

mutate_state(|s| {
Expand All @@ -306,11 +329,14 @@ pub fn send(from: &Account, amount: u128, memo: Option<Memo>, now: u64) -> (Bloc
.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,
phash,
Expand All @@ -330,19 +356,25 @@ 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,
},
timestamp: 1691065957,
phash: None,
Expand Down
1 change: 1 addition & 0 deletions depositor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 55d24c5

Please sign in to comment.