diff --git a/clients/native/src/client/config/mod.rs b/clients/native/src/client/config/mod.rs index 5c0d156bd5..264c3fec5b 100644 --- a/clients/native/src/client/config/mod.rs +++ b/clients/native/src/client/config/mod.rs @@ -19,7 +19,7 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; pub use nym_client_core::config::Config as BaseClientConfig; -pub use nym_client_core::config::{DebugConfig, GatewayEndpointConfig}; +pub use nym_client_core::config::DebugConfig; pub mod old_config_v1_1_13; pub mod old_config_v1_1_20; diff --git a/clients/native/src/client/config/old_config_v1_1_20_2.rs b/clients/native/src/client/config/old_config_v1_1_20_2.rs index b6d9703a92..90e161827a 100644 --- a/clients/native/src/client/config/old_config_v1_1_20_2.rs +++ b/clients/native/src/client/config/old_config_v1_1_20_2.rs @@ -9,7 +9,7 @@ use nym_bin_common::logging::LoggingSettings; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; use nym_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as BaseConfigV1_1_20_2; use nym_client_core::config::old_config_v1_1_30::ConfigV1_1_30 as BaseConfigV1_1_30; -use nym_client_core::config::GatewayEndpointConfig; +use nym_client_core::config::old_config_v1_1_33::OldGatewayEndpointConfigV1_1_33; use nym_config::read_config_from_toml_file; use nym_network_defaults::DEFAULT_WEBSOCKET_LISTENING_PORT; use serde::{Deserialize, Serialize}; @@ -46,7 +46,7 @@ impl ConfigV1_1_20_2 { // in this upgrade, gateway endpoint configuration was moved out of the config file, // so its returned to be stored elsewhere. - pub fn upgrade(self) -> Result<(ConfigV1_1_33, GatewayEndpointConfig), ClientError> { + pub fn upgrade(self) -> Result<(ConfigV1_1_33, OldGatewayEndpointConfigV1_1_33), ClientError> { let gateway_details = self.base.client.gateway_endpoint.clone().into(); let config = ConfigV1_1_33 { base: BaseConfigV1_1_30::from(self.base).into(), diff --git a/clients/native/src/commands/import_credential.rs b/clients/native/src/commands/import_credential.rs index 8554f74ee7..7fa7fa3b52 100644 --- a/clients/native/src/commands/import_credential.rs +++ b/clients/native/src/commands/import_credential.rs @@ -34,7 +34,7 @@ pub(crate) struct Args { } pub(crate) async fn execute(args: Args) -> Result<(), ClientError> { - let config = try_load_current_config(&args.id)?; + let config = try_load_current_config(&args.id).await?; let credentials_store = nym_credential_storage::initialise_persistent_storage( &config.storage_paths.common_paths.credentials_database, diff --git a/clients/native/src/commands/init.rs b/clients/native/src/commands/init.rs index def0072d26..dfc7b95cd9 100644 --- a/clients/native/src/commands/init.rs +++ b/clients/native/src/commands/init.rs @@ -29,8 +29,8 @@ impl InitialisableClient for NativeClientInit { type InitArgs = Init; type Config = Config; - fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { - try_upgrade_config(id) + async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { + try_upgrade_config(id).await } fn initialise_storage_paths(id: &str) -> Result<(), Self::Error> { diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index 2c9dfde3cc..d3947b876e 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -12,10 +12,7 @@ use clap::{Parser, Subcommand}; use log::{error, info}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; -use nym_client_core::client::base_client::storage::OnDiskGatewaysDetails; -use nym_client_core::client::key_manager::persistence::OnDiskKeys; -use nym_client_core::config::GatewayEndpointConfig; -use nym_client_core::error::ClientCoreError; +use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_config::OptionalSet; use std::error::Error; use std::net::IpAddr; @@ -121,41 +118,7 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config { ) } -fn persist_gateway_details( - config: &Config, - details: GatewayEndpointConfig, -) -> Result<(), ClientError> { - todo!() - // let details_store = - // OnDiskGatewaysDetails::new(&config.storage_paths.common_paths.gateway_details); - // let keys_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone()); - // let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { - // ClientError::ClientCoreError(ClientCoreError::KeyStoreError { - // source: Box::new(source), - // }) - // })?; - // let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; - // details_store - // .store_to_disk(&persisted_details) - // .map_err(|source| { - // ClientError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { - // source: Box::new(source), - // }) - // }) -} - -fn migrate_gateway_details( - config: &Config, - old_details: Option, -) -> Result<(), ClientError> { - todo!() -} - -fn extract_gateway_details(config: &ConfigV1_1_33) -> Result<(), ClientError> { - todo!() -} - -fn try_upgrade_v1_1_13_config(id: &str) -> Result { +async fn try_upgrade_v1_1_13_config(id: &str) -> Result { use nym_config::legacy_helpers::nym_config::MigrationNymConfig; // explicitly load it as v1.1.13 (which is incompatible with the next step, i.e. 1.1.19) @@ -170,15 +133,21 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result { let updated_step1: ConfigV1_1_20 = old_config.into(); 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()?; - migrate_gateway_details(&updated, Some(gateway_config))?; + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_20_config(id: &str) -> Result { +async fn try_upgrade_v1_1_20_config(id: &str) -> Result { use nym_config::legacy_helpers::nym_config::MigrationNymConfig; // explicitly load it as v1.1.20 (which is incompatible with the current one, i.e. +1.1.21) @@ -192,15 +161,20 @@ fn try_upgrade_v1_1_20_config(id: &str) -> Result { 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()?; - migrate_gateway_details(&updated, Some(gateway_config))?; - + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_20_2_config(id: &str) -> Result { +async fn try_upgrade_v1_1_20_2_config(id: &str) -> Result { // explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21) let Ok(old_config) = ConfigV1_1_20_2::read_from_default_path(id) else { // if we failed to load it, there might have been nothing to upgrade @@ -211,15 +185,20 @@ fn try_upgrade_v1_1_20_2_config(id: &str) -> Result { info!("It is going to get updated to the current specification."); let (updated_step1, gateway_config) = old_config.upgrade()?; + let old_paths = updated_step1.storage_paths.clone(); let updated = updated_step1.try_upgrade()?; - migrate_gateway_details(&updated, Some(gateway_config))?; - + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_33_config(id: &str) -> Result { +async fn try_upgrade_v1_1_33_config(id: &str) -> Result { // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) let Ok(old_config) = ConfigV1_1_33::read_from_default_path(id) else { // if we failed to load it, there might have been nothing to upgrade @@ -229,32 +208,38 @@ fn try_upgrade_v1_1_33_config(id: &str) -> Result { info!("It seems the client is using <= v1.1.33 config template."); 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()?; - migrate_gateway_details(&updated, None)?; + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + None, + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_config(id: &str) -> Result<(), ClientError> { - if try_upgrade_v1_1_13_config(id)? { +async fn try_upgrade_config(id: &str) -> Result<(), ClientError> { + if try_upgrade_v1_1_13_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_20_config(id)? { + if try_upgrade_v1_1_20_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_20_2_config(id)? { + if try_upgrade_v1_1_20_2_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_33_config(id)? { + if try_upgrade_v1_1_33_config(id).await? { return Ok(()); } Ok(()) } -fn try_load_current_config(id: &str) -> Result { +async fn try_load_current_config(id: &str) -> Result { // try to load the config as is if let Ok(cfg) = Config::read_from_default_path(id) { return if !cfg.validate() { @@ -265,7 +250,7 @@ fn try_load_current_config(id: &str) -> Result { } // we couldn't load it - try upgrading it from older revisions - try_upgrade_config(id)?; + try_upgrade_config(id).await?; let config = match Config::read_from_default_path(id) { Ok(cfg) => cfg, diff --git a/clients/native/src/commands/run.rs b/clients/native/src/commands/run.rs index b836fe6d20..2ab3fc8489 100644 --- a/clients/native/src/commands/run.rs +++ b/clients/native/src/commands/run.rs @@ -69,7 +69,7 @@ fn version_check(cfg: &Config) -> bool { pub(crate) async fn execute(args: Run) -> Result<(), Box> { eprintln!("Starting client {}...", args.common_args.id); - let mut config = try_load_current_config(&args.common_args.id)?; + let mut config = try_load_current_config(&args.common_args.id).await?; config = override_config(config, OverrideConfig::from(args.clone())); if !version_check(&config) { diff --git a/common/client-core/src/cli_helpers/client_init.rs b/common/client-core/src/cli_helpers/client_init.rs index 3fd821a9f4..93ad844b08 100644 --- a/common/client-core/src/cli_helpers/client_init.rs +++ b/common/client-core/src/cli_helpers/client_init.rs @@ -20,13 +20,15 @@ use nym_topology::NymTopology; use rand::rngs::OsRng; use std::path::{Path, PathBuf}; +// we can suppress this warning (as suggested by linter itself) since we're only using it in our own code +#[allow(async_fn_in_trait)] pub trait InitialisableClient { const NAME: &'static str; type Error: From; type InitArgs: AsRef; type Config: ClientConfig; - fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error>; + async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error>; fn initialise_storage_paths(id: &str) -> Result<(), Self::Error>; @@ -134,7 +136,7 @@ where let already_init = if C::default_config_path(id).exists() { // in case we're using old config, try to upgrade it // (if we're using the current version, it's a no-op) - C::try_upgrade_outdated_config(id)?; + C::try_upgrade_outdated_config(id).await?; eprintln!("{} client \"{id}\" was already initialised before", C::NAME); true } else { @@ -273,7 +275,7 @@ where ); if init_args.as_ref().set_active { - set_active_gateway(&init_results.gateway_id, &details_store).await?; + set_active_gateway(&details_store, &init_results.gateway_id).await?; } else { info!("registered with new gateway {} (under address {address}), but this will not be our default address", init_results.gateway_id); } diff --git a/common/client-core/src/client/base_client/storage/helpers.rs b/common/client-core/src/client/base_client/storage/helpers.rs index 8c58605bda..c6f2cf65c2 100644 --- a/common/client-core/src/client/base_client/storage/helpers.rs +++ b/common/client-core/src/client/base_client/storage/helpers.rs @@ -11,8 +11,8 @@ use nym_crypto::asymmetric::identity; // helpers for error wrapping pub async fn set_active_gateway( - gateway_id: &str, details_store: &D, + gateway_id: &str, ) -> Result<(), ClientCoreError> where D: GatewaysDetailsStore, diff --git a/common/client-core/src/client/base_client/storage/migration_helpers.rs b/common/client-core/src/client/base_client/storage/migration_helpers.rs new file mode 100644 index 0000000000..c81011a37f --- /dev/null +++ b/common/client-core/src/client/base_client/storage/migration_helpers.rs @@ -0,0 +1,211 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub mod v1_1_33 { + use crate::client::base_client::{ + non_wasm_helpers::setup_fs_gateways_storage, + storage::helpers::{set_active_gateway, store_gateway_details}, + }; + use crate::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33; + use crate::config::disk_persistence::CommonClientPaths; + use crate::config::old_config_v1_1_33::OldGatewayEndpointConfigV1_1_33; + use crate::error::ClientCoreError; + use nym_client_core_gateways_storage::{ + CustomGatewayDetails, GatewayDetails, GatewayRegistration, RemoteGatewayDetails, + }; + use nym_gateway_requests::registration::handshake::SharedKeys; + use serde::{Deserialize, Serialize}; + use sha2::{digest::Digest, Sha256}; + use std::ops::Deref; + use std::path::Path; + use std::sync::Arc; + use zeroize::Zeroizing; + + mod base64 { + use base64::{engine::general_purpose::STANDARD, Engine as _}; + use serde::{Deserialize, Deserializer, Serializer}; + + pub fn serialize(bytes: &[u8], serializer: S) -> Result { + serializer.serialize_str(&STANDARD.encode(bytes)) + } + + pub fn deserialize<'de, D: Deserializer<'de>>( + deserializer: D, + ) -> Result, D::Error> { + let s = ::deserialize(deserializer)?; + STANDARD.decode(s).map_err(serde::de::Error::custom) + } + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + #[serde(untagged)] + enum PersistedGatewayDetails { + /// Standard details of a remote gateway + Default(PersistedGatewayConfig), + + /// Custom gateway setup, such as for a client embedded inside gateway itself + Custom(PersistedCustomGatewayDetails), + } + + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] + struct PersistedGatewayConfig { + /// The hash of the shared keys to ensure the correct ones are used with those gateway details. + #[serde(with = "base64")] + key_hash: Vec, + + /// Actual gateway details being persisted. + details: OldGatewayEndpointConfigV1_1_33, + } + + impl PersistedGatewayConfig { + fn verify(&self, shared_key: &SharedKeys) -> bool { + let key_bytes = Zeroizing::new(shared_key.to_bytes()); + + let mut key_hasher = Sha256::new(); + key_hasher.update(&key_bytes); + let key_hash = key_hasher.finalize(); + + self.key_hash == key_hash.deref() + } + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + struct PersistedCustomGatewayDetails { + gateway_id: String, + } + + fn load_shared_key>(path: P) -> Result { + // the shared key was a simple pem file + Ok(nym_pemstore::load_key(path)?) + } + + fn gateway_details_from_raw( + gateway_id: String, + gateway_owner: String, + gateway_listener: String, + gateway_shared_key: SharedKeys, + ) -> Result { + Ok(GatewayDetails::Remote(RemoteGatewayDetails { + gateway_id: gateway_id + .parse() + .map_err(|err| ClientCoreError::UpgradeFailure { + message: format!("the stored gateway id was malformed: {err}"), + })?, + derived_aes128_ctr_blake3_hmac_keys: Arc::new(gateway_shared_key), + gateway_owner_address: gateway_owner.parse().map_err(|err| { + ClientCoreError::UpgradeFailure { + message: format!("the stored gateway owner address was malformed: {err}"), + } + })?, + gateway_listener: gateway_listener.parse().map_err(|err| { + ClientCoreError::UpgradeFailure { + message: format!("the stored gateway listener address was malformed: {err}"), + } + })?, + })) + } + + // helper to extract shared key and gateway details into the new GatewayRegistration + fn extract_gateway_registration( + storage_paths: &CommonClientPathsV1_1_33, + ) -> Result { + let details_file = std::fs::File::open(&storage_paths.gateway_details).map_err(|err| { + ClientCoreError::UpgradeFailure { + message: format!( + "failed to open gateway details file at {}: {err}", + storage_paths.gateway_details.display() + ), + } + })?; + + // in v1.1.33 of the clients, the gateway details struct was saved as json + let details: PersistedGatewayDetails = + serde_json::from_reader(details_file).map_err(|err| { + ClientCoreError::UpgradeFailure { + message: format!( + "failed to deserialize gateway details from {}: {err}", + storage_paths.gateway_details.display() + ), + } + })?; + + let details = match details { + PersistedGatewayDetails::Default(config) => { + let gateway_shared_key = + load_shared_key(&storage_paths.keys.gateway_shared_key_file)?; + if !config.verify(&gateway_shared_key) { + return Err(ClientCoreError::UpgradeFailure { + message: "failed to verify consistency of the existing gateway details" + .to_string(), + }); + } + gateway_details_from_raw( + config.details.gateway_id, + config.details.gateway_owner, + config.details.gateway_listener, + gateway_shared_key, + )? + } + PersistedGatewayDetails::Custom(custom) => { + GatewayDetails::Custom(CustomGatewayDetails { + gateway_id: custom.gateway_id.parse().map_err(|err| { + ClientCoreError::UpgradeFailure { + message: format!("the stored gateway id was malformed: {err}"), + } + })?, + data: None, + }) + } + }; + + Ok(details.into()) + } + + // it's responsibility of the caller to ensure this is called **after** new registration has already been saved + fn remove_old_gateway_details(storage_paths: &CommonClientPathsV1_1_33) -> std::io::Result<()> { + std::fs::remove_file(&storage_paths.gateway_details)?; + + if storage_paths.keys.gateway_shared_key_file.exists() { + std::fs::remove_file(&storage_paths.keys.gateway_shared_key_file)?; + } + Ok(()) + } + + pub async fn migrate_gateway_details( + old_storage_paths: &CommonClientPathsV1_1_33, + new_storage_paths: &CommonClientPaths, + preloaded_config: Option, + ) -> Result<(), ClientCoreError> { + let gateway_registration = match preloaded_config { + Some(config) => { + let gateway_shared_key = + load_shared_key(&old_storage_paths.keys.gateway_shared_key_file)?; + gateway_details_from_raw( + config.gateway_id, + config.gateway_owner, + config.gateway_listener, + gateway_shared_key, + )? + .into() + } + None => extract_gateway_registration(old_storage_paths)?, + }; + + // since we're migrating to a brand new store, the store should be empty + // and thus set the 'new' gateway as the active one + let details_store = + setup_fs_gateways_storage(&new_storage_paths.gateway_registrations).await?; + store_gateway_details(&details_store, &gateway_registration).await?; + set_active_gateway( + &details_store, + &gateway_registration.details.gateway_id().to_base58_string(), + ) + .await?; + + remove_old_gateway_details(&old_storage_paths).map_err(|err| { + ClientCoreError::UpgradeFailure { + message: format!("failed to remove old data: {err}"), + } + }) + } +} diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index 70266be27d..2158788cd3 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -27,7 +27,8 @@ use crate::{ use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage; pub use nym_client_core_gateways_storage::{ - GatewaysDetailsStore, GatewaysDetailsStoreExt, InMemGatewaysDetails, + CustomGatewayDetails, GatewayDetails, GatewayRegistration, GatewayType, GatewaysDetailsStore, + GatewaysDetailsStoreExt, InMemGatewaysDetails, RegisteredGateway, RemoteGatewayDetails, }; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] @@ -35,6 +36,13 @@ pub use nym_client_core_gateways_storage::{OnDiskGatewaysDetails, StorageError}; pub mod helpers; +#[cfg(all( + not(target_arch = "wasm32"), + feature = "fs-surb-storage", + feature = "fs-gateways-storage" +))] +pub mod migration_helpers; + // TODO: ideally this should be changed into // `MixnetClientStorage: KeyStore + ReplyStorageBackend + CredentialStorage + GatewaysDetailsStore` pub trait MixnetClientStorage { diff --git a/common/client-core/src/config/mod.rs b/common/client-core/src/config/mod.rs index 1fd2cf26f3..2333c58df4 100644 --- a/common/client-core/src/config/mod.rs +++ b/common/client-core/src/config/mod.rs @@ -1,10 +1,8 @@ // Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::{client::topology_control::geo_aware_provider::CountryGroup, error::ClientCoreError}; +use crate::client::topology_control::geo_aware_provider::CountryGroup; use nym_config::defaults::NymNetworkDetails; -use nym_crypto::asymmetric::identity; -use nym_gateway_client::client::GatewayConfig; use nym_sphinx::{ addressing::clients::Recipient, params::{PacketSize, PacketType}, @@ -13,9 +11,6 @@ use serde::{Deserialize, Serialize}; use std::time::Duration; use url::Url; -#[cfg(target_arch = "wasm32")] -use wasm_bindgen::prelude::*; - pub mod disk_persistence; pub mod old_config_v1_1_13; pub mod old_config_v1_1_20; @@ -232,80 +227,6 @@ impl Config { } } -#[deprecated] -#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen(getter_with_clone))] -pub struct GatewayEndpointConfig { - /// gateway_id specifies ID of the gateway to which the client should send messages. - /// If initially omitted, a random gateway will be chosen from the available topology. - pub gateway_id: String, - - /// Address of the gateway owner to which the client should send messages. - pub gateway_owner: String, - - /// Address of the gateway listener to which all client requests should be sent. - pub gateway_listener: String, -} - -impl TryFrom for GatewayConfig { - type Error = ClientCoreError; - - fn try_from(value: GatewayEndpointConfig) -> Result { - Ok(GatewayConfig { - gateway_identity: identity::PublicKey::from_base58_string(value.gateway_id) - .map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?, - gateway_owner: Some(value.gateway_owner), - gateway_listener: value.gateway_listener, - }) - } -} - -#[deprecated] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] -impl GatewayEndpointConfig { - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(constructor))] - pub fn new( - gateway_id: String, - gateway_owner: String, - gateway_listener: String, - ) -> GatewayEndpointConfig { - GatewayEndpointConfig { - gateway_id, - gateway_owner, - gateway_listener, - } - } -} - -// separate block so it wouldn't be exported via wasm bindgen -#[deprecated] -impl GatewayEndpointConfig { - pub fn try_get_gateway_identity_key(&self) -> Result { - identity::PublicKey::from_base58_string(&self.gateway_id) - .map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId) - } - - pub fn from_node( - node: nym_topology::gateway::Node, - must_use_tls: bool, - ) -> Result { - let gateway_listener = if must_use_tls { - node.clients_address_tls() - .ok_or(ClientCoreError::UnsupportedWssProtocol { - gateway: node.identity_key.to_base58_string(), - })? - } else { - node.clients_address() - }; - - Ok(GatewayEndpointConfig { - gateway_id: node.identity_key.to_base58_string(), - gateway_listener, - gateway_owner: node.owner, - }) - } -} - #[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)] diff --git a/common/client-core/src/config/old_config_v1_1_20_2.rs b/common/client-core/src/config/old_config_v1_1_20_2.rs index a7abd41ddc..5fe039fc82 100644 --- a/common/client-core/src/config/old_config_v1_1_20_2.rs +++ b/common/client-core/src/config/old_config_v1_1_20_2.rs @@ -5,7 +5,7 @@ use crate::config::old_config_v1_1_30::{ AcknowledgementsV1_1_30, ClientV1_1_30, ConfigV1_1_30, CoverTrafficV1_1_30, DebugConfigV1_1_30, GatewayConnectionV1_1_30, ReplySurbsV1_1_30, TopologyV1_1_30, TrafficV1_1_30, }; -use crate::config::GatewayEndpointConfig; +use crate::config::old_config_v1_1_33::OldGatewayEndpointConfigV1_1_33; use nym_sphinx::params::{PacketSize, PacketType}; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -81,9 +81,9 @@ pub struct GatewayEndpointConfigV1_1_20_2 { pub gateway_listener: String, } -impl From for GatewayEndpointConfig { +impl From for OldGatewayEndpointConfigV1_1_33 { fn from(value: GatewayEndpointConfigV1_1_20_2) -> Self { - GatewayEndpointConfig { + OldGatewayEndpointConfigV1_1_33 { gateway_id: value.gateway_id, gateway_owner: value.gateway_owner, gateway_listener: value.gateway_listener, diff --git a/common/client-core/src/config/old_config_v1_1_33.rs b/common/client-core/src/config/old_config_v1_1_33.rs index 0d47b95361..028b35fb52 100644 --- a/common/client-core/src/config/old_config_v1_1_33.rs +++ b/common/client-core/src/config/old_config_v1_1_33.rs @@ -55,6 +55,19 @@ const DEFAULT_MAXIMUM_REPLY_SURB_AGE: Duration = Duration::from_secs(12 * 60 * 6 // 24 hours const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60); +#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] +pub struct OldGatewayEndpointConfigV1_1_33 { + /// gateway_id specifies ID of the gateway to which the client should send messages. + /// If initially omitted, a random gateway will be chosen from the available topology. + pub gateway_id: String, + + /// Address of the gateway owner to which the client should send messages. + pub gateway_owner: String, + + /// Address of the gateway listener to which all client requests should be sent. + pub gateway_listener: String, +} + #[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] pub struct ConfigV1_1_33 { diff --git a/common/client-core/src/error.rs b/common/client-core/src/error.rs index ef2349356b..d2d391f102 100644 --- a/common/client-core/src/error.rs +++ b/common/client-core/src/error.rs @@ -127,6 +127,9 @@ pub enum ClientCoreError { #[error("unable to upgrade config file to `{new_version}`")] UnableToUpgradeConfigFile { new_version: String }, + #[error("failed to upgrade config file: {message}")] + UpgradeFailure { message: String }, + #[error("the provided gateway details don't much the stored data")] MismatchedStoredGatewayDetails,