diff --git a/sdk/rust/nym-sdk/src/error.rs b/sdk/rust/nym-sdk/src/error.rs index 3fb9f727a6..96b172a51e 100644 --- a/sdk/rust/nym-sdk/src/error.rs +++ b/sdk/rust/nym-sdk/src/error.rs @@ -165,6 +165,9 @@ pub enum Error { #[error("Could not find peer address or surb tag")] MixStreamNoPeerOrSurb, + + #[error("No network env specified on new MixStream")] + MissingStreamConfig, } impl Error { diff --git a/sdk/rust/nym-sdk/src/stream_wrapper.rs b/sdk/rust/nym-sdk/src/stream_wrapper.rs index c13ec4aa68..881810d432 100644 --- a/sdk/rust/nym-sdk/src/stream_wrapper.rs +++ b/sdk/rust/nym-sdk/src/stream_wrapper.rs @@ -5,6 +5,8 @@ mod mixnet_stream_wrapper; mod mixnet_stream_wrapper_ipr; +mod network_env; pub use mixnet_stream_wrapper::{MixSocket, MixStream, MixStreamReader, MixStreamWriter}; pub use mixnet_stream_wrapper_ipr::{IpMixStream, IpMixStreamReader, IpMixStreamWriter}; +pub use network_env::NetworkEnvironment; diff --git a/sdk/rust/nym-sdk/src/stream_wrapper/mixnet_stream_wrapper.rs b/sdk/rust/nym-sdk/src/stream_wrapper/mixnet_stream_wrapper.rs index 4de13db33b..8fd7faf4c4 100644 --- a/sdk/rust/nym-sdk/src/stream_wrapper/mixnet_stream_wrapper.rs +++ b/sdk/rust/nym-sdk/src/stream_wrapper/mixnet_stream_wrapper.rs @@ -11,6 +11,7 @@ use nym_network_defaults::setup_env; use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag; use nym_sphinx::receiver::{ReconstructedMessage, ReconstructedMessageCodec}; use std::io; +use std::path::PathBuf; use std::pin::Pin; use std::task::{Context, Poll}; use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt, ReadBuf}; @@ -18,7 +19,6 @@ use tokio::sync::oneshot; use tokio_util::codec::{Encoder, Framed, FramedRead, FramedWrite}; use tracing::{debug, info, warn}; -/// High-level methods for MixnetClient impl MixnetClient { /// Send data to a recipient with reply SURBs. /// @@ -130,7 +130,6 @@ impl MixnetClient { } } -/// High-level methods for MixnetClientSender impl MixnetClientSender { /// Send data to a recipient with optional reply SURBs. /// @@ -192,10 +191,10 @@ impl MixSocket { /// /// Initializes a new mixnet client and prepares it for connections. /// # Arguments - /// * `env` - The environment to use. Defaults to Mainnet if None. - pub async fn new(env: Option) -> Result { + /// * `env` - The environment to use. + pub async fn new(env: PathBuf) -> Result { debug!("Loading env file: {:?}", env); - setup_env(env); + setup_env(Some(env)); let inner = MixnetClient::connect_new().await?; Ok(MixSocket { inner }) } @@ -284,25 +283,27 @@ impl MixStream { /// # Arguments /// * `socket` - Optional existing socket to use /// * `peer` - Optional Nym address to connect to (None = listening mode) - /// * `env` - The environment to use. Defaults to Mainnet if `None`. TODO MAKE PATH AND MAKE MORE CLEAR IN DOCS + /// * `env` - Optional environment to use. Required if not passing in an existing `socket`. pub async fn new( socket: Option, peer: Option, - env: Option, - ) -> Self { + env: Option, + ) -> Result { let client = match socket { Some(socket) => socket.into_inner(), None => { - debug!("Loading env file: {:?}", env); + if env.is_none() { + return Err(Error::MissingStreamConfig); + } setup_env(env); MixnetClient::connect_new().await.unwrap() } }; - Self { + Ok(Self { client, peer, peer_surb_tag: None, - } + }) } /// Create a listening stream that receives from anyone. @@ -322,9 +323,9 @@ impl MixStream { /// listener.send(b"Response").await?; /// } /// ``` - pub async fn listen(env: Option) -> Result { + pub async fn listen(env: PathBuf) -> Result { debug!("Loading env file: {:?}", env); - setup_env(env); + setup_env(Some(env)); let client = MixnetClient::connect_new().await?; Ok(Self { client, @@ -339,10 +340,10 @@ impl MixStream { /// /// # Arguments /// * `peer` - The Nym address to connect to - /// * `env` - The environment to use. Defaults to Mainnet if None - pub async fn connect(peer: Recipient, env: Option) -> Result { + /// * `env` - The environment to use. + pub async fn connect(peer: Recipient, env: PathBuf) -> Result { debug!("Loading env file: {:?}", env); - setup_env(env.clone()); + setup_env(Some(env.clone())); let socket = MixSocket::new(env).await?; Ok(socket.connect(peer).await?) } @@ -848,8 +849,9 @@ impl AsyncWrite for MixStreamWriter { #[cfg(test)] mod tests { - use super::*; + use crate::stream_wrapper::network_env::NetworkEnvironment; + use futures::StreamExt; use std::sync::Once; static INIT: Once = Once::new(); @@ -863,13 +865,6 @@ mod tests { }); } - impl MixSocket { - pub async fn new_test() -> Result { - let inner = MixnetClient::connect_new().await?; - Ok(MixSocket { inner }) - } - } - // #[tokio::test] // async fn change_network() -> Result<(), Box> { // init_logging(); @@ -886,19 +881,21 @@ mod tests { async fn simple_send_recv() -> Result<(), Box> { init_logging(); + let env = NetworkEnvironment::Mainnet; + // Create listener (no peer) - let listener_socket = MixSocket::new_test().await?; + let listener_socket = MixSocket::new(env.env_file_path()).await?; let listener_address = *listener_socket.local_addr(); let mut listener_stream = listener_socket.into_stream(); // Create sender connected to listener - let mut sender_stream = MixStream::connect(listener_address, None).await?; + let mut sender_stream = MixStream::connect(listener_address, env.env_file_path()).await?; - // Sender initiates with SURBs + // Sender initiates sender_stream.send(b"Hello, Mixnet!").await?; info!("Sent initial message"); - // Listener receives and extracts SURB + // Listener receives and extracts SURB tag let msg = tokio::time::timeout(tokio::time::Duration::from_secs(30), listener_stream.recv()) .await??; @@ -927,13 +924,14 @@ mod tests { #[tokio::test] async fn framed() -> Result<(), Box> { init_logging(); - use futures::StreamExt; - let receiver_socket = MixSocket::new_test().await?; + let env = NetworkEnvironment::Mainnet; + + let receiver_socket = MixSocket::new(env.env_file_path()).await?; let receiver_address = *receiver_socket.local_addr(); let mut receiver_stream = receiver_socket.into_stream(); - let sender_socket = MixSocket::new_test().await?; + let sender_socket = MixSocket::new(env.env_file_path()).await?; let sender_stream = sender_socket.connect(receiver_address).await?; let (sender_reader, mut sender_writer) = sender_stream.split(); @@ -968,11 +966,15 @@ mod tests { async fn split_concurrent() -> Result<(), Box> { init_logging(); - let sender_socket = MixSocket::new_test().await?; - let receiver_socket = MixSocket::new_test().await?; + let env = NetworkEnvironment::Mainnet; + + let sender_socket = MixSocket::new(env.env_file_path()).await?; + let receiver_socket = MixSocket::new(env.env_file_path()).await?; let receiver_address = *receiver_socket.local_addr(); - let sender_stream = MixStream::new(Some(sender_socket), Some(receiver_address), None).await; + // Passing no env var to MixStream since we're passing a socket that is already configured to use Mainnet + let sender_stream = + MixStream::new(Some(sender_socket), Some(receiver_address), None).await?; let receiver_stream = receiver_socket.into_stream(); let (mut sender_reader, mut sender_writer) = sender_stream.split(); diff --git a/sdk/rust/nym-sdk/src/stream_wrapper/mixnet_stream_wrapper_ipr.rs b/sdk/rust/nym-sdk/src/stream_wrapper/mixnet_stream_wrapper_ipr.rs index 5e6591e03b..022e469feb 100644 --- a/sdk/rust/nym-sdk/src/stream_wrapper/mixnet_stream_wrapper_ipr.rs +++ b/sdk/rust/nym-sdk/src/stream_wrapper/mixnet_stream_wrapper_ipr.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use super::mixnet_stream_wrapper::{MixStream, MixStreamReader, MixStreamWriter}; +use super::network_env::NetworkEnvironment; use crate::ip_packet_client::{ helpers::check_ipr_message_version, IprListener, MixnetMessageOutcome, }; @@ -10,6 +11,8 @@ use crate::{mixnet::Recipient, Error}; use std::collections::HashMap; use bytes::Bytes; +use futures::StreamExt; +use nym_crypto::asymmetric::ed25519; use nym_ip_packet_requests::{ v8::{ request::IpPacketRequest, @@ -17,12 +20,8 @@ use nym_ip_packet_requests::{ }, IpPair, }; -use nym_network_defaults::setup_env; -use nym_sphinx::receiver::ReconstructedMessageCodec; - -use futures::StreamExt; -use nym_crypto::asymmetric::ed25519; use nym_network_defaults::ApiUrl; +use nym_sphinx::receiver::ReconstructedMessageCodec; use nym_validator_client::nym_api::NymApiClientExt; use std::io; use std::pin::Pin; @@ -195,16 +194,17 @@ impl IpMixStream { /// /// # Returns /// New `IpMixStream` instance ready to connect - pub async fn new() -> Result { - // JS: I think you need some bootstrapping here, something would need to be passed to `new()` - // to indicate what endpoints to use - // again, for now I'm default to mainnet as you did before - let mainnet_network_defaults = crate::NymNetworkDetails::new_mainnet(); - let api_client = - create_nym_api_client(mainnet_network_defaults.nym_api_urls.unwrap_or_default())?; + pub async fn new(env: NetworkEnvironment) -> Result { + let network_defaults = env.network_defaults(); + let api_client = create_nym_api_client(network_defaults.nym_api_urls.unwrap_or_default())?; let ipr_address = get_random_ipr(api_client).await?; - let stream = MixStream::new(None, Some(Recipient::from(ipr_address)), None).await; + let stream = MixStream::new( + None, + Some(Recipient::from(ipr_address)), + Some(env.env_file_path()), + ) + .await?; Ok(Self { stream, @@ -743,7 +743,7 @@ mod tests { async fn connect_to_ipr() -> Result<(), Box> { init_logging(); - let mut stream = IpMixStream::new().await?; + let mut stream = IpMixStream::new(NetworkEnvironment::Mainnet).await?; let ip_pair = stream.connect_tunnel().await?; let ipv4: Ipv4Addr = ip_pair.ipv4; @@ -767,7 +767,7 @@ mod tests { async fn dns_ping_checks() -> Result<(), Box> { init_logging(); - let mut stream = IpMixStream::new().await?; + let mut stream = IpMixStream::new(NetworkEnvironment::Mainnet).await?; let ip_pair = stream.connect_tunnel().await?; info!( @@ -879,7 +879,7 @@ mod tests { async fn split_dns_ping_checks() -> Result<(), Box> { init_logging(); - let mut stream = IpMixStream::new().await?; + let mut stream = IpMixStream::new(NetworkEnvironment::Mainnet).await?; let ip_pair = stream.connect_tunnel().await?; info!(