config migration for removing allow.list

This commit is contained in:
Jędrzej Stuczyński
2024-03-26 14:10:01 +00:00
parent fb2b2c963b
commit bef0a537b2
10 changed files with 236 additions and 78 deletions
@@ -2,17 +2,19 @@
// SPDX-License-Identifier: Apache-2.0
use crate::config::default_config_filepath;
use crate::config::old::v5::ConfigV5;
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::ConfigV14;
use crate::config::old_config_v1_1_33::ConfigV4;
use crate::config::Config;
use crate::error::NetworkRequesterError;
use log::{info, trace};
use nym_client_core::cli_helpers::CliClientConfig;
use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33;
use std::path::Path;
async fn try_upgrade_v1_1_13_config<P: AsRef<Path>>(
async fn try_upgrade_v1_config<P: AsRef<Path>>(
config_path: P,
) -> Result<bool, NetworkRequesterError> {
trace!("Trying to load as v1.1.13 config");
@@ -31,20 +33,22 @@ async fn try_upgrade_v1_1_13_config<P: AsRef<Path>>(
let updated_step2: ConfigV3 = 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 = updated_step3.try_upgrade()?;
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: Config = updated_step4.into();
updated.save_to(config_path)?;
Ok(true)
}
async fn try_upgrade_v1_1_20_config<P: AsRef<Path>>(
async fn try_upgrade_v2_config<P: AsRef<Path>>(
config_path: P,
) -> Result<bool, NetworkRequesterError> {
trace!("Trying to load as v1.1.20 config");
@@ -63,20 +67,22 @@ async fn try_upgrade_v1_1_20_config<P: AsRef<Path>>(
let updated_step1: ConfigV3 = 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 = updated_step2.try_upgrade()?;
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: Config = updated_step3.into();
updated.save_to(config_path)?;
Ok(true)
}
async fn try_upgrade_v1_1_20_2_config<P: AsRef<Path>>(
async fn try_upgrade_v3_config<P: AsRef<Path>>(
config_path: P,
) -> Result<bool, NetworkRequesterError> {
trace!("Trying to load as v1.1.20_2 config");
@@ -92,26 +98,28 @@ async fn try_upgrade_v1_1_20_2_config<P: AsRef<Path>>(
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 = updated_step1.try_upgrade()?;
v1_1_33::migrate_gateway_details(
&old_paths.common_paths,
&updated.storage_paths.common_paths,
&updated_step2.storage_paths.common_paths,
Some(gateway_config),
)
.await?;
let updated: Config = updated_step2.into();
updated.save_to(config_path)?;
Ok(true)
}
async fn try_upgrade_v1_1_33_config<P: AsRef<Path>>(
async fn try_upgrade_v4_config<P: AsRef<Path>>(
config_path: P,
) -> Result<bool, NetworkRequesterError> {
trace!("Trying to load as v1.1.33 config");
// explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34)
let Ok(old_config) = ConfigV14::read_from_toml_file(config_path.as_ref()) else {
let Ok(old_config) = ConfigV4::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);
@@ -120,33 +128,56 @@ async fn try_upgrade_v1_1_33_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 = old_config.try_upgrade()?;
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: Config = updated_step1.into();
updated.save_to(config_path)?;
Ok(true)
}
async fn try_upgrade_v5_config<P: AsRef<Path>>(
config_path: P,
) -> Result<bool, NetworkRequesterError> {
// explicitly load it as v5 (which is incompatible with the current one)
let Ok(old_config) = ConfigV5::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 <= v5 config template.");
info!("It is going to get updated to the current specification.");
let updated: Config = old_config.into();
updated.save_to(config_path)?;
Ok(true)
}
pub async fn try_upgrade_config<P: AsRef<Path>>(
config_path: P,
) -> Result<(), NetworkRequesterError> {
trace!("Attempting to upgrade config");
if try_upgrade_v1_1_13_config(config_path.as_ref()).await? {
if try_upgrade_v1_config(config_path.as_ref()).await? {
return Ok(());
}
if try_upgrade_v1_1_20_config(config_path.as_ref()).await? {
if try_upgrade_v2_config(config_path.as_ref()).await? {
return Ok(());
}
if try_upgrade_v1_1_20_2_config(config_path.as_ref()).await? {
if try_upgrade_v3_config(config_path.as_ref()).await? {
return Ok(());
}
if try_upgrade_v1_1_33_config(config_path).await? {
if try_upgrade_v4_config(config_path.as_ref()).await? {
return Ok(());
}
if try_upgrade_v5_config(config_path).await? {
return Ok(());
}
@@ -245,12 +245,6 @@ pub struct NetworkRequester {
/// This is equivalent to setting debug.traffic.disable_main_poisson_packet_distribution = true,
pub disable_poisson_rate: bool,
/// Specifies whether this network requester should be using the deprecated allow-list,
/// as opposed to the new ExitPolicy.
/// Note: this field will be removed in a near future.
#[deprecated]
pub use_deprecated_allow_list: bool,
/// Specifies the url for an upstream source of the exit policy used by this node.
#[serde(deserialize_with = "de_maybe_stringified")]
pub upstream_exit_policy_url: Option<Url>,
@@ -263,7 +257,6 @@ impl Default for NetworkRequester {
enabled_statistics: false,
statistics_recipient: None,
disable_poisson_rate: true,
use_deprecated_allow_list: true,
upstream_exit_policy_url: Some(
mainnet::EXIT_POLICY_URL
.parse()
@@ -5,18 +5,4 @@ pub mod v1;
pub mod v2;
pub mod v3;
pub mod v4;
// // aliases for backwards compatibility
// pub use v1 as old_config_v1_1_13;
// 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;
/*
deleted: src/config/old_config_v1_1_13.rs
deleted: src/config/old_config_v1_1_19.rs
deleted: src/config/old_config_v1_1_20.rs
deleted: src/config/old_config_v1_1_20_2.rs
deleted: src/config/old_config_v1_1_33.rs
*/
pub mod v5;
@@ -1,10 +1,9 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use super::v4::{ConfigV14, DebugV4, NetworkRequesterV4};
use super::v4::{ConfigV4, DebugV4, NetworkRequesterV4};
use crate::config::persistence::old::v1::NetworkRequesterPathsV1;
use crate::config::persistence::old::v2::NetworkRequesterPathsV2;
use crate::config::persistence::DEFAULT_DESCRIPTION_FILENAME;
use crate::config::persistence::old::v2::{NetworkRequesterPathsV2, DEFAULT_DESCRIPTION_FILENAME};
use crate::{config::default_config_filepath, error::NetworkRequesterError};
use log::trace;
use nym_bin_common::logging::LoggingSettings;
@@ -50,7 +49,7 @@ impl ConfigV3 {
// so its returned to be stored elsewhere.
pub fn upgrade(
self,
) -> Result<(ConfigV14, OldGatewayEndpointConfigV1_1_33), NetworkRequesterError> {
) -> Result<(ConfigV4, OldGatewayEndpointConfigV1_1_33), NetworkRequesterError> {
trace!("Upgrading from v1.1.20_2");
let gateway_details = self.base.client.gateway_endpoint.clone().into();
let nr_description = self
@@ -61,7 +60,7 @@ impl ConfigV3 {
.parent()
.expect("config paths upgrade failure")
.join(DEFAULT_DESCRIPTION_FILENAME);
let config = ConfigV14 {
let config = ConfigV4 {
base: BaseConfigV1_1_30::from(self.base).into(),
storage_paths: NetworkRequesterPathsV2 {
common_paths: self.storage_paths.common_paths.upgrade_default()?,
@@ -1,10 +1,10 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::config::default_config_filepath;
use crate::config::old::v5::{ConfigV5, DebugV5, NetworkRequesterV5};
use crate::config::persistence::old::v2::NetworkRequesterPathsV2;
use crate::config::persistence::NetworkRequesterPaths;
use crate::config::Config;
use crate::config::{default_config_filepath, Debug, NetworkRequester};
use crate::config::persistence::old::v3::NetworkRequesterPathsV3;
use crate::error::NetworkRequesterError;
use nym_bin_common::logging::LoggingSettings;
use nym_client_core::config::old_config_v1_1_33::ConfigV1_1_33 as BaseConfigV1_1_33;
@@ -20,7 +20,7 @@ pub const DEFAULT_STANDARD_LIST_UPDATE_INTERVAL: Duration = Duration::from_secs(
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct ConfigV14 {
pub struct ConfigV4 {
#[serde(flatten)]
pub base: BaseConfigV1_1_33,
@@ -35,7 +35,7 @@ pub struct ConfigV14 {
pub logging: LoggingSettings,
}
impl ConfigV14 {
impl ConfigV4 {
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
read_config_from_toml_file(path)
}
@@ -45,11 +45,11 @@ impl ConfigV14 {
Self::read_from_toml_file(default_config_filepath(id))
}
pub fn try_upgrade(self) -> Result<Config, NetworkRequesterError> {
Ok(Config {
pub fn try_upgrade(self) -> Result<ConfigV5, NetworkRequesterError> {
Ok(ConfigV5 {
base: self.base.into(),
network_requester: self.network_requester.into(),
storage_paths: NetworkRequesterPaths {
storage_paths: NetworkRequesterPathsV3 {
common_paths: self.storage_paths.common_paths.upgrade_default()?,
allowed_list_location: self.storage_paths.allowed_list_location,
unknown_list_location: self.storage_paths.unknown_list_location,
@@ -88,9 +88,9 @@ pub struct NetworkRequesterV4 {
pub upstream_exit_policy_url: Option<Url>,
}
impl From<NetworkRequesterV4> for NetworkRequester {
impl From<NetworkRequesterV4> for NetworkRequesterV5 {
fn from(value: NetworkRequesterV4) -> Self {
NetworkRequester {
NetworkRequesterV5 {
open_proxy: value.open_proxy,
enabled_statistics: value.enabled_statistics,
statistics_recipient: value.statistics_recipient,
@@ -109,9 +109,9 @@ pub struct DebugV4 {
pub standard_list_update_interval: Duration,
}
impl From<DebugV4> for Debug {
impl From<DebugV4> for DebugV5 {
fn from(value: DebugV4) -> Self {
Debug {
DebugV5 {
standard_list_update_interval: value.standard_list_update_interval,
}
}
@@ -0,0 +1,146 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
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_config::read_config_from_toml_file;
use nym_config::serde_helpers::de_maybe_stringified;
use nym_network_defaults::mainnet;
use serde::{Deserialize, Serialize};
use std::io;
use std::path::Path;
use std::time::Duration;
use url::Url;
pub const DEFAULT_STANDARD_LIST_UPDATE_INTERVAL: Duration = Duration::from_secs(30 * 60);
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct ConfigV5 {
// *sigh* currently we point to the most recent config because that's the one that's 'correct'
// but the moment we make breaking changes there, we'll have to update this config too.
// I think we should always keep versioned base config, i.e. `ConfigV1`, `ConfigV2`, etc,
// 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,
#[serde(default)]
pub network_requester: NetworkRequesterV5,
pub storage_paths: NetworkRequesterPathsV3,
#[serde(default)]
pub network_requester_debug: DebugV5,
pub logging: LoggingSettings,
}
impl ConfigV5 {
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<ConfigV5> for Config {
fn from(value: ConfigV5) -> Self {
Config {
base: value.base,
network_requester: value.network_requester.into(),
storage_paths: NetworkRequesterPaths {
common_paths: value.storage_paths.common_paths,
},
network_requester_debug: value.network_requester_debug.into(),
logging: value.logging,
}
}
}
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct NetworkRequesterV5 {
/// specifies whether this network requester should run in 'open-proxy' mode
/// and thus would attempt to resolve **ANY** request it receives.
pub open_proxy: bool,
/// specifies whether this network requester would send anonymized statistics to a statistics aggregator server
pub enabled_statistics: bool,
/// in case of enabled statistics, specifies mixnet client address where a statistics aggregator is running
pub statistics_recipient: Option<String>,
/// Disable Poisson sending rate.
/// This is equivalent to setting debug.traffic.disable_main_poisson_packet_distribution = true,
pub disable_poisson_rate: bool,
/// Specifies whether this network requester should be using the deprecated allow-list,
/// as opposed to the new ExitPolicy.
pub use_deprecated_allow_list: bool,
/// Specifies the url for an upstream source of the exit policy used by this node.
#[serde(deserialize_with = "de_maybe_stringified")]
pub upstream_exit_policy_url: Option<Url>,
}
impl Default for NetworkRequesterV5 {
fn default() -> Self {
NetworkRequesterV5 {
open_proxy: false,
enabled_statistics: false,
statistics_recipient: None,
disable_poisson_rate: true,
use_deprecated_allow_list: true,
upstream_exit_policy_url: Some(
mainnet::EXIT_POLICY_URL
.parse()
.expect("invalid default exit policy URL"),
),
}
}
}
impl From<NetworkRequesterV5> for NetworkRequester {
fn from(value: NetworkRequesterV5) -> Self {
NetworkRequester {
open_proxy: value.open_proxy,
enabled_statistics: value.enabled_statistics,
statistics_recipient: value.statistics_recipient,
disable_poisson_rate: value.disable_poisson_rate,
upstream_exit_policy_url: value.upstream_exit_policy_url,
}
}
}
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct DebugV5 {
/// Defines how often the standard allow list should get updated
/// Deprecated
#[serde(with = "humantime_serde")]
pub standard_list_update_interval: Duration,
}
impl From<DebugV5> for Debug {
fn from(value: DebugV5) -> Self {
Debug {
standard_list_update_interval: value.standard_list_update_interval,
}
}
}
impl Default for DebugV5 {
fn default() -> Self {
DebugV5 {
standard_list_update_interval: DEFAULT_STANDARD_LIST_UPDATE_INTERVAL,
}
}
}
@@ -3,31 +3,14 @@
use nym_client_core::config::disk_persistence::CommonClientPaths;
use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};
use std::path::Path;
pub mod old;
pub const DEFAULT_ALLOWED_LIST_FILENAME: &str = "allowed.list";
pub const DEFAULT_UNKNOWN_LIST_FILENAME: &str = "unknown.list";
pub const DEFAULT_DESCRIPTION_FILENAME: &str = "description.toml";
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)]
pub struct NetworkRequesterPaths {
#[serde(flatten)]
pub common_paths: CommonClientPaths,
/// Deprecated
/// Location of the file containing our allow.list
#[deprecated]
pub allowed_list_location: PathBuf,
/// Deprecated
/// Location of the file containing our unknown.list
#[deprecated]
pub unknown_list_location: PathBuf,
/// Location of the file containing our description
pub nr_description: PathBuf,
}
impl NetworkRequesterPaths {
@@ -36,9 +19,6 @@ impl NetworkRequesterPaths {
NetworkRequesterPaths {
common_paths: CommonClientPaths::new_base(base_dir),
allowed_list_location: base_dir.join(DEFAULT_ALLOWED_LIST_FILENAME),
unknown_list_location: base_dir.join(DEFAULT_UNKNOWN_LIST_FILENAME),
nr_description: base_dir.join(DEFAULT_DESCRIPTION_FILENAME),
}
}
}
@@ -3,3 +3,4 @@
pub mod v1;
pub mod v2;
pub mod v3;
@@ -4,6 +4,7 @@
use nym_client_core::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
pub const DEFAULT_DESCRIPTION_FILENAME: &str = "description.toml";
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)]
pub struct NetworkRequesterPathsV2 {
@@ -0,0 +1,21 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use nym_client_core::config::disk_persistence::CommonClientPaths;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)]
pub struct NetworkRequesterPathsV3 {
#[serde(flatten)]
pub common_paths: CommonClientPaths,
/// Location of the file containing our allow.list
pub allowed_list_location: PathBuf,
/// Location of the file containing our unknown.list
pub unknown_list_location: PathBuf,
/// Location of the file containing our description
pub nr_description: PathBuf,
}