From d2c7d912e64d5161d0eeb61c3ecf5cc589900f01 Mon Sep 17 00:00:00 2001 From: lza_menace Date: Thu, 2 Jul 2020 18:56:14 -0700 Subject: [PATCH] fixing up functions and trying to clean up code --- src/data_types.rs | 10 +- src/main.rs | 240 +++++++++++++++++++++++----------------------- 2 files changed, 123 insertions(+), 127 deletions(-) diff --git a/src/data_types.rs b/src/data_types.rs index f455f25..a5ffd3e 100644 --- a/src/data_types.rs +++ b/src/data_types.rs @@ -36,9 +36,9 @@ impl Default for RPCParams { #[derive(Serialize, Deserialize, Hash, Eq, PartialEq, Debug, Clone)] pub struct GetInfo { - pub jsonrpc: String, - pub id: String, - pub result: GetInfoResult + pub jsonrpc: Option, + pub id: Option, + pub result: Option } #[derive(Serialize, Deserialize, Hash, Eq, PartialEq, Debug, Clone)] @@ -140,7 +140,7 @@ impl GetTransactionsTxs { #[derive(Serialize, Deserialize, Hash, Eq, PartialEq, Debug, Clone)] pub struct GetBlock { - pub id: String, + pub id: i32, pub jsonrpc: String, pub result: GetBlockResult } @@ -202,7 +202,7 @@ pub struct TransactionJSON { pub vin: Vec, pub vout: Vec, pub extra: Vec, - pub rct_signatures: RingSignatures + pub rct_signatures: Option } #[derive(Serialize, Deserialize, Hash, Eq, PartialEq, Debug, Clone)] diff --git a/src/main.rs b/src/main.rs index cc298ec..0ba1046 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,87 +8,77 @@ mod data_types; use rocket::http::RawStr; use rocket::response::Redirect; -use rocket_contrib::json::{Json,JsonValue}; +use rocket_contrib::json::JsonValue; use rocket_contrib::templates::Template; use rocket_contrib::serve::StaticFiles; use reqwest::blocking::{RequestBuilder, Client}; use reqwest::Error; use qrcode_generator::QrCodeEcc; use std::env; -use std::clone; use data_types::*; -// fn issue_rpc(method: &str, params: Option) -> RequestBuilder { -// let http_client = Client::new(); -// let url = format!( -// "{}/json_rpc", -// env::var("DAEMON_URI").unwrap() -// ); -// let post_data = RPCPayload { -// method: Some(method.to_string()), -// params: params, -// ..Default::default() -// }; -// http_client.post(&url).json(&post_data) -// } - -// fn issue_raw_rpc(method: &str, params: JsonValue) -> RequestBuilder { -// let http_client = Client::new(); -// let url = format!( -// "{}/{}", -// env::var("DAEMON_URI").unwrap(), -// &method -// ); -// http_client.post(&url).json(¶ms) -// } -// -fn build_rpc(method: &str, data: Option, raw: bool) -> RequestBuilder { +fn build_rpc(method: &str, raw_data: Option, raw: bool) -> RequestBuilder { let http_client = Client::new(); let daemon_uri = env::var("DAEMON_URI").unwrap(); match raw { true => { let uri = format!("{}/{}", &daemon_uri, &method); - if let None = data { + if let None = raw_data { http_client.post(&uri) } else { - http_client.post(&uri).json(&data) + http_client.post(&uri).json(&raw_data) } }, false => { let uri = format!("{}/json_rpc", &daemon_uri); - let data = RPCPayload { - method: Some(method.to_string()), - ..Default::default() - }; - http_client.post(&uri).json(&data) + if let None = raw_data { + http_client.post(&uri) + } else { + http_client.post(&uri).json(&raw_data) + } } } } -// -// #[get("/block/hash/")] -// fn get_block_by_hash(block_hash: String) -> Template { -// let params = RPCParams { -// hash: Some(block_hash), -// ..Default::default() -// }; -// let res: GetBlock = issue_rpc(&"get_block", Some(params)) -// .send().unwrap().json().unwrap(); -// Template::render("block", &res.result) -// } -// -// #[get("/block/height/")] -// fn get_block_by_height(block_height: String) -> Template { -// let params = RPCParams { -// height: Some(block_height), -// ..Default::default() -// }; -// let res: GetBlock = issue_rpc(&"get_block", Some(params)) -// .send().unwrap().json().unwrap(); -// Template::render("block", &res.result) -// } + +#[get("/block/hash/")] +fn get_block_by_hash(block_hash: String) -> Template { + // https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#get_block + // http POST crypto.int.lzahq.tech:34568/json_rpc method=get_block params:='{"hash": "83faf32a04708bead3e712947b8ad8e1e6ab50f3093948bfb3e71fb0089a7b68"}' + let payload: JsonValue = json!({ + "method": "get_block", + "params": { + "hash": block_hash + } + }); + + let res: GetBlock = build_rpc( + &"get_block", Some(payload), false + ).send().unwrap().json().unwrap(); + Template::render("block", &res.result) +} + +#[get("/block/height/")] +fn get_block_by_height(block_height: String) -> Template { + // https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#get_block + // http POST crypto.int.lzahq.tech:34568/json_rpc method=get_block params:='{"height": 225460}' + let payload: JsonValue = json!({ + "method": "get_block", + "params": { + "height": block_height + } + }); + + let res: GetBlock = build_rpc( + &"get_block", Some(payload), false + ).send().unwrap().json().unwrap(); + Template::render("block", &res.result) +} #[get("/transaction/")] fn get_transaction_by_hash(tx_hash: String) -> Template { + // https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#get_transactions + // echo '{"txs_hashes": ["98f68768d258544856e0b6c3a3aac8773a094fe184f9b9daba1554a9d8fc2e02"], "decode_as_json": true}' \ + // | http POST crypto.int.lzahq.tech:34568/get_transactions let params: JsonValue = json!({ "txs_hashes": [&tx_hash], "decode_as_json": true @@ -137,69 +127,73 @@ fn show_wallet_address( Template::render("address", context) } -// #[get("/search?")] -// fn search(value: &RawStr) -> Redirect { -// // This search implementation is not ideal but it works. -// // We basically check the length of the search value and -// // attempt to redirect to the appropriate route. -// let sl: usize = value.len(); -// if sl == 0 { -// return Redirect::found(uri!(index)); -// } else if sl < 8 { -// // Less than 8 characters is probably a block height. If it can -// // be parsed as valid u32 then redirect to `get_block_by_height`, -// // otherwise redirect to the error response. -// match value.parse::() { -// Ok(_) => return Redirect::found(uri!(get_block_by_height: value.as_str())), -// Err(_) => return Redirect::found(uri!(error)) -// } -// } else if sl == 64 { -// // Equal to 64 characters is probably a hash; block or tx. -// // For this we attempt to query for a block with -// // given hash. If we don't receive a valid/expected -// // response then we attempt to query for a transaction hash. -// // If neither works then redirect to error response. -// let block_hash_params = RPCParams { -// hash: Some(value.to_string()), -// ..Default::default() -// }; -// let check_valid_block_hash: Result = issue_rpc( -// &"get_block", Some(block_hash_params) -// ).send().unwrap().json(); -// -// match check_valid_block_hash { -// Ok(_) => return Redirect::found(uri!(get_block_by_hash: value.as_str())), -// Err(_) => { -// let tx_hash_params: JsonValue = json!({"txs_hashes": [&value.as_str()]}); -// let check_valid_tx_hash: Result = issue_raw_rpc( -// &"get_transactions", tx_hash_params -// ).send().unwrap().json(); -// -// match check_valid_tx_hash { -// Ok(_) => return Redirect::found(uri!(get_transaction_by_hash: value.as_str())), -// Err(_) => return Redirect::found(uri!(error)) -// } -// } -// } -// } else if sl == 95 { -// // Equal to 95 characters is probably a wallet address. -// // For this let's just redirect to the `show_wallet_address` route. -// return Redirect::found(uri!(show_wallet_address: value.as_str(), "", "", "", "")) -// } else if sl == 105 { -// // Equal to 105 characters is probably an integrated address. -// // For this let's just redirect to the `show_wallet_address` route. -// return Redirect::found(uri!(show_wallet_address: value.as_str(), "", "", "", "")) -// } else { -// // Anything else hasn't been implemented yet -// // so redirect to error response. -// return Redirect::found(uri!(error)); -// }; -// } -// +#[get("/search?")] +fn search(value: &RawStr) -> Redirect { + // This search implementation is not ideal but it works. + // We basically check the length of the search value and + // attempt to redirect to the appropriate route. + let sl: usize = value.len(); + if sl == 0 { + return Redirect::found(uri!(index)); + } else if sl < 8 { + // Less than 8 characters is probably a block height. If it can + // be parsed as valid u32 then redirect to `get_block_by_height`, + // otherwise redirect to the error response. + match value.parse::() { + Ok(_) => return Redirect::found(uri!(get_block_by_height: value.as_str())), + Err(_) => return Redirect::found(uri!(error)) + } + } else if sl == 64 { + // Equal to 64 characters is probably a hash; block or tx. + // For this we attempt to query for a block with + // given hash. If we don't receive a valid/expected + // response then we attempt to query for a transaction hash. + // If neither works then redirect to error response. + + let block_hash_params: JsonValue = json!({ + "method": "get_block", + "params": { + "hash": value.to_string() + } + }); + + let check_valid_block_hash: Result = build_rpc( + &"get_block", Some(block_hash_params), false + ).send().unwrap().json(); + + match check_valid_block_hash { + Ok(_) => return Redirect::found(uri!(get_block_by_hash: value.as_str())), + Err(_) => { + let tx_hash_params: JsonValue = json!({"txs_hashes": [&value.as_str()]}); + let check_valid_tx_hash: Result = build_rpc( + &"get_transactions", Some(tx_hash_params), true + ).send().unwrap().json(); + + match check_valid_tx_hash { + Ok(_) => return Redirect::found(uri!(get_transaction_by_hash: value.as_str())), + Err(_) => return Redirect::found(uri!(error)) + } + } + } + } else if sl == 97 { + // Equal to 95 characters is probably a wallet address. + // For this let's just redirect to the `show_wallet_address` route. + return Redirect::found(uri!(show_wallet_address: value.as_str(), "", "", "", "")) + } else if sl == 105 { + // Equal to 105 characters is probably an integrated address. + // For this let's just redirect to the `show_wallet_address` route. + return Redirect::found(uri!(show_wallet_address: value.as_str(), "", "", "", "")) + } else { + // Anything else hasn't been implemented yet + // so redirect to error response. + return Redirect::found(uri!(error)); + }; +} + // #[get("/tx_pool")] // fn show_tx_pool() -> Json { // let mut tx_pool: GetTransactionPool = build_rpc( -// &"get_transaction_pool", None, true +// &"get_transaction_pool", None, None, true // ).send().unwrap().json().unwrap(); // // for f in &mut tx_pool.transactions { @@ -211,14 +205,16 @@ fn show_wallet_address( #[get("/")] fn index() -> Template { - let daemon_info: GetInfo = build_rpc( - &"get_info", None, false + let daemon_info: GetInfoResult = build_rpc( + &"get_info", None, true ).send().unwrap().json().unwrap(); let tx_pool: GetTransactionPool = build_rpc( &"get_transaction_pool", None, true ).send().unwrap().json().unwrap(); + println!("{:#?}", tx_pool); + // let mut tx_pool_txs = tx_pool.transactions; // // match tx_pool_txs { @@ -235,7 +231,7 @@ fn index() -> Template { // }; let context: JsonValue = json!({ - "daemon_info": daemon_info.result, + "daemon_info": daemon_info, "tx_pool_txs": tx_pool.transactions }); @@ -265,10 +261,10 @@ fn main() { rocket::ignite() .mount("/", routes![ index, - // search, + search, // show_tx_pool, - // get_block_by_height, - // get_block_by_hash, + get_block_by_height, + get_block_by_hash, get_transaction_by_hash, show_wallet_address, error