diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs index 8aa5c3ff9d..c447d407e2 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs @@ -50,7 +50,7 @@ impl GatewaysDetailsStore for OnDiskGatewaysDetails { async fn store_gateway_details( &self, - details: GatewayDetails, + details: &GatewayRegistration, ) -> Result<(), Self::StorageError> { todo!() } diff --git a/common/client-core/gateways-storage/src/backend/mem_backend.rs b/common/client-core/gateways-storage/src/backend/mem_backend.rs index 003284622e..092772c9f0 100644 --- a/common/client-core/gateways-storage/src/backend/mem_backend.rs +++ b/common/client-core/gateways-storage/src/backend/mem_backend.rs @@ -66,7 +66,7 @@ impl GatewaysDetailsStore for InMemGatewaysDetails { async fn store_gateway_details( &self, - details: GatewayDetails, + details: &GatewayRegistration, ) -> Result<(), Self::StorageError> { todo!() } diff --git a/common/client-core/gateways-storage/src/lib.rs b/common/client-core/gateways-storage/src/lib.rs index 0c11b51f52..7416abfc90 100644 --- a/common/client-core/gateways-storage/src/lib.rs +++ b/common/client-core/gateways-storage/src/lib.rs @@ -48,7 +48,7 @@ pub trait GatewaysDetailsStore { /// Store the provided gateway details. async fn store_gateway_details( &self, - details: GatewayDetails, + details: &GatewayRegistration, ) -> Result<(), Self::StorageError>; /// Remove given gateway details from the underlying store. diff --git a/common/client-core/src/cli_helpers/client_init.rs b/common/client-core/src/cli_helpers/client_init.rs index 9c93cd1729..a75573b3eb 100644 --- a/common/client-core/src/cli_helpers/client_init.rs +++ b/common/client-core/src/cli_helpers/client_init.rs @@ -5,7 +5,9 @@ use crate::config::disk_persistence::CommonClientPaths; use crate::error::ClientCoreError; use crate::{ client::{ - base_client::non_wasm_helpers::setup_fs_gateways_storage, + base_client::{ + non_wasm_helpers::setup_fs_gateways_storage, storage::helpers::set_active_gateway, + }, key_manager::persistence::OnDiskKeys, }, init::types::{GatewaySelectionSpecification, GatewaySetup, InitResults}, @@ -203,7 +205,8 @@ where crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await? }; - todo!("remove registered gateways from the list"); + let unused_variable = 42; + // todo!("remove registered gateways from the list"); let gateway_setup = GatewaySetup::New { specification: selection_spec, @@ -216,27 +219,30 @@ where // TODO: ask the service provider we specified for its interface version and set it in the config - let config_save_location = config.default_store_location(); - if let Err(err) = config.save_to(&config_save_location) { - return Err(ClientCoreError::ConfigSaveFailure { - typ: C::NAME.to_string(), - id: id.to_string(), - path: config_save_location, - source: err, + if !already_init { + let config_save_location = config.default_store_location(); + if let Err(err) = config.save_to(&config_save_location) { + return Err(ClientCoreError::ConfigSaveFailure { + typ: C::NAME.to_string(), + id: id.to_string(), + path: config_save_location, + source: err, + } + .into()); } - .into()); - } - eprintln!( - "Saved configuration file to {}", - config_save_location.display() - ); + eprintln!( + "Saved configuration file to {}", + config_save_location.display() + ); + } let address = init_details.client_address(); let GatewayDetails::Remote(gateway_details) = init_details.gateway_registration.details else { return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails)?; }; + let init_results = InitResults::new( config.core_config(), address, @@ -244,6 +250,12 @@ where init_details.gateway_registration.registration_timestamp, ); + if init_args.as_ref().set_active { + set_active_gateway(&init_results.gateway_id, &details_store).await?; + } else { + info!("registered with new gateway {} (under address {address}), but this will not be our default address", init_results.gateway_id); + } + Ok(InitResultsWithConfig { config, init_results, diff --git a/common/client-core/src/client/base_client/non_wasm_helpers.rs b/common/client-core/src/client/base_client/non_wasm_helpers.rs index 70ad8358e6..740e75bb33 100644 --- a/common/client-core/src/client/base_client/non_wasm_helpers.rs +++ b/common/client-core/src/client/base_client/non_wasm_helpers.rs @@ -108,7 +108,7 @@ pub async fn setup_fs_gateways_storage>( info!("setting up gateways details storage"); OnDiskGatewaysDetails::init(db_path) .await - .map_err(|source| ClientCoreError::GatewayDetailsStoreError { + .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { source: Box::new(source), }) } diff --git a/common/client-core/src/client/base_client/storage/helpers.rs b/common/client-core/src/client/base_client/storage/helpers.rs new file mode 100644 index 0000000000..54535a918e --- /dev/null +++ b/common/client-core/src/client/base_client/storage/helpers.rs @@ -0,0 +1,101 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::client::key_manager::persistence::KeyStore; +use crate::client::key_manager::KeyManager; +use crate::error::ClientCoreError; +use nym_client_core_gateways_storage::{GatewayRegistration, GatewaysDetailsStore}; + +// helpers for error wrapping +pub async fn set_active_gateway( + gateway_id: &str, + details_store: &D, +) -> Result<(), ClientCoreError> +where + D: GatewaysDetailsStore, + D::StorageError: Send + Sync + 'static, +{ + details_store + .set_active_gateway(gateway_id) + .await + .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { + source: Box::new(source), + }) +} + +pub async fn store_gateway_details( + details_store: &D, + details: &GatewayRegistration, +) -> Result<(), ClientCoreError> +where + D: GatewaysDetailsStore, + D::StorageError: Send + Sync + 'static, +{ + details_store + .store_gateway_details(details) + .await + .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { + source: Box::new(source), + }) +} + +pub async fn load_active_gateway_details( + details_store: &D, +) -> Result +where + D: GatewaysDetailsStore, + D::StorageError: Send + Sync + 'static, +{ + details_store + .active_gateway() + .await + .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { + source: Box::new(source), + })? + .ok_or(ClientCoreError::NoActiveGatewaySet) +} + +pub async fn load_gateway_details( + details_store: &D, + gateway_id: &str, +) -> Result +where + D: GatewaysDetailsStore, + D::StorageError: Send + Sync + 'static, +{ + details_store + .load_gateway_details(gateway_id) + .await + .map_err(|source| ClientCoreError::UnavailableGatewayDetails { + gateway_id: gateway_id.to_string(), + source: Box::new(source), + }) +} + +pub async fn has_gateway_details( + details_store: &D, + gateway_id: &str, +) -> Result +where + D: GatewaysDetailsStore, + D::StorageError: Send + Sync + 'static, +{ + details_store + .has_gateway_details(gateway_id) + .await + .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { + source: Box::new(source), + }) +} + +pub async fn load_client_keys(key_store: &K) -> Result +where + K: KeyStore, + K::StorageError: Send + Sync + 'static, +{ + KeyManager::load_keys(key_store) + .await + .map_err(|source| ClientCoreError::KeyStoreError { + source: Box::new(source), + }) +} 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 f31370a30d..55bfb12e36 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -37,6 +37,7 @@ pub use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDe #[deprecated] pub mod gateway_details; +pub mod helpers; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] pub use nym_client_core_gateways_storage::{OnDiskGatewaysDetails, StorageError}; diff --git a/common/client-core/src/error.rs b/common/client-core/src/error.rs index 72fcf7762e..9fa43c8ef2 100644 --- a/common/client-core/src/error.rs +++ b/common/client-core/src/error.rs @@ -56,8 +56,8 @@ pub enum ClientCoreError { source: Box, }, - #[error("experienced a failure with our gateway details storage: {source}")] - GatewayDetailsStoreError { + #[error("experienced a failure with our gateways details storage: {source}")] + GatewaysDetailsStoreError { source: Box, }, diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index 38b5c398ab..7dce228834 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -3,6 +3,10 @@ //! Collection of initialization steps used by client implementations +use crate::client::base_client::storage::helpers::{ + has_gateway_details, load_active_gateway_details, load_client_keys, load_gateway_details, + store_gateway_details, +}; use crate::client::key_manager::persistence::KeyStore; use crate::client::key_manager::KeyManager; use crate::error::ClientCoreError; @@ -19,89 +23,11 @@ use nym_topology::gateway; use rand::rngs::OsRng; use rand::{CryptoRng, RngCore}; use serde::Serialize; -use std::sync::Arc; pub mod helpers; pub mod types; // helpers for error wrapping -async fn _store_gateway_details( - details_store: &D, - details: &GatewayDetails, -) -> Result<(), ClientCoreError> -where - D: GatewaysDetailsStore, - D::StorageError: Send + Sync + 'static, -{ - todo!() - // details_store - // .store_gateway_details(details) - // .await - // .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { - // source: Box::new(source), - // }) -} - -async fn _load_active_gateway_details( - details_store: &D, -) -> Result -where - D: GatewaysDetailsStore, - D::StorageError: Send + Sync + 'static, -{ - details_store - .active_gateway() - .await - .map_err(|source| ClientCoreError::GatewayDetailsStoreError { - source: Box::new(source), - })? - .ok_or(ClientCoreError::NoActiveGatewaySet) -} - -async fn _load_gateway_details( - details_store: &D, - gateway_id: &str, -) -> Result -where - D: GatewaysDetailsStore, - D::StorageError: Send + Sync + 'static, -{ - details_store - .load_gateway_details(gateway_id) - .await - .map_err(|source| ClientCoreError::UnavailableGatewayDetails { - gateway_id: gateway_id.to_string(), - source: Box::new(source), - }) -} - -async fn _has_gateway_details( - details_store: &D, - gateway_id: &str, -) -> Result -where - D: GatewaysDetailsStore, - D::StorageError: Send + Sync + 'static, -{ - details_store - .has_gateway_details(gateway_id) - .await - .map_err(|source| ClientCoreError::GatewayDetailsStoreError { - source: Box::new(source), - }) -} - -async fn _load_client_keys(key_store: &K) -> Result -where - K: KeyStore, - K::StorageError: Send + Sync + 'static, -{ - KeyManager::load_keys(key_store) - .await - .map_err(|source| ClientCoreError::KeyStoreError { - source: Box::new(source), - }) -} pub async fn generate_new_client_keys( rng: &mut R, @@ -143,15 +69,7 @@ where log::trace!("Setting up new gateway"); // if we're setting up new gateway, we must have had generated long-term client keys before - let client_keys = _load_client_keys(key_store).await?; - - // if we're setting up new gateway, failing to load existing information is fine. - // as a matter of fact, it's only potentially a problem if we DO succeed - - todo!("check gateway details (maybe not even needed anymore, idk)"); - // if _load_gateway_details(details_store).await.is_ok() && !overwrite_data { - // return Err(ClientCoreError::ForbiddenKeyOverwrite); - // } + let client_keys = load_client_keys(key_store).await?; let mut rng = OsRng; @@ -181,13 +99,13 @@ where // check if we already have details associated with this particular gateway // and if so, see if we can overwrite it let selected_id = selected_gateway.gateway_id().to_base58_string(); - if _has_gateway_details(details_store, &selected_id).await? && !overwrite_data { + if has_gateway_details(details_store, &selected_id).await? && !overwrite_data { return Err(ClientCoreError::ForbiddenGatewayKeyOverwrite { gateway_id: selected_id, }); } - let (gateway_details, client) = match selected_gateway { + let (gateway_details, authenticated_ephemeral_client) = match selected_gateway { SelectedGateway::Remote { gateway_id, gateway_owner_address, @@ -196,7 +114,8 @@ where // if we're using a 'normal' gateway setup, do register let our_identity = client_keys.identity_keypair(); let registration = - helpers::register_with_gateway(gateway_id, gateway_listener, our_identity).await?; + helpers::register_with_gateway(gateway_id, gateway_listener.clone(), our_identity) + .await?; ( GatewayDetails::new_remote( gateway_id, @@ -216,13 +135,15 @@ where ), }; + let gateway_registration = gateway_details.into(); + // persist gateway details - _store_gateway_details(details_store, &gateway_details).await?; + store_gateway_details(details_store, &gateway_registration).await?; Ok(InitialisationResult { - gateway_registration: gateway_details.into(), + gateway_registration, client_keys, - authenticated_ephemeral_client: client, + authenticated_ephemeral_client, }) } @@ -238,12 +159,12 @@ where D::StorageError: Send + Sync + 'static, { let loaded_details = if let Some(gateway_id) = gateway_id { - _load_gateway_details(details_store, &gateway_id).await? + load_gateway_details(details_store, &gateway_id).await? } else { - _load_active_gateway_details(details_store).await? + load_active_gateway_details(details_store).await? }; - let loaded_keys = _load_client_keys(key_store).await?; + let loaded_keys = load_client_keys(key_store).await?; // no need to persist anything as we got everything from the storage Ok(InitialisationResult::new_loaded( diff --git a/nym-connect/desktop/src-tauri/src/config/upgrade.rs b/nym-connect/desktop/src-tauri/src/config/upgrade.rs index 5ec509e733..2c7118196e 100644 --- a/nym-connect/desktop/src-tauri/src/config/upgrade.rs +++ b/nym-connect/desktop/src-tauri/src/config/upgrade.rs @@ -37,7 +37,7 @@ fn persist_gateway_details( details_store .store_to_disk(&persisted_details) .map_err(|source| BackendError::ClientCoreError { - source: ClientCoreError::GatewayDetailsStoreError { + source: ClientCoreError::GatewaysDetailsStoreError { source: Box::new(source), }, }) diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index eda51a5554..44b6901438 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -126,7 +126,7 @@ fn persist_gateway_details( details_store .store_to_disk(&persisted_details) .map_err(|source| { - IpPacketRouterError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { + IpPacketRouterError::ClientCoreError(ClientCoreError::GatewaysDetailsStoreError { source: Box::new(source), }) })