From de8030d85a91c588c2a6a0f323bc23b2941c46b0 Mon Sep 17 00:00:00 2001 From: Mark Sinclair Date: Fri, 10 Oct 2025 16:07:22 +0100 Subject: [PATCH] allow NS API to run once for scraping for troubleshooting and debugging --- ...8b2abb437cccdb6ebd2e1087cc822ed737b0e.json | 26 ------------ ...fa3d5c939e7122ba7c88b78a353f00b271ec2.json | 27 +++++++++++++ .../nym-node-status-api/src/main.rs | 40 +++++++++++++------ .../nym-node-status-api/src/monitor/mod.rs | 34 +++++++++++++++- 4 files changed, 87 insertions(+), 40 deletions(-) delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-b010fb91828f7e4f0b72bdfe3b58b2abb437cccdb6ebd2e1087cc822ed737b0e.json create mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-dde9aff827c34086077927bbe33fa3d5c939e7122ba7c88b78a353f00b271ec2.json diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-b010fb91828f7e4f0b72bdfe3b58b2abb437cccdb6ebd2e1087cc822ed737b0e.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-b010fb91828f7e4f0b72bdfe3b58b2abb437cccdb6ebd2e1087cc822ed737b0e.json deleted file mode 100644 index 5379205f8d..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-b010fb91828f7e4f0b72bdfe3b58b2abb437cccdb6ebd2e1087cc822ed737b0e.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO nym_nodes\n (node_id, ed25519_identity_pubkey,\n total_stake,\n ip_addresses, mix_port,\n x25519_sphinx_pubkey, node_role,\n supported_roles, entry,\n self_described,\n bond_info,\n performance, last_updated_utc\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)\n ON CONFLICT(node_id) DO UPDATE SET\n ed25519_identity_pubkey=excluded.ed25519_identity_pubkey,\n ip_addresses=excluded.ip_addresses,\n mix_port=excluded.mix_port,\n x25519_sphinx_pubkey=excluded.x25519_sphinx_pubkey,\n node_role=excluded.node_role,\n supported_roles=excluded.supported_roles,\n entry=excluded.entry,\n self_described=excluded.self_described,\n bond_info=excluded.bond_info,\n performance=excluded.performance,\n last_updated_utc=excluded.last_updated_utc\n ;", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Varchar", - "Int8", - "Jsonb", - "Int4", - "Varchar", - "Jsonb", - "Jsonb", - "Jsonb", - "Jsonb", - "Jsonb", - "Varchar", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "b010fb91828f7e4f0b72bdfe3b58b2abb437cccdb6ebd2e1087cc822ed737b0e" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-dde9aff827c34086077927bbe33fa3d5c939e7122ba7c88b78a353f00b271ec2.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-dde9aff827c34086077927bbe33fa3d5c939e7122ba7c88b78a353f00b271ec2.json new file mode 100644 index 0000000000..0b380650c5 --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-dde9aff827c34086077927bbe33fa3d5c939e7122ba7c88b78a353f00b271ec2.json @@ -0,0 +1,27 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO nym_nodes\n (node_id, ed25519_identity_pubkey,\n total_stake,\n ip_addresses, mix_port,\n x25519_sphinx_pubkey, node_role,\n supported_roles, entry,\n self_described,\n bond_info,\n performance, last_updated_utc, http_api_port\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)\n ON CONFLICT(node_id) DO UPDATE SET\n ed25519_identity_pubkey=excluded.ed25519_identity_pubkey,\n ip_addresses=excluded.ip_addresses,\n mix_port=excluded.mix_port,\n x25519_sphinx_pubkey=excluded.x25519_sphinx_pubkey,\n node_role=excluded.node_role,\n supported_roles=excluded.supported_roles,\n entry=excluded.entry,\n self_described=excluded.self_described,\n bond_info=excluded.bond_info,\n performance=excluded.performance,\n last_updated_utc=excluded.last_updated_utc,\n http_api_port=excluded.http_api_port\n ;", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int4", + "Varchar", + "Int8", + "Jsonb", + "Int4", + "Varchar", + "Jsonb", + "Jsonb", + "Jsonb", + "Jsonb", + "Jsonb", + "Varchar", + "Int4", + "Int4" + ] + }, + "nullable": [] + }, + "hash": "dde9aff827c34086077927bbe33fa3d5c939e7122ba7c88b78a353f00b271ec2" +} diff --git a/nym-node-status-api/nym-node-status-api/src/main.rs b/nym-node-status-api/nym-node-status-api/src/main.rs index 987c9b4bf2..ebb76373ac 100644 --- a/nym-node-status-api/nym-node-status-api/src/main.rs +++ b/nym-node-status-api/nym-node-status-api/src/main.rs @@ -42,13 +42,40 @@ async fn main() -> anyhow::Result<()> { tracing::info!("Registered {} agent keys", agent_key_list.len()); let connection_url = args.database_url.clone(); - tracing::debug!("Using config:\n{:#?}", args); + if std::env::var("SHOW_CONFIG").ok().is_some() { + tracing::debug!("Using config:\n{:#?}", args); + } let storage = db::Storage::init(connection_url, args.sqlx_busy_timeout_s).await?; let db_pool = storage.pool_owned(); + // node geocache is shared between node monitor and HTTP server + let geocache = moka::future::Cache::builder() + .time_to_live(args.geodata_ttl) + .build(); + let delegations_cache = DelegationsCache::new(); + + let client_config = nym_validator_client::nyxd::Config::try_from_nym_network_details( + &nym_network_defaults::NymNetworkDetails::new_from_env(), + )?; + let nyxd_client = NyxdClient::connect(client_config.clone(), args.nyxd_addr.as_str()) + .map_err(|err| anyhow::anyhow!("Couldn't connect: {}", err))?; + match args.command { Some(Commands::ScrapeNode { node_id }) => { + if std::env::var("RUN_ONCE_INIT_NODES").ok().is_some() { + let geocache_clone = geocache.clone(); + let delegations_cache_clone = Arc::clone(&delegations_cache); + monitor::run_once( + db_pool.clone(), + args.nym_api_client_timeout, + nyxd_client, + args.ipinfo_api_token, + geocache_clone, + delegations_cache_clone, + ) + .await?; + } tracing::info!("Scraping node with id {node_id}..."); scrape_and_store_description_by_node_id(&db_pool, node_id).await?; return Ok(()); @@ -71,20 +98,9 @@ async fn main() -> anyhow::Result<()> { scraper.start().await; }); - // node geocache is shared between node monitor and HTTP server - let geocache = moka::future::Cache::builder() - .time_to_live(args.geodata_ttl) - .build(); - let delegations_cache = DelegationsCache::new(); - // Start the monitor let geocache_clone = geocache.clone(); let delegations_cache_clone = Arc::clone(&delegations_cache); - let client_config = nym_validator_client::nyxd::Config::try_from_nym_network_details( - &nym_network_defaults::NymNetworkDetails::new_from_env(), - )?; - let nyxd_client = NyxdClient::connect(client_config.clone(), args.nyxd_addr.as_str()) - .map_err(|err| anyhow::anyhow!("Couldn't connect: {}", err))?; shutdown_manager.spawn_with_shutdown(async move { monitor::run_in_background( diff --git a/nym-node-status-api/nym-node-status-api/src/monitor/mod.rs b/nym-node-status-api/nym-node-status-api/src/monitor/mod.rs index 688e644af5..17117de68c 100644 --- a/nym-node-status-api/nym-node-status-api/src/monitor/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/monitor/mod.rs @@ -68,7 +68,7 @@ pub(crate) async fn run_in_background( loop { tracing::info!("Refreshing node info..."); - if let Err(e) = monitor.run().await { + if let Err(e) = monitor.run(false).await { tracing::error!( "Monitor run failed: {e}, retrying in {}s...", MONITOR_FAILURE_RETRY_DELAY.as_secs() @@ -84,8 +84,33 @@ pub(crate) async fn run_in_background( } } +#[instrument(level = "debug", name = "data_monitor", skip_all)] +pub(crate) async fn run_once( + db_pool: DbPool, + nym_api_client_timeout: Duration, + nyxd_client: nym_validator_client::QueryHttpRpcNyxdClient, + ipinfo_api_token: String, + geocache: NodeGeoCache, + node_delegations: Arc>, +) -> anyhow::Result<()> { + let ipinfo = IpInfoClient::new(ipinfo_api_token.clone()); + + let mut monitor = Monitor { + db_pool, + network_details: nym_network_defaults::NymNetworkDetails::new_from_env(), + nym_api_client_timeout, + nyxd_client, + ipinfo, + geocache, + node_delegations, + }; + + tracing::info!("Refreshing node info..."); + Ok(monitor.run(true).await?) +} + impl Monitor { - async fn run(&mut self) -> anyhow::Result<()> { + async fn run(&mut self, exit_early: bool) -> anyhow::Result<()> { self.check_ipinfo_bandwidth().await; let default_api_url = self @@ -153,6 +178,11 @@ impl Monitor { tracing::debug!("{} nym nodes written to DB!", inserted); })?; + // stop here if running once + if exit_early { + return Ok(()); + } + // refresh geodata for all nodes for node_description in described_nodes.values() { self.location_cached(node_description).await;