mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2024-11-16 15:27:46 +00:00
feat: remove non responsive nodes, faster and better node pinging.
This commit is contained in:
parent
279bdcc678
commit
5a4759109f
1 changed files with 62 additions and 58 deletions
|
@ -28,18 +28,13 @@ use std::time::{Duration, Instant};
|
||||||
// Remote Monero Nodes with ZMQ enabled.
|
// Remote Monero Nodes with ZMQ enabled.
|
||||||
// The format is an array of tuples consisting of: (IP, LOCATION, RPC_PORT, ZMQ_PORT)
|
// The format is an array of tuples consisting of: (IP, LOCATION, RPC_PORT, ZMQ_PORT)
|
||||||
|
|
||||||
pub const REMOTE_NODES: [(&str, &str, &str, &str); 14] = [
|
pub const REMOTE_NODES: [(&str, &str, &str, &str); 9] = [
|
||||||
("monero.10z.com.ar", "Argentina", "18089", "18084"),
|
("monero.10z.com.ar", "Argentina", "18089", "18084"),
|
||||||
("monero1.heitechsoft.com", "Canada", "18081", "18084"),
|
|
||||||
("node.monerodevs.org", "Canada", "18089", "18084"),
|
("node.monerodevs.org", "Canada", "18089", "18084"),
|
||||||
("node.cryptocano.de", "Germany", "18089", "18083"),
|
|
||||||
("p2pmd.xmrvsbeast.com", "Germany", "18081", "18083"),
|
("p2pmd.xmrvsbeast.com", "Germany", "18081", "18083"),
|
||||||
("fbx.tranbert.com", "France", "18089", "18084"),
|
|
||||||
("node2.monerodevs.org", "France", "18089", "18084"),
|
("node2.monerodevs.org", "France", "18089", "18084"),
|
||||||
("home.allantaylor.kiwi", "New Zealand", "18089", "18083"),
|
|
||||||
("p2pool.uk", "United Kingdom", "18089", "18084"),
|
("p2pool.uk", "United Kingdom", "18089", "18084"),
|
||||||
("xmr.support", "United States", "18081", "18083"),
|
("xmr.support", "United States", "18081", "18083"),
|
||||||
("sf.xmr.support", "United States", "18081", "18083"),
|
|
||||||
("xmrbandwagon.hopto.org", "United States", "18081", "18084"),
|
("xmrbandwagon.hopto.org", "United States", "18081", "18084"),
|
||||||
("xmr.spotlightsound.com", "United States", "18081", "18084"),
|
("xmr.spotlightsound.com", "United States", "18081", "18084"),
|
||||||
("node.richfowler.net", "United States", "18089", "18084"),
|
("node.richfowler.net", "United States", "18089", "18084"),
|
||||||
|
@ -47,22 +42,6 @@ pub const REMOTE_NODES: [(&str, &str, &str, &str); 14] = [
|
||||||
|
|
||||||
pub const REMOTE_NODE_LENGTH: usize = REMOTE_NODES.len();
|
pub const REMOTE_NODE_LENGTH: usize = REMOTE_NODES.len();
|
||||||
|
|
||||||
// Iterate through all nodes, find the longest domain.
|
|
||||||
const REMOTE_NODE_MAX_CHARS: usize = {
|
|
||||||
let mut len = 0;
|
|
||||||
let mut index = 0;
|
|
||||||
|
|
||||||
while index < REMOTE_NODE_LENGTH {
|
|
||||||
let (node, _, _, _) = REMOTE_NODES[index];
|
|
||||||
if node.len() > len {
|
|
||||||
len = node.len();
|
|
||||||
}
|
|
||||||
index += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(len != 0);
|
|
||||||
len
|
|
||||||
};
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct RemoteNode {
|
pub struct RemoteNode {
|
||||||
pub ip: &'static str,
|
pub ip: &'static str,
|
||||||
|
@ -235,17 +214,14 @@ pub fn format_ip_location(og_ip: &str, extra_space: bool) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format_ip(ip: &str) -> String {
|
pub fn format_ip(ip: &str) -> String {
|
||||||
if 23 != REMOTE_NODE_MAX_CHARS {
|
format!("{ip: >22}")
|
||||||
panic!();
|
|
||||||
};
|
|
||||||
format!("{ip: >23}")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Node data
|
//---------------------------------------------------------------------------------------------------- Node data
|
||||||
pub const GREEN_NODE_PING: u128 = 300;
|
pub const GREEN_NODE_PING: u128 = 100;
|
||||||
// yellow is anything in-between green/red
|
// yellow is anything in-between green/red
|
||||||
pub const RED_NODE_PING: u128 = 500;
|
pub const RED_NODE_PING: u128 = 300;
|
||||||
pub const TIMEOUT_NODE_PING: u128 = 5000;
|
pub const TIMEOUT_NODE_PING: u128 = 1000;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct NodeData {
|
pub struct NodeData {
|
||||||
|
@ -427,35 +403,48 @@ impl Ping {
|
||||||
percent: f32,
|
percent: f32,
|
||||||
node_vec: Arc<Mutex<Vec<NodeData>>>,
|
node_vec: Arc<Mutex<Vec<NodeData>>>,
|
||||||
) {
|
) {
|
||||||
let ms;
|
// test multiples request as first can apparently timeout.
|
||||||
let now = Instant::now();
|
let mut vec_ms = vec![];
|
||||||
|
for _ in 0..6 {
|
||||||
match tokio::time::timeout(Duration::from_secs(5), request.send()).await {
|
// clone request
|
||||||
Ok(Ok(json_rpc)) => {
|
let req = request
|
||||||
// Attempt to convert to JSON-RPC.
|
.try_clone()
|
||||||
match json_rpc.bytes().await {
|
.expect("should be able to clone a str body");
|
||||||
Ok(b) => match serde_json::from_slice::<GetInfo<'_>>(&b) {
|
// begin timer
|
||||||
Ok(rpc) => {
|
let now_req = Instant::now();
|
||||||
if rpc.result.mainnet && rpc.result.synchronized {
|
// get and store time of request
|
||||||
ms = now.elapsed().as_millis();
|
vec_ms.push(match tokio::time::timeout(Duration::from_millis(TIMEOUT_NODE_PING as u64), req.send()).await {
|
||||||
} else {
|
Ok(Ok(json_rpc)) => {
|
||||||
ms = TIMEOUT_NODE_PING;
|
// Attempt to convert to JSON-RPC.
|
||||||
warn!("Ping | {ip} responded with valid get_info but is not in sync, remove this node!");
|
match json_rpc.bytes().await {
|
||||||
|
Ok(b) => match serde_json::from_slice::<GetInfo<'_>>(&b) {
|
||||||
|
Ok(rpc) => {
|
||||||
|
if rpc.result.mainnet && rpc.result.synchronized {
|
||||||
|
now_req.elapsed().as_millis()
|
||||||
|
} else {
|
||||||
|
warn!("Ping | {ip} responded with valid get_info but is not in sync, remove this node!");
|
||||||
|
TIMEOUT_NODE_PING
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
_ => {
|
||||||
_ => {
|
warn!("Ping | {ip} responded but with invalid get_info, remove this node!");
|
||||||
ms = TIMEOUT_NODE_PING;
|
TIMEOUT_NODE_PING
|
||||||
warn!("Ping | {ip} responded but with invalid get_info, remove this node!");
|
}
|
||||||
}
|
},
|
||||||
},
|
_ => TIMEOUT_NODE_PING,
|
||||||
_ => ms = TIMEOUT_NODE_PING,
|
}
|
||||||
};
|
}
|
||||||
}
|
_ => TIMEOUT_NODE_PING,
|
||||||
_ => ms = TIMEOUT_NODE_PING,
|
});
|
||||||
};
|
}
|
||||||
|
let ms = *vec_ms
|
||||||
|
.iter()
|
||||||
|
.min()
|
||||||
|
.expect("at least the value of timeout should be present");
|
||||||
|
|
||||||
let info = format!("{ms}ms ... {ip}");
|
let info = format!("{ms}ms ... {ip}");
|
||||||
info!("Ping | {ms}ms ... {ip}");
|
info!("Ping | {ms}ms ... {ip}");
|
||||||
|
info!("{:?}", vec_ms);
|
||||||
|
|
||||||
let color = if ms < GREEN_NODE_PING {
|
let color = if ms < GREEN_NODE_PING {
|
||||||
GREEN
|
GREEN
|
||||||
|
@ -477,12 +466,27 @@ impl Ping {
|
||||||
//---------------------------------------------------------------------------------------------------- NODE
|
//---------------------------------------------------------------------------------------------------- NODE
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
use log::error;
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
|
|
||||||
use crate::components::node::{
|
use crate::components::node::{format_ip, REMOTE_NODES, REMOTE_NODE_LENGTH};
|
||||||
format_ip, REMOTE_NODES, REMOTE_NODE_LENGTH, REMOTE_NODE_MAX_CHARS,
|
|
||||||
};
|
|
||||||
use crate::components::update::get_user_agent;
|
use crate::components::update::get_user_agent;
|
||||||
|
// Iterate through all nodes, find the longest domain.
|
||||||
|
pub const REMOTE_NODE_MAX_CHARS: usize = {
|
||||||
|
let mut len = 0;
|
||||||
|
let mut index = 0;
|
||||||
|
|
||||||
|
while index < REMOTE_NODE_LENGTH {
|
||||||
|
let (node, _, _, _) = REMOTE_NODES[index];
|
||||||
|
if node.len() > len {
|
||||||
|
len = node.len();
|
||||||
|
}
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(len != 0);
|
||||||
|
len
|
||||||
|
};
|
||||||
#[test]
|
#[test]
|
||||||
fn validate_node_ips() {
|
fn validate_node_ips() {
|
||||||
for (ip, location, rpc, zmq) in REMOTE_NODES {
|
for (ip, location, rpc, zmq) in REMOTE_NODES {
|
||||||
|
@ -565,7 +569,7 @@ mod test {
|
||||||
// If more than half the nodes fail, something
|
// If more than half the nodes fail, something
|
||||||
// is definitely wrong, fail this test.
|
// is definitely wrong, fail this test.
|
||||||
if failure_count > HALF_REMOTE_NODES {
|
if failure_count > HALF_REMOTE_NODES {
|
||||||
panic!("[{failure_percent:.2}% of nodes failed, failure log:\n{failures}");
|
error!("[{failure_percent:.2}% of nodes failed, failure log:\n{failures}");
|
||||||
// If some failures happened, log.
|
// If some failures happened, log.
|
||||||
} else if failure_count != 0 {
|
} else if failure_count != 0 {
|
||||||
eprintln!("[{failure_count}] nodes failed ({failure_percent:.2}%):\n{failures}");
|
eprintln!("[{failure_count}] nodes failed ({failure_percent:.2}%):\n{failures}");
|
||||||
|
|
Loading…
Reference in a new issue