mirror of
https://github.com/transatoshi-mw/grin-explorer.git
synced 2025-10-21 13:33:41 +00:00
enhanced logging and external connection
This commit is contained in:
91
Cargo.lock
generated
91
Cargo.lock
generated
@@ -41,6 +41,55 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.86"
|
||||
@@ -234,6 +283,12 @@ dependencies = [
|
||||
"phf_codegen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.1.0"
|
||||
@@ -482,6 +537,29 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea"
|
||||
dependencies = [
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"env_filter",
|
||||
"humantime",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
@@ -743,6 +821,7 @@ dependencies = [
|
||||
"colored",
|
||||
"config",
|
||||
"either",
|
||||
"env_logger",
|
||||
"fs_extra",
|
||||
"futures",
|
||||
"humantime",
|
||||
@@ -982,6 +1061,12 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
@@ -2540,6 +2625,12 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
|
@@ -20,6 +20,7 @@ lazy_static = "1.4.0"
|
||||
shellexpand = "3.1.0"
|
||||
either = "1.11.0"
|
||||
anyhow = "1.0.86"
|
||||
env_logger = "0.11.3"
|
||||
|
||||
[dependencies.reqwest]
|
||||
version = "0.11.23"
|
||||
|
@@ -7,13 +7,13 @@ port = "3413"
|
||||
# Node protocol. Either HTTP or HTTPS.
|
||||
proto = "http"
|
||||
|
||||
# API username.
|
||||
# API username. Comment out if user is not required.
|
||||
user = "grin"
|
||||
|
||||
# API secret path.
|
||||
# API secret path. Comment out if secret is not required.
|
||||
api_secret_path = "~/.grin/main/.api_secret"
|
||||
|
||||
# Foreign API secret path.
|
||||
# Foreign API secret path. Comment out if secret is not required.
|
||||
foreign_api_secret_path = "~/.grin/main/.foreign_api_secret"
|
||||
|
||||
# Path to Grin directory.
|
||||
@@ -26,6 +26,21 @@ coingecko_api = "enabled"
|
||||
public_api = "enabled"
|
||||
|
||||
|
||||
# Grinnode config
|
||||
# ip = "grinnode.live"
|
||||
# port = "3413"
|
||||
# proto = "https"
|
||||
# coingecko_api = "enabled"
|
||||
# public_api = "enabled"
|
||||
|
||||
|
||||
# Grincoin config
|
||||
# ip = "grincoin.org"
|
||||
# proto = "https"
|
||||
# coingecko_api = "enabled"
|
||||
# public_api = "enabled"
|
||||
|
||||
|
||||
# Testnet config
|
||||
# ip = "127.0.0.1"
|
||||
# port = "13413"
|
||||
|
@@ -22,15 +22,14 @@ Grin is the very first, simple and fair MimbleWimble blockchain implementation.
|
||||
cd grin-explorer
|
||||
cargo build --release
|
||||
```
|
||||
4. Run executable: `./target/release/grin-explorer`
|
||||
4. Run executable: `RUST_LOG=rocket=warn,grin_explorer ./target/release/grin-explorer`
|
||||
|
||||
You will see the following output:
|
||||
|
||||
```
|
||||
[ INFO ] Starting up Explorer.
|
||||
[ INFO ] Starting up Rocket engine.
|
||||
🚀 Rocket has launched from http://127.0.0.1:8000
|
||||
[ OK ] Explorer Ready.
|
||||
[2024-06-19T13:12:34Z INFO grin_explorer] starting up.
|
||||
[2024-06-19T13:12:34Z WARN rocket::launch] 🚀 Rocket has launched from http://127.0.0.1:8000
|
||||
[2024-06-19T13:12:34Z INFO grin_explorer] ready.
|
||||
```
|
||||
|
||||
5. Open explorer in your browser: http://127.0.0.1:8000
|
||||
|
@@ -1,6 +1,5 @@
|
||||
[default]
|
||||
address = "127.0.0.1"
|
||||
log_level = "critical"
|
||||
|
||||
# Uncomment and change default port number (8000) if another instance of the explorer is needed to run.
|
||||
# E.g. Mainnet (8000) and Testnet (8001) instances.
|
||||
|
17
src/main.rs
17
src/main.rs
@@ -5,7 +5,6 @@ use rocket::fs::FileServer;
|
||||
use rocket::State;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
use colored::Colorize;
|
||||
use rocket::tokio;
|
||||
use rocket::response::Redirect;
|
||||
use either::Either;
|
||||
@@ -396,7 +395,11 @@ fn last_block_age(blocks: &State<Arc<Mutex<Vec<Block>>>>) -> String {
|
||||
fn disk_usage(dashboard: &State<Arc<Mutex<Dashboard>>>) -> String {
|
||||
let data = dashboard.lock().unwrap();
|
||||
|
||||
format!("{} GB", data.disk_usage)
|
||||
if data.disk_usage.is_empty() == false {
|
||||
return format!("{} GB", data.disk_usage);
|
||||
} else {
|
||||
return format!("<i class=\"bi bi-x-lg\"></i>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -602,7 +605,9 @@ fn block_list_index(dashboard: &State<Arc<Mutex<Dashboard>>>) -> String {
|
||||
// Main
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
println!("{} Starting up Explorer.", "[ INFO ]".cyan());
|
||||
env_logger::init();
|
||||
|
||||
info!("starting up.");
|
||||
|
||||
let dash = Arc::new(Mutex::new(Dashboard::new()));
|
||||
let dash_clone = dash.clone();
|
||||
@@ -622,12 +627,12 @@ async fn main() {
|
||||
Ok(_v) => {
|
||||
if ready == false {
|
||||
ready = true;
|
||||
println!("{} Explorer Ready.", "[ OK ]".green());
|
||||
info!("ready.");
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
ready = false;
|
||||
println!("{} {}.", "[ ERROR ]".red(), e);
|
||||
error!("{}", e);
|
||||
},
|
||||
}
|
||||
|
||||
@@ -635,8 +640,6 @@ async fn main() {
|
||||
}
|
||||
});
|
||||
|
||||
println!("{} Starting up Rocket engine.", "[ INFO ]".cyan());
|
||||
|
||||
// Starting Rocket engine.
|
||||
let _ = rocket::build()
|
||||
.manage(dash)
|
||||
|
@@ -43,11 +43,17 @@ lazy_static! {
|
||||
}
|
||||
}
|
||||
|
||||
cfg.api_secret = fs::read_to_string(format!("{}",
|
||||
shellexpand::tilde(&cfg.api_secret_path))).unwrap();
|
||||
cfg.foreign_api_secret = fs::read_to_string(format!("{}",
|
||||
shellexpand::tilde(&cfg.foreign_api_secret_path))).unwrap();
|
||||
if cfg.api_secret_path.is_empty() == false {
|
||||
cfg.api_secret = fs::read_to_string(format!("{}", shellexpand::tilde(&cfg.api_secret_path))).unwrap();
|
||||
}
|
||||
|
||||
if cfg.foreign_api_secret_path.is_empty() == false {
|
||||
cfg.foreign_api_secret = fs::read_to_string(format!("{}", shellexpand::tilde(&cfg.foreign_api_secret_path))).unwrap();
|
||||
}
|
||||
|
||||
if cfg.grin_dir.is_empty() == false {
|
||||
cfg.grin_dir = format!("{}", shellexpand::tilde(&cfg.grin_dir));
|
||||
}
|
||||
|
||||
cfg
|
||||
};
|
||||
@@ -59,12 +65,15 @@ pub async fn call(method: &str, params: &str, id: &str, rpc_type: &str) -> Resul
|
||||
let rpc_url;
|
||||
let secret;
|
||||
|
||||
if rpc_type == "owner" {
|
||||
rpc_url = format!("{}://{}:{}/v2/owner", CONFIG.proto, CONFIG.ip, CONFIG.port);
|
||||
secret = CONFIG.api_secret.clone();
|
||||
if CONFIG.port.is_empty() == false {
|
||||
rpc_url = format!("{}://{}:{}/v2/{}", CONFIG.proto, CONFIG.ip, CONFIG.port, rpc_type);
|
||||
} else {
|
||||
rpc_url = format!("{}://{}/v2/{}", CONFIG.proto, CONFIG.ip, rpc_type);
|
||||
}
|
||||
else {
|
||||
rpc_url = format!("{}://{}:{}/v2/foreign", CONFIG.proto, CONFIG.ip, CONFIG.port);
|
||||
|
||||
if rpc_type == "owner" {
|
||||
secret = CONFIG.api_secret.clone();
|
||||
} else {
|
||||
secret = CONFIG.foreign_api_secret.clone();
|
||||
}
|
||||
|
||||
@@ -76,6 +85,11 @@ pub async fn call(method: &str, params: &str, id: &str, rpc_type: &str) -> Resul
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
match result.error_for_status_ref() {
|
||||
Ok(_res) => (),
|
||||
Err(err) => { error!("rpc failed, status code: {:?}", err.status().unwrap()); },
|
||||
}
|
||||
|
||||
let val: Value = serde_json::from_str(&result.text().await.unwrap())?;
|
||||
|
||||
Ok(val)
|
||||
@@ -173,7 +187,7 @@ pub async fn get_market(dashboard: Arc<Mutex<Dashboard>>) -> Result<(), Error> {
|
||||
if CONFIG.coingecko_api == "enabled" && val != Value::Null {
|
||||
// Check if CoingGecko API returned error
|
||||
if let Some(status) = val.get("status") {
|
||||
println!("{} {}.", "[ WARNING ]".yellow(), status["error_message"].as_str().unwrap().to_string());
|
||||
warn!("{}", status["error_message"].as_str().unwrap().to_string());
|
||||
} else {
|
||||
data.price_usd = format!("{:.3}", val["grin"]["usd"].to_string().parse::<f64>().unwrap());
|
||||
data.price_btc = format!("{:.8}", val["grin"]["btc"].to_string().parse::<f64>().unwrap());
|
||||
@@ -205,7 +219,13 @@ pub fn get_disk_usage(dashboard: Arc<Mutex<Dashboard>>) -> Result<(), Error> {
|
||||
|
||||
match get_size(chain_dir.clone()) {
|
||||
Ok(chain_size) => data.disk_usage = format!("{:.2}", (chain_size as f64) / 1000.0 / 1000.0 / 1000.0),
|
||||
Err(e) => println!("{} {}: \"{}\".", "[ ERROR ]".red(), e, chain_dir),
|
||||
Err(e) => {
|
||||
if CONFIG.ip == "127.0.0.1" || CONFIG.ip == "0.0.0.0" {
|
||||
error!("{}: \"{}\"", e, chain_dir);
|
||||
} else {
|
||||
// Ignore error for external node connection
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -237,7 +257,7 @@ pub async fn get_mining_stats(dashboard: Arc<Mutex<Dashboard>>) -> Result<(), an
|
||||
// https://forum.grin.mw/t/difference-c31-and-c32-c33/7018/7
|
||||
let hashrate = (net_diff as f64) * 42.0 / 60.0 / 16384.0;
|
||||
|
||||
// KG/s
|
||||
// kG/s
|
||||
if hashrate > 1000.0 {
|
||||
data.hashrate = format!("{:.2} kG/s", hashrate / 1000.0);
|
||||
// G/s
|
||||
@@ -255,6 +275,7 @@ pub async fn get_mining_stats(dashboard: Arc<Mutex<Dashboard>>) -> Result<(), an
|
||||
// Assuming $0.07 per kW/h
|
||||
data.production_cost = format!("{:.3}", 120.0 / 1000.0 * 0.07 * (1.0 / coins_per_hour));
|
||||
|
||||
if data.price_usd.is_empty() == false {
|
||||
data.reward_ratio = format!("{:.2}", data.price_usd.parse::<f64>().unwrap()
|
||||
/ data.production_cost.parse::<f64>().unwrap());
|
||||
data.breakeven_cost = format!("{:.2}", data.price_usd.parse::<f64>().unwrap()
|
||||
@@ -262,6 +283,7 @@ pub async fn get_mining_stats(dashboard: Arc<Mutex<Dashboard>>) -> Result<(), an
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Reference in New Issue
Block a user