diff options
Diffstat (limited to 'src/block.rs')
-rw-r--r-- | src/block.rs | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/block.rs b/src/block.rs new file mode 100644 index 0000000..e707779 --- /dev/null +++ b/src/block.rs | |||
@@ -0,0 +1,92 @@ | |||
1 | //! # Data Representations | ||
2 | //! | ||
3 | //! We need persistence for [`Block`]s and [`User`]s, not so much for [`Transaction`]s | ||
4 | //! | ||
5 | //! There are around 30 students, a full fledged database would be an overkill (for next year?) | ||
6 | //! | ||
7 | //! Pending transactions are held in memory, these are cleared with every new block | ||
8 | //! Only the last block is held in memory, every block is written to a file | ||
9 | //! Users are held in memory and they're also backed up to text files | ||
10 | use chrono::{NaiveDate, NaiveDateTime}; | ||
11 | use serde::{Deserialize, Serialize}; | ||
12 | use std::{string::String, vec::Vec}; | ||
13 | |||
14 | pub type Fingerprint = String; | ||
15 | pub type Id = String; | ||
16 | |||
17 | /// A block that was proposed with `transaction_list` and `nonce` | ||
18 | /// that made `hash` valid, 6 zeroes at the left hand side of the hash (24 bytes) | ||
19 | /// | ||
20 | /// We are mining using blake2s algorithm, which produces 256 bit hashes. | ||
21 | /// Hash/second is roughly 20x10^3. | ||
22 | /// | ||
23 | /// <https://serde.rs/container-attrs.html> might be valuable to normalize the | ||
24 | /// serialize/deserialize conventions as these will be hashed | ||
25 | /// | ||
26 | #[derive(Serialize, Deserialize, Debug, PartialEq)] | ||
27 | pub struct Block { | ||
28 | #[serde(skip_serializing_if = "Vec::is_empty")] | ||
29 | pub transaction_list: Vec<Fingerprint>, | ||
30 | pub nonce: u32, | ||
31 | pub timestamp: NaiveDateTime, | ||
32 | pub hash: String, | ||
33 | } | ||
34 | |||
35 | impl Default for Block { | ||
36 | fn default() -> Self { | ||
37 | Block { | ||
38 | transaction_list: vec!["gradecoin_bank".to_owned()], | ||
39 | nonce: 0, | ||
40 | timestamp: NaiveDate::from_ymd(2022, 4, 11).and_hms(20, 45, 00), | ||
41 | hash: String::from("not_actually_mined"), | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | |||
46 | /// For prototyping and letting serde handle everything json | ||
47 | #[derive(Serialize, Deserialize, Debug, PartialEq)] | ||
48 | pub struct NakedBlock { | ||
49 | #[serde(skip_serializing_if = "Vec::is_empty", default)] | ||
50 | pub transaction_list: Vec<Fingerprint>, | ||
51 | pub nonce: u32, | ||
52 | pub timestamp: NaiveDateTime, | ||
53 | } | ||
54 | |||
55 | /// A transaction between `source` and `target` that moves `amount` | ||
56 | #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] | ||
57 | pub struct Transaction { | ||
58 | pub source: Fingerprint, | ||
59 | pub target: Fingerprint, | ||
60 | pub amount: u16, | ||
61 | pub timestamp: NaiveDateTime, | ||
62 | } | ||
63 | |||
64 | /// A JWT Payload/Claims representation | ||
65 | /// | ||
66 | /// <https://tools.ietf.org/html/rfc7519#section-4.1> | ||
67 | /// | ||
68 | /// - `tha`: Transaction Hash, String (custom field) | ||
69 | /// - `iat`: Issued At, Unix Time, epoch | ||
70 | /// - `exp`: Expiration Time, epoch | ||
71 | #[derive(Debug, Serialize, Deserialize, PartialEq)] | ||
72 | pub struct Claims { | ||
73 | pub tha: String, | ||
74 | pub iat: usize, | ||
75 | pub exp: usize, | ||
76 | } | ||
77 | |||
78 | /// The plaintext of the initial user authentication request | ||
79 | #[derive(Serialize, Deserialize, Debug, PartialEq)] | ||
80 | pub struct AuthRequest { | ||
81 | pub student_id: String, | ||
82 | pub passwd: String, | ||
83 | pub public_key: String, | ||
84 | } | ||
85 | |||
86 | /// Ciphertext of the initial authentication request, or what we will receive | ||
87 | #[derive(Serialize, Deserialize, Debug)] | ||
88 | pub struct InitialAuthRequest { | ||
89 | pub c: String, | ||
90 | pub iv: String, | ||
91 | pub key: String, | ||
92 | } | ||