diff options
author | Yigit Sever | 2021-04-07 04:33:45 +0300 |
---|---|---|
committer | Yigit Sever | 2021-04-07 04:35:44 +0300 |
commit | 84d9c14a17e864058527981e3388cef148827c11 (patch) | |
tree | 19c7b4b4d67d2ba2d3d87ba7eca009ff997e0cd0 /src/schema.rs | |
parent | 95ff6371303ac28d05b25fd9f6e436c5d0a58d4c (diff) | |
download | gradecoin-84d9c14a17e864058527981e3388cef148827c11.tar.gz gradecoin-84d9c14a17e864058527981e3388cef148827c11.tar.bz2 gradecoin-84d9c14a17e864058527981e3388cef148827c11.zip |
Implement Block GET/PUT with new schema
- `Arc`+`Mutex` is replaced by `parking_lot::RwLock,` decoupled
Read+Write and ability to upgrade read locks into write locks if
needed
- Schema has changed, `Db` is now a struct that implements `new()` to
return a new instance of itself, pros/cons listed in code but tl;dr
blockchain and pending transactions are separate now
- `custom_filters` now supports extracting Block json and Transaction
json in separate functions too
- /block GET and PUT implemented, `Blocks` currently have one check
(transactions appear in pending transaction)
- debug is working after something, dunno how I fixed it
Diffstat (limited to 'src/schema.rs')
-rw-r--r-- | src/schema.rs | 65 |
1 files changed, 45 insertions, 20 deletions
diff --git a/src/schema.rs b/src/schema.rs index ea36a70..57210a3 100644 --- a/src/schema.rs +++ b/src/schema.rs | |||
@@ -1,31 +1,46 @@ | |||
1 | // Common types used across API | 1 | use chrono::NaiveDateTime; |
2 | 2 | use parking_lot::RwLock; | |
3 | use chrono::{NaiveDate, NaiveDateTime}; | ||
4 | use serde::{Deserialize, Serialize}; | 3 | use serde::{Deserialize, Serialize}; |
4 | use std::collections::HashMap; | ||
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | use tokio::sync::Mutex; | ||
7 | 6 | ||
8 | // use crate::validators; | 7 | // use crate::validators; |
9 | 8 | ||
10 | pub fn ledger() -> Db { | 9 | // In memory data structure |
11 | // TODO: there was something simpler in one of the other tutorials? <07-04-21, yigit> // | 10 | |
12 | 11 | // Two approaches here | |
13 | Arc::new(Mutex::new(vec![ | 12 | // 1. Db is a type |
14 | Transaction { | 13 | // pub type Db = Arc<RwLock<Vec<Ledger>>>; |
15 | source: String::from("Myself"), | 14 | // Ledger is a struct, we wrap the ledger with arc + mutex in ledger() |
16 | target: String::from("Nobody"), | 15 | // to access transactions we need to unwrap blocks as well, vice versa |
17 | amount: 4, | 16 | // |
18 | timestamp: NaiveDate::from_ymd(2021, 4, 7).and_hms(00, 17, 00), | 17 | // 2. Db is a struct, attributes are wrapped |
19 | }, | 18 | // we can offload ::new() to it's member method |
20 | ])) | 19 | // blocks and transactions are accessible separately, which is the biggest pro |
20 | |||
21 | /// Creates a new database | ||
22 | pub fn create_database() -> Db { | ||
23 | Db::new() | ||
21 | } | 24 | } |
22 | 25 | ||
26 | #[derive(Debug, Clone)] | ||
27 | pub struct Db { | ||
28 | // heh. also https://doc.rust-lang.org/std/collections/struct.LinkedList.html says Vec is generally faster | ||
29 | pub blockchain: Arc<RwLock<Vec<Block>>>, | ||
30 | // every proposer can have _one_ pending transaction, a way to enforce this, String is proposer identifier | ||
31 | pub pending_transactions: Arc<RwLock<HashMap<String, Transaction>>>, | ||
32 | } | ||
23 | 33 | ||
24 | // For presentation purposes keep mocked data in in-memory structure | 34 | impl Db { |
25 | // In real life scenario connection with regular database would be established | 35 | fn new() -> Self { |
26 | 36 | Db { | |
27 | pub type Db = Arc<Mutex<Vec<Transaction>>>; | 37 | blockchain: Arc::new(RwLock::new(Vec::new())), |
38 | pending_transactions: Arc::new(RwLock::new(HashMap::new())), | ||
39 | } | ||
40 | } | ||
41 | } | ||
28 | 42 | ||
43 | /// A transaction between `source` and `target` that moves `amount` | ||
29 | #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] | 44 | #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] |
30 | pub struct Transaction { | 45 | pub struct Transaction { |
31 | pub source: String, | 46 | pub source: String, |
@@ -34,14 +49,22 @@ pub struct Transaction { | |||
34 | pub timestamp: NaiveDateTime, | 49 | pub timestamp: NaiveDateTime, |
35 | } | 50 | } |
36 | 51 | ||
52 | /// A block that was proposed with `transaction_list` and `nonce` that made `hash` valid | ||
37 | #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] | 53 | #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] |
38 | pub struct Block { | 54 | pub struct Block { |
39 | pub transaction_list: Vec<Transaction>, // [Transaction; N] | 55 | pub transaction_list: Vec<String>, // hashes of the transactions (or just "source" for now) |
40 | pub nonce: i32, | 56 | pub nonce: i32, |
41 | pub timestamp: NaiveDateTime, | 57 | pub timestamp: NaiveDateTime, |
42 | pub hash: String, // future proof'd baby | 58 | pub hash: String, // future proof'd baby |
43 | } | 59 | } |
44 | 60 | ||
61 | // pub struct Ledger { | ||
62 | // // heh. also https://doc.rust-lang.org/std/collections/struct.LinkedList.html says Vec is generally faster | ||
63 | // blockchain: Vec<Block>, | ||
64 | // // every proposer can have _one_ pending transaction, a way to enforce this, String is proposer identifier | ||
65 | // pending_transactions: HashMap<String, Transaction>, | ||
66 | // } | ||
67 | |||
45 | // #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] | 68 | // #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] |
46 | // #[serde(rename_all = "camelCase")] | 69 | // #[serde(rename_all = "camelCase")] |
47 | // pub struct Game { | 70 | // pub struct Game { |
@@ -99,6 +122,8 @@ pub struct Block { | |||
99 | // )) | 122 | // )) |
100 | // } | 123 | // } |
101 | 124 | ||
125 | // TODO: these tests are amazing, we should write some when schema is decided upon <07-04-21, yigit> // | ||
126 | |||
102 | // #[cfg(test)] | 127 | // #[cfg(test)] |
103 | // mod tests { | 128 | // mod tests { |
104 | // use super::*; | 129 | // use super::*; |