diff options
Diffstat (limited to 'src/handlers.rs')
-rw-r--r-- | src/handlers.rs | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/src/handlers.rs b/src/handlers.rs index bfd57bc..6edc96f 100644 --- a/src/handlers.rs +++ b/src/handlers.rs | |||
@@ -2,12 +2,15 @@ | |||
2 | use log::debug; | 2 | use log::debug; |
3 | use parking_lot::RwLockUpgradableReadGuard; | 3 | use parking_lot::RwLockUpgradableReadGuard; |
4 | use serde_json; | 4 | use serde_json; |
5 | use serde_json::json; | ||
5 | use std::convert::Infallible; | 6 | use std::convert::Infallible; |
6 | use warp::{http::Response, http::StatusCode, reply}; | 7 | use warp::{http::Response, http::StatusCode, reply}; |
7 | 8 | ||
9 | use blake2::{Blake2s, Digest}; | ||
10 | |||
8 | use std::fs; | 11 | use std::fs; |
9 | 12 | ||
10 | use crate::schema::{AuthRequest, Block, Db, MetuId, Transaction, User}; | 13 | use gradecoin::schema::{AuthRequest, Block, Db, MetuId, NakedBlock, Transaction, User}; |
11 | 14 | ||
12 | /// POST /register | 15 | /// POST /register |
13 | /// Enables a student to introduce themselves to the system | 16 | /// Enables a student to introduce themselves to the system |
@@ -22,7 +25,6 @@ pub async fn authenticate_user( | |||
22 | let userlist = db.users.upgradable_read(); | 25 | let userlist = db.users.upgradable_read(); |
23 | 26 | ||
24 | if userlist.contains_key(&given_id) { | 27 | if userlist.contains_key(&given_id) { |
25 | |||
26 | let res = Response::builder() | 28 | let res = Response::builder() |
27 | .status(StatusCode::BAD_REQUEST) | 29 | .status(StatusCode::BAD_REQUEST) |
28 | .body("This user is already authenticated"); | 30 | .body("This user is already authenticated"); |
@@ -124,24 +126,44 @@ pub async fn propose_block(new_block: Block, db: Db) -> Result<impl warp::Reply, | |||
124 | } | 126 | } |
125 | } | 127 | } |
126 | 128 | ||
127 | // TODO: check 2, block hash (\w nonce) asserts $hash_condition? <07-04-21, yigit> // | 129 | let naked_block = NakedBlock { |
128 | // assume it is for now | 130 | transaction_list: new_block.transaction_list.clone(), |
131 | nonce: new_block.nonce.clone(), | ||
132 | timestamp: new_block.timestamp.clone(), | ||
133 | }; | ||
129 | 134 | ||
130 | let mut blockchain = RwLockUpgradableReadGuard::upgrade(blockchain); | 135 | let naked_block_flat = serde_json::to_vec(&naked_block).unwrap(); |
131 | 136 | ||
132 | let block_json = serde_json::to_string(&new_block).unwrap(); | 137 | let hashvalue = Blake2s::digest(&naked_block_flat); |
138 | let hash_string = format!("{:x}", hashvalue); | ||
133 | 139 | ||
134 | // let mut file = File::create(format!("{}.block", new_block.timestamp.timestamp())).unwrap(); | 140 | // 5 rightmost bits are zero |
135 | fs::write( | 141 | let should_zero = hashvalue[31] as i32 + hashvalue[30] as i32 + (hashvalue[29] << 4) as i32; |
136 | format!("blocks/{}.block", new_block.timestamp.timestamp()), | ||
137 | block_json, | ||
138 | ) | ||
139 | .unwrap(); | ||
140 | 142 | ||
141 | *blockchain = new_block; | 143 | if should_zero == 0 { |
144 | // one last check to see if block is telling the truth | ||
145 | if hash_string == new_block.hash { | ||
146 | let mut blockchain = RwLockUpgradableReadGuard::upgrade(blockchain); | ||
142 | 147 | ||
143 | let mut pending_transactions = RwLockUpgradableReadGuard::upgrade(pending_transactions); | 148 | let block_json = serde_json::to_string(&new_block).unwrap(); |
144 | pending_transactions.clear(); | ||
145 | 149 | ||
146 | Ok(StatusCode::CREATED) | 150 | fs::write( |
151 | format!("blocks/{}.block", new_block.timestamp.timestamp()), | ||
152 | block_json, | ||
153 | ) | ||
154 | .unwrap(); | ||
155 | |||
156 | *blockchain = new_block; | ||
157 | |||
158 | let mut pending_transactions = RwLockUpgradableReadGuard::upgrade(pending_transactions); | ||
159 | pending_transactions.clear(); | ||
160 | |||
161 | Ok(StatusCode::CREATED) | ||
162 | } else { | ||
163 | Ok(StatusCode::BAD_REQUEST) | ||
164 | } | ||
165 | } else { | ||
166 | // reject | ||
167 | Ok(StatusCode::BAD_REQUEST) | ||
168 | } | ||
147 | } | 169 | } |