From cd4214da789df660c5d1d70f390ff164da244335 Mon Sep 17 00:00:00 2001 From: Yigit Sever Date: Sat, 17 Apr 2021 19:47:39 +0300 Subject: Implement block/tx bounds --- src/handlers.rs | 48 +++++++++++++++++++++++++++++++++++++++--------- src/schema.rs | 7 +++---- 2 files changed, 42 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/handlers.rs b/src/handlers.rs index c2c8aca..9be9764 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -19,7 +19,8 @@ use warp::{http::StatusCode, reply}; use crate::PRIVATE_KEY; const BLOCK_TRANSACTION_COUNT: u8 = 10; -const BLOCK_REWARD: u8 = 3; +const BLOCK_REWARD: u16 = 3; +const TX_UPPER_LIMIT: u16 = 2; // Encryption primitive type Aes128Cbc = Cbc; @@ -341,7 +342,7 @@ pub async fn authorized_propose_block( warn!("{:?}", &new_block); - if new_block.transaction_list.is_empty() { + if new_block.transaction_list.len() != BLOCK_TRANSACTION_COUNT as usize { let res_json = warp::reply::json(&GradeCoinResponse { res: ResponseType::Error, message: format!( @@ -480,7 +481,7 @@ pub async fn authorized_propose_block( } if let Some(coinbase_user) = users_store.get_mut(coinbase_fingerprint) { - coinbase_user.balance += BLOCK_REWARD as i32; + coinbase_user.balance += BLOCK_REWARD; } } @@ -565,11 +566,10 @@ pub async fn authorized_propose_transaction( StatusCode::BAD_REQUEST, )); } - } else if new_transaction.by == new_transaction.target - && new_transaction.source - != "31415926535897932384626433832795028841971693993751058209749445923" - { - // Propose to transact with the bank + } + + // Is transaction amount within bounds + if new_transaction.amount > TX_UPPER_LIMIT { return Ok(warp::reply::with_status( warp::reply::json(&GradeCoinResponse { res: ResponseType::Error, @@ -577,6 +577,36 @@ pub async fn authorized_propose_transaction( }), StatusCode::BAD_REQUEST, )); + } + + if new_transaction.by == new_transaction.source { + // check if user can afford the transaction + if internal_user.balance < new_transaction.amount { + return Ok(warp::reply::with_status( + warp::reply::json(&GradeCoinResponse { + res: ResponseType::Error, + message: + "User does not have enough balance in their account for this transaction" + .to_owned(), + }), + StatusCode::BAD_REQUEST, + )); + } + } else if new_transaction.by == new_transaction.target { + // Only transactions FROM bank could appear here + + if new_transaction.source + != "31415926535897932384626433832795028841971693993751058209749445923" + { + return Ok(warp::reply::with_status( + warp::reply::json(&GradeCoinResponse { + res: ResponseType::Error, + message: "Transactions cannot extort Gradecoin from unsuspecting users" + .to_owned(), + }), + StatusCode::BAD_REQUEST, + )); + } } else { return Ok(warp::reply::with_status( warp::reply::json(&GradeCoinResponse { @@ -719,7 +749,7 @@ struct UserTemplate<'a> { struct DisplayUsers { fingerprint: String, - balance: i32, + balance: u16, } pub async fn user_list_handler(db: Db) -> Result { diff --git a/src/schema.rs b/src/schema.rs index df7b14a..957f0a9 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -27,7 +27,7 @@ pub type Fingerprint = String; fn block_parser(path: String) -> u64 { let end_pos = path.find(".block").unwrap(); let block_str = path[9..end_pos].to_string(); - let block_u64 : u64 = block_str.parse().unwrap(); + let block_u64: u64 = block_str.parse().unwrap(); block_u64 } @@ -51,7 +51,6 @@ fn last_block_content() -> Option { } } return Some(blocks[last_block_index].to_str().unwrap().parse().unwrap()); - } fn read_block_name() -> io::Result> { @@ -180,7 +179,7 @@ pub struct Transaction { pub by: Fingerprint, pub source: Fingerprint, pub target: Fingerprint, - pub amount: i32, + pub amount: u16, pub timestamp: NaiveDateTime, } @@ -238,7 +237,7 @@ impl Default for Block { pub struct User { pub user_id: MetuId, pub public_key: String, - pub balance: i32, + pub balance: u16, } /// The values are hard coded in [`OUR_STUDENTS`] so MetuId::new() can accept/reject values based on that -- cgit v1.2.3-70-g09d2