diff --git a/Cargo.lock b/Cargo.lock index 911b7e4..5cc456a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -736,7 +736,7 @@ dependencies = [ [[package]] name = "grin-explorer" -version = "0.1.3" +version = "0.1.4" dependencies = [ "anyhow", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 164b703..8d3ddc1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin-explorer" -version = "0.1.3" +version = "0.1.4" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/data.rs b/src/data.rs index d529320..bae2440 100644 --- a/src/data.rs +++ b/src/data.rs @@ -118,6 +118,7 @@ pub struct Kernel { pub excess: String, pub ker_type: String, pub fee: String, + pub status: String, pub raw_data: String, } @@ -128,6 +129,7 @@ impl Kernel { excess: String::new(), ker_type: String::new(), fee: String::new(), + status: String::new(), raw_data: String::new(), } } diff --git a/src/main.rs b/src/main.rs index 3584b85..5e74b06 100644 --- a/src/main.rs +++ b/src/main.rs @@ -126,7 +126,7 @@ async fn kernel(excess: &str) -> Template { let _ = requests::get_kernel(&excess, &mut kernel).await; - if kernel.height.is_empty() == false { + if kernel.excess.is_empty() == false { return Template::render("kernel", context! { route: "kernel", kernel, @@ -140,28 +140,30 @@ async fn kernel(excess: &str) -> Template { // Handling search request. -#[post("/search", data="")] -fn search(input: &str) -> Either { - //Check input length - if input.len() > "search=".len() { - // Trim 'search=' from the request data - let input = &input[7..].to_lowercase(); +// Using Option<&str> to match '/search' query without input params. +// https://github.com/rwf2/Rocket/issues/608 +#[get("/search?")] +fn search(input: Option<&str>) -> Either { + // Unwrap Option and forward to Search page if no parameters + let input = match input { + Some(value) => value, + None => return Either::Left(Template::render("search", context! { route: "search", })), + }; - // Check for valid chars - if input.chars().all(|x| (x >= 'a' && x <= 'f') || (x >= '0' && x <= '9')) == true { + // Check for valid chars + if input.chars().all(|x| (x >= 'a' && x <= 'f') || (x >= '0' && x <= '9')) == true { - // Block number - if input.chars().all(char::is_numeric) == true { - return Either::Right(Redirect::to(uri!(block_details_by_height(input)))); + // Block number + if input.chars().all(char::is_numeric) == true { + return Either::Right(Redirect::to(uri!(block_details_by_height(input)))); - // Block hash - } else if input.len() == 64 { - return Either::Right(Redirect::to(uri!(block_header_by_hash(input)))); + // Block hash + } else if input.len() == 64 { + return Either::Right(Redirect::to(uri!(block_header_by_hash(input)))); - // Kernel - } else if input.len() == 66 { - return Either::Right(Redirect::to(uri!(kernel(input)))); - } + // Kernel + } else if input.len() == 66 { + return Either::Right(Redirect::to(uri!(kernel(input)))); } } @@ -218,8 +220,6 @@ async fn api_foreign(data: &str) -> String { _ => return "{\"error\":\"bad syntax\"}".to_string(), }; - println!("{}", method); - println!("{}", data); let resp = requests::call(method, v["params"].to_string().as_str(), v["id"].to_string().as_str(), "foreign").await; let result = match resp { @@ -255,9 +255,9 @@ fn sync_status(dashboard: &State>>) -> String { if data.sync == "no_sync" { "Synced".to_string() } else { - format!("Syncing ({}) + format!("Syncing - Syncing...", data.sync) + Syncing...") } } diff --git a/src/requests.rs b/src/requests.rs index 0fc6020..b6f62dd 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -404,15 +404,35 @@ pub async fn get_block_header(hash: &str, height: &mut String) // Get kernel. -pub async fn get_kernel(excess: &str, kernel: &mut Kernel) - -> Result<(), anyhow::Error> { - let params = &format!("[\"{}\", null, null]", excess)[..]; - - let resp = call("get_kernel", params, "1", "foreign").await?; +pub async fn get_kernel(excess: &str, kernel: &mut Kernel) -> Result<(), anyhow::Error> { + // First check whether kernel is broadcasted but not confirmed yet (in mempool) + let mut resp = call("get_unconfirmed_transactions", "[]", "1", "foreign").await?; if resp["result"]["Ok"].is_null() == false { - kernel.height = resp["result"]["Ok"]["height"].to_string(); - kernel.excess = resp["result"]["Ok"]["tx_kernel"]["excess"].as_str().unwrap().to_string(); + for tx in resp["result"]["Ok"].as_array().unwrap() { + for ker in tx["tx"]["body"]["kernels"].as_array().unwrap() { + if ker["excess"].as_str().unwrap() == excess { + // Only Plain kernels in the mempool + kernel.ker_type = "Plain".to_string(); + kernel.excess = ker["excess"].as_str().unwrap().to_string(); + kernel.status = "Unconfirmed".to_string(); + kernel.fee = format!("ツ {}", + ker["features"]["Plain"]["fee"] + .to_string().parse::().unwrap() / 1000000000.0); + // Found it, no need to continue + return Ok(()); + } + } + } + } + + let params = &format!("[\"{}\", null, null]", excess)[..]; + + resp = call("get_kernel", params, "1", "foreign").await?; + + if resp["result"]["Ok"].is_null() == false { + kernel.height = resp["result"]["Ok"]["height"].to_string(); + kernel.excess = resp["result"]["Ok"]["tx_kernel"]["excess"].as_str().unwrap().to_string(); if resp["result"]["Ok"]["tx_kernel"]["features"]["Plain"].is_null() == false { kernel.ker_type = "Plain".to_string(); kernel.fee = format!("ツ {}", @@ -420,7 +440,6 @@ pub async fn get_kernel(excess: &str, kernel: &mut Kernel) .to_string().parse::().unwrap() / 1000000000.0); } else { kernel.ker_type = resp["result"]["Ok"]["tx_kernel"]["features"].as_str().unwrap().to_string(); - kernel.fee = "ツ 0".to_string(); } kernel.raw_data = serde_json::to_string_pretty(&resp).unwrap() diff --git a/templates/base.html.tera b/templates/base.html.tera index c9d1e2a..4b3bb6a 100644 --- a/templates/base.html.tera +++ b/templates/base.html.tera @@ -61,8 +61,8 @@ - - + + @@ -211,8 +211,11 @@ - - v.0.1.3 + + v.0.1.4 + + + search diff --git a/templates/error.html.tera b/templates/error.html.tera index 88b82f8..5bda901 100644 --- a/templates/error.html.tera +++ b/templates/error.html.tera @@ -7,7 +7,10 @@ No results found. - Explorer supports requests by block number, block hash or kernel. + Supported search inputs: + block number + block hash + kernel diff --git a/templates/kernel.html.tera b/templates/kernel.html.tera index 2f92fa8..c86b200 100644 --- a/templates/kernel.html.tera +++ b/templates/kernel.html.tera @@ -6,12 +6,18 @@ - KERNEL + + KERNEL + {% if kernel.status == "Unconfirmed" %} + UNCONFIRMED + {% endif %} + Excess {{ kernel.excess }} + {% if kernel.status != "Unconfirmed" %} Block Height @@ -21,28 +27,32 @@ + {% endif %} Type {{ kernel.ker_type }} - - - Fee - {{ kernel.fee }} + {% if kernel.ker_type == "Plain" %} + + + Fee + {{ kernel.fee }} + + {% endif %} + + + + {% if kernel.status != "Unconfirmed" %} + + + + RAW DATA + + {{ kernel.raw_data }} - - - - - - - RAW DATA - - {{ kernel.raw_data }} - - + {% endif %} diff --git a/templates/search.html.tera b/templates/search.html.tera new file mode 100644 index 0000000..d702ed3 --- /dev/null +++ b/templates/search.html.tera @@ -0,0 +1,32 @@ +{% extends "base" %} + +{% block content %} + + + + + + + + + + + + + + + + + Supported search inputs: + block number + block hash + kernel + + + + + + + +{% endblock %} +
+ + + + + + + + + + + + + + + Supported search inputs: + block number + block hash + kernel + + + + + +