nym-connect: select gateway based on latency in medium mode

This commit is contained in:
Jon Häggblad
2023-08-28 11:32:55 +02:00
parent 769a26fdeb
commit cfc86ba9f5
10 changed files with 65 additions and 5 deletions
@@ -303,7 +303,7 @@ impl GeoAwareTopologyProvider {
filter_on: GroupBy,
) -> GeoAwareTopologyProvider {
log::info!(
"Creating geo-aware topology provider with filter on {:?}",
"Creating geo-aware topology provider with filter on {}",
filter_on
);
nym_api_urls.shuffle(&mut thread_rng());
+9
View File
@@ -498,6 +498,15 @@ pub enum GroupBy {
NymAddress(Recipient),
}
impl std::fmt::Display for GroupBy {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
GroupBy::CountryGroup(group) => write!(f, "group: {}", group),
GroupBy::NymAddress(address) => write!(f, "address: {}", address),
}
}
}
impl Default for Topology {
fn default() -> Self {
Topology {
+1 -1
View File
@@ -149,7 +149,7 @@ async fn measure_latency(gateway: &gateway::Node) -> Result<GatewayWithLatency,
Ok(GatewayWithLatency::new(gateway, avg))
}
pub(super) async fn choose_gateway_by_latency<R: Rng>(
pub async fn choose_gateway_by_latency<R: Rng>(
rng: &mut R,
gateways: &[gateway::Node],
) -> Result<gateway::Node, ClientCoreError> {
+2
View File
@@ -4014,8 +4014,10 @@ dependencies = [
"nym-socks5-client-core",
"nym-sphinx",
"nym-task",
"nym-topology",
"nym-validator-client",
"pretty_env_logger",
"rand 0.7.3",
"rand 0.8.5",
"reqwest",
"rust-embed",
+1
View File
@@ -1,2 +1,3 @@
[workspace]
members = ["src-tauri"]
resolver = "2"
+2
View File
@@ -30,6 +30,7 @@ itertools = "0.10.5"
log = { version = "0.4", features = ["serde"] }
pretty_env_logger = "0.4.0"
rand = "0.8"
rand-07 = { package = "rand", version = "0.7.3" }
reqwest = { version = "0.11.18", features = ["json", "socks"] }
rust-embed = { version = "6.4.2", features = ["include-exclude"] }
serde = { version = "1.0", features = ["derive"] }
@@ -58,6 +59,7 @@ nym-bin-common = { path = "../../../common/bin-common"}
nym-socks5-client-core = { path = "../../../common/socks5-client-core" }
nym-sphinx = { path = "../../../common/nymsphinx" }
nym-task = { path = "../../../common/task" }
nym-topology = { path = "../../../common/topology" }
nym-validator-client = { path = "../../../common/client-libs/validator-client" }
[dev-dependencies]
+3 -1
View File
@@ -86,8 +86,10 @@ fn main() {
crate::operations::connection::status::get_connection_status,
crate::operations::connection::status::get_gateway_connection_status,
crate::operations::connection::status::start_connection_health_check_task,
crate::operations::directory::get_services,
crate::operations::directory::get_gateway_with_low_latency,
crate::operations::directory::get_gateway_with_low_latency_from_list,
crate::operations::directory::get_gateways,
crate::operations::directory::get_services,
crate::operations::export::export_keys,
crate::operations::window::hide_window,
crate::operations::growth::test_and_earn::growth_tne_get_client_id,
@@ -11,6 +11,7 @@ use nym_api_requests::models::GatewayBondAnnotated;
use nym_bin_common::version_checker::is_minor_version_compatible;
use nym_config::defaults::var_names::{NETWORK_NAME, NYM_API};
use nym_contracts_common::types::Percent;
use nym_topology::gateway;
use nym_validator_client::nym_api::Client as ApiClient;
use std::str::FromStr;
use std::sync::Arc;
@@ -164,3 +165,41 @@ pub async fn get_gateways() -> Result<Vec<Gateway>> {
Ok(filtered_gateways)
}
async fn select_gateway_by_latency(gateways: Vec<GatewayBondAnnotated>) -> Result<gateway::Node> {
let gateways_as_nodes: Vec<gateway::Node> = gateways
.into_iter()
.filter_map(|g| g.gateway_bond.try_into().ok())
.collect();
let mut rng = rand_07::rngs::OsRng;
let selected_gateway =
nym_client_core::init::helpers::choose_gateway_by_latency(&mut rng, &gateways_as_nodes)
.await?;
Ok(selected_gateway)
}
#[tauri::command]
pub async fn get_gateway_with_low_latency() -> Result<Gateway> {
let all_gateways = fetch_gateways().await?;
let selected_gateway = select_gateway_by_latency(all_gateways).await?;
Ok(Gateway {
identity: selected_gateway.identity().to_base58_string(),
})
}
#[tauri::command]
pub async fn get_gateway_with_low_latency_from_list(gateways: Vec<Gateway>) -> Result<Gateway> {
log::debug!("Selecting a gateway with low latency");
let gateways = gateways.into_iter().map(|g| g.identity).collect_vec();
let all_gateways = fetch_gateways().await?;
let gateways_union_set: Vec<GatewayBondAnnotated> = all_gateways
.into_iter()
.filter(|g| gateways.contains(g.identity()))
.collect();
let selected_gateway = select_gateway_by_latency(gateways_union_set).await?;
log::debug!("Selected gateway: {}", selected_gateway);
Ok(Gateway {
identity: selected_gateway.identity().to_base58_string(),
})
}
+1 -1
View File
@@ -57,7 +57,7 @@ fn override_config_from_env(config: &mut Config, privacy_level: &PrivacyLevel) {
.provider_mix_address
.parse()
.expect("failed to parse provider mix address");
log::warn!("Using geo-aware mixnode selection baseon the location of: {address}");
log::warn!("Using geo-aware mixnode selection based on the location of: {address}");
config
.core
.base
+6 -1
View File
@@ -214,7 +214,12 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => {
const setGateway = async () => {
if (gateways) {
const randomGateway = getRandomFromList(gateways);
let randomGateway;
if (userData?.privacy_level === 'Medium') {
randomGateway = await invoke<Gateway>('get_gateway_with_low_latency_from_list', { gateways });
} else {
randomGateway = getRandomFromList(gateways);
}
const withUserDefinitions = await buildGateway(randomGateway);
await invoke('set_gateway', {
gateway: shouldUseUserGateway ? userDefinedGateway.address : withUserDefinitions.identity,