b3_users/data/
transaction.rs1#[cfg(test)]
2use crate::mocks::ic_timestamp;
3
4#[cfg(not(test))]
5use ic_cdk::api::time as ic_timestamp;
6
7use ic_cdk::export::{candid::CandidType, serde::Deserialize};
8
9#[derive(CandidType, Debug, Deserialize, Clone, PartialEq)]
10pub struct UserTransactionData {
11 pub data: Vec<u8>,
12 pub cycle: u64,
13 pub timestamp: u64,
14}
15
16impl UserTransactionData {
17 pub fn default() -> Self {
19 UserTransactionData {
20 cycle: 0,
21 data: vec![],
22 timestamp: 0,
23 }
24 }
25
26 pub fn new(data: Vec<u8>, cycle: u64, timestamp: u64) -> Self {
28 UserTransactionData {
29 data,
30 cycle,
31 timestamp,
32 }
33 }
34
35 pub fn new_with_current_time(data: Vec<u8>, cycle: u64) -> Self {
37 let timestamp = ic_timestamp();
38
39 UserTransactionData {
40 data,
41 cycle,
42 timestamp,
43 }
44 }
45
46 pub fn get_hash(&self) -> Vec<u8> {
48 let mut hash = vec![];
49 hash.extend_from_slice(&self.data);
50 hash.extend_from_slice(&self.timestamp.to_be_bytes());
51
52 hash
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59 use proptest::prelude::*;
60
61 proptest! {
62 #[test]
63 fn test_transaction_hash(data: Vec<u8>,cycle: u64, timestamp: u64) {
64 let transaction = UserTransactionData::new(data.clone(), cycle, timestamp);
65 let hash = transaction.get_hash();
66
67 assert_eq!(hash.len(), data.len() + 8);
68 assert_eq!(&hash[0..data.len()], data.as_slice());
69 assert_eq!(&hash[data.len()..], ×tamp.to_be_bytes());
70 }
71
72 #[test]
73 fn test_transaction_hash_with_current_time(data: Vec<u8>, cycle: u64) {
74 let transaction = UserTransactionData::new_with_current_time(data.clone(), cycle);
75 let hash = transaction.get_hash();
76
77 assert_eq!(hash.len(), data.len() + 8);
78 assert_eq!(&hash[0..data.len()], data.as_slice());
79 assert_eq!(&hash[data.len()..], &transaction.timestamp.to_be_bytes());
80 }
81 }
82}