From 55f3fc278f205d4bdc8bd1401f6edcd7c46d324d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 15 Aug 2023 14:43:52 +0100 Subject: [PATCH] new GatewaySetup variant to reuse the connection --- clients/native/src/commands/init.rs | 2 +- clients/socks5/src/commands/init.rs | 2 +- clients/webassembly/src/helpers.rs | 2 +- .../client-core/src/client/base_client/mod.rs | 27 +++++++++++----- common/client-core/src/init/mod.rs | 31 ++++++++++++++++--- .../client-libs/gateway-client/src/client.rs | 6 ++++ .../desktop/src-tauri/src/config/mod.rs | 2 +- sdk/rust/nym-sdk/src/mixnet/client.rs | 2 +- .../network-requester/src/cli/init.rs | 2 +- 9 files changed, 59 insertions(+), 17 deletions(-) diff --git a/clients/native/src/commands/init.rs b/clients/native/src/commands/init.rs index 3f1911fe01..d61b31b52d 100644 --- a/clients/native/src/commands/init.rs +++ b/clients/native/src/commands/init.rs @@ -174,7 +174,7 @@ pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> { let details_store = OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details); let init_details = nym_client_core::init::setup_gateway( - &gateway_setup, + gateway_setup, &key_store, &details_store, register_gateway, diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index be241b96b7..77782ed262 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -186,7 +186,7 @@ pub(crate) async fn execute(args: &Init) -> Result<(), Socks5ClientError> { let details_store = OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details); let init_details = nym_client_core::init::setup_gateway( - &gateway_setup, + gateway_setup, &key_store, &details_store, register_gateway, diff --git a/clients/webassembly/src/helpers.rs b/clients/webassembly/src/helpers.rs index ba59b19096..68831dd19b 100644 --- a/clients/webassembly/src/helpers.rs +++ b/clients/webassembly/src/helpers.rs @@ -89,7 +89,7 @@ async fn setup_gateway( GatewaySetup::new_fresh(chosen_gateway.clone(), None) }; - setup_gateway_from(&setup, client_store, client_store, false, Some(gateways)) + setup_gateway_from(setup, client_store, client_store, false, Some(gateways)) .await .map_err(Into::into) } diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index 9b67c0309b..c7e47cab0e 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -455,17 +455,23 @@ where Ok(mem_store) } - async fn initialise_keys_and_gateway(&self) -> Result + async fn initialise_keys_and_gateway( + setup_method: GatewaySetup, + key_store: &S::KeyStore, + details_store: &S::GatewayDetailsStore, + overwrite_data: bool, + validator_servers: Option<&[Url]>, + ) -> Result where ::StorageError: Sync + Send, ::StorageError: Sync + Send, { setup_gateway( - &self.setup_method, - self.client_store.key_store(), - self.client_store.gateway_details_store(), - false, - Some(&self.config.client.nym_api_urls), + setup_method, + key_store, + details_store, + overwrite_data, + validator_servers, ) .await } @@ -481,7 +487,14 @@ where info!("Starting nym client"); // derive (or load) client keys and gateway configuration - let init_res = self.initialise_keys_and_gateway().await?; + let init_res = Self::initialise_keys_and_gateway( + self.setup_method, + self.client_store.key_store(), + self.client_store.gateway_details_store(), + false, + Some(&self.config.client.nym_api_urls), + ) + .await?; let (reply_storage_backend, credential_store) = self.client_store.into_runtime_stores(); diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index 8e4a14203a..8e848837ef 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -97,7 +97,6 @@ impl InitialisationDetails { } } -#[derive(Debug, Clone)] pub enum GatewaySetup { /// The gateway specification MUST BE loaded from the underlying storage. MustLoad, @@ -115,6 +114,13 @@ pub enum GatewaySetup { /// Full gateway configuration details: PersistedGatewayDetails, }, + ReuseConnection { + /// The authenticated ephemeral client that was created during `init` + authenticated_ephemeral_client: GatewayClient, + + /// Details of this pre-initialised client + details: InitialisationDetails, + }, } impl From for GatewaySetup { @@ -289,7 +295,7 @@ fn ensure_valid_details( } pub async fn setup_gateway_from( - setup: &GatewaySetup, + setup: GatewaySetup, key_store: &K, details_store: &D, overwrite_data: bool, @@ -301,6 +307,20 @@ where K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, { + // I don't like how we can't deal with this variant in the match below, but we need to take ownership of internal values. + if let GatewaySetup::ReuseConnection { + authenticated_ephemeral_client, + details, + } = setup + { + // if we have already performed the full setup, forward the details. + // it's up to the caller to ensure persistence + return Ok(InitialisationResult { + details, + authenticated_ephemeral_client: Some(authenticated_ephemeral_client), + }); + } + let mut rng = OsRng; // try load gateway details @@ -309,7 +329,7 @@ where // try load keys and decide what to do based on the GatewaySetup let mut managed_keys = match ManagedKeys::try_load(key_store).await { Ok(loaded_keys) => { - match setup { + match &setup { GatewaySetup::MustLoad => { // get EVERYTHING from the storage let details = loaded_details?; @@ -376,6 +396,9 @@ where return Err(ClientCoreError::ForbiddenKeyOverwrite); } } + GatewaySetup::ReuseConnection { .. } => { + unreachable!("the reuse connection variant was already manually covered") + } } } Err(_) => { @@ -419,7 +442,7 @@ where } pub async fn setup_gateway( - setup: &GatewaySetup, + setup: GatewaySetup, key_store: &K, details_store: &D, overwrite_data: bool, diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index ed395d73a7..b7d9a2c882 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -809,6 +809,12 @@ impl GatewayClient { bandwidth_controller: Option>, shutdown: TaskClient, ) -> GatewayClient { + // invariants that can't be broken + // (unless somebody decided to expose some field that wasn't meant to be exposed) + assert!(self.authenticated); + assert!(self.connection.is_available()); + assert!(self.shared_key.is_some()); + GatewayClient { authenticated: self.authenticated, disabled_credentials_mode: self.disabled_credentials_mode, diff --git a/nym-connect/desktop/src-tauri/src/config/mod.rs b/nym-connect/desktop/src-tauri/src/config/mod.rs index 0817e6d8fa..b65abc70d1 100644 --- a/nym-connect/desktop/src-tauri/src/config/mod.rs +++ b/nym-connect/desktop/src-tauri/src/config/mod.rs @@ -183,7 +183,7 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str let details_store = OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details); let init_details = nym_client_core::init::setup_gateway( - &gateway_setup, + gateway_setup, &key_store, &details_store, register_gateway, diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index 33185ccd88..8f19074605 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -323,7 +323,7 @@ where // this will perform necessary key and details load and optional store let _init_result = nym_client_core::init::setup_gateway( - &gateway_setup, + gateway_setup, self.storage.key_store(), self.storage.gateway_details_store(), !self.config.key_mode.is_keep(), diff --git a/service-providers/network-requester/src/cli/init.rs b/service-providers/network-requester/src/cli/init.rs index 154a018473..a1eb89f518 100644 --- a/service-providers/network-requester/src/cli/init.rs +++ b/service-providers/network-requester/src/cli/init.rs @@ -149,7 +149,7 @@ pub(crate) async fn execute(args: &Init) -> Result<(), NetworkRequesterError> { let details_store = OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details); let init_details = nym_client_core::init::setup_gateway( - &gateway_setup, + gateway_setup, &key_store, &details_store, register_gateway,