@@ -28,6 +28,10 @@ struct ConfigView {
2828 p2p_socket_addr : String ,
2929 max_concurrent_uni_streams : Option < u64 > ,
3030 max_concurrent_bidi_streams : Option < u64 > ,
31+ p2p_discovery_methods : Vec < String > ,
32+ p2p_discovery_dns_origins : Vec < String > ,
33+ p2p_relay_method : String ,
34+ p2p_relay_urls : Vec < String > ,
3135 bootstrap_nodes : Vec < String > ,
3236 bootstrap_endpoints : Vec < String > ,
3337 default_metadata_replication_factor : u32 ,
@@ -158,6 +162,10 @@ impl ConfigView {
158162 . unwrap_or_else ( |_| http_socket_addr. to_string ( ) ) ,
159163 max_concurrent_uni_streams : parse_optional_env ( "MAX_CONCURRENT_UNI_STREAMS" ) ?,
160164 max_concurrent_bidi_streams : parse_optional_env ( "MAX_CONCURRENT_BIDI_STREAMS" ) ?,
165+ p2p_discovery_methods : discovery_methods_from_env ( ) ?,
166+ p2p_discovery_dns_origins : parse_list_env ( "P2P_DISCOVERY_DNS_ORIGINS" ) ,
167+ p2p_relay_method : relay_method_from_env ( ) ?,
168+ p2p_relay_urls : parse_list_env ( "P2P_RELAY_URLS" ) ,
161169 bootstrap_nodes : parse_list_env ( "BOOTSTRAP_NODES" ) ,
162170 bootstrap_endpoints : parse_list_env ( "BOOTSTRAP_ENDPOINTS" ) ,
163171 default_metadata_replication_factor : parse_optional_env ( "METADATA_REPLICATION_FACTOR" ) ?
@@ -208,6 +216,56 @@ fn parse_list_env(key: &str) -> Vec<String> {
208216 . collect ( )
209217}
210218
219+ fn discovery_methods_from_env ( ) -> Result < Vec < String > , CliError > {
220+ let value = optional_env ( "P2P_DISCOVERY_METHOD" ) . unwrap_or_else ( || "none" . to_string ( ) ) ;
221+ match normalize_env_value ( & value) . as_str ( ) {
222+ "none" => Ok ( Vec :: new ( ) ) ,
223+ "n0" | "n0_dns" => Ok ( vec ! [ "n0_dns" . to_string( ) ] ) ,
224+ "custom_dns" => Ok ( vec ! [ "custom_dns" . to_string( ) ] ) ,
225+ _ => Err ( invalid_config_value (
226+ "P2P_DISCOVERY_METHOD" ,
227+ value,
228+ "expected one of none, n0, n0_dns, custom_dns" ,
229+ ) ) ,
230+ }
231+ }
232+
233+ fn relay_method_from_env ( ) -> Result < String , CliError > {
234+ let value = optional_env ( "P2P_RELAY_METHOD" ) . unwrap_or_else ( || "none" . to_string ( ) ) ;
235+ match normalize_env_value ( & value) . as_str ( ) {
236+ "none" => Ok ( "none" . to_string ( ) ) ,
237+ "n0" => Ok ( "n0" . to_string ( ) ) ,
238+ "custom" => Ok ( "custom" . to_string ( ) ) ,
239+ _ => Err ( invalid_config_value (
240+ "P2P_RELAY_METHOD" ,
241+ value,
242+ "expected one of none, n0, custom" ,
243+ ) ) ,
244+ }
245+ }
246+
247+ fn optional_env ( key : & str ) -> Option < String > {
248+ dotenvy:: var ( key)
249+ . ok ( )
250+ . filter ( |value| !value. trim ( ) . is_empty ( ) )
251+ }
252+
253+ fn normalize_env_value ( value : & str ) -> String {
254+ value. trim ( ) . to_ascii_lowercase ( ) . replace ( '-' , "_" )
255+ }
256+
257+ fn invalid_config_value (
258+ key : & ' static str ,
259+ value : impl Into < String > ,
260+ message : impl std:: fmt:: Display ,
261+ ) -> CliError {
262+ CliError :: InvalidConfigValue {
263+ key,
264+ value : value. into ( ) ,
265+ message : message. to_string ( ) ,
266+ }
267+ }
268+
211269fn env_key ( id : & str ) -> String {
212270 id. to_ascii_uppercase ( ) . replace ( '-' , "_" )
213271}
@@ -397,6 +455,28 @@ mod tests {
397455
398456 assert_eq ! ( view. http_base_url, "http://127.0.0.1:3000" ) ;
399457 assert ! ( view. onboarding_secret_present) ;
458+ assert ! ( view. p2p_discovery_methods. is_empty( ) ) ;
459+ assert_eq ! ( view. p2p_relay_method, "none" ) ;
460+ }
461+
462+ #[ tokio:: test]
463+ async fn config_view_reports_p2p_discovery_and_relay_config ( ) {
464+ let _env_lock = env_lock ( ) . lock ( ) . await ;
465+ let _guard = TestEnvGuard :: set ( & [
466+ ( "P2P_DISCOVERY_METHOD" , "n0" . to_string ( ) ) ,
467+ ( "P2P_RELAY_METHOD" , "custom" . to_string ( ) ) ,
468+ ( "P2P_RELAY_URLS" , "https://relay.example.com" . to_string ( ) ) ,
469+ ( "BOOTSTRAP_ENDPOINTS" , "node.example.invalid" . to_string ( ) ) ,
470+ ] ) ;
471+ let view = ConfigView :: from_env ( "0.0.0.0:3000" . parse ( ) . unwrap ( ) ) . unwrap ( ) ;
472+
473+ assert_eq ! ( view. p2p_discovery_methods, vec![ "n0_dns" ] ) ;
474+ assert_eq ! ( view. p2p_relay_method, "custom" ) ;
475+ assert_eq ! (
476+ view. p2p_relay_urls,
477+ vec![ "https://relay.example.com" . to_string( ) ]
478+ ) ;
479+ assert_eq ! ( view. bootstrap_endpoints, vec![ "node.example.invalid" ] ) ;
400480 }
401481
402482 #[ tokio:: test]
@@ -410,6 +490,8 @@ mod tests {
410490 info. net_state. status,
411491 aruna_api:: routes:: info:: ServiceStatus :: Available
412492 ) ;
493+ assert ! ( info. net_state. discovery_methods. is_empty( ) ) ;
494+ assert_eq ! ( info. net_state. relay_method. as_deref( ) , Some ( "none" ) ) ;
413495 assert_eq ! (
414496 info. interface_status. rest. status,
415497 aruna_api:: routes:: info:: ServiceStatus :: Available
0 commit comments