diff --git a/Cargo.lock b/Cargo.lock index 4ff0f9a693..0822e3aee2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3821,6 +3821,7 @@ dependencies = [ "nym-explorer-api-requests", "nym-gateway-client", "nym-gateway-requests", + "nym-mixnet-contract-common", "nym-network-defaults", "nym-nonexhaustive-delayqueue", "nym-pemstore", diff --git a/clients/native/src/commands/init.rs b/clients/native/src/commands/init.rs index d61b31b52d..ef4451dfa9 100644 --- a/clients/native/src/commands/init.rs +++ b/clients/native/src/commands/init.rs @@ -164,6 +164,7 @@ pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> { user_chosen_gateway_id.map(|id| id.to_base58_string()), Some(args.latency_based_selection), ); + dbg!(&gateway_setup); // Load and potentially override config let config = override_config(Config::new(id), OverrideConfig::from(args.clone())); diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index bcb21899fe..b1a175d7a0 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -45,6 +45,8 @@ nym-task = { path = "../task" } nym-credential-storage = { path = "../credential-storage" } nym-network-defaults = { path = "../network-defaults" } +nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" } + [target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream] version = "0.1.11" features = ["time"] diff --git a/common/client-core/src/client/topology_control/nym_api_provider.rs b/common/client-core/src/client/topology_control/nym_api_provider.rs index 0b7538b7eb..291d10ebce 100644 --- a/common/client-core/src/client/topology_control/nym_api_provider.rs +++ b/common/client-core/src/client/topology_control/nym_api_provider.rs @@ -78,11 +78,21 @@ impl NymApiTopologyProvider { return None; } Ok(gateways) => { - dbg!(&gateways); - panic!(); + // dbg!(&gateways); gateways } }; + let mut g = gateways[0].clone(); + g.gateway = nym_mixnet_contract_common::Gateway { + host: "127.0.0.1".to_string(), + mix_port: 1789, + clients_port: 9000, + location: "local".to_string(), + sphinx_key: "9PgtqBP8Xo3icVvvgrtxWKcNEFGnvDAXd7tWHmpA5UPR".to_string(), + identity_key: "GapWkU8o3goXH5sjKw7TWGE3NwLKq7gBqzdD77qahC28".to_string(), + version: "1.1.25".to_string(), + }; + let gateways = vec![g]; let topology = nym_topology_from_detailed(mixnodes, gateways) .filter_system_version(&self.client_version); diff --git a/common/client-core/src/init/helpers.rs b/common/client-core/src/init/helpers.rs index 535870798d..09fb58bea5 100644 --- a/common/client-core/src/init/helpers.rs +++ b/common/client-core/src/init/helpers.rs @@ -68,42 +68,16 @@ pub async fn current_gateways( log::trace!("Fetching list of gateways from: {nym_api}"); let gateways = client.get_cached_gateways().await?; - dbg!(&gateways); + // dbg!(&gateways); let mut g = gateways[0].clone(); - g.gateway = Gateway { - // pub host: String, - // pub mix_port: u16, - // pub clients_port: u16, - // pub location: String, - // pub sphinx_key: String, - // pub identity_key: String, - // pub version: String, - - /* -pub struct Gateway { - /// Network address of this gateway, for example 1.1.1.1 or foo.gateway.com - pub host: String, - - /// Port used by this gateway for listening for mix packets. - pub mix_port: u16, - - /// Port used by this gateway for listening for client requests. - pub clients_port: u16, - - /// The physical, self-reported, location of this gateway. - // this field should be deprecated in favour of externally hosted information, like the mixnodes'. - pub location: String, - - /// Base58-encoded x25519 public key used for sphinx key derivation. - pub sphinx_key: SphinxKey, - - /// Base58 encoded ed25519 EdDSA public key of the gateway used to derive shared keys with clients - pub identity_key: IdentityKey, - - /// The self-reported semver version of this gateway. - pub version: String, -} - */ + g.gateway = nym_mixnet_contract_common::Gateway { + host: "127.0.0.1".to_string(), + mix_port: 1789, + clients_port: 9000, + location: "local".to_string(), + sphinx_key: "9PgtqBP8Xo3icVvvgrtxWKcNEFGnvDAXd7tWHmpA5UPR".to_string(), + identity_key: "GapWkU8o3goXH5sjKw7TWGE3NwLKq7gBqzdD77qahC28".to_string(), + version: "1.1.25".to_string(), }; let gateways = vec![g]; let valid_gateways = gateways diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index 8e848837ef..a6dab3995d 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -97,6 +97,7 @@ impl InitialisationDetails { } } +#[derive(Debug)] pub enum GatewaySetup { /// The gateway specification MUST BE loaded from the underlying storage. MustLoad, @@ -307,6 +308,7 @@ where K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, { + dbg!(&overwrite_data); // 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, @@ -331,6 +333,7 @@ where Ok(loaded_keys) => { match &setup { GatewaySetup::MustLoad => { + println!("GatewaySetup::MustLoad"); // get EVERYTHING from the storage let details = loaded_details?; ensure_valid_details(&details, &loaded_keys)?; @@ -339,6 +342,7 @@ where return Ok(InitialisationDetails::new(details.into(), loaded_keys).into()); } GatewaySetup::Predefined { details } => { + println!("GatewaySetup::Predefined"); // we already have defined gateway details AND a shared key ensure_valid_details(details, &loaded_keys)?; @@ -352,6 +356,7 @@ where ); } GatewaySetup::Specified { gateway_identity } => { + println!("GatewaySetup::Specified"); // if that data was already stored... if let Ok(existing_gateway) = loaded_details { ensure_valid_details(&existing_gateway, &loaded_keys)?; @@ -379,7 +384,9 @@ where } } GatewaySetup::New { .. } => { + println!("GatewaySetup::New"); if let Ok(existing_gateway) = loaded_details { + println!("GatewaySetup::New - existing_gateway"); ensure_valid_details(&existing_gateway, &loaded_keys)?; return Ok(InitialisationDetails::new( existing_gateway.into(), @@ -391,6 +398,7 @@ where // we didn't get full details from the store and we have loaded some keys // so we can only continue if we're allowed to overwrite keys if overwrite_data { + println!("GatewaySetup::New - overwrite_data"); ManagedKeys::generate_new(&mut rng) } else { return Err(ClientCoreError::ForbiddenKeyOverwrite); @@ -456,6 +464,7 @@ where { let mut rng = OsRng; let gateways = current_gateways(&mut rng, validator_servers.unwrap_or_default()).await?; + dbg!(&gateways); setup_gateway_from( setup, diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index 188d84e2c9..caa6318a3a 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -25,6 +25,7 @@ use nym_task::TaskClient; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use rand::rngs::OsRng; use std::convert::TryFrom; +use std::fmt; use std::sync::Arc; use std::time::Duration; use tungstenite::protocol::Message; @@ -68,6 +69,34 @@ pub struct GatewayClient { shutdown: TaskClient, } +impl fmt::Debug for GatewayClient { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("GatewayClient") + .field("authenticated", &self.authenticated) + .field("disabled_credentials_mode", &self.disabled_credentials_mode) + .field("bandwidth_remaining", &self.bandwidth_remaining) + .field("gateway_address", &self.gateway_address) + .field("gateway_identity", &self.gateway_identity) + .field("local_identity", &self.local_identity) + .field("shared_key", &self.shared_key) + // .field("connection", &self.connection) + .field("packet_router", &self.packet_router) + .field( + "response_timeout_duration", + &self.response_timeout_duration, + ) + // .field("bandwidth_controller", &self.bandwidth_controller) + .field( + "should_reconnect_on_failure", + &self.should_reconnect_on_failure, + ) + .field("reconnection_attempts", &self.reconnection_attempts) + .field("reconnection_backoff", &self.reconnection_backoff) + .field("shutdown", &self.shutdown) + .finish() + } +} + impl GatewayClient { // TODO: put it all in a Config struct #[allow(clippy::too_many_arguments)] diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 0fe930a96d..f9753cbdf8 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -383,6 +383,7 @@ where log::trace!("client_handling::AuthenticatedHandler: received shutdown"); } socket_msg = self.inner.read_websocket_message() => { + println!("socket_msg"); let socket_msg = match socket_msg { None => break, Some(Ok(socket_msg)) => socket_msg, @@ -406,7 +407,11 @@ where } }, mix_messages = self.mix_receiver.next() => { - let mix_messages = mix_messages.expect("sender was unexpectedly closed! this shouldn't have ever happened!"); + // let mix_messages = mix_messages.expect("sender was unexpectedly closed! this shouldn't have ever happened!"); + let mix_messages = match mix_messages { + None => { println!("None"); break; }, + Some(mix_messages) => mix_messages, + }; if let Err(err) = self.inner.push_packets_to_client(&self.client.shared_keys, mix_messages).await { warn!("failed to send the unwrapped sphinx packets back to the client - {err}, assuming the connection is dead"); break; diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index f03cdc26f9..b1dd9458b1 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -419,7 +419,9 @@ where let iv = IV::try_from_base58_string(iv)?; if self.active_clients_store.get(address).is_some() { - return Err(InitialAuthenticationError::DuplicateConnection); + println!("duplicate connection when authenticating"); + // return Err(InitialAuthenticationError::DuplicateConnection); + self.active_clients_store.disconnect(address) } let shared_keys = self @@ -504,7 +506,8 @@ where let remote_address = remote_identity.derive_destination_address(); if self.active_clients_store.get(remote_address).is_some() { - return Err(InitialAuthenticationError::DuplicateConnection); + println!("duplicate connection when registering"); + // return Err(InitialAuthenticationError::DuplicateConnection); } let shared_keys = self.perform_registration_handshake(init_data).await?; diff --git a/gateway/src/node/client_handling/websocket/connection_handler/mod.rs b/gateway/src/node/client_handling/websocket/connection_handler/mod.rs index ad6a0d03a1..ee7474f3a7 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/mod.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/mod.rs @@ -100,7 +100,7 @@ pub(crate) async fn handle_connection( .await { None => { - trace!("received shutdown signal while performing initial authetnication"); + trace!("received shutdown signal while performing initial authentication"); return; } Some(None) => {