From dc0835f1f338bbe383c4c4692c8d46ae6cb47c8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 25 May 2026 11:38:51 +0100 Subject: [PATCH] more logs, timeouts and general duct taping --- Cargo.lock | 4 +-- nym-gateway-probe/netstack_ping/lib.go | 14 +++++------ nym-gateway-probe/src/common/probe_tests.rs | 25 +++++++++++++------ nym-gateway-probe/src/config/netstack.rs | 2 +- nym-gateway-probe/src/config/socks5.rs | 4 +-- nym-gateway-probe/src/lib.rs | 15 ++++++++++- .../nym-node-status-agent/Cargo.toml | 2 +- .../nym-node-status-agent/src/cli/mod.rs | 14 ++++++++--- .../nym-node-status-api/Cargo.toml | 2 +- .../nym-node-status-api/src/cli/mod.rs | 2 +- .../src/http/api/testruns.rs | 11 +++++++- 11 files changed, 67 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 375edc2d14..c71fe45850 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7747,7 +7747,7 @@ dependencies = [ [[package]] name = "nym-node-status-agent" -version = "2.0.1-rc2" +version = "2.0.1-rc3" dependencies = [ "anyhow", "clap", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "nym-node-status-api" -version = "4.6.2-rc4" +version = "4.6.2-rc5" dependencies = [ "ammonia", "anyhow", diff --git a/nym-gateway-probe/netstack_ping/lib.go b/nym-gateway-probe/netstack_ping/lib.go index 7d04b7cbf2..a80af4bee5 100644 --- a/nym-gateway-probe/netstack_ping/lib.go +++ b/nym-gateway-probe/netstack_ping/lib.go @@ -330,7 +330,7 @@ func pingTwoHop(req TwoHopNetstackRequest) (NetstackResponse, error) { // Ping hosts (DNS resolution test) for _, host := range req.PingHosts { consecutiveFailures := 0 - maxConsecutiveFailures := 3 + maxConsecutiveFailures := 2 for i := uint8(0); i < req.NumPing; i++ { log.Printf("Pinging %s seq=%d (via two-hop)", host, i) @@ -355,7 +355,7 @@ func pingTwoHop(req TwoHopNetstackRequest) (NetstackResponse, error) { // Ping IPs (direct connectivity test) for _, ip := range req.PingIps { consecutiveFailures := 0 - maxConsecutiveFailures := 3 + maxConsecutiveFailures := 2 for i := uint8(0); i < req.NumPing; i++ { log.Printf("Pinging %s seq=%d (via two-hop)", ip, i) @@ -375,7 +375,7 @@ func pingTwoHop(req TwoHopNetstackRequest) (NetstackResponse, error) { } if i < req.NumPing-1 { - time.Sleep(5 * time.Second) + time.Sleep(1 * time.Second) } } } @@ -481,7 +481,7 @@ func ping(req NetstackRequestGo) (NetstackResponse, error) { for _, host := range req.PingHosts { consecutiveFailures := 0 - maxConsecutiveFailures := 3 + maxConsecutiveFailures := 2 for i := uint8(0); i < req.NumPing; i++ { log.Printf("Pinging %s seq=%d", host, i) @@ -509,7 +509,7 @@ func ping(req NetstackRequestGo) (NetstackResponse, error) { for _, ip := range req.PingIps { consecutiveFailures := 0 - maxConsecutiveFailures := 3 + maxConsecutiveFailures := 2 for i := uint8(0); i < req.NumPing; i++ { log.Printf("Pinging %s seq=%d", ip, i) @@ -533,7 +533,7 @@ func ping(req NetstackRequestGo) (NetstackResponse, error) { // Sleep between ping attempts (except for the last one) if i < req.NumPing-1 { - time.Sleep(5 * time.Second) + time.Sleep(1 * time.Second) } } } @@ -689,7 +689,7 @@ func downloadFileWithRetry(urls []string, timeoutSecs uint64, tnet *netstack.Net maxRetries := 3 baseDelay := 1 * time.Second consecutiveFailures := 0 - maxConsecutiveFailures := 3 + maxConsecutiveFailures := 2 for attempt := 0; attempt < maxRetries; attempt++ { // Shuffle URLs for each attempt to try different ones diff --git a/nym-gateway-probe/src/common/probe_tests.rs b/nym-gateway-probe/src/common/probe_tests.rs index d37a1042d2..c9fc0531b0 100644 --- a/nym-gateway-probe/src/common/probe_tests.rs +++ b/nym-gateway-probe/src/common/probe_tests.rs @@ -26,7 +26,7 @@ use nym_credentials_interface::{CredentialSpendingData, TicketType}; use nym_ip_packet_client::IprClientConnect; use nym_ip_packet_requests::{IpPair, codec::MultiIpPacketCodec}; use nym_lp::peer::DHKeyPair; -use nym_registration_client::LpRegistrationClient; +use nym_registration_client::{LpClientError, LpRegistrationClient}; use nym_sdk::NymNetworkDetails; use nym_sdk::mixnet::{MixnetClient, MixnetClientBuilder, NodeIdentity, Recipient, Socks5}; use nym_topology::HardcodedTopologyProvider; @@ -186,7 +186,11 @@ pub async fn lp_registration_probe( // LpRegistrationClient uses packet-per-connection model - connect() is gone, // connection is established during handshake and registration automatically. info!("Performing LP handshake at {lp_address}..."); - match client.perform_handshake().await { + let handshake_result = + tokio::time::timeout(Duration::from_secs(15), client.perform_handshake()) + .await + .unwrap_or_else(|_| Err(LpClientError::HandshakeTimeout)); + match handshake_result { Ok(_) => { info!("LP handshake completed successfully"); lp_outcome.can_connect = true; // Connection succeeded if handshake succeeded @@ -209,16 +213,23 @@ pub async fn lp_registration_probe( // Register using the new packet-per-connection API (returns GatewayData directly) let ticket_type = TicketType::V1WireguardEntry; - let gateway_data = match client - .register_dvpn( + let register_result = tokio::time::timeout( + Duration::from_secs(15), + client.register_dvpn( &mut rng09, &wg_keypair, &gateway_identity, bandwidth_controller, ticket_type, - ) - .await - { + ), + ) + .await + .unwrap_or_else(|_| { + Err(LpClientError::Other( + "LP registration timed out after 15s".to_string(), + )) + }); + let gateway_data = match register_result { Ok(data) => data, Err(e) => { let error_msg = format!("LP registration failed: {}", e); diff --git a/nym-gateway-probe/src/config/netstack.rs b/nym-gateway-probe/src/config/netstack.rs index 2d8ff10137..5fdd052413 100644 --- a/nym-gateway-probe/src/config/netstack.rs +++ b/nym-gateway-probe/src/config/netstack.rs @@ -43,7 +43,7 @@ impl Default for NetstackArgs { fn default() -> Self { Self { netstack_download_timeout_sec: 30, - metadata_timeout_sec: 30, + metadata_timeout_sec: 10, netstack_v4_dns: String::from("1.1.1.1"), netstack_v6_dns: String::from("2606:4700:4700::1111"), netstack_num_ping: 5, diff --git a/nym-gateway-probe/src/config/socks5.rs b/nym-gateway-probe/src/config/socks5.rs index 04045560ef..0eca0830fd 100644 --- a/nym-gateway-probe/src/config/socks5.rs +++ b/nym-gateway-probe/src/config/socks5.rs @@ -38,9 +38,9 @@ impl Default for Socks5Args { "https://cloudflare-eth.com".to_string(), "https://ethereum-rpc.publicnode.com".to_string(), ], - mixnet_client_timeout_sec: 30, + mixnet_client_timeout_sec: 20, test_count: 10, - failure_count_cutoff: 3, + failure_count_cutoff: 2, } } } diff --git a/nym-gateway-probe/src/lib.rs b/nym-gateway-probe/src/lib.rs index 582c80f89e..fe4dbffc47 100644 --- a/nym-gateway-probe/src/lib.rs +++ b/nym-gateway-probe/src/lib.rs @@ -135,7 +135,20 @@ impl Probe { // Mixnet client start let mixnet_client = if self.config.test_mode.needs_mixnet() { - Some(disconnected_mixnet_client.connect_to_mixnet().await) + Some( + tokio::time::timeout( + std::time::Duration::from_secs(30), + disconnected_mixnet_client.connect_to_mixnet(), + ) + .await + .unwrap_or_else(|_| { + Err(std::io::Error::new( + std::io::ErrorKind::TimedOut, + "mixnet connect timed out after 30s", + ) + .into()) + }), + ) } else { // Make sure keys are generated, in case we don't start the mixnet client let key_store = storage.key_store(); diff --git a/nym-node-status-api/nym-node-status-agent/Cargo.toml b/nym-node-status-api/nym-node-status-agent/Cargo.toml index 96031146de..46d25e8e28 100644 --- a/nym-node-status-api/nym-node-status-agent/Cargo.toml +++ b/nym-node-status-api/nym-node-status-agent/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-agent" -version = "2.0.1-rc2" +version = "2.0.1-rc3" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs b/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs index a0cc67ccfb..d9ceaed452 100644 --- a/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs +++ b/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs @@ -3,6 +3,8 @@ use clap::{Parser, Subcommand}; use nym_bin_common::bin_info; use nym_crypto::asymmetric::ed25519::PrivateKey; use std::{env, sync::OnceLock}; +use tokio::time::Instant; +use tracing::info; pub(crate) mod generate_keypair; pub(crate) mod run_probe; @@ -81,17 +83,21 @@ impl Args { match parse_server_config(s) { Ok(config) => servers.push(config), Err(e) => { - tracing::error!("Invalid server config '{}': {}", s, e); - anyhow::bail!("Invalid server config '{}': {}", s, e); + tracing::error!("Invalid server config '{s}': {e}"); + anyhow::bail!("Invalid server config '{s}': {e}"); } } } - run_probe::run_probe(&servers, args.probe_config, log_capture) + let start = Instant::now(); + let res = run_probe::run_probe(&servers, args.probe_config, log_capture) .await .inspect_err(|err| { tracing::error!("{err}"); - })? + }); + info!("Probe completed in {:.2}ms", start.elapsed().as_secs_f32()); + + let _ = res?; } Command::GenerateKeypair { path } => { let path = path diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml index 1fa2fff49f..783d8c9b8f 100644 --- a/nym-node-status-api/nym-node-status-api/Cargo.toml +++ b/nym-node-status-api/nym-node-status-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-api" -version = "4.6.2-rc4" +version = "4.6.2-rc5" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-api/src/cli/mod.rs b/nym-node-status-api/nym-node-status-api/src/cli/mod.rs index 259b1ef0f4..e52a97ca32 100644 --- a/nym-node-status-api/nym-node-status-api/src/cli/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/cli/mod.rs @@ -76,7 +76,7 @@ pub(crate) struct Cli { #[clap( long, - default_value = "300", + default_value = "450", env = "NODE_STATUS_API_TESTRUN_REFRESH_INTERVAL" )] #[arg(value_parser = parse_duration_std)] diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs index b4c11164d1..8aa9160d18 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs @@ -11,6 +11,7 @@ use crate::{ }; use axum::Json; use axum::extract::DefaultBodyLimit; +use axum::extract::rejection::JsonRejection; use axum::{ Router, extract::{Path, State}, @@ -120,8 +121,16 @@ async fn request_testrun( async fn submit_testrun( Path(submitted_testrun_id): Path, State(state): State, - Json(submitted_result): Json, + submitted_result: Result, JsonRejection>, ) -> HttpResult { + let submitted_result = match submitted_result { + Ok(json) => json.0, + Err(err) => { + tracing::error!("json got rejected: {err}"); + return Err(HttpError::invalid_input(err)); + } + }; + state.authenticate_agent_submission(&submitted_result)?; debug!("attempting to submit testrun {submitted_testrun_id} from an authenticated agent");