From 6f5bc31c903eb900ff22144fa68cf35e8c57a2db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Thu, 8 Dec 2022 15:50:14 +0100 Subject: [PATCH 1/2] clients: dedup gateway setup logic --- clients/client-core/src/error.rs | 2 + clients/client-core/src/init.rs | 37 +++++++++++++- clients/native/src/commands/init.rs | 67 +++++++------------------ clients/socks5/src/commands/init.rs | 66 +++++++----------------- nym-connect/src-tauri/src/config/mod.rs | 60 ++-------------------- 5 files changed, 79 insertions(+), 153 deletions(-) diff --git a/clients/client-core/src/error.rs b/clients/client-core/src/error.rs index e173a987fc..f81a7536e8 100644 --- a/clients/client-core/src/error.rs +++ b/clients/client-core/src/error.rs @@ -26,6 +26,8 @@ pub enum ClientCoreError { NoGatewayWithId(String), #[error("No gateways on network")] NoGatewaysOnNetwork, + #[error("Failed to setup gateway")] + FailedToSetupGateway, #[error("List of validator apis is empty")] ListOfValidatorApisIsEmpty, #[error("Could not load existing gateway configuration: {0}")] diff --git a/clients/client-core/src/init.rs b/clients/client-core/src/init.rs index 5cbd4bfcc6..9964b6f60a 100644 --- a/clients/client-core/src/init.rs +++ b/clients/client-core/src/init.rs @@ -21,7 +21,7 @@ use url::Url; use crate::{ client::key_manager::KeyManager, - config::{persistence::key_pathfinder::ClientKeyPathfinder, Config}, + config::{persistence::key_pathfinder::ClientKeyPathfinder, Config, GatewayEndpointConfig}, error::ClientCoreError, }; @@ -140,6 +140,41 @@ async fn register_with_gateway( Ok(shared_keys) } +pub async fn setup_gateway( + register: bool, + user_chosen_gateway_id: Option<&str>, + config: &Config, +) -> Result { + if register { + // Get the gateway details by querying the validator-api. Either pick one at random or use + // the chosen one if it's among the available ones. + println!("Configuring gateway"); + let gateway = + query_gateway_details(config.get_validator_api_endpoints(), user_chosen_gateway_id) + .await?; + log::debug!("Querying gateway gives: {}", gateway); + + // Registering with gateway by setting up and writing shared keys to disk + log::trace!("Registering gateway"); + register_with_gateway_and_store_keys(gateway.clone(), config).await?; + println!("Saved all generated keys"); + + Ok(gateway.into()) + } else if user_chosen_gateway_id.is_some() { + // Just set the config, don't register or create any keys + // This assumes that the user knows what they are doing, and that the existing keys are + // valid for the gateway being used + println!("Using gateway provided by user, keeping existing keys"); + let gateway = + query_gateway_details(config.get_validator_api_endpoints(), user_chosen_gateway_id) + .await?; + log::debug!("Querying gateway gives: {}", gateway); + Ok(gateway.into()) + } else { + Err(ClientCoreError::FailedToSetupGateway) + } +} + pub fn get_client_address(config: &Config) -> Result where T: config::NymConfig, diff --git a/clients/native/src/commands/init.rs b/clients/native/src/commands/init.rs index f30c5c1fe3..56a9cc1da1 100644 --- a/clients/native/src/commands/init.rs +++ b/clients/native/src/commands/init.rs @@ -134,12 +134,20 @@ pub(crate) async fn execute(args: &Init) { let override_config_fields = OverrideConfig::from(args.clone()); config = override_config(config, override_config_fields); - let gateway = setup_gateway(id, register_gateway, user_chosen_gateway_id, &config) + let gateway = if !register_gateway && user_chosen_gateway_id.is_none() { + reuse_gateway_config(id) + } else { + client_core::init::setup_gateway( + register_gateway, + user_chosen_gateway_id, + config.get_base(), + ) .await - .unwrap_or_else(|err| { - eprintln!("Failed to setup gateway\nError: {err}"); - std::process::exit(1) - }); + } + .unwrap_or_else(|err| { + eprintln!("Failed to setup gateway\nError: {err}"); + std::process::exit(1) + }); config.get_base_mut().with_gateway_endpoint(gateway); let config_save_location = config.get_config_file_save_location(); @@ -180,45 +188,11 @@ pub(crate) async fn execute(args: &Init) { } } -async fn setup_gateway( - id: &str, - register: bool, - user_chosen_gateway_id: Option<&str>, - config: &Config, -) -> Result { - if register { - // Get the gateway details by querying the validator-api. Either pick one at random or use - // the chosen one if it's among the available ones. - println!("Configuring gateway"); - let gateway = client_core::init::query_gateway_details( - config.get_base().get_validator_api_endpoints(), - user_chosen_gateway_id, - ) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - - // Registering with gateway by setting up and writing shared keys to disk - log::trace!("Registering gateway"); - client_core::init::register_with_gateway_and_store_keys(gateway.clone(), config.get_base()) - .await?; - println!("Saved all generated keys"); - - Ok(gateway.into()) - } else if user_chosen_gateway_id.is_some() { - // Just set the config, don't register or create any keys - // This assumes that the user knows what they are doing, and that the existing keys are - // valid for the gateway being used - println!("Using gateway provided by user, keeping existing keys"); - let gateway = client_core::init::query_gateway_details( - config.get_base().get_validator_api_endpoints(), - user_chosen_gateway_id, - ) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - Ok(gateway.into()) - } else { - println!("Not registering gateway, will reuse existing config and keys"); - let existing_config = Config::load_from_file(Some(id)).map_err(|err| { +fn reuse_gateway_config(id: &str) -> Result { + println!("Not registering gateway, will reuse existing config and keys"); + Config::load_from_file(Some(id)) + .map(|existing_config| existing_config.get_base().get_gateway_endpoint().clone()) + .map_err(|err| { log::error!( "Unable to configure gateway: {err}. \n Seems like the client was already initialized but it was not possible to read \ @@ -227,8 +201,5 @@ async fn setup_gateway( removing the existing configuration and starting over." ); ClientCoreError::CouldNotLoadExistingGatewayConfiguration(err) - })?; - - Ok(existing_config.get_base().get_gateway_endpoint().clone()) - } + }) } diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index c0d46480f3..a71852913d 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -133,12 +133,20 @@ pub(crate) async fn execute(args: &Init) { let override_config_fields = OverrideConfig::from(args.clone()); config = override_config(config, override_config_fields); - let gateway = setup_gateway(id, register_gateway, user_chosen_gateway_id, &config) + let gateway = if !register_gateway && user_chosen_gateway_id.is_none() { + reuse_gateway_config(id) + } else { + client_core::init::setup_gateway( + register_gateway, + user_chosen_gateway_id, + config.get_base(), + ) .await - .unwrap_or_else(|err| { - eprintln!("Failed to setup gateway\nError: {err}"); - std::process::exit(1) - }); + } + .unwrap_or_else(|err| { + eprintln!("Failed to setup gateway\nError: {err}"); + std::process::exit(1) + }); config.get_base_mut().with_gateway_endpoint(gateway); let config_save_location = config.get_config_file_save_location(); @@ -179,45 +187,11 @@ pub(crate) async fn execute(args: &Init) { println!("\nThe address of this client is: {}\n", address); } -async fn setup_gateway( - id: &str, - register: bool, - user_chosen_gateway_id: Option<&str>, - config: &Config, -) -> Result { - if register { - // Get the gateway details by querying the validator-api. Either pick one at random or use - // the chosen one if it's among the available ones. - println!("Configuring gateway"); - let gateway = client_core::init::query_gateway_details( - config.get_base().get_validator_api_endpoints(), - user_chosen_gateway_id, - ) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - - // Registering with gateway by setting up and writing shared keys to disk - log::trace!("Registering gateway"); - client_core::init::register_with_gateway_and_store_keys(gateway.clone(), config.get_base()) - .await?; - println!("Saved all generated keys"); - - Ok(gateway.into()) - } else if user_chosen_gateway_id.is_some() { - // Just set the config, don't register or create any keys - // This assumes that the user knows what they are doing, and that the existing keys are - // valid for the gateway being used - println!("Using gateway provided by user, keeping existing keys"); - let gateway = client_core::init::query_gateway_details( - config.get_base().get_validator_api_endpoints(), - user_chosen_gateway_id, - ) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - Ok(gateway.into()) - } else { - println!("Not registering gateway, will reuse existing config and keys"); - let existing_config = Config::load_from_file(Some(id)).map_err(|err| { +fn reuse_gateway_config(id: &str) -> Result { + println!("Not registering gateway, will reuse existing config and keys"); + Config::load_from_file(Some(id)) + .map(|existing_config| existing_config.get_base().get_gateway_endpoint().clone()) + .map_err(|err| { log::error!( "Unable to configure gateway: {err}. \n Seems like the client was already initialized but it was not possible to read \ @@ -226,7 +200,5 @@ async fn setup_gateway( removing the existing configuration and starting over." ); ClientCoreError::CouldNotLoadExistingGatewayConfiguration(err) - })?; - Ok(existing_config.get_base().get_gateway_endpoint().clone()) - } + }) } diff --git a/nym-connect/src-tauri/src/config/mod.rs b/nym-connect/src-tauri/src/config/mod.rs index 91adefbc53..536efde382 100644 --- a/nym-connect/src-tauri/src/config/mod.rs +++ b/nym-connect/src-tauri/src/config/mod.rs @@ -1,6 +1,5 @@ use std::path::PathBuf; -use client_core::config::GatewayEndpointConfig; use std::sync::Arc; use tap::TapFallible; use tokio::sync::RwLock; @@ -127,13 +126,13 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str .set_custom_validator_apis(config_common::parse_validators(&raw_validators)); } - let gateway = setup_gateway( - &id, + let gateway = client_core::init::setup_gateway( register_gateway, Some(&chosen_gateway_id), - config.get_socks5(), + config.get_base(), ) .await?; + config.get_base_mut().with_gateway_endpoint(gateway); let config_save_location = config.get_socks5().get_config_file_save_location(); @@ -163,56 +162,3 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str println!("\nThe address of this client is: {}\n", address); Ok(()) } - -// TODO: deduplicate with same functions in other client -async fn setup_gateway( - id: &str, - register: bool, - user_chosen_gateway_id: Option<&str>, - config: &Socks5Config, -) -> Result { - if register { - // Get the gateway details by querying the validator-api. Either pick one at random or use - // the chosen one if it's among the available ones. - println!("Configuring gateway"); - let gateway = client_core::init::query_gateway_details( - config.get_base().get_validator_api_endpoints(), - user_chosen_gateway_id, - ) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - - // Registering with gateway by setting up and writing shared keys to disk - log::trace!("Registering gateway"); - client_core::init::register_with_gateway_and_store_keys(gateway.clone(), config.get_base()) - .await?; - println!("Saved all generated keys"); - - Ok(gateway.into()) - } else if user_chosen_gateway_id.is_some() { - // Just set the config, don't register or create any keys - // This assumes that the user knows what they are doing, and that the existing keys are - // valid for the gateway being used - println!("Using gateway provided by user, keeping existing keys"); - let gateway = client_core::init::query_gateway_details( - config.get_base().get_validator_api_endpoints(), - user_chosen_gateway_id, - ) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - Ok(gateway.into()) - } else { - println!("Not registering gateway, will reuse existing config and keys"); - let existing_config = Socks5Config::load_from_file(Some(id)).map_err(|err| { - log::error!( - "Unable to configure gateway: {err}. \n - Seems like the client was already initialized but it was not possible to read \ - the existing configuration file. \n - CAUTION: Consider backing up your gateway keys and try force gateway registration, or \ - removing the existing configuration and starting over." - ); - BackendError::CouldNotLoadExistingGatewayConfiguration(err) - })?; - Ok(existing_config.get_base().get_gateway_endpoint().clone()) - } -} From 4099033ce0d66e9d00c7e9a47bbae0690470c90b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Thu, 8 Dec 2022 22:40:00 +0100 Subject: [PATCH 2/2] nym-connect: extract out print_save_config --- nym-connect/src-tauri/src/config/mod.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/nym-connect/src-tauri/src/config/mod.rs b/nym-connect/src-tauri/src/config/mod.rs index 536efde382..3a851cdba5 100644 --- a/nym-connect/src-tauri/src/config/mod.rs +++ b/nym-connect/src-tauri/src/config/mod.rs @@ -135,12 +135,22 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str config.get_base_mut().with_gateway_endpoint(gateway); - let config_save_location = config.get_socks5().get_config_file_save_location(); config.get_socks5().save_to_file(None).tap_err(|_| { log::error!("Failed to save the config file"); })?; - log::info!("Saved configuration file to {:?}", config_save_location); + print_save_config(&config); + + let address = client_core::init::get_client_address(config.get_base())?; + log::info!("The address of this client is: {}", address); + Ok(()) +} + +fn print_save_config(config: &Config) { + log::info!( + "Saved configuration file to {:?}", + config.get_socks5().get_config_file_save_location() + ); log::info!("Gateway id: {}", config.get_base().get_gateway_id()); log::info!("Gateway owner: {}", config.get_base().get_gateway_owner()); log::info!( @@ -157,8 +167,4 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str config.get_socks5().get_listening_port() ); log::info!("Client configuration completed."); - - let address = client_core::init::get_client_address(config.get_base())?; - println!("\nThe address of this client is: {}\n", address); - Ok(()) }