diff --git a/Cargo.lock b/Cargo.lock index d78c53720c..c8a2f0ca1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3944,6 +3944,7 @@ dependencies = [ "nym-crypto", "nym-gateway-requests", "nym-network-defaults", + "nym-noise", "nym-pemstore", "nym-sphinx", "nym-task", diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index aecb7eb5c1..c7a84ca610 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -306,15 +306,21 @@ where { let gateway_address = gateway_config.gateway_listener.clone(); let gateway_id = gateway_config.gateway_id; + let gateway_sphinx = gateway_config.gateway_sphinx; // TODO: in theory, at this point, this should be infallible let gateway_identity = identity::PublicKey::from_base58_string(gateway_id) .map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?; + let gateway_sphinx_key = encryption::PublicKey::from_base58_string(gateway_sphinx) + .map_err(ClientCoreError::UnableToCreateSphinxKeyFromGatewayId)?; + let mut gateway_client = GatewayClient::new( gateway_address, managed_keys.identity_keypair(), + managed_keys.encryption_keypair(), gateway_identity, + gateway_sphinx_key, Some(managed_keys.must_get_gateway_shared_key()), mixnet_message_sender, ack_sender, diff --git a/common/client-core/src/config/mod.rs b/common/client-core/src/config/mod.rs index e8f08adfaa..4015f0191c 100644 --- a/common/client-core/src/config/mod.rs +++ b/common/client-core/src/config/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use nym_config::defaults::NymNetworkDetails; -use nym_crypto::asymmetric::identity; +use nym_crypto::asymmetric::{encryption, identity}; use nym_sphinx::params::{PacketSize, PacketType}; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -207,6 +207,8 @@ pub struct GatewayEndpointConfig { /// If initially omitted, a random gateway will be chosen from the available topology. pub gateway_id: String, + pub gateway_sphinx: String, + /// Address of the gateway owner to which the client should send messages. pub gateway_owner: String, @@ -219,11 +221,13 @@ impl GatewayEndpointConfig { #[cfg_attr(target_arch = "wasm32", wasm_bindgen(constructor))] pub fn new( gateway_id: String, + gateway_sphinx: String, gateway_owner: String, gateway_listener: String, ) -> GatewayEndpointConfig { GatewayEndpointConfig { gateway_id, + gateway_sphinx, gateway_owner, gateway_listener, } @@ -236,6 +240,11 @@ impl GatewayEndpointConfig { identity::PublicKey::from_base58_string(&self.gateway_id) .map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId) } + + pub fn try_get_gateway_sphinx_key(&self) -> Result { + encryption::PublicKey::from_base58_string(&self.gateway_sphinx) + .map_err(ClientCoreError::UnableToCreateSphinxKeyFromGatewayId) + } } impl From for GatewayEndpointConfig { @@ -243,6 +252,7 @@ impl From for GatewayEndpointConfig { let gateway_listener = node.clients_address(); GatewayEndpointConfig { gateway_id: node.identity_key.to_base58_string(), + gateway_sphinx: node.sphinx_key.to_base58_string(), gateway_owner: node.owner, gateway_listener, } diff --git a/common/client-core/src/config/old_config_v1_1_20.rs b/common/client-core/src/config/old_config_v1_1_20.rs index b3a4a189d8..98f317fbc2 100644 --- a/common/client-core/src/config/old_config_v1_1_20.rs +++ b/common/client-core/src/config/old_config_v1_1_20.rs @@ -68,6 +68,7 @@ pub struct ConfigV1_1_20 { #[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] pub struct GatewayEndpointConfigV1_1_20 { pub gateway_id: String, + pub gateway_sphinx: String, pub gateway_owner: String, pub gateway_listener: String, } @@ -76,6 +77,7 @@ impl From for GatewayEndpointConfigV1_1_20_2 { fn from(value: GatewayEndpointConfigV1_1_20) -> Self { GatewayEndpointConfigV1_1_20_2 { gateway_id: value.gateway_id, + gateway_sphinx: value.gateway_sphinx, gateway_owner: value.gateway_owner, gateway_listener: value.gateway_listener, } diff --git a/common/client-core/src/config/old_config_v1_1_20_2.rs b/common/client-core/src/config/old_config_v1_1_20_2.rs index ed0cd0356a..f2cef4ab4e 100644 --- a/common/client-core/src/config/old_config_v1_1_20_2.rs +++ b/common/client-core/src/config/old_config_v1_1_20_2.rs @@ -73,6 +73,8 @@ pub struct GatewayEndpointConfigV1_1_20_2 { /// If initially omitted, a random gateway will be chosen from the available topology. pub gateway_id: String, + pub gateway_sphinx: String, + /// Address of the gateway owner to which the client should send messages. pub gateway_owner: String, @@ -84,6 +86,7 @@ impl From for GatewayEndpointConfig { fn from(value: GatewayEndpointConfigV1_1_20_2) -> Self { GatewayEndpointConfig { gateway_id: value.gateway_id, + gateway_sphinx: value.gateway_sphinx, gateway_owner: value.gateway_owner, gateway_listener: value.gateway_listener, } diff --git a/common/client-core/src/error.rs b/common/client-core/src/error.rs index ff3f36e4cb..50de910d12 100644 --- a/common/client-core/src/error.rs +++ b/common/client-core/src/error.rs @@ -1,6 +1,7 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use nym_crypto::asymmetric::encryption::KeyRecoveryError; use nym_crypto::asymmetric::identity::Ed25519RecoveryError; use nym_gateway_client::error::GatewayClientError; use nym_topology::gateway::GatewayConversionError; @@ -58,6 +59,9 @@ pub enum ClientCoreError { #[error("The gateway id is invalid - {0}")] UnableToCreatePublicKeyFromGatewayId(Ed25519RecoveryError), + #[error("The gateway sphinx is invalid - {0}")] + UnableToCreateSphinxKeyFromGatewayId(KeyRecoveryError), + #[error("The identity of the gateway is unknown - did you run init?")] GatewayIdUnknown, diff --git a/common/client-core/src/init/helpers.rs b/common/client-core/src/init/helpers.rs index 6ad04678f8..c82100034b 100644 --- a/common/client-core/src/init/helpers.rs +++ b/common/client-core/src/init/helpers.rs @@ -5,7 +5,7 @@ use crate::config::GatewayEndpointConfig; use crate::error::ClientCoreError; use futures::{SinkExt, StreamExt}; use log::{debug, info, trace, warn}; -use nym_crypto::asymmetric::identity; +use nym_crypto::asymmetric::{encryption, identity}; use nym_gateway_client::GatewayClient; use nym_gateway_requests::registration::handshake::SharedKeys; use nym_topology::{filter::VersionFilterable, gateway}; @@ -200,12 +200,15 @@ pub(super) fn uniformly_random_gateway( pub(super) async fn register_with_gateway( gateway: &GatewayEndpointConfig, our_identity: Arc, + our_sphinx: Arc, ) -> Result, ClientCoreError> { let timeout = Duration::from_millis(1500); let mut gateway_client: GatewayClient = GatewayClient::new_init( gateway.gateway_listener.clone(), gateway.try_get_gateway_identity_key()?, + gateway.try_get_gateway_sphinx_key()?, our_identity.clone(), + our_sphinx.clone(), timeout, ); gateway_client diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index 6ebc123b4b..77833b44b8 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -370,8 +370,11 @@ where // get our identity key let our_identity = managed_keys.identity_keypair(); + let our_sphinx = managed_keys.encryption_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 shared_keys = + helpers::register_with_gateway(&gateway_details, our_identity, our_sphinx).await?; let persisted_details = PersistedGatewayDetails::new(gateway_details, &shared_keys); diff --git a/common/client-libs/gateway-client/Cargo.toml b/common/client-libs/gateway-client/Cargo.toml index 20d5c958b0..8e2f930125 100644 --- a/common/client-libs/gateway-client/Cargo.toml +++ b/common/client-libs/gateway-client/Cargo.toml @@ -27,6 +27,7 @@ nym-sphinx = { path = "../../nymsphinx" } nym-pemstore = { path = "../../pemstore" } nym-validator-client = { path = "../validator-client" } nym-task = { path = "../../task" } +nym-noise = { path = "../../nymnoise"} serde = { workspace = true, features = ["derive"] } diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index a6ef774d8f..b82745854e 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -14,24 +14,27 @@ use nym_bandwidth_controller::BandwidthController; use nym_coconut_interface::Credential; use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage; use nym_credential_storage::storage::Storage as CredentialStorage; -use nym_crypto::asymmetric::identity; +use nym_crypto::asymmetric::{encryption, identity}; use nym_gateway_requests::authentication::encrypted_address::EncryptedAddressBytes; use nym_gateway_requests::iv::IV; use nym_gateway_requests::registration::handshake::{client_handshake, SharedKeys}; use nym_gateway_requests::{BinaryRequest, ClientControlRequest, ServerResponse, PROTOCOL_VERSION}; use nym_network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN}; +use nym_noise::upgrade_noise_initiator; use nym_sphinx::forwarding::packet::MixPacket; use nym_task::TaskClient; use rand::rngs::OsRng; use std::convert::TryFrom; +use std::net::SocketAddr; use std::sync::Arc; use std::time::Duration; +use tokio::net::TcpStream; use tungstenite::protocol::Message; #[cfg(not(target_arch = "wasm32"))] use nym_validator_client::nyxd::traits::DkgQueryClient; #[cfg(not(target_arch = "wasm32"))] -use tokio_tungstenite::connect_async; +use tokio_tungstenite::client_async; #[cfg(target_arch = "wasm32")] use nym_bandwidth_controller::wasm_mockups::DkgQueryClient; @@ -49,7 +52,9 @@ pub struct GatewayClient { bandwidth_remaining: i64, gateway_address: String, gateway_identity: identity::PublicKey, + gateway_sphinx: encryption::PublicKey, local_identity: Arc, + local_sphinx: Arc, shared_key: Option>, connection: SocketState, packet_router: PacketRouter, @@ -75,7 +80,9 @@ impl GatewayClient { pub fn new( gateway_address: String, local_identity: Arc, + local_sphinx: Arc, gateway_identity: identity::PublicKey, + gateway_sphinx: encryption::PublicKey, // TODO: make it mandatory. if you don't want to pass it, use `new_init` shared_key: Option>, mixnet_message_sender: MixnetMessageSender, @@ -89,8 +96,10 @@ impl GatewayClient { disabled_credentials_mode: true, bandwidth_remaining: 0, gateway_address, - gateway_identity, local_identity, + local_sphinx, + gateway_identity, + gateway_sphinx, shared_key, connection: SocketState::NotConnected, packet_router: PacketRouter::new(ack_sender, mixnet_message_sender, shutdown.clone()), @@ -163,7 +172,50 @@ impl GatewayClient { #[cfg(not(target_arch = "wasm32"))] pub async fn establish_connection(&mut self) -> Result<(), GatewayClientError> { - let ws_stream = match connect_async(&self.gateway_address).await { + let socket_addr: SocketAddr = self.gateway_address.parse().unwrap(); + let connection_fut = TcpStream::connect(socket_addr); + + //arbitrary TO, it's a POC + let noise_conn = match tokio::time::timeout(Duration::from_secs(5), connection_fut).await { + Ok(stream_res) => match stream_res { + Ok(stream) => { + debug!("Managed to establish connection to gateway"); + let noise_stream = match upgrade_noise_initiator( + stream, + None, //as a client, the gateway cannot know my pub key + &self.local_sphinx.private_key().to_bytes(), + &self.gateway_sphinx.to_bytes(), + ) + .await + { + Ok(noise_stream) => noise_stream, + Err(err) => { + error!( + "Failed to perform Noise handshake with {:?} - {err}", + self.gateway_address + ); + return Err(GatewayClientError::ConnectionNotEstablished); + } + }; + debug!( + "Noise initiator handshake completed for {:?}", + self.gateway_address + ); + noise_stream + } + Err(err) => { + debug!("failed to establish connection to gateway (err: {})", err); + return Err(GatewayClientError::NetworkIoError(err)); + } + }, + Err(_) => { + debug!("failed to connect to {} within 5s", self.gateway_address); + return Err(GatewayClientError::Timeout); + } + }; + let ws_address = format!("ws://{}", self.gateway_address); + + let ws_stream = match client_async(ws_address, noise_conn).await { Ok((ws_stream, _)) => ws_stream, Err(e) => return Err(GatewayClientError::NetworkError(e)), }; @@ -773,7 +825,9 @@ impl GatewayClient { pub fn new_init( gateway_address: String, gateway_identity: identity::PublicKey, + gateway_sphinx: encryption::PublicKey, local_identity: Arc, + local_sphinx: Arc, response_timeout_duration: Duration, ) -> Self { use futures::channel::mpsc; @@ -791,7 +845,9 @@ impl GatewayClient { bandwidth_remaining: 0, gateway_address, gateway_identity, + gateway_sphinx, local_identity, + local_sphinx, shared_key: None, connection: SocketState::NotConnected, packet_router, diff --git a/common/client-libs/gateway-client/src/error.rs b/common/client-libs/gateway-client/src/error.rs index 64414bcf99..39388af847 100644 --- a/common/client-libs/gateway-client/src/error.rs +++ b/common/client-libs/gateway-client/src/error.rs @@ -19,6 +19,9 @@ pub enum GatewayClientError { #[error("There was a network error - {0}")] NetworkError(#[from] WsError), + #[error("There was a network error - {0}")] + NetworkIoError(#[from] io::Error), + // TODO: see if `JsValue` is a reasonable type for this #[cfg(target_arch = "wasm32")] #[error("There was a network error")] diff --git a/common/client-libs/gateway-client/src/socket_state.rs b/common/client-libs/gateway-client/src/socket_state.rs index 0ffbcea034..b82a18c1ac 100644 --- a/common/client-libs/gateway-client/src/socket_state.rs +++ b/common/client-libs/gateway-client/src/socket_state.rs @@ -9,14 +9,13 @@ use futures::stream::{SplitSink, SplitStream}; use futures::{SinkExt, StreamExt}; use log::*; use nym_gateway_requests::registration::handshake::SharedKeys; +use nym_noise::NoiseStream; use nym_task::TaskClient; use std::sync::Arc; use tungstenite::Message; #[cfg(not(target_arch = "wasm32"))] -use tokio::net::TcpStream; -#[cfg(not(target_arch = "wasm32"))] -use tokio_tungstenite::{MaybeTlsStream, WebSocketStream}; +use tokio_tungstenite::WebSocketStream; #[cfg(target_arch = "wasm32")] use wasm_bindgen_futures; @@ -26,7 +25,7 @@ use wasm_utils::websocket::JSWebsocket; // type alias for not having to type the whole thing every single time (and now it makes it easier // to use different types based on compilation target) #[cfg(not(target_arch = "wasm32"))] -type WsConn = WebSocketStream>; +type WsConn = WebSocketStream; #[cfg(target_arch = "wasm32")] type WsConn = JSWebsocket; diff --git a/common/topology/src/gateway.rs b/common/topology/src/gateway.rs index 9602043e42..8b1a10fe73 100644 --- a/common/topology/src/gateway.rs +++ b/common/topology/src/gateway.rs @@ -67,7 +67,7 @@ impl Node { } pub fn clients_address(&self) -> String { - format!("ws://{}:{}", self.host, self.clients_port) + format!("{}:{}", self.host, self.clients_port) } } diff --git a/gateway/src/node/client_handling/websocket/listener.rs b/gateway/src/node/client_handling/websocket/listener.rs index 2cbcae2579..24cbcddfd3 100644 --- a/gateway/src/node/client_handling/websocket/listener.rs +++ b/gateway/src/node/client_handling/websocket/listener.rs @@ -62,49 +62,48 @@ impl Listener { while !shutdown.is_shutdown() { tokio::select! { - biased; - _ = shutdown.recv() => { - log::trace!("client_handling::Listener: received shutdown"); - } - connection = tcp_listener.accept() => { - match connection { - Ok((socket, remote_addr)) => { - trace!("received a socket connection from {remote_addr}"); - // TODO: I think we *REALLY* need a mechanism for having a maximum number of connected - // clients or spawned tokio tasks -> perhaps a worker system? - // let noise_stream = match upgrade_noise_responder( - // socket, - // &self.local_sphinx.public_key().to_bytes(), - // &self.local_sphinx.private_key().to_bytes(), - // None, //connection from client, no remote pub key - // ) - // .await - // { - // Ok(noise_stream) => noise_stream, - // Err(err) => { - // error!("Failed to perform Noise handshake with {remote_addr} - {err}"); - // return; - // } - // }; - let handle = FreshHandler::new( - OsRng, - socket, - // noise_stream, - self.only_coconut_credentials, - outbound_mix_sender.clone(), - Arc::clone(&self.local_identity), - storage.clone(), - active_clients_store.clone(), - Arc::clone(&self.coconut_verifier), - ); - let shutdown = shutdown.clone(); - tokio::spawn(async move { handle.start_handling(shutdown).await }); - } - Err(err) => warn!("failed to get client: {err}"), + biased; + _ = shutdown.recv() => { + log::trace!("client_handling::Listener: received shutdown"); + } + connection = tcp_listener.accept() => { + match connection { + Ok((socket, remote_addr)) => { + trace!("received a socket connection from {remote_addr}"); + // TODO: I think we *REALLY* need a mechanism for having a maximum number of connected + // clients or spawned tokio tasks -> perhaps a worker system? + let noise_stream = match upgrade_noise_responder( + socket, + &self.local_sphinx.public_key().to_bytes(), + &self.local_sphinx.private_key().to_bytes(), + None, //connection from client, no remote pub key + ) + .await + { + Ok(noise_stream) => noise_stream, + Err(err) => { + error!("Failed to perform Noise handshake with {remote_addr} - {err}"); + return; } - } - + }; + let handle = FreshHandler::new( + OsRng, + noise_stream, + self.only_coconut_credentials, + outbound_mix_sender.clone(), + Arc::clone(&self.local_identity), + storage.clone(), + active_clients_store.clone(), + Arc::clone(&self.coconut_verifier), + ); + let shutdown = shutdown.clone(); + tokio::spawn(async move { handle.start_handling(shutdown).await }); } + Err(err) => warn!("failed to get client: {err}"), + } + } + + } } } diff --git a/nym-api/src/network_monitor/mod.rs b/nym-api/src/network_monitor/mod.rs index ae49caf020..da1ff1088e 100644 --- a/nym-api/src/network_monitor/mod.rs +++ b/nym-api/src/network_monitor/mod.rs @@ -105,6 +105,7 @@ impl<'a> NetworkMonitorBuilder<'a> { self.config, gateway_status_update_sender, Arc::clone(&identity_keypair), + Arc::clone(&encryption_keypair), self.config.debug.gateway_sending_rate, bandwidth_controller, self.config.debug.disabled_credentials_mode, @@ -177,6 +178,7 @@ fn new_packet_sender( config: &config::NetworkMonitor, gateways_status_updater: GatewayClientUpdateSender, local_identity: Arc, + local_sphinx: Arc, max_sending_rate: usize, bandwidth_controller: BandwidthController, disabled_credentials_mode: bool, @@ -184,6 +186,7 @@ fn new_packet_sender( PacketSender::new( gateways_status_updater, local_identity, + local_sphinx, config.debug.gateway_response_timeout, config.debug.gateway_connection_timeout, config.debug.max_concurrent_gateway_clients, diff --git a/nym-api/src/network_monitor/monitor/preparer.rs b/nym-api/src/network_monitor/monitor/preparer.rs index b873669f99..b6ca18dcee 100644 --- a/nym-api/src/network_monitor/monitor/preparer.rs +++ b/nym-api/src/network_monitor/monitor/preparer.rs @@ -310,6 +310,7 @@ impl PacketPreparer { GatewayPackets::new( route.gateway_clients_address(), route.gateway_identity(), + route.gateway_sphinx(), mix_packets, ) } @@ -387,6 +388,7 @@ impl PacketPreparer { let route_ext = test_route.test_message_ext(test_nonce); let gateway_address = test_route.gateway_clients_address(); let gateway_identity = test_route.gateway_identity(); + let gateway_sphinx = test_route.gateway_sphinx(); let mut mix_tester = self.ephemeral_mix_tester(test_route); @@ -408,7 +410,9 @@ impl PacketPreparer { let gateway_packets = all_gateway_packets .entry(gateway_identity.to_bytes()) - .or_insert_with(|| GatewayPackets::empty(gateway_address, gateway_identity)); + .or_insert_with(|| { + GatewayPackets::empty(gateway_address, gateway_identity, gateway_sphinx) + }); gateway_packets.push_packets(mix_packets); // and generate test packets for gateways (note the variable recipient) @@ -436,7 +440,9 @@ impl PacketPreparer { // or create a new one let gateway_packets = all_gateway_packets .entry(gateway_identity.to_bytes()) - .or_insert_with(|| GatewayPackets::empty(gateway_address, gateway_identity)); + .or_insert_with(|| { + GatewayPackets::empty(gateway_address, gateway_identity, gateway_sphinx) + }); gateway_packets.push_packets(gateway_mix_packets); } } diff --git a/nym-api/src/network_monitor/monitor/sender.rs b/nym-api/src/network_monitor/monitor/sender.rs index bbf40e6f72..dc12109f14 100644 --- a/nym-api/src/network_monitor/monitor/sender.rs +++ b/nym-api/src/network_monitor/monitor/sender.rs @@ -15,6 +15,7 @@ use log::{debug, info, trace, warn}; use nym_bandwidth_controller::BandwidthController; use nym_config::defaults::REMAINING_BANDWIDTH_THRESHOLD; use nym_credential_storage::persistent_storage::PersistentStorage; +use nym_crypto::asymmetric::encryption; use nym_crypto::asymmetric::identity::{self, PUBLIC_KEY_LENGTH}; use nym_gateway_client::error::GatewayClientError; use nym_gateway_client::{AcknowledgementReceiver, GatewayClient, MixnetMessageReceiver}; @@ -38,6 +39,8 @@ pub(crate) struct GatewayPackets { /// Public key of the target gateway. pub(crate) pub_key: identity::PublicKey, + pub(crate) encryption_key: encryption::PublicKey, + /// All the packets that are going to get sent to the gateway. pub(crate) packets: Vec, } @@ -46,19 +49,26 @@ impl GatewayPackets { pub(crate) fn new( clients_address: String, pub_key: identity::PublicKey, + encryption_key: encryption::PublicKey, packets: Vec, ) -> Self { GatewayPackets { clients_address, pub_key, + encryption_key, packets, } } - pub(crate) fn empty(clients_address: String, pub_key: identity::PublicKey) -> Self { + pub(crate) fn empty( + clients_address: String, + pub_key: identity::PublicKey, + encryption_key: encryption::PublicKey, + ) -> Self { GatewayPackets { clients_address, pub_key, + encryption_key, packets: Vec::new(), } } @@ -79,6 +89,7 @@ impl GatewayPackets { struct FreshGatewayClientData { gateways_status_updater: GatewayClientUpdateSender, local_identity: Arc, + local_sphinx: Arc, gateway_response_timeout: Duration, bandwidth_controller: BandwidthController, disabled_credentials_mode: bool, @@ -134,6 +145,7 @@ impl PacketSender { pub(crate) fn new( gateways_status_updater: GatewayClientUpdateSender, local_identity: Arc, + local_sphinx: Arc, gateway_response_timeout: Duration, gateway_connection_timeout: Duration, max_concurrent_clients: usize, @@ -146,6 +158,7 @@ impl PacketSender { fresh_gateway_client_data: Arc::new(FreshGatewayClientData { gateways_status_updater, local_identity, + local_sphinx, gateway_response_timeout, bandwidth_controller, disabled_credentials_mode, @@ -171,6 +184,7 @@ impl PacketSender { fn new_gateway_client_handle( address: String, identity: identity::PublicKey, + sphinx: encryption::PublicKey, fresh_gateway_client_data: &FreshGatewayClientData, ) -> ( GatewayClientHandle, @@ -187,7 +201,9 @@ impl PacketSender { let mut gateway_client = GatewayClient::new( address, Arc::clone(&fresh_gateway_client_data.local_identity), + Arc::clone(&fresh_gateway_client_data.local_sphinx), identity, + sphinx, None, message_sender, ack_sender, @@ -267,6 +283,7 @@ impl PacketSender { async fn create_new_gateway_client_handle_and_authenticate( address: String, identity: identity::PublicKey, + sphinx: encryption::PublicKey, fresh_gateway_client_data: &FreshGatewayClientData, gateway_connection_timeout: Duration, ) -> Option<( @@ -274,7 +291,7 @@ impl PacketSender { (MixnetMessageReceiver, AcknowledgementReceiver), )> { let (new_client, (message_receiver, ack_receiver)) = - Self::new_gateway_client_handle(address, identity, fresh_gateway_client_data); + Self::new_gateway_client_handle(address, identity, sphinx, fresh_gateway_client_data); // Put this in timeout in case the gateway has incorrectly set their ulimit and our connection // gets stuck in their TCP queue and just hangs on our end but does not terminate @@ -351,6 +368,7 @@ impl PacketSender { Self::create_new_gateway_client_handle_and_authenticate( packets.clients_address, packets.pub_key, + packets.encryption_key, &fresh_gateway_client_data, gateway_connection_timeout, ) diff --git a/nym-api/src/network_monitor/test_route/mod.rs b/nym-api/src/network_monitor/test_route/mod.rs index 48eede18b5..eea322a4dc 100644 --- a/nym-api/src/network_monitor/test_route/mod.rs +++ b/nym-api/src/network_monitor/test_route/mod.rs @@ -3,7 +3,7 @@ use crate::network_monitor::test_packet::NymApiTestMessageExt; use crate::network_monitor::ROUTE_TESTING_TEST_NONCE; -use nym_crypto::asymmetric::identity; +use nym_crypto::asymmetric::{encryption, identity}; use nym_topology::{gateway, mix, NymTopology}; use std::fmt::{Debug, Formatter}; @@ -63,6 +63,10 @@ impl TestRoute { self.gateway().identity_key } + pub(crate) fn gateway_sphinx(&self) -> encryption::PublicKey { + self.gateway().sphinx_key + } + pub(crate) fn topology(&self) -> &NymTopology { &self.nodes }