Decrease default average packet delay to 15 ms (#5754)

* Decrease default average packet delay to 15 ms

* Add upgrade for config value

* Fix ip packet router too

* Fix clippy

* Remove message_sending_average_delay from template too
This commit is contained in:
Bogdan-Ștefan Neacşu
2025-05-14 16:24:34 +03:00
committed by GitHub
parent 52e06a7eb4
commit ea90d7b558
34 changed files with 1096 additions and 111 deletions
+1
View File
@@ -25,6 +25,7 @@ pub mod old_config_v1_1_13;
pub mod old_config_v1_1_20;
pub mod old_config_v1_1_20_2;
pub mod old_config_v1_1_33;
pub mod old_config_v1_1_54;
mod persistence;
mod template;
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::client::config::persistence::ClientPaths;
use crate::client::config::{default_config_filepath, Config, Socket, SocketType};
use crate::client::config::{default_config_filepath, Socket, SocketType};
use crate::error::ClientError;
use nym_bin_common::logging::LoggingSettings;
use nym_client_core::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33;
@@ -14,6 +14,8 @@ use std::io;
use std::net::{IpAddr, Ipv4Addr};
use std::path::Path;
use super::old_config_v1_1_54::ConfigV1_1_54;
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)]
pub struct ClientPathsV1_1_33 {
#[serde(flatten)]
@@ -33,6 +35,21 @@ pub struct ConfigV1_1_33 {
pub logging: LoggingSettings,
}
impl TryFrom<ConfigV1_1_33> for ConfigV1_1_54 {
type Error = ClientError;
fn try_from(value: ConfigV1_1_33) -> Result<Self, Self::Error> {
Ok(ConfigV1_1_54 {
base: value.base.into(),
socket: value.socket.into(),
storage_paths: ClientPaths {
common_paths: value.storage_paths.common_paths.upgrade_default()?,
},
logging: value.logging,
})
}
}
impl ConfigV1_1_33 {
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
read_config_from_toml_file(path)
@@ -41,17 +58,6 @@ impl ConfigV1_1_33 {
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
Self::read_from_toml_file(default_config_filepath(id))
}
pub fn try_upgrade(self) -> Result<Config, ClientError> {
Ok(Config {
base: self.base.into(),
socket: self.socket.into(),
storage_paths: ClientPaths {
common_paths: self.storage_paths.common_paths.upgrade_default()?,
},
logging: self.logging,
})
}
}
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone, Copy)]
@@ -0,0 +1,41 @@
use std::{io, path::Path};
use nym_bin_common::logging::LoggingSettings;
use nym_client_core::config::old_config_v1_1_54::ConfigV1_1_54 as BaseConfigV1_1_54;
use nym_config::read_config_from_toml_file;
use serde::{Deserialize, Serialize};
use crate::error::ClientError;
use super::{default_config_filepath, persistence::ClientPaths, Config, Socket};
#[derive(Debug, Deserialize, PartialEq, Serialize, Clone)]
pub struct ConfigV1_1_54 {
#[serde(flatten)]
pub base: BaseConfigV1_1_54,
pub socket: Socket,
pub storage_paths: ClientPaths,
pub logging: LoggingSettings,
}
impl ConfigV1_1_54 {
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
read_config_from_toml_file(path)
}
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
Self::read_from_toml_file(default_config_filepath(id))
}
pub fn try_upgrade(self) -> Result<Config, ClientError> {
Ok(Config {
base: self.base.into(),
socket: self.socket,
storage_paths: self.storage_paths,
logging: self.logging,
})
}
}
@@ -92,10 +92,6 @@ host = '{{ socket.host }}'
[debug]
[debug.traffic]
average_packet_delay = '{{ debug.traffic.average_packet_delay }}'
message_sending_average_delay = '{{ debug.traffic.message_sending_average_delay }}'
[debug.acknowledgements]
average_ack_delay = '{{ debug.acknowledgements.average_ack_delay }}'
+28 -4
View File
@@ -5,6 +5,7 @@ use crate::client::config::old_config_v1_1_13::OldConfigV1_1_13;
use crate::client::config::old_config_v1_1_20::ConfigV1_1_20;
use crate::client::config::old_config_v1_1_20_2::ConfigV1_1_20_2;
use crate::client::config::old_config_v1_1_33::ConfigV1_1_33;
use crate::client::config::old_config_v1_1_54::ConfigV1_1_54;
use crate::client::config::{BaseClientConfig, Config};
use crate::commands::ecash::Ecash;
use crate::error::ClientError;
@@ -177,7 +178,8 @@ async fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, ClientError> {
let updated_step2: ConfigV1_1_20_2 = updated_step1.into();
let (updated_step3, gateway_config) = updated_step2.upgrade()?;
let old_paths = updated_step3.storage_paths.clone();
let updated = updated_step3.try_upgrade()?;
let updated_step4: ConfigV1_1_54 = updated_step3.try_into()?;
let updated = updated_step4.try_upgrade()?;
v1_1_33::migrate_gateway_details(
&old_paths.common_paths,
@@ -205,7 +207,8 @@ async fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, ClientError> {
let updated_step1: ConfigV1_1_20_2 = old_config.into();
let (updated_step2, gateway_config) = updated_step1.upgrade()?;
let old_paths = updated_step2.storage_paths.clone();
let updated = updated_step2.try_upgrade()?;
let updated_step3: ConfigV1_1_54 = updated_step2.try_into()?;
let updated = updated_step3.try_upgrade()?;
v1_1_33::migrate_gateway_details(
&old_paths.common_paths,
@@ -229,7 +232,8 @@ async fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, ClientError> {
let (updated_step1, gateway_config) = old_config.upgrade()?;
let old_paths = updated_step1.storage_paths.clone();
let updated = updated_step1.try_upgrade()?;
let updated_step2: ConfigV1_1_54 = updated_step1.try_into()?;
let updated = updated_step2.try_upgrade()?;
v1_1_33::migrate_gateway_details(
&old_paths.common_paths,
@@ -252,7 +256,8 @@ async fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, ClientError> {
info!("It is going to get updated to the current specification.");
let old_paths = old_config.storage_paths.clone();
let updated = old_config.try_upgrade()?;
let updated_step1: ConfigV1_1_54 = old_config.try_into()?;
let updated = updated_step1.try_upgrade()?;
v1_1_33::migrate_gateway_details(
&old_paths.common_paths,
@@ -265,6 +270,22 @@ async fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, ClientError> {
Ok(true)
}
async fn try_upgrade_v1_1_54_config(id: &str) -> Result<bool, ClientError> {
// explicitly load it as v1.1.54 (which is incompatible with the current one, i.e. +1.1.55)
let Ok(old_config) = ConfigV1_1_54::read_from_default_path(id) else {
// if we failed to load it, there might have been nothing to upgrade
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
return Ok(false);
};
info!("It seems the client is using <= v1.1.54 config template.");
info!("It is going to get updated to the current specification.");
let updated = old_config.try_upgrade()?;
updated.save_to_default_location()?;
Ok(true)
}
async fn try_upgrade_config(id: &str) -> Result<(), ClientError> {
if try_upgrade_v1_1_13_config(id).await? {
return Ok(());
@@ -278,6 +299,9 @@ async fn try_upgrade_config(id: &str) -> Result<(), ClientError> {
if try_upgrade_v1_1_33_config(id).await? {
return Ok(());
}
if try_upgrade_v1_1_54_config(id).await? {
return Ok(());
}
Ok(())
}
+36 -10
View File
@@ -7,6 +7,7 @@ use crate::config::old_config_v1_1_20::ConfigV1_1_20;
use crate::config::old_config_v1_1_20_2::ConfigV1_1_20_2;
use crate::config::old_config_v1_1_30::ConfigV1_1_30;
use crate::config::old_config_v1_1_33::ConfigV1_1_33;
use crate::config::old_config_v1_1_54::ConfigV1_1_54;
use crate::config::{BaseClientConfig, Config};
use crate::error::Socks5ClientError;
use clap::CommandFactory;
@@ -204,15 +205,16 @@ async fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, Socks5ClientError>
let old_paths = updated_step3.storage_paths.clone();
let updated_step4: ConfigV1_1_33 = updated_step3.into();
let updated = updated_step4.try_upgrade()?;
let updated_step5: ConfigV1_1_54 = updated_step4.try_into()?;
v1_1_33::migrate_gateway_details(
&old_paths.common_paths,
&updated.storage_paths.common_paths,
&updated_step5.storage_paths.common_paths,
Some(gateway_config),
)
.await?;
let updated = updated_step5.try_upgrade()?;
updated.save_to_default_location()?;
Ok(true)
}
@@ -234,15 +236,16 @@ async fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, Socks5ClientError>
let old_paths = updated_step2.storage_paths.clone();
let updated_step3: ConfigV1_1_33 = updated_step2.into();
let updated = updated_step3.try_upgrade()?;
let updated_step4: ConfigV1_1_54 = updated_step3.try_into()?;
v1_1_33::migrate_gateway_details(
&old_paths.common_paths,
&updated.storage_paths.common_paths,
&updated_step4.storage_paths.common_paths,
Some(gateway_config),
)
.await?;
let updated = updated_step4.try_upgrade()?;
updated.save_to_default_location()?;
Ok(true)
}
@@ -261,15 +264,17 @@ async fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, Socks5ClientErro
let old_paths = updated_step1.storage_paths.clone();
let updated_step2: ConfigV1_1_33 = updated_step1.into();
let updated = updated_step2.try_upgrade()?;
let updated_step3: ConfigV1_1_54 = updated_step2.try_into()?;
v1_1_33::migrate_gateway_details(
&old_paths.common_paths,
&updated.storage_paths.common_paths,
&updated_step3.storage_paths.common_paths,
Some(gateway_config),
)
.await?;
let updated = updated_step3.try_upgrade()?;
updated.save_to_default_location()?;
Ok(true)
}
@@ -287,15 +292,16 @@ async fn try_upgrade_v1_1_30_config(id: &str) -> Result<bool, Socks5ClientError>
let old_paths = old_config.storage_paths.clone();
let updated_step1: ConfigV1_1_33 = old_config.into();
let updated = updated_step1.try_upgrade()?;
let updated_step2: ConfigV1_1_54 = updated_step1.try_into()?;
v1_1_33::migrate_gateway_details(
&old_paths.common_paths,
&updated.storage_paths.common_paths,
&updated_step2.storage_paths.common_paths,
None,
)
.await?;
let updated = updated_step2.try_upgrade()?;
updated.save_to_default_location()?;
Ok(true)
}
@@ -312,15 +318,32 @@ async fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, Socks5ClientError>
let old_paths = old_config.storage_paths.clone();
let updated = old_config.try_upgrade()?;
let updated_step1: ConfigV1_1_54 = old_config.try_into()?;
v1_1_33::migrate_gateway_details(
&old_paths.common_paths,
&updated.storage_paths.common_paths,
&updated_step1.storage_paths.common_paths,
None,
)
.await?;
let updated = updated_step1.try_upgrade()?;
updated.save_to_default_location()?;
Ok(true)
}
async fn try_upgrade_v1_1_54_config(id: &str) -> Result<bool, Socks5ClientError> {
// explicitly load it as v1.1.54 (which is incompatible with the current one, i.e. +1.1.55)
let Ok(old_config) = ConfigV1_1_54::read_from_default_path(id) else {
// if we failed to load it, there might have been nothing to upgrade
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
return Ok(false);
};
info!("It seems the client is using <= v1.1.54 config template.");
info!("It is going to get updated to the current specification.");
let updated = old_config.try_upgrade()?;
updated.save_to_default_location()?;
Ok(true)
}
@@ -341,6 +364,9 @@ async fn try_upgrade_config(id: &str) -> Result<(), Socks5ClientError> {
if try_upgrade_v1_1_33_config(id).await? {
return Ok(());
}
if try_upgrade_v1_1_54_config(id).await? {
return Ok(());
}
Ok(())
}
+1
View File
@@ -25,6 +25,7 @@ pub mod old_config_v1_1_20;
pub mod old_config_v1_1_20_2;
pub mod old_config_v1_1_30;
pub mod old_config_v1_1_33;
pub mod old_config_v1_1_54;
mod persistence;
mod template;
+17 -11
View File
@@ -1,7 +1,7 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::config::{default_config_filepath, Config, SocksClientPaths};
use crate::config::{default_config_filepath, SocksClientPaths};
use crate::error::Socks5ClientError;
use nym_bin_common::logging::LoggingSettings;
use nym_client_core::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33;
@@ -11,6 +11,8 @@ use serde::{Deserialize, Serialize};
use std::io;
use std::path::Path;
use super::old_config_v1_1_54::ConfigV1_1_54;
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct SocksClientPathsV1_1_33 {
#[serde(flatten)]
@@ -28,6 +30,20 @@ pub struct ConfigV1_1_33 {
pub logging: LoggingSettings,
}
impl TryFrom<ConfigV1_1_33> for ConfigV1_1_54 {
type Error = Socks5ClientError;
fn try_from(value: ConfigV1_1_33) -> Result<Self, Self::Error> {
Ok(ConfigV1_1_54 {
core: value.core.into(),
storage_paths: SocksClientPaths {
common_paths: value.storage_paths.common_paths.upgrade_default()?,
},
logging: value.logging,
})
}
}
impl ConfigV1_1_33 {
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
read_config_from_toml_file(path)
@@ -36,14 +52,4 @@ impl ConfigV1_1_33 {
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
Self::read_from_toml_file(default_config_filepath(id))
}
pub fn try_upgrade(self) -> Result<Config, Socks5ClientError> {
Ok(Config {
core: self.core.into(),
storage_paths: SocksClientPaths {
common_paths: self.storage_paths.common_paths.upgrade_default()?,
},
logging: self.logging,
})
}
}
@@ -0,0 +1,39 @@
use std::{io, path::Path};
use nym_bin_common::logging::LoggingSettings;
use nym_config::read_config_from_toml_file;
use nym_socks5_client_core::config::old_config_v1_1_54::ConfigV1_1_54 as CoreConfigV1_1_54;
use serde::{Deserialize, Serialize};
use crate::config::Config;
use crate::error::Socks5ClientError;
use super::{default_config_filepath, SocksClientPaths};
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct ConfigV1_1_54 {
pub core: CoreConfigV1_1_54,
pub storage_paths: SocksClientPaths,
pub logging: LoggingSettings,
}
impl ConfigV1_1_54 {
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
read_config_from_toml_file(path)
}
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
Self::read_from_toml_file(default_config_filepath(id))
}
pub fn try_upgrade(self) -> Result<Config, Socks5ClientError> {
Ok(Config {
core: self.core.into(),
storage_paths: self.storage_paths,
logging: self.logging,
})
}
}
-4
View File
@@ -98,10 +98,6 @@ send_anonymously = {{ core.socks5.send_anonymously }}
[core.debug]
[core.debug.traffic]
average_packet_delay = '{{ core.debug.traffic.average_packet_delay }}'
message_sending_average_delay = '{{ core.debug.traffic.message_sending_average_delay }}'
[core.debug.acknowledgements]
average_ack_delay = '{{ core.debug.acknowledgements.average_ack_delay }}'
+1 -3
View File
@@ -23,7 +23,7 @@ const DEFAULT_ACK_WAIT_MULTIPLIER: f64 = 1.5;
const DEFAULT_ACK_WAIT_ADDITION: Duration = Duration::from_millis(1_500);
const DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY: Duration = Duration::from_millis(200);
const DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY: Duration = Duration::from_millis(20);
const DEFAULT_AVERAGE_PACKET_DELAY: Duration = Duration::from_millis(50);
const DEFAULT_AVERAGE_PACKET_DELAY: Duration = Duration::from_millis(15);
const DEFAULT_TOPOLOGY_REFRESH_RATE: Duration = Duration::from_secs(5 * 60); // every 5min
const DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT: Duration = Duration::from_millis(5_000);
@@ -376,14 +376,12 @@ pub struct Traffic {
/// sent packet is going to be delayed at any given mix node.
/// So for a packet going through three mix nodes, on average, it will take three times this value
/// until the packet reaches its destination.
#[serde(with = "humantime_serde")]
pub average_packet_delay: Duration,
/// The parameter of Poisson distribution determining how long, on average,
/// it is going to take another 'real traffic stream' message to be sent.
/// If no real packets are available and cover traffic is enabled,
/// a loop cover message is sent instead in order to preserve the rate.
#[serde(with = "humantime_serde")]
pub message_sending_average_delay: Duration,
/// Controls whether the main packet stream constantly produces packets according to the predefined
@@ -6,6 +6,7 @@ pub mod v2;
pub mod v3;
pub mod v4;
pub mod v5;
pub mod v6;
// aliases for backwards compatibility
pub use v1 as old_config_v1_1_13;
@@ -13,3 +14,4 @@ pub use v2 as old_config_v1_1_20;
pub use v3 as old_config_v1_1_20_2;
pub use v4 as old_config_v1_1_30;
pub use v5 as old_config_v1_1_33;
pub use v6 as old_config_v1_1_54;
+12 -14
View File
@@ -1,16 +1,14 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{
Acknowledgements, Client, Config, CoverTraffic, DebugConfig, GatewayConnection, ReplySurbs,
Topology, Traffic,
};
use nym_sphinx_addressing::Recipient;
use nym_sphinx_params::{PacketSize, PacketType};
use serde::{Deserialize, Serialize};
use std::time::Duration;
use url::Url;
use super::v6::*;
// 'DEBUG'
const DEFAULT_ACK_WAIT_MULTIPLIER: f64 = 1.5;
@@ -87,18 +85,18 @@ pub struct ConfigV5 {
pub debug: DebugConfigV5,
}
impl From<ConfigV5> for Config {
impl From<ConfigV5> for ConfigV6 {
fn from(value: ConfigV5) -> Self {
Config {
client: Client {
ConfigV6 {
client: ClientV6 {
version: value.client.version,
id: value.client.id,
disabled_credentials_mode: value.client.disabled_credentials_mode,
nyxd_urls: value.client.nyxd_urls,
nym_api_urls: value.client.nym_api_urls,
},
debug: DebugConfig {
traffic: Traffic {
debug: DebugConfigV6 {
traffic: TrafficV6 {
average_packet_delay: value.debug.traffic.average_packet_delay,
message_sending_average_delay: value
.debug
@@ -113,7 +111,7 @@ impl From<ConfigV5> for Config {
packet_type: value.debug.traffic.packet_type,
..Default::default()
},
cover_traffic: CoverTraffic {
cover_traffic: CoverTrafficV6 {
loop_cover_traffic_average_delay: value
.debug
.cover_traffic
@@ -127,18 +125,18 @@ impl From<ConfigV5> for Config {
.cover_traffic
.disable_loop_cover_traffic_stream,
},
gateway_connection: GatewayConnection {
gateway_connection: GatewayConnectionV6 {
gateway_response_timeout: value
.debug
.gateway_connection
.gateway_response_timeout,
},
acknowledgements: Acknowledgements {
acknowledgements: AcknowledgementsV6 {
average_ack_delay: value.debug.acknowledgements.average_ack_delay,
ack_wait_multiplier: value.debug.acknowledgements.ack_wait_multiplier,
ack_wait_addition: value.debug.acknowledgements.ack_wait_addition,
},
topology: Topology {
topology: TopologyV6 {
topology_refresh_rate: value.debug.topology.topology_refresh_rate,
topology_resolution_timeout: value.debug.topology.topology_resolution_timeout,
disable_refreshing: value.debug.topology.disable_refreshing,
@@ -148,7 +146,7 @@ impl From<ConfigV5> for Config {
.max_startup_gateway_waiting_period,
..Default::default()
},
reply_surbs: ReplySurbs {
reply_surbs: ReplySurbsV6 {
minimum_reply_surb_storage_threshold: value
.debug
.reply_surbs
@@ -0,0 +1,623 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{
Acknowledgements, Client, Config, CoverTraffic, DebugConfig, ForgetMe, GatewayConnection,
RememberMe, ReplySurbs, StatsReporting, Topology, Traffic,
};
use nym_config::serde_helpers::{de_maybe_stringified, ser_maybe_stringified};
use nym_sphinx_addressing::Recipient;
use nym_sphinx_params::{PacketSize, PacketType};
use nym_statistics_common::types::SessionType;
use serde::{Deserialize, Serialize};
use std::time::Duration;
use url::Url;
// 'DEBUG'
const DEFAULT_ACK_WAIT_MULTIPLIER: f64 = 1.5;
const DEFAULT_ACK_WAIT_ADDITION: Duration = Duration::from_millis(1_500);
const DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY: Duration = Duration::from_millis(200);
const DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY: Duration = Duration::from_millis(20);
const DEFAULT_AVERAGE_PACKET_DELAY: Duration = Duration::from_millis(15);
const DEFAULT_TOPOLOGY_REFRESH_RATE: Duration = Duration::from_secs(5 * 60); // every 5min
const DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT: Duration = Duration::from_millis(5_000);
// the same values as our current (10.06.24) blacklist
const DEFAULT_MIN_MIXNODE_PERFORMANCE: u8 = 50;
const DEFAULT_MIN_GATEWAY_PERFORMANCE: u8 = 50;
const DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD: Duration = Duration::from_secs(70 * 60); // 70min -> full epoch (1h) + a bit of overhead
// Set this to a high value for now, so that we don't risk sporadic timeouts that might cause
// bought bandwidth tokens to not have time to be spent; Once we remove the gateway from the
// bandwidth bridging protocol, we can come back to a smaller timeout value
const DEFAULT_GATEWAY_RESPONSE_TIMEOUT: Duration = Duration::from_secs(5 * 60);
const DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO: f64 = 0.70;
// reply-surbs related:
// define when to request
// clients/client-core/src/client/replies/reply_storage/surb_storage.rs
const DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 10;
const DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 200;
const DEFAULT_MINIMUM_REPLY_SURB_THRESHOLD_BUFFER: usize = 0;
// define how much to request at once
// clients/client-core/src/client/replies/reply_controller.rs
const DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 10;
const DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 50;
const DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE: u32 = 500;
const DEFAULT_MAXIMUM_REPLY_SURB_REREQUEST_WAITING_PERIOD: Duration = Duration::from_secs(10);
const DEFAULT_MAXIMUM_REPLY_SURB_DROP_WAITING_PERIOD: Duration = Duration::from_secs(5 * 60);
// 12 hours
const DEFAULT_MAXIMUM_REPLY_SURB_AGE: Duration = Duration::from_secs(12 * 60 * 60);
// 24 hours
const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60);
// stats reporting related
/// Time interval between reporting statistics to the given provider if it exists
const STATS_REPORT_INTERVAL_SECS: Duration = Duration::from_secs(300);
// aliases for backwards compatibility
pub type ConfigV1_1_54 = ConfigV6;
pub type ClientV1_1_54 = ClientV6;
pub type DebugConfigV1_1_54 = DebugConfigV6;
pub type TrafficV1_1_54 = TrafficV6;
pub type CoverTrafficV1_1_54 = CoverTrafficV6;
pub type GatewayConnectionV1_1_54 = GatewayConnectionV6;
pub type AcknowledgementsV1_1_54 = AcknowledgementsV6;
pub type TopologyV1_1_54 = TopologyV6;
pub type ReplySurbsV1_1_54 = ReplySurbsV6;
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct ConfigV6 {
pub client: ClientV6,
#[serde(default)]
pub debug: DebugConfigV6,
}
impl From<ConfigV6> for Config {
fn from(value: ConfigV6) -> Self {
Config {
client: Client {
version: value.client.version,
id: value.client.id,
disabled_credentials_mode: value.client.disabled_credentials_mode,
nyxd_urls: value.client.nyxd_urls,
nym_api_urls: value.client.nym_api_urls,
},
debug: DebugConfig {
traffic: Traffic {
average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY,
message_sending_average_delay: value
.debug
.traffic
.message_sending_average_delay,
disable_main_poisson_packet_distribution: value
.debug
.traffic
.disable_main_poisson_packet_distribution,
primary_packet_size: value.debug.traffic.primary_packet_size,
secondary_packet_size: value.debug.traffic.secondary_packet_size,
packet_type: value.debug.traffic.packet_type,
deterministic_route_selection: value
.debug
.traffic
.deterministic_route_selection,
maximum_number_of_retransmissions: value
.debug
.traffic
.maximum_number_of_retransmissions,
use_legacy_sphinx_format: value.debug.traffic.use_legacy_sphinx_format,
disable_mix_hops: value.debug.traffic.disable_mix_hops,
},
cover_traffic: CoverTraffic {
loop_cover_traffic_average_delay: value
.debug
.cover_traffic
.loop_cover_traffic_average_delay,
cover_traffic_primary_size_ratio: value
.debug
.cover_traffic
.cover_traffic_primary_size_ratio,
disable_loop_cover_traffic_stream: value
.debug
.cover_traffic
.disable_loop_cover_traffic_stream,
},
gateway_connection: GatewayConnection {
gateway_response_timeout: value
.debug
.gateway_connection
.gateway_response_timeout,
},
acknowledgements: Acknowledgements {
average_ack_delay: value.debug.acknowledgements.average_ack_delay,
ack_wait_multiplier: value.debug.acknowledgements.ack_wait_multiplier,
ack_wait_addition: value.debug.acknowledgements.ack_wait_addition,
},
topology: Topology {
topology_refresh_rate: value.debug.topology.topology_refresh_rate,
topology_resolution_timeout: value.debug.topology.topology_resolution_timeout,
disable_refreshing: value.debug.topology.disable_refreshing,
max_startup_gateway_waiting_period: value
.debug
.topology
.max_startup_gateway_waiting_period,
minimum_mixnode_performance: value.debug.topology.minimum_mixnode_performance,
minimum_gateway_performance: value.debug.topology.minimum_gateway_performance,
use_extended_topology: value.debug.topology.use_extended_topology,
ignore_egress_epoch_role: value.debug.topology.ignore_egress_epoch_role,
ignore_ingress_epoch_role: value.debug.topology.ignore_ingress_epoch_role,
},
reply_surbs: ReplySurbs {
minimum_reply_surb_storage_threshold: value
.debug
.reply_surbs
.minimum_reply_surb_storage_threshold,
maximum_reply_surb_storage_threshold: value
.debug
.reply_surbs
.maximum_reply_surb_storage_threshold,
minimum_reply_surb_request_size: value
.debug
.reply_surbs
.minimum_reply_surb_request_size,
maximum_reply_surb_request_size: value
.debug
.reply_surbs
.maximum_reply_surb_request_size,
maximum_allowed_reply_surb_request_size: value
.debug
.reply_surbs
.maximum_allowed_reply_surb_request_size,
maximum_reply_surb_rerequest_waiting_period: value
.debug
.reply_surbs
.maximum_reply_surb_rerequest_waiting_period,
maximum_reply_surb_drop_waiting_period: value
.debug
.reply_surbs
.maximum_reply_surb_drop_waiting_period,
maximum_reply_surb_age: value.debug.reply_surbs.maximum_reply_surb_age,
maximum_reply_key_age: value.debug.reply_surbs.maximum_reply_key_age,
surb_mix_hops: value.debug.reply_surbs.surb_mix_hops,
minimum_reply_surb_threshold_buffer: value
.debug
.reply_surbs
.minimum_reply_surb_threshold_buffer,
fresh_sender_tags: value.debug.reply_surbs.fresh_sender_tags,
},
stats_reporting: StatsReporting {
enabled: value.debug.stats_reporting.enabled,
provider_address: value.debug.stats_reporting.provider_address,
reporting_interval: value.debug.stats_reporting.reporting_interval,
},
forget_me: ForgetMe {
client: value.debug.forget_me.client,
stats: value.debug.forget_me.stats,
},
remember_me: RememberMe {
stats: value.debug.remember_me.stats,
session_type: value.debug.remember_me.session_type.into(),
},
},
}
}
}
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
// note: the deny_unknown_fields is VITAL here to allow upgrades from v1.1.20_2
#[serde(deny_unknown_fields)]
pub struct ClientV6 {
/// Version of the client for which this configuration was created.
pub version: String,
/// ID specifies the human readable ID of this particular client.
pub id: String,
/// Indicates whether this client is running in a disabled credentials mode, thus attempting
/// to claim bandwidth without presenting bandwidth credentials.
// TODO: this should be moved to `debug.gateway_connection`
#[serde(default)]
pub disabled_credentials_mode: bool,
/// Addresses to nyxd validators via which the client can communicate with the chain.
#[serde(alias = "validator_urls")]
pub nyxd_urls: Vec<Url>,
/// Addresses to APIs running on validator from which the client gets the view of the network.
#[serde(alias = "validator_api_urls")]
pub nym_api_urls: Vec<Url>,
}
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct TrafficV6 {
/// The parameter of Poisson distribution determining how long, on average,
/// sent packet is going to be delayed at any given mix node.
/// So for a packet going through three mix nodes, on average, it will take three times this value
/// until the packet reaches its destination.
#[serde(with = "humantime_serde")]
pub average_packet_delay: Duration,
/// The parameter of Poisson distribution determining how long, on average,
/// it is going to take another 'real traffic stream' message to be sent.
/// If no real packets are available and cover traffic is enabled,
/// a loop cover message is sent instead in order to preserve the rate.
#[serde(with = "humantime_serde")]
pub message_sending_average_delay: Duration,
/// Controls whether the main packet stream constantly produces packets according to the predefined
/// poisson distribution.
pub disable_main_poisson_packet_distribution: bool,
/// Specify whether route selection should be determined by the packet header.
pub deterministic_route_selection: bool,
/// Specify how many times particular packet can be retransmitted
/// None - no limit
pub maximum_number_of_retransmissions: Option<u32>,
/// Specifies the packet size used for sent messages.
/// Do not override it unless you understand the consequences of that change.
pub primary_packet_size: PacketSize,
/// Specifies the optional auxiliary packet size for optimizing message streams.
/// Note that its use decreases overall anonymity.
/// Do not set it unless you understand the consequences of that change.
pub secondary_packet_size: Option<PacketSize>,
/// Specify whether any constructed sphinx packets should use the legacy format,
/// where the payload keys are explicitly attached rather than using the seeds
/// this affects any forward packets, acks and reply surbs
/// this flag should remain disabled until sufficient number of nodes on the network has upgraded
/// and support updated format.
/// in the case of reply surbs, the recipient must also understand the new encoding
pub use_legacy_sphinx_format: bool,
pub packet_type: PacketType,
/// Indicates whether to mix hops or not. If mix hops are enabled, traffic
/// will be routed as usual, to the entry gateway, through three mix nodes, egressing
/// through the exit gateway. If mix hops are disabled, traffic will be routed directly
/// from the entry gateway to the exit gateway, bypassing the mix nodes.
pub disable_mix_hops: bool,
}
impl Default for TrafficV6 {
fn default() -> Self {
TrafficV6 {
average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY,
message_sending_average_delay: DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY,
disable_main_poisson_packet_distribution: false,
deterministic_route_selection: false,
maximum_number_of_retransmissions: None,
primary_packet_size: PacketSize::RegularPacket,
secondary_packet_size: None,
packet_type: PacketType::Mix,
// we should use the legacy format until sufficient number of nodes understand the
// improved encoding
use_legacy_sphinx_format: true,
disable_mix_hops: false,
}
}
}
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct CoverTrafficV6 {
/// The parameter of Poisson distribution determining how long, on average,
/// it is going to take for another loop cover traffic message to be sent.
#[serde(with = "humantime_serde")]
pub loop_cover_traffic_average_delay: Duration,
/// Specifies the ratio of `primary_packet_size` to `secondary_packet_size` used in cover traffic.
/// Only applicable if `secondary_packet_size` is enabled.
pub cover_traffic_primary_size_ratio: f64,
/// Controls whether the dedicated loop cover traffic stream should be enabled.
/// (and sending packets, on average, every [Self::loop_cover_traffic_average_delay])
pub disable_loop_cover_traffic_stream: bool,
}
impl Default for CoverTrafficV6 {
fn default() -> Self {
CoverTrafficV6 {
loop_cover_traffic_average_delay: DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY,
cover_traffic_primary_size_ratio: DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO,
disable_loop_cover_traffic_stream: false,
}
}
}
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct GatewayConnectionV6 {
/// How long we're willing to wait for a response to a message sent to the gateway,
/// before giving up on it.
#[serde(with = "humantime_serde")]
pub gateway_response_timeout: Duration,
}
impl Default for GatewayConnectionV6 {
fn default() -> Self {
GatewayConnectionV6 {
gateway_response_timeout: DEFAULT_GATEWAY_RESPONSE_TIMEOUT,
}
}
}
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct AcknowledgementsV6 {
/// The parameter of Poisson distribution determining how long, on average,
/// sent acknowledgement is going to be delayed at any given mix node.
/// So for an ack going through three mix nodes, on average, it will take three times this value
/// until the packet reaches its destination.
#[serde(with = "humantime_serde")]
pub average_ack_delay: Duration,
/// Value multiplied with the expected round trip time of an acknowledgement packet before
/// it is assumed it was lost and retransmission of the data packet happens.
/// In an ideal network with 0 latency, this value would have been 1.
pub ack_wait_multiplier: f64,
/// Value added to the expected round trip time of an acknowledgement packet before
/// it is assumed it was lost and retransmission of the data packet happens.
/// In an ideal network with 0 latency, this value would have been 0.
#[serde(with = "humantime_serde")]
pub ack_wait_addition: Duration,
}
impl Default for AcknowledgementsV6 {
fn default() -> Self {
AcknowledgementsV6 {
average_ack_delay: DEFAULT_AVERAGE_PACKET_DELAY,
ack_wait_multiplier: DEFAULT_ACK_WAIT_MULTIPLIER,
ack_wait_addition: DEFAULT_ACK_WAIT_ADDITION,
}
}
}
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct TopologyV6 {
/// The uniform delay every which clients are querying the directory server
/// to try to obtain a compatible network topology to send sphinx packets through.
#[serde(with = "humantime_serde")]
pub topology_refresh_rate: Duration,
/// During topology refresh, test packets are sent through every single possible network
/// path. This timeout determines waiting period until it is decided that the packet
/// did not reach its destination.
#[serde(with = "humantime_serde")]
pub topology_resolution_timeout: Duration,
/// Specifies whether the client should not refresh the network topology after obtaining
/// the first valid instance.
/// Supersedes `topology_refresh_rate_ms`.
pub disable_refreshing: bool,
/// Defines how long the client is going to wait on startup for its gateway to come online,
/// before abandoning the procedure.
#[serde(with = "humantime_serde")]
pub max_startup_gateway_waiting_period: Duration,
/// Specifies a minimum performance of a mixnode that is used on route construction.
/// This setting is only applicable when `NymApi` topology is used.
pub minimum_mixnode_performance: u8,
/// Specifies a minimum performance of a gateway that is used on route construction.
/// This setting is only applicable when `NymApi` topology is used.
pub minimum_gateway_performance: u8,
/// Specifies whether this client should attempt to retrieve all available network nodes
/// as opposed to just active mixnodes/gateways.
pub use_extended_topology: bool,
/// Specifies whether this client should ignore the current epoch role of the target egress node
/// when constructing the final hop packets.
pub ignore_egress_epoch_role: bool,
/// Specifies whether this client should ignore the current epoch role of the ingress node
/// when attempting to establish new connection
pub ignore_ingress_epoch_role: bool,
}
impl Default for TopologyV6 {
fn default() -> Self {
TopologyV6 {
topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE,
topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT,
disable_refreshing: false,
max_startup_gateway_waiting_period: DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD,
minimum_mixnode_performance: DEFAULT_MIN_MIXNODE_PERFORMANCE,
minimum_gateway_performance: DEFAULT_MIN_GATEWAY_PERFORMANCE,
use_extended_topology: false,
ignore_egress_epoch_role: true,
ignore_ingress_epoch_role: true,
}
}
}
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct ReplySurbsV6 {
/// Defines the minimum number of reply surbs the client wants to keep in its storage at all times.
/// It can only allow to go below that value if its to request additional reply surbs.
pub minimum_reply_surb_storage_threshold: usize,
/// Defines the maximum number of reply surbs the client wants to keep in its storage at any times.
pub maximum_reply_surb_storage_threshold: usize,
/// Defines the soft threshold ontop of the minimum reply surb storage threshold for when the client
/// should proactively request additional reply surbs.
pub minimum_reply_surb_threshold_buffer: usize,
/// Defines the minimum number of reply surbs the client would request.
pub minimum_reply_surb_request_size: u32,
/// Defines the maximum number of reply surbs the client would request.
pub maximum_reply_surb_request_size: u32,
/// Defines the maximum number of reply surbs a remote party is allowed to request from this client at once.
pub maximum_allowed_reply_surb_request_size: u32,
/// Defines maximum amount of time the client is going to wait for reply surbs before explicitly asking
/// for more even though in theory they wouldn't need to.
#[serde(with = "humantime_serde")]
pub maximum_reply_surb_rerequest_waiting_period: Duration,
/// Defines maximum amount of time the client is going to wait for reply surbs before
/// deciding it's never going to get them and would drop all pending messages
#[serde(with = "humantime_serde")]
pub maximum_reply_surb_drop_waiting_period: Duration,
/// Defines maximum amount of time given reply surb is going to be valid for.
/// This is going to be superseded by key rotation once implemented.
#[serde(with = "humantime_serde")]
pub maximum_reply_surb_age: Duration,
/// Defines maximum amount of time given reply key is going to be valid for.
/// This is going to be superseded by key rotation once implemented.
#[serde(with = "humantime_serde")]
pub maximum_reply_key_age: Duration,
/// Specifies the number of mixnet hops the packet should go through. If not specified, then
/// the default value is used.
pub surb_mix_hops: Option<u8>,
/// Specifies if we should reset all the sender tags on startup
pub fresh_sender_tags: bool,
}
impl Default for ReplySurbsV6 {
fn default() -> Self {
ReplySurbsV6 {
minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD,
maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD,
minimum_reply_surb_threshold_buffer: DEFAULT_MINIMUM_REPLY_SURB_THRESHOLD_BUFFER,
minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE,
maximum_reply_surb_request_size: DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE,
maximum_allowed_reply_surb_request_size: DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE,
maximum_reply_surb_rerequest_waiting_period:
DEFAULT_MAXIMUM_REPLY_SURB_REREQUEST_WAITING_PERIOD,
maximum_reply_surb_drop_waiting_period: DEFAULT_MAXIMUM_REPLY_SURB_DROP_WAITING_PERIOD,
maximum_reply_surb_age: DEFAULT_MAXIMUM_REPLY_SURB_AGE,
maximum_reply_key_age: DEFAULT_MAXIMUM_REPLY_KEY_AGE,
surb_mix_hops: None,
fresh_sender_tags: false,
}
}
}
#[derive(Debug, Default, Clone, Copy, Deserialize, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct DebugConfigV6 {
/// Defines all configuration options related to traffic streams.
pub traffic: TrafficV6,
/// Defines all configuration options related to cover traffic stream(s).
pub cover_traffic: CoverTrafficV6,
/// Defines all configuration options related to the gateway connection.
pub gateway_connection: GatewayConnectionV6,
/// Defines all configuration options related to acknowledgements, such as delays or wait timeouts.
pub acknowledgements: AcknowledgementsV6,
/// Defines all configuration options related topology, such as refresh rates or timeouts.
pub topology: TopologyV6,
/// Defines all configuration options related to reply SURBs.
pub reply_surbs: ReplySurbsV6,
/// Defines all configuration options related to stats reporting.
pub stats_reporting: StatsReportingV6,
/// Defines all configuration options related to the forget me flag.
pub forget_me: ForgetMeV6,
/// Defines all configuration options related to the remember me flag.
pub remember_me: RememberMeV6,
}
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct StatsReportingV6 {
/// Is stats reporting enabled
pub enabled: bool,
/// Address of the stats collector. If this is none, no reporting will happen, regardless of `enabled`
#[serde(
serialize_with = "ser_maybe_stringified",
deserialize_with = "de_maybe_stringified"
)]
pub provider_address: Option<Recipient>,
/// With what frequence will statistics be sent
#[serde(with = "humantime_serde")]
pub reporting_interval: Duration,
}
impl Default for StatsReportingV6 {
fn default() -> Self {
StatsReportingV6 {
enabled: true,
provider_address: None,
reporting_interval: STATS_REPORT_INTERVAL_SECS,
}
}
}
#[derive(Clone, Default, Debug, Deserialize, PartialEq, Serialize, Copy)]
pub struct ForgetMeV6 {
client: bool,
stats: bool,
}
#[derive(Clone, Default, Debug, Deserialize, PartialEq, Serialize, Copy)]
pub struct RememberMeV6 {
/// Signal that this client should be accounted for in the stats
stats: bool,
/// Type of the session to remember, if it should be remembered
session_type: SessionTypeV6,
}
#[derive(PartialEq, Copy, Clone, Serialize, Deserialize, Default, Debug)]
pub enum SessionTypeV6 {
Vpn,
Mixnet,
Wasm,
Native,
Socks5,
#[default]
Unknown,
}
impl From<SessionTypeV6> for SessionType {
fn from(value: SessionTypeV6) -> Self {
match value {
SessionTypeV6::Vpn => Self::Vpn,
SessionTypeV6::Mixnet => Self::Mixnet,
SessionTypeV6::Wasm => Self::Wasm,
SessionTypeV6::Native => Self::Native,
SessionTypeV6::Socks5 => Self::Socks5,
SessionTypeV6::Unknown => Self::Unknown,
}
}
}
+1 -1
View File
@@ -4,6 +4,6 @@
pub use nym_client_core_config_types::disk_persistence;
pub use nym_client_core_config_types::old::{
old_config_v1_1_13, old_config_v1_1_20, old_config_v1_1_20_2, old_config_v1_1_30,
old_config_v1_1_33,
old_config_v1_1_33, old_config_v1_1_54,
};
pub use nym_client_core_config_types::*;
@@ -13,6 +13,7 @@ use std::str::FromStr;
pub mod old_config_v1_1_20_2;
pub mod old_config_v1_1_30;
pub mod old_config_v1_1_33;
pub mod old_config_v1_1_54;
pub use nym_service_providers_common::interface::ProviderInterfaceVersion;
pub use nym_socks5_requests::Socks5ProtocolVersion;
@@ -1,7 +1,8 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::{Config, Socks5, Socks5Debug};
use super::old_config_v1_1_54::ConfigV1_1_54;
use super::{Socks5, Socks5Debug};
pub use nym_client_core::config::old_config_v1_1_33::ConfigV1_1_33 as BaseClientConfigV1_1_33;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
@@ -23,9 +24,9 @@ pub struct ConfigV1_1_33 {
pub socks5: Socks5V1_1_33,
}
impl From<ConfigV1_1_33> for Config {
impl From<ConfigV1_1_33> for ConfigV1_1_54 {
fn from(value: ConfigV1_1_33) -> Self {
Config {
ConfigV1_1_54 {
base: value.base.into(),
socks5: value.socks5.into(),
}
@@ -0,0 +1,23 @@
use super::Config;
pub use nym_client_core::config::old_config_v1_1_54::ConfigV1_1_54 as BaseClientConfigV1_1_54;
use serde::{Deserialize, Serialize};
use super::Socks5;
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct ConfigV1_1_54 {
#[serde(flatten)]
pub base: BaseClientConfigV1_1_54,
pub socks5: Socks5,
}
impl From<ConfigV1_1_54> for Config {
fn from(value: ConfigV1_1_54) -> Self {
Config {
base: value.base.into(),
socks5: value.socks5,
}
}
}
@@ -1,13 +1,32 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use log::trace;
use log::{info, trace};
use std::path::Path;
use crate::error::AuthenticatorError;
use crate::{config::old_config_v1_1_54::ConfigV1_1_54, error::AuthenticatorError};
pub async fn try_upgrade_config<P: AsRef<Path>>(_config_path: P) -> Result<(), AuthenticatorError> {
async fn try_upgrade_v1_1_54_config<P: AsRef<Path>>(id: P) -> Result<bool, AuthenticatorError> {
// explicitly load it as v1.1.54 (which is incompatible with the current one, i.e. +1.1.55)
let Ok(old_config) = ConfigV1_1_54::read_from_default_path(id) else {
// if we failed to load it, there might have been nothing to upgrade
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
return Ok(false);
};
info!("It seems the client is using <= v1.1.54 config template.");
info!("It is going to get updated to the current specification.");
let updated = old_config.try_upgrade()?;
updated.save_to_default_location()?;
Ok(true)
}
pub async fn try_upgrade_config<P: AsRef<Path>>(id: P) -> Result<(), AuthenticatorError> {
trace!("Attempting to upgrade config");
if try_upgrade_v1_1_54_config(id).await? {
return Ok(());
}
Ok(())
}
@@ -24,6 +24,7 @@ use std::{
use template::CONFIG_TEMPLATE;
pub mod helpers;
pub mod old_config_v1_1_54;
pub mod persistence;
pub mod template;
@@ -0,0 +1,43 @@
use std::{io, path::Path};
use nym_bin_common::logging::LoggingSettings;
pub use nym_client_core::config::old_config_v1_1_54::ConfigV1_1_54 as BaseConfigV1_1_54;
use nym_config::read_config_from_toml_file;
use serde::{Deserialize, Serialize};
use crate::{config::Config, error::AuthenticatorError};
use super::{default_config_filepath, Authenticator, AuthenticatorPaths};
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct ConfigV1_1_54 {
#[serde(flatten)]
pub base: BaseConfigV1_1_54,
#[serde(default)]
pub authenticator: Authenticator,
pub storage_paths: AuthenticatorPaths,
pub logging: LoggingSettings,
}
impl ConfigV1_1_54 {
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
read_config_from_toml_file(path)
}
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
Self::read_from_toml_file(default_config_filepath(id))
}
pub fn try_upgrade(self) -> Result<Config, AuthenticatorError> {
Ok(Config {
base: self.base.into(),
authenticator: self.authenticator,
storage_paths: self.storage_paths,
logging: self.logging,
})
}
}
@@ -85,10 +85,6 @@ unknown_list_location = '{{ storage_paths.unknown_list_location }}'
[debug]
[debug.traffic]
average_packet_delay = '{{ debug.traffic.average_packet_delay }}'
message_sending_average_delay = '{{ debug.traffic.message_sending_average_delay }}'
[debug.acknowledgements]
average_ack_delay = '{{ debug.acknowledgements.average_ack_delay }}'
@@ -4,7 +4,7 @@ use log::error;
use nym_bin_common::bin_info;
use nym_bin_common::completions::{fig_generate, ArgShell};
use nym_client_core::cli_helpers::CliClient;
use nym_ip_packet_router::config::helpers::try_upgrade_config;
use nym_ip_packet_router::config::helpers::{try_upgrade_config, try_upgrade_config_by_id};
use nym_ip_packet_router::config::{BaseClientConfig, Config};
use nym_ip_packet_router::error::IpPacketRouterError;
use std::sync::OnceLock;
@@ -151,7 +151,7 @@ async fn try_load_current_config(id: &str) -> Result<Config, IpPacketRouterError
}
// we couldn't load it - try upgrading it from older revisions
try_upgrade_config(id).await?;
try_upgrade_config_by_id(id).await?;
let config = match Config::read_from_default_path(id) {
Ok(cfg) => cfg,
@@ -3,6 +3,7 @@
use crate::config::default_config_filepath;
use crate::config::old_config_v1::ConfigV1;
use crate::config::old_config_v2::ConfigV2;
use crate::error::IpPacketRouterError;
use log::{info, trace};
use nym_client_core::cli_helpers::CliClientConfig;
@@ -22,22 +23,45 @@ async fn try_upgrade_v1_config<P: AsRef<Path>>(
info!("It is going to get updated to the current specification.");
let old_paths = old_config.storage_paths.clone();
let updated = old_config.try_upgrade()?;
let updated_step1: ConfigV2 = old_config.try_into()?;
v1_1_33::migrate_gateway_details(
&old_paths.common_paths,
&updated.storage_paths.common_paths,
&updated_step1.storage_paths.common_paths,
None,
)
.await?;
let updated = updated_step1.try_upgrade()?;
updated.save_to(config_path)?;
Ok(true)
}
async fn try_upgrade_v2_config<P: AsRef<Path>>(
config_path: P,
) -> Result<bool, IpPacketRouterError> {
// explicitly load it as v2 (which is incompatible with the current one)
let Ok(old_config) = ConfigV2::read_from_toml_file(config_path.as_ref()) else {
// if we failed to load it, there might have been nothing to upgrade
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
return Ok(false);
};
info!("It seems the client is using v2 config template.");
info!("It is going to get updated to the current specification.");
let updated = old_config.try_upgrade()?;
updated.save_to(config_path)?;
Ok(true)
}
pub async fn try_upgrade_config<P: AsRef<Path>>(config_path: P) -> Result<(), IpPacketRouterError> {
trace!("Attempting to upgrade config");
if try_upgrade_v1_config(config_path).await? {
if try_upgrade_v1_config(config_path.as_ref()).await? {
return Ok(());
}
if try_upgrade_v2_config(config_path).await? {
return Ok(());
}
@@ -22,6 +22,7 @@ use self::template::CONFIG_TEMPLATE;
pub mod helpers;
pub mod old_config_v1;
pub mod old_config_v2;
mod persistence;
mod template;
@@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::config::persistence::IpPacketRouterPaths;
use crate::config::Config;
use crate::config::{default_config_filepath, IpPacketRouter};
use crate::error::IpPacketRouterError;
use nym_bin_common::logging::LoggingSettings;
@@ -16,6 +15,8 @@ use std::io;
use std::path::{Path, PathBuf};
use url::Url;
use super::old_config_v2::ConfigV2;
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)]
pub struct IpPacketRouterPathsV1 {
#[serde(flatten)]
@@ -39,6 +40,22 @@ pub struct ConfigV1 {
pub logging: LoggingSettings,
}
impl TryFrom<ConfigV1> for ConfigV2 {
type Error = IpPacketRouterError;
fn try_from(value: ConfigV1) -> Result<Self, Self::Error> {
Ok(ConfigV2 {
base: value.base.into(),
ip_packet_router: value.ip_packet_router.into(),
storage_paths: IpPacketRouterPaths {
common_paths: value.storage_paths.common_paths.upgrade_default()?,
ip_packet_router_description: value.storage_paths.ip_packet_router_description,
},
logging: value.logging,
})
}
}
impl ConfigV1 {
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
read_config_from_toml_file(path)
@@ -47,18 +64,6 @@ impl ConfigV1 {
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
Self::read_from_toml_file(default_config_filepath(id))
}
pub fn try_upgrade(self) -> Result<Config, IpPacketRouterError> {
Ok(Config {
base: self.base.into(),
ip_packet_router: self.ip_packet_router.into(),
storage_paths: IpPacketRouterPaths {
common_paths: self.storage_paths.common_paths.upgrade_default()?,
ip_packet_router_description: self.storage_paths.ip_packet_router_description,
},
logging: self.logging,
})
}
}
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
@@ -0,0 +1,42 @@
use std::{io, path::Path};
use crate::{config::Config, error::IpPacketRouterError};
use nym_bin_common::logging::LoggingSettings;
use nym_client_core::config::old_config_v1_1_54::ConfigV1_1_54 as BaseConfigV1_1_54;
use nym_config::read_config_from_toml_file;
use serde::{Deserialize, Serialize};
use super::{default_config_filepath, IpPacketRouter, IpPacketRouterPaths};
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct ConfigV2 {
#[serde(flatten)]
pub base: BaseConfigV1_1_54,
#[serde(default)]
pub ip_packet_router: IpPacketRouter,
pub storage_paths: IpPacketRouterPaths,
pub logging: LoggingSettings,
}
impl ConfigV2 {
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
read_config_from_toml_file(path)
}
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
Self::read_from_toml_file(default_config_filepath(id))
}
pub fn try_upgrade(self) -> Result<Config, IpPacketRouterError> {
Ok(Config {
base: self.base.into(),
ip_packet_router: self.ip_packet_router,
storage_paths: self.storage_paths,
logging: self.logging,
})
}
}
@@ -88,10 +88,6 @@ ip_packet_router_description = '{{ storage_paths.ip_packet_router_description }}
[debug]
[debug.traffic]
average_packet_delay = '{{ debug.traffic.average_packet_delay }}'
message_sending_average_delay = '{{ debug.traffic.message_sending_average_delay }}'
[debug.acknowledgements]
average_ack_delay = '{{ debug.acknowledgements.average_ack_delay }}'
@@ -2,11 +2,12 @@
// SPDX-License-Identifier: Apache-2.0
use crate::config::default_config_filepath;
use crate::config::old::v5::ConfigV5;
use crate::config::old::v6::ConfigV6;
use crate::config::old_config_v1_1_13::OldConfigV1;
use crate::config::old_config_v1_1_20::ConfigV2;
use crate::config::old_config_v1_1_20_2::ConfigV3;
use crate::config::old_config_v1_1_33::ConfigV4;
use crate::config::old_config_v1_1_54::ConfigV5;
use crate::config::Config;
use crate::error::NetworkRequesterError;
use log::{info, trace};
@@ -42,7 +43,8 @@ async fn try_upgrade_v1_config<P: AsRef<Path>>(
)
.await?;
let updated: Config = updated_step4.into();
let updated_step5: ConfigV6 = updated_step4.into();
let updated: Config = updated_step5.into();
updated.save_to(config_path)?;
Ok(true)
@@ -76,7 +78,8 @@ async fn try_upgrade_v2_config<P: AsRef<Path>>(
)
.await?;
let updated: Config = updated_step3.into();
let updated_step4: ConfigV6 = updated_step3.into();
let updated: Config = updated_step4.into();
updated.save_to(config_path)?;
Ok(true)
@@ -107,7 +110,8 @@ async fn try_upgrade_v3_config<P: AsRef<Path>>(
)
.await?;
let updated: Config = updated_step2.into();
let updated_step3: ConfigV6 = updated_step2.into();
let updated: Config = updated_step3.into();
updated.save_to(config_path)?;
Ok(true)
@@ -137,7 +141,8 @@ async fn try_upgrade_v4_config<P: AsRef<Path>>(
)
.await?;
let updated: Config = updated_step1.into();
let updated_step2: ConfigV6 = updated_step1.into();
let updated: Config = updated_step2.into();
updated.save_to(config_path)?;
Ok(true)
@@ -155,6 +160,25 @@ async fn try_upgrade_v5_config<P: AsRef<Path>>(
info!("It seems the client is using <= v5 config template.");
info!("It is going to get updated to the current specification.");
let updated_step1: ConfigV6 = old_config.into();
let updated: Config = updated_step1.into();
updated.save_to(config_path)?;
Ok(true)
}
async fn try_upgrade_v6_config<P: AsRef<Path>>(
config_path: P,
) -> Result<bool, NetworkRequesterError> {
// explicitly load it as v6 (which is incompatible with the current one)
let Ok(old_config) = ConfigV6::read_from_toml_file(config_path.as_ref()) else {
// if we failed to load it, there might have been nothing to upgrade
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
return Ok(false);
};
info!("It seems the client is using <= v6 config template.");
info!("It is going to get updated to the current specification.");
let updated: Config = old_config.into();
updated.save_to(config_path)?;
@@ -177,7 +201,10 @@ pub async fn try_upgrade_config<P: AsRef<Path>>(
if try_upgrade_v4_config(config_path.as_ref()).await? {
return Ok(());
}
if try_upgrade_v5_config(config_path).await? {
if try_upgrade_v5_config(config_path.as_ref()).await? {
return Ok(());
}
if try_upgrade_v6_config(config_path).await? {
return Ok(());
}
@@ -32,6 +32,7 @@ pub use old::v1 as old_config_v1_1_13;
pub use old::v2 as old_config_v1_1_20;
pub use old::v3 as old_config_v1_1_20_2;
pub use old::v4 as old_config_v1_1_33;
pub use old::v5 as old_config_v1_1_54;
const DEFAULT_NETWORK_REQUESTERS_DIR: &str = "network-requester";
@@ -6,3 +6,4 @@ pub mod v2;
pub mod v3;
pub mod v4;
pub mod v5;
pub mod v6;
@@ -3,10 +3,9 @@
use crate::config::persistence::old::v3::NetworkRequesterPathsV3;
use crate::config::persistence::NetworkRequesterPaths;
use crate::config::Config;
use crate::config::{default_config_filepath, Debug, NetworkRequester};
use nym_bin_common::logging::LoggingSettings;
use nym_client_core::config::Config as BaseClientConfig;
use nym_client_core::config::old_config_v1_1_54::ConfigV1_1_54 as BaseConfigV1_1_54;
use nym_config::read_config_from_toml_file;
use nym_config::serde_helpers::de_maybe_stringified;
use nym_network_defaults::mainnet;
@@ -16,6 +15,8 @@ use std::path::Path;
use std::time::Duration;
use url::Url;
use super::v6::ConfigV6;
pub const DEFAULT_STANDARD_LIST_UPDATE_INTERVAL: Duration = Duration::from_secs(30 * 60);
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
@@ -27,7 +28,7 @@ pub struct ConfigV5 {
// and then just make type alias for the current one, i.e. `type Config = ConfigV2`.
// then in 'old' configs we could simply use the underlying type as opposed to the alias for easier upgrades.
#[serde(flatten)]
pub base: BaseClientConfig,
pub base: BaseConfigV1_1_54,
#[serde(default)]
pub network_requester: NetworkRequesterV5,
@@ -51,10 +52,10 @@ impl ConfigV5 {
}
}
impl From<ConfigV5> for Config {
impl From<ConfigV5> for ConfigV6 {
fn from(value: ConfigV5) -> Self {
Config {
base: value.base,
ConfigV6 {
base: value.base.into(),
network_requester: value.network_requester.into(),
storage_paths: NetworkRequesterPaths {
common_paths: value.storage_paths.common_paths,
@@ -0,0 +1,50 @@
use std::{io, path::Path};
use nym_bin_common::logging::LoggingSettings;
use nym_client_core::config::Config as BaseClientConfig;
use nym_config::read_config_from_toml_file;
use serde::{Deserialize, Serialize};
use crate::config::{
default_config_filepath, Config, Debug, NetworkRequester, NetworkRequesterPaths,
};
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct ConfigV6 {
#[serde(flatten)]
pub base: BaseClientConfig,
#[serde(default)]
pub network_requester: NetworkRequester,
pub storage_paths: NetworkRequesterPaths,
#[serde(default)]
pub network_requester_debug: Debug,
pub logging: LoggingSettings,
}
impl ConfigV6 {
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
read_config_from_toml_file(path)
}
#[allow(dead_code)]
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
Self::read_from_toml_file(default_config_filepath(id))
}
}
impl From<ConfigV6> for Config {
fn from(value: ConfigV6) -> Self {
Config {
base: value.base,
network_requester: value.network_requester,
storage_paths: value.storage_paths,
network_requester_debug: value.network_requester_debug,
logging: value.logging,
}
}
}
@@ -101,10 +101,6 @@ upstream_exit_policy_url = '{{ network_requester.upstream_exit_policy_url }}'
[debug]
[debug.traffic]
average_packet_delay = '{{ debug.traffic.average_packet_delay }}'
message_sending_average_delay = '{{ debug.traffic.message_sending_average_delay }}'
[debug.acknowledgements]
average_ack_delay = '{{ debug.acknowledgements.average_ack_delay }}'