Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class AndroidLibTest {
val listenAddress1 = "127.0.0.1:2323"
val listenAddress2 = "127.0.0.1:2324"

val config1 = Config(tmpDir1, network, listenAddress1, 2048u)
val config2 = Config(tmpDir2, network, listenAddress2, 2048u)
val config1 = Config(tmpDir1, network, listOf(listenAddress1), 2048u)
val config2 = Config(tmpDir2, network, listOf(listenAddress2), 2048u)

val builder1 = Builder.fromConfig(config1)
val builder2 = Builder.fromConfig(config2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,15 @@ class LibraryTest {

val config1 = Config()
config1.storageDirPath = tmpDir1
config1.listeningAddress = listenAddress1
config1.listeningAddresses = listOf(listenAddress1)
config1.network = Network.REGTEST
config1.logLevel = LogLevel.TRACE

println("Config 1: $config1")

val config2 = Config()
config2.storageDirPath = tmpDir2
config2.listeningAddress = listenAddress2
config2.listeningAddresses = listOf(listenAddress2)
config2.network = Network.REGTEST
config2.logLevel = LogLevel.TRACE
println("Config 2: $config2")
Expand Down
8 changes: 5 additions & 3 deletions bindings/ldk_node.udl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ dictionary Config {
string storage_dir_path = "/tmp/ldk_node/";
string? log_dir_path = null;
Network network = "Bitcoin";
SocketAddress? listening_address = null;
sequence<SocketAddress>? listening_addresses = null;
u32 default_cltv_expiry_delta = 144;
u64 onchain_wallet_sync_interval_secs = 80;
u64 wallet_sync_interval_secs = 30;
Expand All @@ -29,7 +29,8 @@ interface Builder {
void set_gossip_source_rgs(string rgs_server_url);
void set_storage_dir_path(string storage_dir_path);
void set_network(Network network);
void set_listening_address(SocketAddress listening_address);
[Throws=BuildError]
void set_listening_addresses(sequence<SocketAddress> listening_addresses);
[Throws=BuildError]
LDKNode build();
};
Expand All @@ -43,7 +44,7 @@ interface LDKNode {
Event wait_next_event();
void event_handled();
PublicKey node_id();
SocketAddress? listening_address();
sequence<SocketAddress>? listening_addresses();
[Throws=NodeError]
Address new_onchain_address();
[Throws=NodeError]
Expand Down Expand Up @@ -133,6 +134,7 @@ enum BuildError {
"InvalidSeedFile",
"InvalidSystemTime",
"InvalidChannelMonitor",
"InvalidListeningAddresses",
"ReadFailed",
"WriteFailed",
"StoragePathAccessFailed",
Expand Down
14 changes: 7 additions & 7 deletions bindings/python/src/ldk_node/test_ldk_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@ def send_to_address(address, amount_sats):
return res


def setup_node(tmp_dir, esplora_endpoint, listening_address):
def setup_node(tmp_dir, esplora_endpoint, listening_addresses):
config = Config()
builder = Builder.from_config(config)
builder.set_storage_dir_path(tmp_dir)
builder.set_esplora_server(esplora_endpoint)
builder.set_network(DEFAULT_TEST_NETWORK)
builder.set_listening_address(listening_address)
builder.set_listening_addresses(listening_addresses)
return builder.build()

def get_esplora_endpoint():
Expand All @@ -109,8 +109,8 @@ def test_channel_full_cycle(self):
tmp_dir_1 = tempfile.TemporaryDirectory("_ldk_node_1")
print("TMP DIR 1:", tmp_dir_1.name)

listening_address_1 = "127.0.0.1:2323"
node_1 = setup_node(tmp_dir_1.name, esplora_endpoint, listening_address_1)
listening_addresses_1 = ["127.0.0.1:2323"]
node_1 = setup_node(tmp_dir_1.name, esplora_endpoint, listening_addresses_1)
node_1.start()
node_id_1 = node_1.node_id()
print("Node ID 1:", node_id_1)
Expand All @@ -119,8 +119,8 @@ def test_channel_full_cycle(self):
tmp_dir_2 = tempfile.TemporaryDirectory("_ldk_node_2")
print("TMP DIR 2:", tmp_dir_2.name)

listening_address_2 = "127.0.0.1:2324"
node_2 = setup_node(tmp_dir_2.name, esplora_endpoint, listening_address_2)
listening_addresses_2 = ["127.0.0.1:2324"]
node_2 = setup_node(tmp_dir_2.name, esplora_endpoint, listening_addresses_2)
node_2.start()
node_id_2 = node_2.node_id()
print("Node ID 2:", node_id_2)
Expand Down Expand Up @@ -155,7 +155,7 @@ def test_channel_full_cycle(self):
print("TOTAL 2:", total_balance_2)
self.assertEqual(total_balance_2, 100000)

node_1.connect_open_channel(node_id_2, listening_address_2, 50000, None, None, True)
node_1.connect_open_channel(node_id_2, listening_addresses_2[0], 50000, None, None, True)

channel_pending_event_1 = node_1.wait_next_event()
assert isinstance(channel_pending_event_1, Event.CHANNEL_PENDING)
Expand Down
23 changes: 17 additions & 6 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ pub enum BuildError {
InvalidSystemTime,
/// The a read channel monitor is invalid.
InvalidChannelMonitor,
/// The given listening addresses are invalid, e.g. too many were passed.
InvalidListeningAddresses,
/// We failed to read data from the [`KVStore`].
ReadFailed,
/// We failed to write data to the [`KVStore`].
Expand All @@ -113,8 +115,9 @@ impl fmt::Display for BuildError {
write!(f, "System time is invalid. Clocks might have gone back in time.")
}
Self::InvalidChannelMonitor => {
write!(f, "Failed to watch a deserialzed ChannelMonitor")
write!(f, "Failed to watch a deserialized ChannelMonitor")
}
Self::InvalidListeningAddresses => write!(f, "Given listening addresses are invalid."),
Self::ReadFailed => write!(f, "Failed to read from store."),
Self::WriteFailed => write!(f, "Failed to write to store."),
Self::StoragePathAccessFailed => write!(f, "Failed to access the given storage path."),
Expand Down Expand Up @@ -231,9 +234,15 @@ impl NodeBuilder {
}

/// Sets the IP address and TCP port on which [`Node`] will listen for incoming network connections.
pub fn set_listening_address(&mut self, listening_address: SocketAddress) -> &mut Self {
self.config.listening_address = Some(listening_address);
self
pub fn set_listening_addresses(
&mut self, listening_addresses: Vec<SocketAddress>,
) -> Result<&mut Self, BuildError> {
if listening_addresses.len() > 100 {
return Err(BuildError::InvalidListeningAddresses);
}

self.config.listening_addresses = Some(listening_addresses);
Ok(self)
}

/// Sets the level at which [`Node`] will log messages.
Expand Down Expand Up @@ -386,8 +395,10 @@ impl ArcedNodeBuilder {
}

/// Sets the IP address and TCP port on which [`Node`] will listen for incoming network connections.
pub fn set_listening_address(&self, listening_address: SocketAddress) {
self.inner.write().unwrap().set_listening_address(listening_address);
pub fn set_listening_addresses(
&self, listening_addresses: Vec<SocketAddress>,
) -> Result<(), BuildError> {
self.inner.write().unwrap().set_listening_addresses(listening_addresses).map(|_| ())
}

/// Sets the level at which [`Node`] will log messages.
Expand Down
54 changes: 27 additions & 27 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ const WALLET_KEYS_SEED_LEN: usize = 64;
/// | `storage_dir_path` | /tmp/ldk_node/ |
/// | `log_dir_path` | None |
/// | `network` | Bitcoin |
/// | `listening_address` | None |
/// | `listening_addresses` | None |
/// | `default_cltv_expiry_delta` | 144 |
/// | `onchain_wallet_sync_interval_secs` | 80 |
/// | `wallet_sync_interval_secs` | 30 |
Expand All @@ -225,8 +225,8 @@ pub struct Config {
pub log_dir_path: Option<String>,
/// The used Bitcoin network.
pub network: Network,
/// The IP address and TCP port the node will listen on.
pub listening_address: Option<SocketAddress>,
/// The addresses on which the node will listen for incoming connections.
pub listening_addresses: Option<Vec<SocketAddress>>,
/// The default CLTV expiry delta to be used for payments.
pub default_cltv_expiry_delta: u32,
/// The time in-between background sync attempts of the onchain wallet, in seconds.
Expand Down Expand Up @@ -264,7 +264,7 @@ impl Default for Config {
storage_dir_path: DEFAULT_STORAGE_DIR_PATH.to_string(),
log_dir_path: None,
network: DEFAULT_NETWORK,
listening_address: None,
listening_addresses: None,
default_cltv_expiry_delta: DEFAULT_CLTV_EXPIRY_DELTA,
onchain_wallet_sync_interval_secs: DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS,
wallet_sync_interval_secs: DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS,
Expand Down Expand Up @@ -490,38 +490,33 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
});
}

if let Some(listening_address) = &self.config.listening_address {
if let Some(listening_addresses) = &self.config.listening_addresses {
// Setup networking
let peer_manager_connection_handler = Arc::clone(&self.peer_manager);
let mut stop_listen = self.stop_receiver.clone();
let listening_address = listening_address.clone();
let listening_logger = Arc::clone(&self.logger);

let bind_addr = listening_address
.to_socket_addrs()
.map_err(|_| {
log_error!(
self.logger,
"Unable to resolve listing address: {:?}",
listening_address
);
Error::InvalidSocketAddress
})?
.next()
.ok_or_else(|| {
let mut bind_addrs = Vec::with_capacity(listening_addresses.len());

for listening_addr in listening_addresses {
let resolved_address = listening_addr.to_socket_addrs().map_err(|e| {
log_error!(
self.logger,
"Unable to resolve listing address: {:?}",
listening_address
"Unable to resolve listening address: {:?}. Error details: {}",
listening_addr,
e,
);
Error::InvalidSocketAddress
})?;

bind_addrs.extend(resolved_address);
}

runtime.spawn(async move {
let listener =
tokio::net::TcpListener::bind(bind_addr).await
tokio::net::TcpListener::bind(&*bind_addrs).await
.unwrap_or_else(|e| {
log_error!(listening_logger, "Failed to bind to listen address/port - is something else already listening on it?: {}", e);
log_error!(listening_logger, "Failed to bind to listen addresses/ports - is something else already listening on it?: {}", e);
panic!(
"Failed to bind to listen address/port - is something else already listening on it?",
);
Expand Down Expand Up @@ -631,8 +626,13 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
continue;
}

let addresses =
bcast_config.listening_address.iter().cloned().collect();
let addresses = bcast_config.listening_addresses.clone().unwrap_or(Vec::new());

if addresses.is_empty() {
// Skip if we are not listening on any addresses.
continue;
}

bcast_pm.broadcast_node_announcement([0; 3], [0; 32], addresses);

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

/// Returns our own listening address.
pub fn listening_address(&self) -> Option<SocketAddress> {
self.config.listening_address.clone()
/// Returns our own listening addresses.
pub fn listening_addresses(&self) -> Option<Vec<SocketAddress>> {
self.config.listening_addresses.clone()
}

/// Retrieve a new on-chain/funding address.
Expand Down
4 changes: 2 additions & 2 deletions src/test/functional_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fn do_channel_full_cycle<K: KVStore + Sync + Send>(
node_a
.connect_open_channel(
node_b.node_id(),
node_b.listening_address().unwrap().into(),
node_b.listening_addresses().unwrap().first().unwrap().clone(),
funding_amount_sat,
Some(push_msat),
None,
Expand Down Expand Up @@ -332,7 +332,7 @@ fn channel_open_fails_when_funds_insufficient() {
Err(Error::InsufficientFunds),
node_a.connect_open_channel(
node_b.node_id(),
node_b.listening_address().unwrap().into(),
node_b.listening_addresses().unwrap().first().unwrap().clone(),
120000,
None,
None,
Expand Down
21 changes: 17 additions & 4 deletions src/test/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::builder::NodeBuilder;
use crate::io::test_utils::TestSyncStore;
use crate::{Config, Node};
use lightning::ln::msgs::SocketAddress;
use lightning::util::logger::{Level, Logger, Record};

use bitcoin::{Address, Amount, Network, OutPoint, Txid};
Expand Down Expand Up @@ -134,6 +135,19 @@ pub fn random_port() -> u16 {
rng.gen_range(5000..65535)
}

pub fn random_listening_addresses() -> Vec<SocketAddress> {
let num_addresses = 2;
let mut listening_addresses = Vec::with_capacity(num_addresses);

for _ in 0..num_addresses {
let rand_port = random_port();
let address: SocketAddress = format!("127.0.0.1:{}", rand_port).parse().unwrap();
listening_addresses.push(address);
}

listening_addresses
}

pub fn random_config() -> Config {
let mut config = Config::default();

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

let rand_port = random_port();
println!("Setting random LDK listening port: {}", rand_port);
let listening_address_str = format!("127.0.0.1:{}", rand_port);
config.listening_address = Some(listening_address_str.parse().unwrap());
let rand_listening_addresses = random_listening_addresses();
println!("Setting random LDK listening addresses: {:?}", rand_listening_addresses);
config.listening_addresses = Some(rand_listening_addresses);

config.log_level = Level::Trace;

Expand Down