From eae677a898d1cfdc619f524c1d91612f080a2cbf Mon Sep 17 00:00:00 2001 From: dynco-nym <173912580+dynco-nym@users.noreply.github.com> Date: Wed, 11 Jun 2025 00:07:45 +0200 Subject: [PATCH] Different entry/exit selection criteria --- .../src/http/api/dvpn/entry.rs | 25 +++-------- .../src/http/api/dvpn/exit.rs | 25 +++-------- .../nym-node-status-api/src/http/models.rs | 44 ++++++++++++++++--- .../nym-node-status-api/src/http/state.rs | 38 ++++++++++++---- 4 files changed, 79 insertions(+), 53 deletions(-) diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/entry.rs b/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/entry.rs index c6c2f292bc..4c883bd1c4 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/entry.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/entry.rs @@ -11,7 +11,6 @@ use axum::{ Json, Router, }; use itertools::Itertools; -use nym_validator_client::nym_nodes::NodeRole; use tracing::instrument; pub(crate) fn routes() -> Router { @@ -43,11 +42,8 @@ pub async fn get_entry_gateways(state: State) -> HttpResult) -> HttpResult Router { @@ -43,11 +42,8 @@ pub async fn get_exit_gateways(state: State) -> HttpResult) -> HttpResult bool { + self.last_probe + .as_ref() + .map(|probe| match &probe.outcome.as_entry { + directory_gw_probe_outcome::Entry::Tested(entry_test_result) => { + entry_test_result.can_route + } + directory_gw_probe_outcome::Entry::NotTested + | directory_gw_probe_outcome::Entry::EntryFailure => false, + }) + .unwrap_or(false) + } + + pub fn can_route_exit(&self) -> bool { + self.last_probe + .as_ref() + .map(|probe| { + probe + .outcome + .as_exit + .as_ref() + .map(|outcome| { + outcome.can_route_ip_external_v4 && outcome.can_route_ip_external_v6 + }) + .unwrap_or(false) + }) + .unwrap_or(false) + } +} + /// based on /// https://github.com/nymtech/nym-vpn-client/blob/nym-vpn-core-v1.10.0/nym-vpn-core/crates/nym-gateway-probe/src/types.rs /// TODO: long term types should be moved into this repo because nym-vpn-client @@ -109,11 +139,11 @@ pub mod directory_gw_probe_outcome { #[derive(Debug, Clone, Deserialize, Serialize, ToSchema)] pub struct Exit { - can_connect: bool, - can_route_ip_v4: bool, - can_route_ip_external_v4: bool, - can_route_ip_v6: bool, - can_route_ip_external_v6: bool, + pub can_connect: bool, + pub can_route_ip_v4: bool, + pub can_route_ip_external_v4: bool, + pub can_route_ip_v6: bool, + pub can_route_ip_external_v6: bool, } } diff --git a/nym-node-status-api/nym-node-status-api/src/http/state.rs b/nym-node-status-api/nym-node-status-api/src/http/state.rs index 4c947199e8..508c88d24b 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/state.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/state.rs @@ -81,6 +81,7 @@ impl AppState { } static GATEWAYS_LIST_KEY: &str = "gateways"; +static DVPN_GATEWAYS_LIST_KEY: &str = "dvpn_gateways"; static MIXNODES_LIST_KEY: &str = "mixnodes"; static NYM_NODES_LIST_KEY: &str = "nym_nodes"; static MIXSTATS_LIST_KEY: &str = "mixstats"; @@ -92,8 +93,7 @@ const MIXNODE_STATS_HISTORY_DAYS: usize = 30; #[derive(Debug, Clone)] pub(crate) struct HttpCache { gateways: Cache>>>, - // each min_version has their own cached list - dvpn_gateways: Cache>>>, + dvpn_gateways: Cache>>>, mixnodes: Cache>>>, nym_nodes: Cache>>>, mixstats: Cache>>>, @@ -183,10 +183,9 @@ impl HttpCache { pub async fn upsert_dvpn_gateway_list( &self, new_gateway_list: Vec, - min_node_version: &Version, - ) -> Entry>>> { + ) -> Entry>>> { self.dvpn_gateways - .entry_by_ref(min_node_version) + .entry_by_ref(DVPN_GATEWAYS_LIST_KEY) .and_upsert_with(|maybe_entry| async { if let Some(entry) = maybe_entry { let v = entry.into_value(); @@ -205,7 +204,7 @@ impl HttpCache { db: &DbPool, min_node_version: &Version, ) -> Vec { - match self.dvpn_gateways.get(min_node_version).await { + match self.dvpn_gateways.get(DVPN_GATEWAYS_LIST_KEY).await { Some(guard) => { tracing::trace!("Fetching from cache..."); let read_lock = guard.read().await; @@ -297,8 +296,7 @@ impl HttpCache { if res_gws.is_empty() && started_with > 0 { tracing::warn!("Started with {}, got 0 gateways", started_with); } else { - self.upsert_dvpn_gateway_list(res_gws.clone(), min_node_version) - .await; + self.upsert_dvpn_gateway_list(res_gws.clone()).await; } res_gws @@ -306,6 +304,30 @@ impl HttpCache { } } + pub async fn get_entry_dvpn_gateways( + &self, + db: &DbPool, + min_node_version: &Version, + ) -> Vec { + self.get_dvpn_gateway_list(db, min_node_version) + .await + .into_iter() + .filter(DVpnGateway::can_route_entry) + .collect() + } + + pub async fn get_exit_dvpn_gateways( + &self, + db: &DbPool, + min_node_version: &Version, + ) -> Vec { + self.get_dvpn_gateway_list(db, min_node_version) + .await + .into_iter() + .filter(DVpnGateway::can_route_exit) + .collect() + } + pub async fn upsert_mixnode_list( &self, new_mixnode_list: Vec,