11// Copyright 2025 - Nym Technologies SA <[email protected] > 22// SPDX-License-Identifier: GPL-3.0-only
3-
3+
44use nym_credential_storage:: persistent_storage:: PersistentStorage ;
55use nym_registration_common:: NymNode ;
66use nym_sdk:: {
@@ -10,24 +10,24 @@ use nym_sdk::{
1010 MixnetClientStorage , OnDiskPersistent , ReplyStorageBackend , StoragePaths , x25519:: KeyPair ,
1111 } ,
1212} ;
13-
13+
1414#[ cfg( unix) ]
1515use std:: os:: fd:: RawFd ;
1616use std:: { path:: PathBuf , sync:: Arc , time:: Duration } ;
1717use tokio_util:: sync:: CancellationToken ;
1818use typed_builder:: TypedBuilder ;
19-
19+
2020use crate :: error:: RegistrationClientError ;
21-
21+
2222const VPN_AVERAGE_PACKET_DELAY : Duration = Duration :: from_millis ( 15 ) ;
2323const MIXNET_CLIENT_STARTUP_TIMEOUT : Duration = Duration :: from_secs ( 30 ) ;
24-
24+
2525#[ derive( Clone ) ]
2626pub struct NymNodeWithKeys {
2727 pub node : NymNode ,
2828 pub keys : Arc < KeyPair > ,
2929}
30-
30+
3131#[ derive( TypedBuilder ) ]
3232pub struct BuilderConfig {
3333 pub entry_node : NymNodeWithKeys ,
@@ -44,27 +44,29 @@ pub struct BuilderConfig {
4444 #[ cfg( unix) ]
4545 pub connection_fd_callback : Arc < dyn Fn ( RawFd ) + Send + Sync > ,
4646}
47-
47+
4848#[ derive( Clone , Default , Debug , Eq , PartialEq ) ]
4949pub struct MixnetClientConfig {
5050 /// Disable Poission process rate limiting of outbound traffic.
51- pub disable_poisson_rate : bool ,
52-
51+ pub disable_real_traffic_poisson_process : bool ,
52+
5353 /// Disable constant rate background loop cover traffic
5454 pub disable_background_cover_traffic : bool ,
55-
55+
5656 /// The minimum performance of mixnodes to use.
5757 pub min_mixnode_performance : Option < u8 > ,
58-
58+
5959 /// The minimum performance of gateways to use.
6060 pub min_gateway_performance : Option < u8 > ,
61+
6162 ///Setting optionally the poisson rate for cover traffic stream
62- pub poisson_rate : Option < u32 > ,
63+ pub loop_cover_traffic_average_delay : Option < Duration > ,
64+
6365 /// Average packet delay in milliseconds.
64- pub average_packet_delay : Option < u32 > ,
65-
66+ pub average_packet_delay : Option < Duration > ,
67+
6668 /// Average message sending delay in milliseconds.
67- pub message_sending_average_delay : Option < u32 > ,
69+ pub message_sending_average_delay : Option < Duration > ,
6870}
6971impl BuilderConfig {
7072 pub fn mixnet_client_debug_config ( & self ) -> DebugConfig {
@@ -74,16 +76,16 @@ impl BuilderConfig {
7476 mixnet_debug_config ( & self . mixnet_client_config )
7577 }
7678 }
77-
79+
7880 pub async fn setup_storage (
7981 & self ,
8082 ) -> Result < Option < ( OnDiskPersistent , PersistentStorage ) > , RegistrationClientError > {
8183 if let Some ( path) = & self . data_path {
8284 tracing:: debug!( "Using custom key storage path: {}" , path. display( ) ) ;
83-
85+
8486 let storage_paths = StoragePaths :: new_from_dir ( path)
8587 . map_err ( |err| RegistrationClientError :: BuildMixnetClient ( Box :: new ( err) ) ) ?;
86-
88+
8789 let mixnet_client_storage = storage_paths
8890 . initialise_persistent_storage ( & self . mixnet_client_debug_config ( ) )
8991 . await
@@ -92,13 +94,13 @@ impl BuilderConfig {
9294 . persistent_credential_storage ( )
9395 . await
9496 . map_err ( |err| RegistrationClientError :: BuildMixnetClient ( Box :: new ( err) ) ) ?;
95-
97+
9698 Ok ( Some ( ( mixnet_client_storage, credential_storage) ) )
9799 } else {
98100 Ok ( None )
99101 }
100102 }
101-
103+
102104 pub async fn build_and_connect_mixnet_client < S > (
103105 self ,
104106 builder : MixnetClientBuilder < S > ,
@@ -118,7 +120,7 @@ impl BuilderConfig {
118120 } else {
119121 RememberMe :: new_mixnet ( )
120122 } ;
121-
123+
122124 let builder = builder
123125 . with_user_agent ( self . user_agent )
124126 . request_gateway ( self . entry_node . node . identity . to_string ( ) )
@@ -128,10 +130,10 @@ impl BuilderConfig {
128130 . no_hostname ( true )
129131 . with_remember_me ( remember_me)
130132 . custom_topology_provider ( self . custom_topology_provider ) ;
131-
133+
132134 #[ cfg( unix) ]
133135 let builder = builder. with_connection_fd_callback ( self . connection_fd_callback ) ;
134-
136+
135137 builder
136138 . build ( )
137139 . map_err ( |err| RegistrationClientError :: BuildMixnetClient ( Box :: new ( err) ) ) ?
@@ -140,12 +142,12 @@ impl BuilderConfig {
140142 . map_err ( |err| RegistrationClientError :: ConnectToMixnet ( Box :: new ( err) ) )
141143 }
142144}
143-
145+
144146fn two_hop_debug_config ( mixnet_client_config : & MixnetClientConfig ) -> DebugConfig {
145147 let mut debug_config = DebugConfig :: default ( ) ;
146-
148+
147149 debug_config. traffic . average_packet_delay = VPN_AVERAGE_PACKET_DELAY ;
148-
150+
149151 // We disable mix hops for the mixnet connection.
150152 debug_config. traffic . disable_mix_hops = true ;
151153 // Always disable poisson process for outbound traffic in wireguard.
@@ -154,60 +156,73 @@ fn two_hop_debug_config(mixnet_client_config: &MixnetClientConfig) -> DebugConfi
154156 . disable_main_poisson_packet_distribution = true ;
155157 // Always disable background cover traffic in wireguard.
156158 debug_config. cover_traffic . disable_loop_cover_traffic_stream = true ;
157-
159+
158160 if let Some ( min_mixnode_performance) = mixnet_client_config. min_mixnode_performance {
159161 debug_config. topology . minimum_mixnode_performance = min_mixnode_performance;
160162 }
161-
163+
162164 if let Some ( min_gateway_performance) = mixnet_client_config. min_gateway_performance {
163165 debug_config. topology . minimum_gateway_performance = min_gateway_performance;
164166 }
165167 if let Some ( avg_packet_ms) = mixnet_client_config. average_packet_delay {
166- debug_config. traffic . average_packet_delay = Duration :: from_millis ( avg_packet_ms as u64 ) ;
167- debug_config. acknowledgements . average_ack_delay = Duration :: from_millis ( avg_packet_ms as u64 ) ;
168-
168+ debug_config. traffic . average_packet_delay = avg_packet_ms;
169+ debug_config. acknowledgements . average_ack_delay = avg_packet_ms;
169170 }
170-
171+
171172 if let Some ( msg_delay_ms) = mixnet_client_config. message_sending_average_delay {
172- debug_config. traffic . message_sending_average_delay = Duration :: from_millis ( msg_delay_ms as u64 ) ;
173- } log_mixnet_client_config ( & debug_config) ;
173+ debug_config. traffic . message_sending_average_delay = msg_delay_ms;
174+ }
175+ log_mixnet_client_config ( & debug_config) ;
174176 debug_config
175177}
176-
178+
177179fn mixnet_debug_config ( mixnet_client_config : & MixnetClientConfig ) -> DebugConfig {
178180 let mut debug_config = DebugConfig :: default ( ) ;
179181 debug_config. traffic . average_packet_delay = VPN_AVERAGE_PACKET_DELAY ;
180-
182+
181183 debug_config
182184 . traffic
183- . disable_main_poisson_packet_distribution = mixnet_client_config. disable_poisson_rate ;
184-
185+ . disable_main_poisson_packet_distribution =
186+ mixnet_client_config. disable_real_traffic_poisson_process ;
187+
185188 debug_config. cover_traffic . disable_loop_cover_traffic_stream =
186189 mixnet_client_config. disable_background_cover_traffic ;
187-
190+
188191 if let Some ( min_mixnode_performance) = mixnet_client_config. min_mixnode_performance {
189192 debug_config. topology . minimum_mixnode_performance = min_mixnode_performance;
190193 }
191-
194+
192195 if let Some ( min_gateway_performance) = mixnet_client_config. min_gateway_performance {
193196 debug_config. topology . minimum_gateway_performance = min_gateway_performance;
194197 }
195198 if let Some ( avg_packet_ms) = mixnet_client_config. average_packet_delay {
196- debug_config. traffic . average_packet_delay = Duration :: from_millis ( avg_packet_ms as u64 ) ;
197- debug_config. acknowledgements . average_ack_delay = Duration :: from_millis ( avg_packet_ms as u64 ) ;
199+ debug_config. traffic . average_packet_delay = avg_packet_ms;
200+ debug_config. acknowledgements . average_ack_delay = avg_packet_ms ;
198201 }
199-
202+
200203 if let Some ( msg_delay_ms) = mixnet_client_config. message_sending_average_delay {
201- debug_config. traffic . message_sending_average_delay = Duration :: from_millis ( msg_delay_ms as u64 ) ;
204+ if msg_delay_ms. is_zero ( ) {
205+ debug_config
206+ . traffic
207+ . disable_main_poisson_packet_distribution = true ;
208+ } else {
209+ debug_config. traffic . message_sending_average_delay = msg_delay_ms;
210+ }
202211 }
203- if let Some ( poisson_rate) = mixnet_client_config. poisson_rate {
204- let duration = std:: time:: Duration :: from_millis ( ( poisson_rate as f64 ) . round ( ) as u64 ) ;
205- debug_config. cover_traffic . loop_cover_traffic_average_delay = duration;
206-
207- } log_mixnet_client_config ( & debug_config) ;
212+ if let Some ( loop_cover_traffic_average_delay) =
213+ mixnet_client_config. loop_cover_traffic_average_delay
214+ {
215+ if loop_cover_traffic_average_delay. is_zero ( ) {
216+ debug_config. cover_traffic . disable_loop_cover_traffic_stream = true ;
217+ } else {
218+ debug_config. cover_traffic . loop_cover_traffic_average_delay =
219+ loop_cover_traffic_average_delay;
220+ }
221+ }
222+ log_mixnet_client_config ( & debug_config) ;
208223 debug_config
209224}
210-
225+
211226fn log_mixnet_client_config ( debug_config : & DebugConfig ) {
212227 tracing:: info!(
213228 "mixnet client poisson rate limiting: {}" ,
@@ -217,35 +232,65 @@ fn log_mixnet_client_config(debug_config: &DebugConfig) {
217232 . disable_main_poisson_packet_distribution
218233 )
219234 ) ;
220-
235+
221236 tracing:: info!(
222237 "mixnet client background loop cover traffic stream: {}" ,
223238 true_to_disabled( debug_config. cover_traffic. disable_loop_cover_traffic_stream)
224239 ) ;
225-
240+
226241 tracing:: info!(
227242 "mixnet client minimum mixnode performance: {}" ,
228243 debug_config. topology. minimum_mixnode_performance,
229244 ) ;
230-
245+
231246 tracing:: info!(
232247 "mixnet client minimum gateway performance: {}" ,
233248 debug_config. topology. minimum_gateway_performance,
234249 ) ;
250+
251+ tracing:: info!(
252+ "mixnet client loop cover traffic average delay: {} ms" ,
253+ debug_config
254+ . cover_traffic
255+ . loop_cover_traffic_average_delay
256+ . as_millis( )
257+ ) ;
258+
259+ tracing:: info!(
260+ "mixnet client average packet delay: {} ms" ,
261+ debug_config. traffic. average_packet_delay. as_millis( )
262+ ) ;
263+
264+ tracing:: info!(
265+ "mixnet client message sending average delay: {} ms" ,
266+ debug_config
267+ . traffic
268+ . message_sending_average_delay
269+ . as_millis( )
270+ ) ;
271+
272+ tracing:: info!(
273+ "mixnet client disable_loop_cover_traffic_average_delay: {}" ,
274+ true_to_disabled(
275+ debug_config
276+ . traffic
277+ . disable_main_poisson_packet_distribution
278+ )
279+ ) ;
235280}
236-
281+
237282fn true_to_disabled ( val : bool ) -> & ' static str {
238283 if val { "disabled" } else { "enabled" }
239284}
240-
285+
241286#[ cfg( test) ]
242287mod tests {
243288 use super :: * ;
244-
289+
245290 #[ test]
246291 fn test_mixnet_client_config_default_values ( ) {
247292 let config = MixnetClientConfig :: default ( ) ;
248- assert ! ( !config. disable_poisson_rate ) ;
293+ assert ! ( !config. disable_real_traffic_poisson_process ) ;
249294 assert ! ( !config. disable_background_cover_traffic) ;
250295 assert_eq ! ( config. min_mixnode_performance, None ) ;
251296 assert_eq ! ( config. min_gateway_performance, None ) ;
0 commit comments