@@ -64,6 +64,7 @@ pub struct Config {
6464 pub poll_metrics_interval : Option < u64 > ,
6565 pub metrics_username : Option < String > ,
6666 pub metrics_password : Option < String > ,
67+ pub tor_config : Option < TorConfig > ,
6768}
6869
6970#[ derive( Debug , Clone , PartialEq , Eq ) ]
@@ -87,6 +88,11 @@ pub enum ChainSource {
8788 Esplora { server_url : String } ,
8889}
8990
91+ #[ derive( Debug , PartialEq , Eq ) ]
92+ pub struct TorConfig {
93+ pub proxy_address : SocketAddress ,
94+ }
95+
9096/// A builder for `Config`.
9197#[ derive( Default ) ]
9298struct ConfigBuilder {
@@ -113,6 +119,7 @@ struct ConfigBuilder {
113119 poll_metrics_interval : Option < u64 > ,
114120 metrics_username : Option < String > ,
115121 metrics_password : Option < String > ,
122+ tor_proxy_address : Option < String > ,
116123}
117124
118125impl ConfigBuilder {
@@ -180,6 +187,10 @@ impl ConfigBuilder {
180187 self . metrics_username = metrics. username . or ( self . metrics_username . clone ( ) ) ;
181188 self . metrics_password = metrics. password . or ( self . metrics_password . clone ( ) ) ;
182189 }
190+
191+ if let Some ( tor) = toml. tor {
192+ self . tor_proxy_address = Some ( tor. proxy_address )
193+ }
183194 }
184195
185196 fn merge_args ( & mut self , args : & ArgsConfig ) {
@@ -238,6 +249,10 @@ impl ConfigBuilder {
238249 if let Some ( metrics_password) = & args. metrics_password {
239250 self . metrics_password = Some ( metrics_password. clone ( ) ) ;
240251 }
252+
253+ if let Some ( tor_proxy_address) = & args. tor_proxy_address {
254+ self . tor_proxy_address = Some ( tor_proxy_address. clone ( ) ) ;
255+ }
241256 }
242257
243258 fn build ( self ) -> io:: Result < Config > {
@@ -410,6 +425,18 @@ impl ConfigBuilder {
410425 "Both `metrics.username` and `metrics.password` must be set if authentication is used for metrics." ) ) ;
411426 }
412427
428+ let tor_proxy_address: Option < SocketAddress > = self
429+ . tor_proxy_address
430+ . map ( |addrs| {
431+ SocketAddress :: from_str ( & addrs) . map_err ( |e| {
432+ io:: Error :: new (
433+ io:: ErrorKind :: InvalidInput ,
434+ format ! ( "Invalid proxy address configured: {}" , e) ,
435+ )
436+ } )
437+ } )
438+ . transpose ( ) ?;
439+
413440 Ok ( Config {
414441 network,
415442 listening_addrs,
@@ -431,6 +458,7 @@ impl ConfigBuilder {
431458 poll_metrics_interval,
432459 metrics_username,
433460 metrics_password,
461+ tor_config : tor_proxy_address. map ( |proxy_address| TorConfig { proxy_address } ) ,
434462 } )
435463 }
436464}
@@ -448,6 +476,7 @@ pub struct TomlConfig {
448476 log : Option < LogConfig > ,
449477 tls : Option < TomlTlsConfig > ,
450478 metrics : Option < MetricsTomlConfig > ,
479+ tor : Option < TomlTorConfig > ,
451480}
452481
453482#[ derive( Deserialize , Serialize ) ]
@@ -515,6 +544,11 @@ struct MetricsTomlConfig {
515544 password : Option < String > ,
516545}
517546
547+ #[ derive( Deserialize , Serialize ) ]
548+ struct TomlTorConfig {
549+ proxy_address : String ,
550+ }
551+
518552#[ derive( Deserialize , Serialize ) ]
519553struct LiquidityConfig {
520554 lsps2_client : Option < LSPSClientTomlConfig > ,
@@ -702,6 +736,13 @@ pub struct ArgsConfig {
702736 help = "The password required to access the metrics endpoint (Basic Auth)."
703737 ) ]
704738 metrics_password : Option < String > ,
739+
740+ #[ arg(
741+ long,
742+ env = "LDK_SERVER_TOR_PROXY_ADDRESS" ,
743+ help = "Tor daemon SOCKS proxy address. Only connections to OnionV3 peers will be made via this proxy; other connections (IPv4 peers, Electrum server) will not be routed over Tor."
744+ ) ]
745+ tor_proxy_address : Option < String > ,
705746}
706747
707748pub fn load_config ( args : & ArgsConfig ) -> io:: Result < Config > {
@@ -820,6 +861,9 @@ mod tests {
820861 min_payment_size_msat = 10000000 # 10,000 satoshis
821862 max_payment_size_msat = 25000000000 # 0.25 BTC
822863 client_trusts_lsp = true
864+
865+ [tor]
866+ proxy_address = "127.0.0.1:9050"
823867 "# ;
824868
825869 fn default_args_config ( ) -> ArgsConfig {
@@ -839,6 +883,7 @@ mod tests {
839883 poll_metrics_interval : None ,
840884 metrics_username : None ,
841885 metrics_password : None ,
886+ tor_proxy_address : None ,
842887 }
843888 }
844889
@@ -859,6 +904,7 @@ mod tests {
859904 poll_metrics_interval : None ,
860905 metrics_username : None ,
861906 metrics_password : None ,
907+ tor_proxy_address : None ,
862908 }
863909 }
864910
@@ -939,6 +985,9 @@ mod tests {
939985 poll_metrics_interval : None ,
940986 metrics_username : None ,
941987 metrics_password : None ,
988+ tor_config : Some ( TorConfig {
989+ proxy_address : SocketAddress :: from_str ( "127.0.0.1:9050" ) . unwrap ( ) ,
990+ } ) ,
942991 } ;
943992
944993 assert_eq ! ( config. listening_addrs, expected. listening_addrs) ;
@@ -958,6 +1007,7 @@ mod tests {
9581007 assert_eq ! ( config. log_file_path, expected. log_file_path) ;
9591008 assert_eq ! ( config. pathfinding_scores_source_url, expected. pathfinding_scores_source_url) ;
9601009 assert_eq ! ( config. metrics_enabled, expected. metrics_enabled) ;
1010+ assert_eq ! ( config. tor_config, expected. tor_config) ;
9611011
9621012 // Test case where only electrum is set
9631013
@@ -1267,6 +1317,7 @@ mod tests {
12671317 poll_metrics_interval : None ,
12681318 metrics_username : None ,
12691319 metrics_password : None ,
1320+ tor_config : None ,
12701321 } ;
12711322
12721323 assert_eq ! ( config. listening_addrs, expected. listening_addrs) ;
@@ -1281,6 +1332,7 @@ mod tests {
12811332 assert ! ( config. lsps2_service_config. is_none( ) ) ;
12821333 assert_eq ! ( config. pathfinding_scores_source_url, expected. pathfinding_scores_source_url) ;
12831334 assert_eq ! ( config. metrics_enabled, expected. metrics_enabled) ;
1335+ assert_eq ! ( config. tor_config, expected. tor_config) ;
12841336 }
12851337
12861338 #[ test]
@@ -1383,6 +1435,9 @@ mod tests {
13831435 poll_metrics_interval : None ,
13841436 metrics_username : None ,
13851437 metrics_password : None ,
1438+ tor_config : Some ( TorConfig {
1439+ proxy_address : SocketAddress :: from_str ( "127.0.0.1:9050" ) . unwrap ( ) ,
1440+ } ) ,
13861441 } ;
13871442
13881443 assert_eq ! ( config. listening_addrs, expected. listening_addrs) ;
@@ -1399,6 +1454,7 @@ mod tests {
13991454 assert_eq ! ( config. lsps2_service_config. is_some( ) , expected. lsps2_service_config. is_some( ) ) ;
14001455 assert_eq ! ( config. pathfinding_scores_source_url, expected. pathfinding_scores_source_url) ;
14011456 assert_eq ! ( config. metrics_enabled, expected. metrics_enabled) ;
1457+ assert_eq ! ( config. tor_config, expected. tor_config) ;
14021458 }
14031459
14041460 #[ test]
0 commit comments