aboutsummaryrefslogtreecommitdiffstats
path: root/src/schema.rs
diff options
context:
space:
mode:
authorYigit Sever2021-04-13 04:05:44 +0300
committerYigit Sever2021-04-13 04:05:49 +0300
commitb06cbd69fc2a7544f6f62c20cbdfb30bda194101 (patch)
treee639c13328c3c0083f3f343fb5633290ec2bf29c /src/schema.rs
parent42cad1e409727ae8e1fd9f9d1c0b520e9c0565f8 (diff)
downloadgradecoin-b06cbd69fc2a7544f6f62c20cbdfb30bda194101.tar.gz
gradecoin-b06cbd69fc2a7544f6f62c20cbdfb30bda194101.tar.bz2
gradecoin-b06cbd69fc2a7544f6f62c20cbdfb30bda194101.zip
Housekeeping
Moved tests out of routes.rs into their own file Learned how to use lib.rs, now we have cargo doc support as well
Diffstat (limited to 'src/schema.rs')
-rw-r--r--src/schema.rs68
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
1use chrono::{NaiveDate, NaiveDateTime}; 10use chrono::{NaiveDate, NaiveDateTime};
2use lazy_static::lazy_static; 11use lazy_static::lazy_static;
3use parking_lot::RwLock; 12use 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 21pub 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
19pub fn create_database() -> Db { 24pub 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)]
38pub 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)]
26pub struct Db { 58pub 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
44pub 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)]
48pub struct Transaction { 76pub 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)]
60pub struct Block { 94pub 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)]
94pub struct User { 123pub 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)]
107pub struct AuthRequest { 137pub struct AuthRequest {
108 pub student_id: String, 138 pub student_id: String,