aboutsummaryrefslogtreecommitdiffstats
path: root/src/block.rs
blob: e70777925b1268917852ceb00712ed1a2982bfb1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//! # Data Representations
//!
//! We need persistence for [`Block`]s and [`User`]s, not so much for [`Transaction`]s
//!
//! There are around 30 students, a full fledged database would be an overkill (for next year?)
//!
//! Pending transactions are held in memory, these are cleared with every new block
//! Only the last block is held in memory, every block is written to a file
//! Users are held in memory and they're also backed up to text files
use chrono::{NaiveDate, NaiveDateTime};
use serde::{Deserialize, Serialize};
use std::{string::String, vec::Vec};

pub type Fingerprint = String;
pub type Id = String;

/// A block that was proposed with `transaction_list` and `nonce`
/// that made `hash` valid, 6 zeroes at the left hand side of the hash (24 bytes)
///
/// We are mining using blake2s algorithm, which produces 256 bit hashes.
/// Hash/second is roughly 20x10^3.
///
/// <https://serde.rs/container-attrs.html> might be valuable to normalize the
/// serialize/deserialize conventions as these will be hashed
///
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Block {
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub transaction_list: Vec<Fingerprint>,
    pub nonce: u32,
    pub timestamp: NaiveDateTime,
    pub hash: String,
}

impl Default for Block {
    fn default() -> Self {
        Block {
            transaction_list: vec!["gradecoin_bank".to_owned()],
            nonce: 0,
            timestamp: NaiveDate::from_ymd(2022, 4, 11).and_hms(20, 45, 00),
            hash: String::from("not_actually_mined"),
        }
    }
}

/// For prototyping and letting serde handle everything json
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct NakedBlock {
    #[serde(skip_serializing_if = "Vec::is_empty", default)]
    pub transaction_list: Vec<Fingerprint>,
    pub nonce: u32,
    pub timestamp: NaiveDateTime,
}

/// A transaction between `source` and `target` that moves `amount`
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Transaction {
    pub source: Fingerprint,
    pub target: Fingerprint,
    pub amount: u16,
    pub timestamp: NaiveDateTime,
}

/// A JWT Payload/Claims representation
///
/// <https://tools.ietf.org/html/rfc7519#section-4.1>
///
/// - `tha`: Transaction Hash, String (custom field)
/// - `iat`: Issued At, Unix Time, epoch
/// - `exp`: Expiration Time, epoch
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Claims {
    pub tha: String,
    pub iat: usize,
    pub exp: usize,
}

/// The plaintext of the initial user authentication request
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct AuthRequest {
    pub student_id: String,
    pub passwd: String,
    pub public_key: String,
}

/// Ciphertext of the initial authentication request, or what we will receive
#[derive(Serialize, Deserialize, Debug)]
pub struct InitialAuthRequest {
    pub c: String,
    pub iv: String,
    pub key: String,
}