diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index a934793953..04cd6347c6 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -51,7 +51,7 @@ use url::Url; use nym_bandwidth_controller::wasm_mockups::DkgQueryClient; use crate::client::base_client::storage::gateway_details::GatewayDetailsStore; -use crate::init::{setup_gateway, GatewaySetup, InitialisationDetails}; +use crate::init::{setup_gateway, GatewaySetup, InitialisationResult}; #[cfg(not(target_arch = "wasm32"))] use nym_validator_client::nyxd::traits::DkgQueryClient; @@ -445,7 +445,7 @@ where Ok(mem_store) } - async fn initialise_keys_and_gateway(&self) -> Result + async fn initialise_keys_and_gateway(&self) -> Result where ::StorageError: Sync + Send, ::StorageError: Sync + Send, @@ -471,9 +471,9 @@ where info!("Starting nym client"); // derive (or load) client keys and gateway configuration - let details = self.initialise_keys_and_gateway().await?; - let gateway_config = details.gateway_details; - let managed_keys = details.managed_keys; + let init_res = self.initialise_keys_and_gateway().await?; + let gateway_config = init_res.details.gateway_details; + let managed_keys = init_res.details.managed_keys; let (reply_storage_backend, credential_store) = self.client_store.into_runtime_stores(); diff --git a/common/client-core/src/init/helpers.rs b/common/client-core/src/init/helpers.rs index 723e9d02a2..8541bf5ad0 100644 --- a/common/client-core/src/init/helpers.rs +++ b/common/client-core/src/init/helpers.rs @@ -7,7 +7,6 @@ use futures::{SinkExt, StreamExt}; use log::{debug, info, trace, warn}; use nym_crypto::asymmetric::identity; use nym_gateway_client::GatewayClient; -use nym_gateway_requests::registration::handshake::SharedKeys; use nym_topology::{filter::VersionFilterable, gateway}; use rand::{seq::SliceRandom, Rng}; use std::{sync::Arc, time::Duration}; @@ -15,8 +14,6 @@ use tap::TapFallible; use tungstenite::Message; use url::Url; -#[cfg(not(target_arch = "wasm32"))] -use nym_validator_client::nyxd::DirectSigningNyxdClient; #[cfg(not(target_arch = "wasm32"))] use tokio::net::TcpStream; #[cfg(not(target_arch = "wasm32"))] @@ -30,8 +27,7 @@ type WsConn = WebSocketStream>; #[cfg(not(target_arch = "wasm32"))] use tokio::time::sleep; -#[cfg(target_arch = "wasm32")] -use nym_bandwidth_controller::wasm_mockups::DirectSigningNyxdClient; +use crate::init::RegistrationResult; #[cfg(target_arch = "wasm32")] use wasm_utils::websocket::JSWebsocket; #[cfg(target_arch = "wasm32")] @@ -205,9 +201,9 @@ pub(super) fn uniformly_random_gateway( pub(super) async fn register_with_gateway( gateway: &GatewayEndpointConfig, our_identity: Arc, -) -> Result, ClientCoreError> { +) -> Result { let timeout = Duration::from_millis(1500); - let mut gateway_client: GatewayClient = GatewayClient::new_init( + let mut gateway_client = GatewayClient::new_init( gateway.gateway_listener.clone(), gateway.try_get_gateway_identity_key()?, our_identity.clone(), @@ -221,5 +217,8 @@ pub(super) async fn register_with_gateway( .perform_initial_authentication() .await .tap_err(|_| log::warn!("Failed to register with the gateway!"))?; - Ok(shared_keys) + Ok(RegistrationResult { + shared_keys, + authenticated_ephemeral_client: Some(gateway_client), + }) } diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index 6ebc123b4b..8e4a14203a 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -14,16 +14,39 @@ use crate::{ error::ClientCoreError, }; use nym_crypto::asymmetric::identity; +use nym_gateway_client::client::InitOnly; +use nym_gateway_client::GatewayClient; +use nym_gateway_requests::registration::handshake::SharedKeys; use nym_sphinx::addressing::{clients::Recipient, nodes::NodeIdentity}; use nym_topology::gateway; use nym_validator_client::client::IdentityKey; use rand::rngs::OsRng; use serde::Serialize; use std::fmt::{Debug, Display}; +use std::sync::Arc; use url::Url; pub mod helpers; +pub struct RegistrationResult { + pub shared_keys: Arc, + pub authenticated_ephemeral_client: Option>, +} + +pub struct InitialisationResult { + pub details: InitialisationDetails, + pub authenticated_ephemeral_client: Option>, +} + +impl From for InitialisationResult { + fn from(details: InitialisationDetails) -> Self { + InitialisationResult { + details, + authenticated_ephemeral_client: None, + } + } +} + // TODO: rename to something better... #[derive(Debug)] pub struct InitialisationDetails { @@ -271,7 +294,7 @@ pub async fn setup_gateway_from( details_store: &D, overwrite_data: bool, gateways: Option<&[gateway::Node]>, -) -> Result +) -> Result where K: KeyStore, D: GatewayDetailsStore, @@ -293,7 +316,7 @@ where ensure_valid_details(&details, &loaded_keys)?; // no need to persist anything as we got everything from the storage - return Ok(InitialisationDetails::new(details.into(), loaded_keys)); + return Ok(InitialisationDetails::new(details.into(), loaded_keys).into()); } GatewaySetup::Predefined { details } => { // we already have defined gateway details AND a shared key @@ -304,10 +327,9 @@ where _store_gateway_details(details_store, details).await?; } - return Ok(InitialisationDetails::new( - details.clone().into(), - loaded_keys, - )); + return Ok( + InitialisationDetails::new(details.clone().into(), loaded_keys).into(), + ); } GatewaySetup::Specified { gateway_identity } => { // if that data was already stored... @@ -323,7 +345,8 @@ where return Ok(InitialisationDetails::new( existing_gateway.into(), loaded_keys, - )); + ) + .into()); } } @@ -341,7 +364,8 @@ where return Ok(InitialisationDetails::new( existing_gateway.into(), loaded_keys, - )); + ) + .into()); } // we didn't get full details from the store and we have loaded some keys @@ -371,7 +395,9 @@ where let our_identity = managed_keys.identity_keypair(); // Establish connection, authenticate and generate keys for talking with the gateway - let shared_keys = helpers::register_with_gateway(&gateway_details, our_identity).await?; + let registration_result = + helpers::register_with_gateway(&gateway_details, our_identity).await?; + let shared_keys = registration_result.shared_keys; let persisted_details = PersistedGatewayDetails::new(gateway_details, &shared_keys); @@ -386,10 +412,10 @@ where // persist gateway config _store_gateway_details(details_store, &persisted_details).await?; - Ok(InitialisationDetails::new( - persisted_details.into(), - managed_keys, - )) + Ok(InitialisationResult { + details: InitialisationDetails::new(persisted_details.into(), managed_keys), + authenticated_ephemeral_client: registration_result.authenticated_ephemeral_client, + }) } pub async fn setup_gateway( @@ -398,7 +424,7 @@ pub async fn setup_gateway( details_store: &D, overwrite_data: bool, validator_servers: Option<&[Url]>, -) -> Result +) -> Result where K: KeyStore, D: GatewayDetailsStore, diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index bdc2c626df..821291edda 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -45,7 +45,7 @@ use wasmtimer::tokio::sleep; const DEFAULT_RECONNECTION_ATTEMPTS: usize = 10; const DEFAULT_RECONNECTION_BACKOFF: Duration = Duration::from_secs(5); -pub struct GatewayClient { +pub struct GatewayClient { authenticated: bool, disabled_credentials_mode: bool, bandwidth_remaining: i64, @@ -755,7 +755,9 @@ impl GatewayClient { } } -impl GatewayClient { +pub struct InitOnly; + +impl GatewayClient { // for initialisation we do not need credential storage. Though it's still a bit weird we have to set the generic... pub fn new_init( gateway_address: String, @@ -772,7 +774,7 @@ impl GatewayClient { let shutdown = TaskClient::dummy(); let packet_router = PacketRouter::new(ack_tx, mix_tx, shutdown.clone()); - GatewayClient:: { + GatewayClient:: { authenticated: false, disabled_credentials_mode: true, bandwidth_remaining: 0,