Skip to content

Commit 4c401fc

Browse files
allow to listen and advertise on multiple SocketAddr
1 parent d955e62 commit 4c401fc

File tree

7 files changed

+66
-48
lines changed

7 files changed

+66
-48
lines changed

bindings/kotlin/ldk-node-android/lib/src/androidTest/kotlin/org/lightningdevkit/ldknode/AndroidLibTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ class AndroidLibTest {
2626
val listenAddress1 = "127.0.0.1:2323"
2727
val listenAddress2 = "127.0.0.1:2324"
2828

29-
val config1 = Config(tmpDir1, network, listenAddress1, 2048u)
30-
val config2 = Config(tmpDir2, network, listenAddress2, 2048u)
29+
val config1 = Config(tmpDir1, network, listOf(listenAddress1), 2048u)
30+
val config2 = Config(tmpDir2, network, listOf(listenAddress2), 2048u)
3131

3232
val builder1 = Builder.fromConfig(config1)
3333
val builder2 = Builder.fromConfig(config2)

bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,15 @@ class LibraryTest {
116116

117117
val config1 = Config()
118118
config1.storageDirPath = tmpDir1
119-
config1.listeningAddress = listenAddress1
119+
config1.listeningAddresses = listOf(listenAddress1)
120120
config1.network = Network.REGTEST
121121
config1.logLevel = LogLevel.TRACE
122122

123123
println("Config 1: $config1")
124124

125125
val config2 = Config()
126126
config2.storageDirPath = tmpDir2
127-
config2.listeningAddress = listenAddress2
127+
config2.listeningAddresses = listOf(listenAddress2)
128128
config2.network = Network.REGTEST
129129
config2.logLevel = LogLevel.TRACE
130130
println("Config 2: $config2")

bindings/ldk_node.udl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ dictionary Config {
66
string storage_dir_path = "/tmp/ldk_node/";
77
string? log_dir_path = null;
88
Network network = "Bitcoin";
9-
SocketAddress? listening_address = null;
9+
sequence<SocketAddress>? listening_addresses = null;
1010
u32 default_cltv_expiry_delta = 144;
1111
u64 onchain_wallet_sync_interval_secs = 80;
1212
u64 wallet_sync_interval_secs = 30;
@@ -29,7 +29,7 @@ interface Builder {
2929
void set_gossip_source_rgs(string rgs_server_url);
3030
void set_storage_dir_path(string storage_dir_path);
3131
void set_network(Network network);
32-
void set_listening_address(SocketAddress listening_address);
32+
void set_listening_addresses(sequence<SocketAddress> listening_addresses);
3333
[Throws=BuildError]
3434
LDKNode build();
3535
};
@@ -43,7 +43,7 @@ interface LDKNode {
4343
Event wait_next_event();
4444
void event_handled();
4545
PublicKey node_id();
46-
SocketAddress? listening_address();
46+
sequence<SocketAddress>? listening_addresses();
4747
[Throws=NodeError]
4848
Address new_onchain_address();
4949
[Throws=NodeError]

src/builder.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,12 @@ impl NodeBuilder {
231231
}
232232

233233
/// Sets the IP address and TCP port on which [`Node`] will listen for incoming network connections.
234-
pub fn set_listening_address(&mut self, listening_address: SocketAddress) -> &mut Self {
235-
self.config.listening_address = Some(listening_address);
234+
pub fn set_listening_addresses(&mut self, listening_addresses: Vec<SocketAddress>) -> &mut Self {
235+
if listening_addresses.len() > 100 {
236+
panic!("Listening addresses can not exceed 100");
237+
}
238+
239+
self.config.listening_addresses = Some(listening_addresses);
236240
self
237241
}
238242

@@ -386,8 +390,8 @@ impl ArcedNodeBuilder {
386390
}
387391

388392
/// Sets the IP address and TCP port on which [`Node`] will listen for incoming network connections.
389-
pub fn set_listening_address(&self, listening_address: SocketAddress) {
390-
self.inner.write().unwrap().set_listening_address(listening_address);
393+
pub fn set_listening_addresses(&self, listening_addresses: Vec<SocketAddress>) {
394+
self.inner.write().unwrap().set_listening_addresses(listening_addresses);
391395
}
392396

393397
/// Sets the level at which [`Node`] will log messages.

src/lib.rs

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ use bitcoin::{Address, Txid};
152152
use rand::Rng;
153153

154154
use std::default::Default;
155-
use std::net::ToSocketAddrs;
155+
use std::net::{SocketAddr, ToSocketAddrs};
156156
use std::sync::{Arc, Mutex, RwLock};
157157
use std::time::{Duration, Instant, SystemTime};
158158

@@ -207,7 +207,7 @@ const WALLET_KEYS_SEED_LEN: usize = 64;
207207
/// | `storage_dir_path` | /tmp/ldk_node/ |
208208
/// | `log_dir_path` | None |
209209
/// | `network` | Bitcoin |
210-
/// | `listening_address` | None |
210+
/// | `listening_addresses` | None |
211211
/// | `default_cltv_expiry_delta` | 144 |
212212
/// | `onchain_wallet_sync_interval_secs` | 80 |
213213
/// | `wallet_sync_interval_secs` | 30 |
@@ -226,7 +226,7 @@ pub struct Config {
226226
/// The used Bitcoin network.
227227
pub network: Network,
228228
/// The IP address and TCP port the node will listen on.
229-
pub listening_address: Option<SocketAddress>,
229+
pub listening_addresses: Option<Vec<SocketAddress>>,
230230
/// The default CLTV expiry delta to be used for payments.
231231
pub default_cltv_expiry_delta: u32,
232232
/// The time in-between background sync attempts of the onchain wallet, in seconds.
@@ -264,7 +264,7 @@ impl Default for Config {
264264
storage_dir_path: DEFAULT_STORAGE_DIR_PATH.to_string(),
265265
log_dir_path: None,
266266
network: DEFAULT_NETWORK,
267-
listening_address: None,
267+
listening_addresses: None,
268268
default_cltv_expiry_delta: DEFAULT_CLTV_EXPIRY_DELTA,
269269
onchain_wallet_sync_interval_secs: DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS,
270270
wallet_sync_interval_secs: DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS,
@@ -490,38 +490,37 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
490490
});
491491
}
492492

493-
if let Some(listening_address) = &self.config.listening_address {
493+
if let Some(listening_addresses) = &self.config.listening_addresses {
494494
// Setup networking
495495
let peer_manager_connection_handler = Arc::clone(&self.peer_manager);
496496
let mut stop_listen = self.stop_receiver.clone();
497-
let listening_address = listening_address.clone();
497+
let listening_addresses = listening_addresses.clone();
498498
let listening_logger = Arc::clone(&self.logger);
499499

500-
let bind_addr = listening_address
501-
.to_socket_addrs()
502-
.map_err(|_| {
503-
log_error!(
504-
self.logger,
505-
"Unable to resolve listing address: {:?}",
506-
listening_address
507-
);
508-
Error::InvalidSocketAddress
509-
})?
510-
.next()
511-
.ok_or_else(|| {
512-
log_error!(
513-
self.logger,
514-
"Unable to resolve listing address: {:?}",
515-
listening_address
516-
);
517-
Error::InvalidSocketAddress
518-
})?;
500+
let collected_addrs: Vec<SocketAddr> = listening_addresses
501+
.iter()
502+
.flat_map(|socket_address| {
503+
socket_address.to_socket_addrs().map_err(|_| {
504+
log_error!(
505+
self.logger,
506+
"Unable to resolve listing address: {:?}",
507+
socket_address
508+
);
509+
Error::InvalidSocketAddress
510+
})
511+
})
512+
.flatten()
513+
.collect::<Vec<SocketAddr>>();
514+
515+
assert!(!collected_addrs.is_empty());
516+
517+
let bind_addrs: Arc<[SocketAddr]> = collected_addrs.clone().into();
519518

520519
runtime.spawn(async move {
521520
let listener =
522-
tokio::net::TcpListener::bind(bind_addr).await
521+
tokio::net::TcpListener::bind(&*bind_addrs).await
523522
.unwrap_or_else(|e| {
524-
log_error!(listening_logger, "Failed to bind to listen address/port - is something else already listening on it?: {}", e);
523+
log_error!(listening_logger, "Failed to bind to listen addresses/ports - is something else already listening on it?: {}", e);
525524
panic!(
526525
"Failed to bind to listen address/port - is something else already listening on it?",
527526
);
@@ -632,7 +631,7 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
632631
}
633632

634633
let addresses =
635-
bcast_config.listening_address.iter().cloned().collect();
634+
bcast_config.listening_addresses.clone().unwrap();
636635
bcast_pm.broadcast_node_announcement([0; 3], [0; 32], addresses);
637636

638637
let unix_time_secs = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
@@ -781,9 +780,9 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
781780
self.channel_manager.get_our_node_id()
782781
}
783782

784-
/// Returns our own listening address.
785-
pub fn listening_address(&self) -> Option<SocketAddress> {
786-
self.config.listening_address.clone()
783+
/// Returns our own listening addresses.
784+
pub fn listening_addresses(&self) -> Option<Vec<SocketAddress>> {
785+
self.config.listening_addresses.clone()
787786
}
788787

789788
/// Retrieve a new on-chain/funding address.

src/test/functional_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ fn do_channel_full_cycle<K: KVStore + Sync + Send>(
7777
node_a
7878
.connect_open_channel(
7979
node_b.node_id(),
80-
node_b.listening_address().unwrap().into(),
80+
node_b.listening_addresses().unwrap().first().unwrap().clone(),
8181
funding_amount_sat,
8282
Some(push_msat),
8383
None,
@@ -332,7 +332,7 @@ fn channel_open_fails_when_funds_insufficient() {
332332
Err(Error::InsufficientFunds),
333333
node_a.connect_open_channel(
334334
node_b.node_id(),
335-
node_b.listening_address().unwrap().into(),
335+
node_b.listening_addresses().unwrap().first().unwrap().clone(),
336336
120000,
337337
None,
338338
None,

src/test/utils.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::path::PathBuf;
2020
use std::sync::Arc;
2121
use std::sync::Mutex;
2222
use std::time::Duration;
23+
use lightning::ln::msgs::SocketAddress;
2324

2425
macro_rules! expect_event {
2526
($node: expr, $event_type: ident) => {{
@@ -134,6 +135,21 @@ pub fn random_port() -> u16 {
134135
rng.gen_range(5000..65535)
135136
}
136137

138+
pub fn random_listening_addresses() -> Vec<SocketAddress> {
139+
let mut rng = thread_rng();
140+
let num_addresses = rng.gen_range(1..=3);
141+
142+
let listening_addresses: Vec<SocketAddress> = (0..num_addresses)
143+
.map(|_| {
144+
let rand_port = random_port();
145+
println!("Setting random LDK listening port: {}", rand_port);
146+
format!("127.0.0.1:{}", rand_port).parse().unwrap()
147+
})
148+
.collect();
149+
150+
listening_addresses
151+
}
152+
137153
pub fn random_config() -> Config {
138154
let mut config = Config::default();
139155

@@ -144,10 +160,9 @@ pub fn random_config() -> Config {
144160
println!("Setting random LDK storage dir: {}", rand_dir.display());
145161
config.storage_dir_path = rand_dir.to_str().unwrap().to_owned();
146162

147-
let rand_port = random_port();
148-
println!("Setting random LDK listening port: {}", rand_port);
149-
let listening_address_str = format!("127.0.0.1:{}", rand_port);
150-
config.listening_address = Some(listening_address_str.parse().unwrap());
163+
let rand_listening_addresses = random_listening_addresses();
164+
println!("Setting random LDK listening addresses: {:?}", rand_listening_addresses);
165+
config.listening_addresses = Some(rand_listening_addresses);
151166

152167
config.log_level = Level::Trace;
153168

0 commit comments

Comments
 (0)