aboutsummaryrefslogtreecommitdiffstats
path: root/src/handlers.rs
diff options
context:
space:
mode:
authorYigit Sever2021-04-07 04:33:45 +0300
committerYigit Sever2021-04-07 04:35:44 +0300
commit20dad7d4290f2c98583168cd4b9afcdec4802944 (patch)
treeb761b56e8b629d8a295b4dd7ca55a5d7745fd4c6 /src/handlers.rs
parent95ff6371303ac28d05b25fd9f6e436c5d0a58d4c (diff)
downloadgradecoin-20dad7d4290f2c98583168cd4b9afcdec4802944.tar.gz
gradecoin-20dad7d4290f2c98583168cd4b9afcdec4802944.tar.bz2
gradecoin-20dad7d4290f2c98583168cd4b9afcdec4802944.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/handlers.rs')
-rw-r--r--src/handlers.rs94
1 files changed, 71 insertions, 23 deletions
diff --git a/src/handlers.rs b/src/handlers.rs
index 51c7b63..ecf5a92 100644
--- a/src/handlers.rs
+++ b/src/handlers.rs
@@ -1,45 +1,93 @@
1// API handlers, the ends of each filter chain 1/// API handlers, the ends of each filter chain
2 2use log::debug; // this is more useful than debug! learn how to use this
3use log::debug; 3use parking_lot::RwLockUpgradableReadGuard;
4use std::convert::Infallible; 4use std::convert::Infallible;
5use warp::{http::StatusCode, reply}; 5use warp::{http::StatusCode, reply};
6 6
7use crate::schema::{Db, Transaction}; // `Block` coming later 7use crate::schema::{Block, Db, Transaction};
8
9/// GET /transaction
10/// Returns JSON array of transactions
11/// Cannot fail
12pub async fn list_transactions(db: Db) -> Result<impl warp::Reply, Infallible> {
13 debug!("list all transactions");
14 let mut result = Vec::new();
15
16 let transactions = db.pending_transactions.read();
17 // let transactions = transactions.clone().into_iter().collect();
18
19 for (_, value) in transactions.iter() {
20 result.push(value)
21 }
22
23 Ok(reply::with_status(reply::json(&result), StatusCode::OK))
24}
25
26/// GET /block
27/// Returns JSON array of blocks
28/// Cannot fail
29/// Mostly around for debug purposes
30pub async fn list_blocks(db: Db) -> Result<impl warp::Reply, Infallible> {
31 debug!("list all blocks");
32
33 let mut result = Vec::new();
34 let blocks = db.blockchain.read();
35
36 for block in blocks.iter() {
37 result.push(block);
38 }
8 39
9// PROPOSE Transaction 40 Ok(reply::with_status(reply::json(&result), StatusCode::OK))
10// POST /transaction 41}
42
43/// POST /transaction
44/// Pushes a new transaction for pending transaction pool
45/// Can reject the transaction proposal
46/// TODO: when is a new transaction rejected <07-04-21, yigit> //
11pub async fn propose_transaction( 47pub async fn propose_transaction(
12 new_transaction: Transaction, 48 new_transaction: Transaction,
13 db: Db, 49 db: Db,
14) -> Result<impl warp::Reply, warp::Rejection> { 50) -> Result<impl warp::Reply, warp::Rejection> {
15 debug!("new transaction request {:?}", new_transaction); 51 debug!("new transaction request {:?}", new_transaction);
16 52
17 let mut transactions = db.lock().await; 53 // let mut transactions = db.lock().await;
54 let mut transactions = db.pending_transactions.write();
18 55
19 transactions.push(new_transaction); 56 transactions.insert(new_transaction.source.to_owned(), new_transaction);
20 57
21 Ok(StatusCode::CREATED) 58 Ok(StatusCode::CREATED)
22} 59}
23 60
24// GET Transaction List 61/// POST /block
25// GET /transaction 62/// Proposes a new block for the next round
26// Returns JSON array of transactions 63/// Can reject the block
27// Cannot fail? 64pub async fn propose_block(new_block: Block, db: Db) -> Result<impl warp::Reply, warp::Rejection> {
28pub async fn list_transactions(db: Db) -> Result<impl warp::Reply, Infallible> { 65 debug!("new block request {:?}", new_block);
29 debug!("list all transactions");
30 66
31 let transactions = db.lock().await; 67 // https://blog.logrocket.com/create-an-async-crud-web-service-in-rust-with-warp/ (this has
68 // error.rs, error struct, looks very clean)
32 69
33 let transactions: Vec<Transaction> = transactions.clone().into_iter().collect(); 70 let pending_transactions = db.pending_transactions.upgradable_read();
71 let blockchain = db.blockchain.upgradable_read();
34 72
35 Ok(reply::with_status( 73 // TODO: check 1, new_block.transaction_list from pending_transactions pool? <07-04-21, yigit> //
36 reply::json(&transactions), 74 for transaction_hash in new_block.transaction_list.iter() {
37 StatusCode::OK, 75 if !pending_transactions.contains_key(transaction_hash) {
38 )) 76 return Ok(StatusCode::BAD_REQUEST);
39} 77 }
78 }
40 79
41// PROPOSE Block 80 // TODO: check 2, block hash (\w nonce) asserts $hash_condition? <07-04-21, yigit> //
42// POST /block 81 // assume it is for now
82
83 let mut blockchain = RwLockUpgradableReadGuard::upgrade(blockchain);
84 blockchain.push(new_block);
85
86 let mut pending_transactions = RwLockUpgradableReadGuard::upgrade(pending_transactions);
87 pending_transactions.clear();
88
89 Ok(StatusCode::CREATED)
90}
43 91
44// `GET /games` 92// `GET /games`
45// Returns JSON array of todos 93// Returns JSON array of todos