aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/handlers.rs48
-rw-r--r--src/schema.rs7
-rw-r--r--tests/route_tests.rs10
3 files changed, 46 insertions, 19 deletions
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};
19 19
20use crate::PRIVATE_KEY; 20use crate::PRIVATE_KEY;
21const BLOCK_TRANSACTION_COUNT: u8 = 10; 21const BLOCK_TRANSACTION_COUNT: u8 = 10;
22const BLOCK_REWARD: u8 = 3; 22const BLOCK_REWARD: u16 = 3;
23const TX_UPPER_LIMIT: u16 = 2;
23 24
24// Encryption primitive 25// Encryption primitive
25type Aes128Cbc = Cbc<Aes128, Pkcs7>; 26type Aes128Cbc = Cbc<Aes128, Pkcs7>;
@@ -341,7 +342,7 @@ pub async fn authorized_propose_block(
341 342
342 warn!("{:?}", &new_block); 343 warn!("{:?}", &new_block);
343 344
344 if new_block.transaction_list.is_empty() { 345 if new_block.transaction_list.len() != BLOCK_TRANSACTION_COUNT as usize {
345 let res_json = warp::reply::json(&GradeCoinResponse { 346 let res_json = warp::reply::json(&GradeCoinResponse {
346 res: ResponseType::Error, 347 res: ResponseType::Error,
347 message: format!( 348 message: format!(
@@ -480,7 +481,7 @@ pub async fn authorized_propose_block(
480 } 481 }
481 482
482 if let Some(coinbase_user) = users_store.get_mut(coinbase_fingerprint) { 483 if let Some(coinbase_user) = users_store.get_mut(coinbase_fingerprint) {
483 coinbase_user.balance += BLOCK_REWARD as i32; 484 coinbase_user.balance += BLOCK_REWARD;
484 } 485 }
485 } 486 }
486 487
@@ -565,11 +566,10 @@ pub async fn authorized_propose_transaction(
565 StatusCode::BAD_REQUEST, 566 StatusCode::BAD_REQUEST,
566 )); 567 ));
567 } 568 }
568 } else if new_transaction.by == new_transaction.target 569 }
569 && new_transaction.source 570
570 != "31415926535897932384626433832795028841971693993751058209749445923" 571 // Is transaction amount within bounds
571 { 572 if new_transaction.amount > TX_UPPER_LIMIT {
572 // Propose to transact with the bank
573 return Ok(warp::reply::with_status( 573 return Ok(warp::reply::with_status(
574 warp::reply::json(&GradeCoinResponse { 574 warp::reply::json(&GradeCoinResponse {
575 res: ResponseType::Error, 575 res: ResponseType::Error,
@@ -577,6 +577,36 @@ pub async fn authorized_propose_transaction(
577 }), 577 }),
578 StatusCode::BAD_REQUEST, 578 StatusCode::BAD_REQUEST,
579 )); 579 ));
580 }
581
582 if new_transaction.by == new_transaction.source {
583 // check if user can afford the transaction
584 if internal_user.balance < new_transaction.amount {
585 return Ok(warp::reply::with_status(
586 warp::reply::json(&GradeCoinResponse {
587 res: ResponseType::Error,
588 message:
589 "User does not have enough balance in their account for this transaction"
590 .to_owned(),
591 }),
592 StatusCode::BAD_REQUEST,
593 ));
594 }
595 } else if new_transaction.by == new_transaction.target {
596 // Only transactions FROM bank could appear here
597
598 if new_transaction.source
599 != "31415926535897932384626433832795028841971693993751058209749445923"
600 {
601 return Ok(warp::reply::with_status(
602 warp::reply::json(&GradeCoinResponse {
603 res: ResponseType::Error,
604 message: "Transactions cannot extort Gradecoin from unsuspecting users"
605 .to_owned(),
606 }),
607 StatusCode::BAD_REQUEST,
608 ));
609 }
580 } else { 610 } else {
581 return Ok(warp::reply::with_status( 611 return Ok(warp::reply::with_status(
582 warp::reply::json(&GradeCoinResponse { 612 warp::reply::json(&GradeCoinResponse {
@@ -719,7 +749,7 @@ struct UserTemplate<'a> {
719 749
720struct DisplayUsers { 750struct DisplayUsers {
721 fingerprint: String, 751 fingerprint: String,
722 balance: i32, 752 balance: u16,
723} 753}
724 754
725pub async fn user_list_handler(db: Db) -> Result<impl warp::Reply, warp::Rejection> { 755pub async fn user_list_handler(db: Db) -> Result<impl warp::Reply, warp::Rejection> {
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;
27fn block_parser(path: String) -> u64 { 27fn block_parser(path: String) -> u64 {
28 let end_pos = path.find(".block").unwrap(); 28 let end_pos = path.find(".block").unwrap();
29 let block_str = path[9..end_pos].to_string(); 29 let block_str = path[9..end_pos].to_string();
30 let block_u64 : u64 = block_str.parse().unwrap(); 30 let block_u64: u64 = block_str.parse().unwrap();
31 block_u64 31 block_u64
32} 32}
33 33
@@ -51,7 +51,6 @@ fn last_block_content() -> Option<String> {
51 } 51 }
52 } 52 }
53 return Some(blocks[last_block_index].to_str().unwrap().parse().unwrap()); 53 return Some(blocks[last_block_index].to_str().unwrap().parse().unwrap());
54
55} 54}
56 55
57fn read_block_name() -> io::Result<Vec<PathBuf>> { 56fn read_block_name() -> io::Result<Vec<PathBuf>> {
@@ -180,7 +179,7 @@ pub struct Transaction {
180 pub by: Fingerprint, 179 pub by: Fingerprint,
181 pub source: Fingerprint, 180 pub source: Fingerprint,
182 pub target: Fingerprint, 181 pub target: Fingerprint,
183 pub amount: i32, 182 pub amount: u16,
184 pub timestamp: NaiveDateTime, 183 pub timestamp: NaiveDateTime,
185} 184}
186 185
@@ -238,7 +237,7 @@ impl Default for Block {
238pub struct User { 237pub struct User {
239 pub user_id: MetuId, 238 pub user_id: MetuId,
240 pub public_key: String, 239 pub public_key: String,
241 pub balance: i32, 240 pub balance: u16,
242} 241}
243 242
244/// The values are hard coded in [`OUR_STUDENTS`] so MetuId::new() can accept/reject values based on that 243/// The values are hard coded in [`OUR_STUDENTS`] so MetuId::new() can accept/reject values based on that
diff --git a/tests/route_tests.rs b/tests/route_tests.rs
index 3d8b7f4..3125bc8 100644
--- a/tests/route_tests.rs
+++ b/tests/route_tests.rs
@@ -80,7 +80,7 @@ FQIDAQAB
80 source: "31415926535897932384626433832795028841971693993751058209749445923" 80 source: "31415926535897932384626433832795028841971693993751058209749445923"
81 .to_owned(), 81 .to_owned(),
82 target: "mock_transaction_source".to_owned(), 82 target: "mock_transaction_source".to_owned(),
83 amount: 3, 83 amount: 2,
84 timestamp: chrono::NaiveDate::from_ymd(2021, 04, 13).and_hms(20, 55, 30), 84 timestamp: chrono::NaiveDate::from_ymd(2021, 04, 13).and_hms(20, 55, 30),
85 }, 85 },
86 ); 86 );
@@ -105,7 +105,7 @@ FQIDAQAB
105 by: "mock_transaction_source".to_owned(), 105 by: "mock_transaction_source".to_owned(),
106 source: "mock_transaction_source".to_owned(), 106 source: "mock_transaction_source".to_owned(),
107 target: "mock_transaction_target".to_owned(), 107 target: "mock_transaction_target".to_owned(),
108 amount: 25, 108 amount: 2,
109 timestamp: chrono::NaiveDate::from_ymd(2021, 04, 09).and_hms(14, 30, 00), 109 timestamp: chrono::NaiveDate::from_ymd(2021, 04, 09).and_hms(14, 30, 00),
110 } 110 }
111 } 111 }
@@ -114,11 +114,10 @@ FQIDAQAB
114 by: "mock_transaction_source2".to_owned(), 114 by: "mock_transaction_source2".to_owned(),
115 source: "mock_transaction_source2".to_owned(), 115 source: "mock_transaction_source2".to_owned(),
116 target: "mock_transaction_target".to_owned(), 116 target: "mock_transaction_target".to_owned(),
117 amount: 25, 117 amount: 2,
118 timestamp: chrono::NaiveDate::from_ymd(2021, 04, 09).and_hms(14, 30, 00), 118 timestamp: chrono::NaiveDate::from_ymd(2021, 04, 09).and_hms(14, 30, 00),
119 } 119 }
120 } 120 }
121 // r#"{"by":"mock_transaction_source","source":"mock_transaction_source","target":"mock_transaction_target","amount":25,"timestamp":"2021-04-09T14:30:00"}"#
122 121
123 /// Test simple GET request to /transaction, an endpoint that exists 122 /// Test simple GET request to /transaction, an endpoint that exists
124 /// https://tools.ietf.org/html/rfc7231#section-6.3.1 123 /// https://tools.ietf.org/html/rfc7231#section-6.3.1
@@ -137,7 +136,7 @@ FQIDAQAB
137 136
138 assert_eq!(res.status(), StatusCode::OK); 137 assert_eq!(res.status(), StatusCode::OK);
139 138
140 let expected_json_body = r#"{"mock_transaction_source":{"by":"mock_transaction_source","source":"31415926535897932384626433832795028841971693993751058209749445923","target":"mock_transaction_source","amount":3,"timestamp":"2021-04-13T20:55:30"}}"#; 139 let expected_json_body = r#"{"mock_transaction_source":{"by":"mock_transaction_source","source":"31415926535897932384626433832795028841971693993751058209749445923","target":"mock_transaction_source","amount":2,"timestamp":"2021-04-13T20:55:30"}}"#;
141 140
142 assert_eq!(res.body(), expected_json_body); 141 assert_eq!(res.body(), expected_json_body);
143 } 142 }
@@ -242,7 +241,6 @@ FQIDAQAB
242 /// the block 241 /// the block
243 #[tokio::test] 242 #[tokio::test]
244 async fn post_block_auth_201() { 243 async fn post_block_auth_201() {
245 println!("Wtf");
246 let db = mocked_db(); 244 let db = mocked_db();
247 let filter = consensus_routes(db.clone()); 245 let filter = consensus_routes(db.clone());
248 246