diff --git a/src/node.rs b/src/node.rs index 817da0a..f3ab5d0 100644 --- a/src/node.rs +++ b/src/node.rs @@ -236,6 +236,25 @@ impl NodeData { } } +//---------------------------------------------------------------------------------------------------- `/get_info` +// A struct repr of the JSON-RPC we're +// expecting back from the pinged nodes. +// +// This structs leave out most fields on purpose, +// we only need a few to verify it works. +#[derive(Debug, serde::Deserialize)] +struct GetInfo<'a> { + id: &'a str, + jsonrpc: &'a str, + result: GetInfoResult, +} + +#[derive(Debug, serde::Deserialize)] +struct GetInfoResult { + mainnet: bool, + synchronized: bool, +} + //---------------------------------------------------------------------------------------------------- Ping data #[derive(Debug)] pub struct Ping { @@ -363,26 +382,37 @@ impl Ping { async fn response(client: Client, request: Request, ip: &'static str, ping: Arc>, percent: f32, node_vec: Arc>>) { let ms; - let info; let now = Instant::now(); + + const DEAD_NODE_PING: u128 = 5000; + match tokio::time::timeout(Duration::from_secs(5), client.request(request)).await { - Ok(_) => { - ms = now.elapsed().as_millis(); - info = format!("{}ms ... {}", ms, ip); - info!("Ping | {}", info) - }, - Err(_) => { - ms = 5000; - info = format!("{}ms ... {}", ms, ip); - warn!("Ping | {}", info) + Ok(Ok(json_rpc)) => { + // Attempt to convert to JSON-RPC. + match hyper::body::to_bytes(json_rpc.into_body()).await { + Ok(b) => { + if serde_json::from_slice::>(&b).is_ok() { + ms = now.elapsed().as_millis(); + } else { + ms = DEAD_NODE_PING; + warn!("Ping | {ip} responded but with invalid get_info, remove this node!"); + } + }, + _ => ms = DEAD_NODE_PING, + }; }, + _ => ms = DEAD_NODE_PING, }; + + let info = format!("{ms}ms ... {ip}"); + info!("Ping | {ms}ms ... {ip}"); + let color; if ms < 300 { color = GREEN; } else if ms < 500 { color = YELLOW; - } else if ms < 5000 { + } else if ms < DEAD_NODE_PING { color = RED; } else { color = BLACK; diff --git a/src/update.rs b/src/update.rs index 089ff9a..7c10f32 100644 --- a/src/update.rs +++ b/src/update.rs @@ -826,9 +826,11 @@ impl Pkg { //---------------------------------------------------------------------------------------------------- Pkg functions // Generate fake [User-Agent] HTTP header pub fn get_user_agent() -> &'static str { - let rand = thread_rng().gen_range(0..50); + let index = FAKE_USER_AGENT.len() - 1; + + let rand = thread_rng().gen_range(0..index); let user_agent = FAKE_USER_AGENT[rand]; - info!("Randomly selected User-Agent ({}/50) ... {}", rand, user_agent); + info!("Randomly selected User-Agent ({rand}/{index}) ... {user_agent}"); user_agent }