diff --git a/Cargo.toml b/Cargo.toml index 619fa9008..e2e4f6c48 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,18 +41,18 @@ default = [] # lightning-liquidity = { version = "0.2.0", features = ["std"] } # lightning-macros = { version = "0.2.0" } -# Branch: https://github.com/moneydevkit/rust-lightning/tree/lsp-0.2.0_accept-underpaying-htlcs_with_timing_logs -lightning = { git = "https://github.com/moneydevkit/rust-lightning", rev = "070b31d93ca28a80a204e9ddf540eb7767b72611", features = ["std"] } -lightning-types = { git = "https://github.com/moneydevkit/rust-lightning", rev = "070b31d93ca28a80a204e9ddf540eb7767b72611" } -lightning-invoice = { git = "https://github.com/moneydevkit/rust-lightning", rev = "070b31d93ca28a80a204e9ddf540eb7767b72611", features = ["std"] } -lightning-net-tokio = { git = "https://github.com/moneydevkit/rust-lightning", rev = "070b31d93ca28a80a204e9ddf540eb7767b72611" } -lightning-persister = { git = "https://github.com/moneydevkit/rust-lightning", rev = "070b31d93ca28a80a204e9ddf540eb7767b72611", features = ["tokio"] } -lightning-background-processor = { git = "https://github.com/moneydevkit/rust-lightning", rev = "070b31d93ca28a80a204e9ddf540eb7767b72611" } -lightning-rapid-gossip-sync = { git = "https://github.com/moneydevkit/rust-lightning", rev = "070b31d93ca28a80a204e9ddf540eb7767b72611" } -lightning-block-sync = { git = "https://github.com/moneydevkit/rust-lightning", rev = "070b31d93ca28a80a204e9ddf540eb7767b72611", features = ["rest-client", "rpc-client", "tokio"] } -lightning-transaction-sync = { git = "https://github.com/moneydevkit/rust-lightning", rev = "070b31d93ca28a80a204e9ddf540eb7767b72611", features = ["esplora-async-https", "time", "electrum-rustls-ring"] } -lightning-liquidity = { git = "https://github.com/moneydevkit/rust-lightning", rev = "070b31d93ca28a80a204e9ddf540eb7767b72611", features = ["std"] } -lightning-macros = { git = "https://github.com/moneydevkit/rust-lightning", rev = "070b31d93ca28a80a204e9ddf540eb7767b72611" } +# Branch: https://github.com/moneydevkit/rust-lightning/tree/lsp-0.2.0_socks-support +lightning = { git = "https://github.com/moneydevkit/rust-lightning", rev = "adf445e5d5e5c9f0f3c0e3925989404707e06e3f", features = ["std"] } +lightning-types = { git = "https://github.com/moneydevkit/rust-lightning", rev = "adf445e5d5e5c9f0f3c0e3925989404707e06e3f" } +lightning-invoice = { git = "https://github.com/moneydevkit/rust-lightning", rev = "adf445e5d5e5c9f0f3c0e3925989404707e06e3f", features = ["std"] } +lightning-net-tokio = { git = "https://github.com/moneydevkit/rust-lightning", rev = "adf445e5d5e5c9f0f3c0e3925989404707e06e3f", features = ["socks"] } +lightning-persister = { git = "https://github.com/moneydevkit/rust-lightning", rev = "adf445e5d5e5c9f0f3c0e3925989404707e06e3f", features = ["tokio"] } +lightning-background-processor = { git = "https://github.com/moneydevkit/rust-lightning", rev = "adf445e5d5e5c9f0f3c0e3925989404707e06e3f" } +lightning-rapid-gossip-sync = { git = "https://github.com/moneydevkit/rust-lightning", rev = "adf445e5d5e5c9f0f3c0e3925989404707e06e3f" } +lightning-block-sync = { git = "https://github.com/moneydevkit/rust-lightning", rev = "adf445e5d5e5c9f0f3c0e3925989404707e06e3f", features = ["rest-client", "rpc-client", "tokio"] } +lightning-transaction-sync = { git = "https://github.com/moneydevkit/rust-lightning", rev = "adf445e5d5e5c9f0f3c0e3925989404707e06e3f", features = ["esplora-async-https", "time", "electrum-rustls-ring"] } +lightning-liquidity = { git = "https://github.com/moneydevkit/rust-lightning", rev = "adf445e5d5e5c9f0f3c0e3925989404707e06e3f", features = ["std"] } +lightning-macros = { git = "https://github.com/moneydevkit/rust-lightning", rev = "adf445e5d5e5c9f0f3c0e3925989404707e06e3f" } #lightning = { path = "../rust-lightning/lightning", features = ["std"] } #lightning-types = { path = "../rust-lightning/lightning-types" } @@ -100,8 +100,8 @@ winapi = { version = "0.3", features = ["winbase"] } [dev-dependencies] # lightning = { version = "0.2.0", features = ["std", "_test_utils"] } -# Branch: https://github.com/moneydevkit/rust-lightning/commits/lsp-0.2.0_accept-underpaying-htlcs -lightning = { git = "https://github.com/moneydevkit/rust-lightning", rev = "070b31d93ca28a80a204e9ddf540eb7767b72611", features = ["std", "_test_utils"] } +# Branch: https://github.com/moneydevkit/rust-lightning/commits/lsp-0.2.0_socks-support +lightning = { git = "https://github.com/moneydevkit/rust-lightning", rev = "adf445e5d5e5c9f0f3c0e3925989404707e06e3f", features = ["std", "_test_utils"] } #lightning = { path = "../rust-lightning/lightning", features = ["std", "_test_utils"] } proptest = "1.0.0" regex = "1.5.6" diff --git a/src/builder.rs b/src/builder.rs index ddb298add..cbf67195c 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -605,6 +605,12 @@ impl NodeBuilder { Ok(self) } + /// Sets the SOCKS5 proxy address for all outbound connections. + pub fn set_socks5_proxy(&mut self, addr: std::net::SocketAddr) -> &mut Self { + self.config.socks5_proxy_addr = Some(addr); + self + } + /// Sets the role of the node in an asynchronous payments context. /// /// See for more information about the async payments protocol. @@ -1126,6 +1132,11 @@ impl ArcedNodeBuilder { self.inner.write().unwrap().set_node_alias(node_alias).map(|_| ()) } + /// Sets the SOCKS5 proxy address for all outbound connections. + pub fn set_socks5_proxy(&self, addr: std::net::SocketAddr) { + self.inner.write().unwrap().set_socks5_proxy(addr); + } + /// Sets the role of the node in an asynchronous payments context. pub fn set_async_payments_role( &self, role: Option, @@ -1922,7 +1933,7 @@ fn build_with_store_internal( ); let connection_manager = - Arc::new(ConnectionManager::new(Arc::clone(&peer_manager), Arc::clone(&logger))); + Arc::new(ConnectionManager::new(Arc::clone(&peer_manager), config.socks5_proxy_addr, Arc::clone(&logger))); // read_output_sweeper (peer_info was already read in the spawned group above) let step_start = Instant::now(); diff --git a/src/chain/esplora.rs b/src/chain/esplora.rs index 82dc69ad4..ebda12eaa 100644 --- a/src/chain/esplora.rs +++ b/src/chain/esplora.rs @@ -57,6 +57,10 @@ impl EsploraChainSource { client_builder = client_builder.header(header_name, header_value); } + if let Some(proxy_addr) = config.socks5_proxy_addr { + client_builder = client_builder.proxy(&format!("socks5://{}", proxy_addr)); + } + let esplora_client = client_builder.build_async().unwrap(); let tx_sync = Arc::new(EsploraSyncClient::from_client(esplora_client.clone(), Arc::clone(&logger))); diff --git a/src/config.rs b/src/config.rs index 510bcc875..2b5b6905a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,6 +8,7 @@ //! Objects for configuring the node. use std::fmt; +use std::net::SocketAddr; use std::time::Duration; use bitcoin::secp256k1::PublicKey; @@ -184,6 +185,11 @@ pub struct Config { /// **Note:** If unset, default parameters will be used, and you will be able to override the /// parameters on a per-payment basis in the corresponding method calls. pub route_parameters: Option, + /// Optional SOCKS5 proxy address for all outbound connections (peer, Esplora, Electrum). + /// + /// When set, Lightning peer connections and chain-source HTTP requests will be routed + /// through the given SOCKS5 proxy. + pub socks5_proxy_addr: Option, } impl Default for Config { @@ -198,6 +204,7 @@ impl Default for Config { anchor_channels_config: Some(AnchorChannelsConfig::default()), route_parameters: None, node_alias: None, + socks5_proxy_addr: None, } } } diff --git a/src/connection.rs b/src/connection.rs index e3a25f357..7ef6eb17a 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -6,8 +6,10 @@ // accordance with one or both of these licenses. use std::collections::hash_map::{self, HashMap}; -use std::net::ToSocketAddrs; +use std::future::Future; +use std::net::{SocketAddr, ToSocketAddrs}; use std::ops::Deref; +use std::pin::Pin; use std::sync::{Arc, Mutex}; use std::time::Duration; @@ -25,6 +27,7 @@ where pending_connections: Mutex>>>>, peer_manager: Arc, + socks5_proxy_addr: Option, logger: L, } @@ -32,9 +35,11 @@ impl ConnectionManager where L::Target: LdkLogger, { - pub(crate) fn new(peer_manager: Arc, logger: L) -> Self { + pub(crate) fn new( + peer_manager: Arc, socks5_proxy_addr: Option, logger: L, + ) -> Self { let pending_connections = Mutex::new(HashMap::new()); - Self { pending_connections, peer_manager, logger } + Self { pending_connections, peer_manager, socks5_proxy_addr, logger } } pub(crate) async fn connect_peer_if_necessary( @@ -78,15 +83,29 @@ where Error::InvalidSocketAddress })?; - let connection_future = lightning_net_tokio::connect_outbound( - Arc::clone(&self.peer_manager), - node_id, - socket_addr, - ); - - let res = match connection_future.await { - Some(connection_closed_future) => { - let mut connection_closed_future = Box::pin(connection_closed_future); + let connection_future = + if let Some(proxy_addr) = self.socks5_proxy_addr { + log_info!(self.logger, "Connecting via SOCKS5 proxy {} to peer: {}@{}", proxy_addr, node_id, addr); + lightning_net_tokio::connect_outbound_via_socks5( + Arc::clone(&self.peer_manager), + node_id, + socket_addr, + proxy_addr, + ) + .await + .map(|f| Box::pin(f) as Pin + Send>>) + } else { + lightning_net_tokio::connect_outbound( + Arc::clone(&self.peer_manager), + node_id, + socket_addr, + ) + .await + .map(|f| Box::pin(f) as Pin + Send>>) + }; + + let res = match connection_future { + Some(mut connection_closed_future) => { loop { tokio::select! { _ = &mut connection_closed_future => {