diff options
Diffstat (limited to 'src/schema.rs')
-rw-r--r-- | src/schema.rs | 68 |
1 files changed, 49 insertions, 19 deletions
diff --git a/src/schema.rs b/src/schema.rs index 39921b8..4eb2f0a 100644 --- a/src/schema.rs +++ b/src/schema.rs | |||
@@ -1,3 +1,12 @@ | |||
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 | ||
1 | use chrono::{NaiveDate, NaiveDateTime}; | 10 | use chrono::{NaiveDate, NaiveDateTime}; |
2 | use lazy_static::lazy_static; | 11 | use lazy_static::lazy_static; |
3 | use parking_lot::RwLock; | 12 | use parking_lot::RwLock; |
@@ -9,24 +18,45 @@ use std::sync::Arc; | |||
9 | 18 | ||
10 | // use crate::validators; | 19 | // use crate::validators; |
11 | 20 | ||
12 | /// We need persistence for blocks and users, not so much for transactions | 21 | pub type PublicKeySignature = String; |
13 | /// There are around 30 students, a full fledged database would be an overkill (for next year?) | ||
14 | /// Pending transactions are held in memory, these are cleared with every new block | ||
15 | /// Only the last block is held in memory, every block is written to a file | ||
16 | /// Users are held in memory and they're also backed up to text files | ||
17 | 22 | ||
18 | /// Creates a new database connection | 23 | /// Creates a new database |
19 | pub fn create_database() -> Db { | 24 | pub fn create_database() -> Db { |
20 | fs::create_dir_all("blocks").unwrap(); | 25 | fs::create_dir_all("blocks").unwrap(); |
21 | fs::create_dir_all("users").unwrap(); | 26 | fs::create_dir_all("users").unwrap(); |
22 | Db::new() | 27 | Db::new() |
23 | } | 28 | } |
24 | 29 | ||
30 | /// A JWT Payload/Claims representation | ||
31 | /// | ||
32 | /// https://tools.ietf.org/html/rfc7519#section-4.1 | ||
33 | /// | ||
34 | /// - `tha`: Transaction Hash, String (custom field) | ||
35 | /// - `iat`: Issued At, Unix Time, epoch | ||
36 | /// - `exp`: Expiration Time, epoch | ||
37 | #[derive(Debug, Serialize, Deserialize)] | ||
38 | pub struct Claims { | ||
39 | pub tha: String, | ||
40 | pub iat: usize, | ||
41 | pub exp: usize, | ||
42 | } | ||
43 | |||
44 | /// Global Database representation | ||
45 | /// | ||
46 | /// [`blockchain`] is just the last block that was mined. All the blocks are written to disk as text | ||
47 | /// files whenever they are accepted. | ||
48 | /// | ||
49 | /// [`pending_transactions`] is the in memory representation of the waiting transactions. Every | ||
50 | /// user can have only one outstanding transaction at any given time. | ||
51 | /// | ||
52 | /// [`users`] is the in memory representation of the users, with their public keys, metu_ids and | ||
53 | /// gradecoin balances. | ||
54 | /// | ||
55 | /// TODO: Replace the pending_transactions HashMap<String, Transaction> with | ||
56 | /// HashMap<PublicKeySignature, Transaction> | ||
25 | #[derive(Debug, Clone)] | 57 | #[derive(Debug, Clone)] |
26 | pub struct Db { | 58 | pub struct Db { |
27 | // heh. also https://doc.rust-lang.org/std/collections/struct.LinkedList.html says Vec is generally faster | ||
28 | pub blockchain: Arc<RwLock<Block>>, | 59 | pub blockchain: Arc<RwLock<Block>>, |
29 | // every proposer can have _one_ pending transaction, a way to enforce this, String is proposer identifier | ||
30 | pub pending_transactions: Arc<RwLock<HashMap<String, Transaction>>>, | 60 | pub pending_transactions: Arc<RwLock<HashMap<String, Transaction>>>, |
31 | pub users: Arc<RwLock<HashMap<String, User>>>, | 61 | pub users: Arc<RwLock<HashMap<String, User>>>, |
32 | } | 62 | } |
@@ -41,8 +71,6 @@ impl Db { | |||
41 | } | 71 | } |
42 | } | 72 | } |
43 | 73 | ||
44 | pub type PublicKeySignature = String; | ||
45 | |||
46 | /// A transaction between `source` and `target` that moves `amount` | 74 | /// A transaction between `source` and `target` that moves `amount` |
47 | #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] | 75 | #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] |
48 | pub struct Transaction { | 76 | pub struct Transaction { |
@@ -53,20 +81,21 @@ pub struct Transaction { | |||
53 | pub timestamp: NaiveDateTime, | 81 | pub timestamp: NaiveDateTime, |
54 | } | 82 | } |
55 | 83 | ||
56 | /// A block that was proposed with `transaction_list` and `nonce` that made `hash` valid | 84 | /// A block that was proposed with `transaction_list` and `nonce` that made `hash` valid, 6 zeroes |
85 | /// at the right hand side of the hash (24 bytes) | ||
86 | /// | ||
87 | /// We are mining using blake2s algorithm, which produces 256 bit hashes. Hash/second is roughly | ||
88 | /// 20x10^3. | ||
89 | /// | ||
57 | /// https://serde.rs/container-attrs.html might be valuable to normalize the serialize/deserialize | 90 | /// https://serde.rs/container-attrs.html might be valuable to normalize the serialize/deserialize |
58 | /// conventions as these will be hashed | 91 | /// conventions as these will be hashed |
92 | /// | ||
59 | #[derive(Serialize, Deserialize, Debug)] | 93 | #[derive(Serialize, Deserialize, Debug)] |
60 | pub struct Block { | 94 | pub struct Block { |
61 | // TODO: transaction list should hold transaction hash values <09-04-21, yigit> // | 95 | pub transaction_list: Vec<PublicKeySignature>, |
62 | // but do we link them somehow? (like a log of old transactions?) | ||
63 | // we can leave this as is and whenever we have a new block we _could_ just log it to file | ||
64 | // somewhere | ||
65 | // I want to keep this as a String vector because it makes things easier elsewhere | ||
66 | pub transaction_list: Vec<PublicKeySignature>, // hashes of the transactions (or just "source" for now) | ||
67 | pub nonce: u32, | 96 | pub nonce: u32, |
68 | pub timestamp: NaiveDateTime, | 97 | pub timestamp: NaiveDateTime, |
69 | pub hash: String, // future proof'd baby | 98 | pub hash: String, |
70 | } | 99 | } |
71 | 100 | ||
72 | /// For prototyping and letting serde handle everything json | 101 | /// For prototyping and letting serde handle everything json |
@@ -89,7 +118,7 @@ impl Block { | |||
89 | } | 118 | } |
90 | } | 119 | } |
91 | 120 | ||
92 | /// Or simply a Student | 121 | /// Simply a Student |
93 | #[derive(Serialize, Deserialize, Debug)] | 122 | #[derive(Serialize, Deserialize, Debug)] |
94 | pub struct User { | 123 | pub struct User { |
95 | pub user_id: MetuId, | 124 | pub user_id: MetuId, |
@@ -103,6 +132,7 @@ pub struct MetuId { | |||
103 | id: String, | 132 | id: String, |
104 | } | 133 | } |
105 | 134 | ||
135 | // TODO: this will arrive encrypted <13-04-21, yigit> // | ||
106 | #[derive(Serialize, Deserialize, Debug)] | 136 | #[derive(Serialize, Deserialize, Debug)] |
107 | pub struct AuthRequest { | 137 | pub struct AuthRequest { |
108 | pub student_id: String, | 138 | pub student_id: String, |