Skip to content

Commit 60e4bed

Browse files
authored
Merge pull request lightningdevkit#85 from tnull/2023-05-switch-to-netaddress
2 parents 8fd30e8 + 63f3105 commit 60e4bed

File tree

7 files changed

+234
-130
lines changed

7 files changed

+234
-130
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LDK Node is a non-custodial Lightning node in library form. Its central goal is
88
The primary abstraction of the library is the `Node`, which can be retrieved by setting up and configuring a `Builder` to your liking and calling `build()`. `Node` can then be controlled via commands such as `start`, `stop`, `connect_open_channel`, `send_payment`, etc.:
99

1010
```rust
11-
use ldk_node::Builder;
11+
use ldk_node::{Builder, NetAddress};
1212
use ldk_node::lightning_invoice::Invoice;
1313
use ldk_node::bitcoin::secp256k1::PublicKey;
1414
use std::str::FromStr;
@@ -28,7 +28,7 @@ fn main() {
2828
node.sync_wallets().unwrap();
2929

3030
let node_id = PublicKey::from_str("NODE_ID").unwrap();
31-
let node_addr = "IP_ADDR:PORT".parse().unwrap();
31+
let node_addr = NetAddress::from_str("IP_ADDR:PORT").unwrap();
3232
node.connect_open_channel(node_id, node_addr, 10000, None, false).unwrap();
3333

3434
let invoice = Invoice::from_str("INVOICE_STR").unwrap();

bindings/ldk_node.udl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ dictionary Config {
55
string storage_dir_path;
66
string esplora_server_url;
77
Network network;
8-
SocketAddr? listening_address;
8+
NetAddress? listening_address;
99
u32 default_cltv_expiry_delta;
1010
};
1111

@@ -25,7 +25,7 @@ interface Node {
2525
Event wait_next_event();
2626
void event_handled();
2727
PublicKey node_id();
28-
SocketAddr? listening_address();
28+
NetAddress? listening_address();
2929
[Throws=NodeError]
3030
Address new_funding_address();
3131
[Throws=NodeError]
@@ -37,11 +37,11 @@ interface Node {
3737
[Throws=NodeError]
3838
u64 total_onchain_balance_sats();
3939
[Throws=NodeError]
40-
void connect(PublicKey node_id, SocketAddr address, boolean permanently);
40+
void connect(PublicKey node_id, NetAddress address, boolean permanently);
4141
[Throws=NodeError]
4242
void disconnect(PublicKey node_id);
4343
[Throws=NodeError]
44-
void connect_open_channel(PublicKey node_id, SocketAddr address, u64 channel_amount_sats, u64? push_to_counterparty_msat, boolean announce_channel);
44+
void connect_open_channel(PublicKey node_id, NetAddress address, u64 channel_amount_sats, u64? push_to_counterparty_msat, boolean announce_channel);
4545
[Throws=NodeError]
4646
void close_channel([ByRef]ChannelId channel_id, PublicKey counterparty_node_id);
4747
[Throws=NodeError]
@@ -74,7 +74,6 @@ enum NodeError {
7474
"ConnectionFailed",
7575
"InvoiceCreationFailed",
7676
"PaymentFailed",
77-
"PeerInfoParseFailed",
7877
"ChannelCreationFailed",
7978
"ChannelClosingFailed",
8079
"PersistenceFailed",
@@ -84,6 +83,7 @@ enum NodeError {
8483
"TxSyncFailed",
8584
"GossipUpdateFailed",
8685
"InvalidAddress",
86+
"InvalidNetAddress",
8787
"InvalidPublicKey",
8888
"InvalidPaymentHash",
8989
"InvalidPaymentPreimage",
@@ -152,15 +152,15 @@ dictionary ChannelDetails {
152152

153153
dictionary PeerDetails {
154154
PublicKey node_id;
155-
SocketAddr address;
155+
NetAddress address;
156156
boolean is_connected;
157157
};
158158

159159
[Custom]
160160
typedef string Txid;
161161

162162
[Custom]
163-
typedef string SocketAddr;
163+
typedef string NetAddress;
164164

165165
[Custom]
166166
typedef string PublicKey;

src/error.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ pub enum Error {
1515
InvoiceCreationFailed,
1616
/// An attempted payment has failed.
1717
PaymentFailed,
18-
/// A given peer info could not be parsed.
19-
PeerInfoParseFailed,
2018
/// A channel could not be opened.
2119
ChannelCreationFailed,
2220
/// A channel could not be closed.
@@ -35,6 +33,8 @@ pub enum Error {
3533
GossipUpdateFailed,
3634
/// The given address is invalid.
3735
InvalidAddress,
36+
/// The given network address is invalid.
37+
InvalidNetAddress,
3838
/// The given public key is invalid.
3939
InvalidPublicKey,
4040
/// The given payment hash is invalid.
@@ -68,7 +68,6 @@ impl fmt::Display for Error {
6868
Self::ConnectionFailed => write!(f, "Network connection closed."),
6969
Self::InvoiceCreationFailed => write!(f, "Failed to create invoice."),
7070
Self::PaymentFailed => write!(f, "Failed to send the given payment."),
71-
Self::PeerInfoParseFailed => write!(f, "Failed to parse the given peer information."),
7271
Self::ChannelCreationFailed => write!(f, "Failed to create channel."),
7372
Self::ChannelClosingFailed => write!(f, "Failed to close channel."),
7473
Self::PersistenceFailed => write!(f, "Failed to persist data."),
@@ -78,6 +77,7 @@ impl fmt::Display for Error {
7877
Self::TxSyncFailed => write!(f, "Failed to sync transactions."),
7978
Self::GossipUpdateFailed => write!(f, "Failed to update gossip data."),
8079
Self::InvalidAddress => write!(f, "The given address is invalid."),
80+
Self::InvalidNetAddress => write!(f, "The given network address is invalid."),
8181
Self::InvalidPublicKey => write!(f, "The given public key is invalid."),
8282
Self::InvalidPaymentHash => write!(f, "The given payment hash is invalid."),
8383
Self::InvalidPaymentPreimage => write!(f, "The given payment preimage is invalid."),

src/lib.rs

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
//! [`send_payment`], etc.:
2727
//!
2828
//! ```no_run
29-
//! use ldk_node::Builder;
29+
//! use ldk_node::{Builder, NetAddress};
3030
//! use ldk_node::lightning_invoice::Invoice;
3131
//! use ldk_node::bitcoin::secp256k1::PublicKey;
3232
//! use std::str::FromStr;
@@ -46,7 +46,7 @@
4646
//! node.sync_wallets().unwrap();
4747
//!
4848
//! let node_id = PublicKey::from_str("NODE_ID").unwrap();
49-
//! let node_addr = "IP_ADDR:PORT".parse().unwrap();
49+
//! let node_addr = NetAddress::from_str("IP_ADDR:PORT").unwrap();
5050
//! node.connect_open_channel(node_id, node_addr, 10000, None, false).unwrap();
5151
//!
5252
//! let invoice = Invoice::from_str("INVOICE_STR").unwrap();
@@ -97,6 +97,8 @@ pub use error::Error as NodeError;
9797
use error::Error;
9898

9999
pub use event::Event;
100+
pub use types::NetAddress;
101+
100102
use event::{EventHandler, EventQueue};
101103
use gossip::GossipSource;
102104
use io::fs_store::FilesystemStore;
@@ -149,7 +151,7 @@ use rand::Rng;
149151
use std::convert::TryInto;
150152
use std::default::Default;
151153
use std::fs;
152-
use std::net::SocketAddr;
154+
use std::net::ToSocketAddrs;
153155
use std::str::FromStr;
154156
use std::sync::atomic::{AtomicBool, Ordering};
155157
use std::sync::{Arc, Mutex, RwLock};
@@ -183,7 +185,7 @@ pub struct Config {
183185
/// The used Bitcoin network.
184186
pub network: Network,
185187
/// The IP address and TCP port the node will listen on.
186-
pub listening_address: Option<SocketAddr>,
188+
pub listening_address: Option<NetAddress>,
187189
/// The default CLTV expiry delta to be used for payments.
188190
pub default_cltv_expiry_delta: u32,
189191
}
@@ -307,7 +309,7 @@ impl Builder {
307309
/// Sets the IP address and TCP port on which [`Node`] will listen for incoming network connections.
308310
///
309311
/// Default: `0.0.0.0:9735`
310-
pub fn set_listening_address(&mut self, listening_address: SocketAddr) -> &mut Self {
312+
pub fn set_listening_address(&mut self, listening_address: NetAddress) -> &mut Self {
311313
self.config.listening_address = Some(listening_address);
312314
self
313315
}
@@ -814,9 +816,15 @@ impl Node {
814816
let stop_listen = Arc::clone(&stop_running);
815817
let listening_address = listening_address.clone();
816818

819+
let bind_addr = listening_address
820+
.to_socket_addrs()
821+
.expect("Unable to resolve listing address")
822+
.next()
823+
.expect("Unable to resolve listing address");
824+
817825
runtime.spawn(async move {
818826
let listener =
819-
tokio::net::TcpListener::bind(listening_address).await.expect(
827+
tokio::net::TcpListener::bind(bind_addr).await.expect(
820828
"Failed to bind to listen address/port - is something else already listening on it?",
821829
);
822830
loop {
@@ -861,7 +869,7 @@ impl Node {
861869
{
862870
if let Some(peer_info) = connect_peer_store.get_peer(&node_id) {
863871
let _ = do_connect_peer(
864-
peer_info.pubkey,
872+
peer_info.node_id,
865873
peer_info.address,
866874
Arc::clone(&connect_pm),
867875
Arc::clone(&connect_logger),
@@ -962,8 +970,8 @@ impl Node {
962970
}
963971

964972
/// Returns our own listening address.
965-
pub fn listening_address(&self) -> Option<SocketAddr> {
966-
self.config.listening_address
973+
pub fn listening_address(&self) -> Option<NetAddress> {
974+
self.config.listening_address.clone()
967975
}
968976

969977
/// Retrieve a new on-chain/funding address.
@@ -1024,18 +1032,18 @@ impl Node {
10241032
///
10251033
/// If `permanently` is set to `true`, we'll remember the peer and reconnect to it on restart.
10261034
pub fn connect(
1027-
&self, node_id: PublicKey, address: SocketAddr, permanently: bool,
1035+
&self, node_id: PublicKey, address: NetAddress, permanently: bool,
10281036
) -> Result<(), Error> {
10291037
let rt_lock = self.runtime.read().unwrap();
10301038
if rt_lock.is_none() {
10311039
return Err(Error::NotRunning);
10321040
}
10331041
let runtime = rt_lock.as_ref().unwrap();
10341042

1035-
let peer_info = PeerInfo { pubkey: node_id, address };
1043+
let peer_info = PeerInfo { node_id, address };
10361044

1037-
let con_peer_pubkey = peer_info.pubkey;
1038-
let con_peer_addr = peer_info.address;
1045+
let con_node_id = peer_info.node_id;
1046+
let con_addr = peer_info.address.clone();
10391047
let con_success = Arc::new(AtomicBool::new(false));
10401048
let con_success_cloned = Arc::clone(&con_success);
10411049
let con_logger = Arc::clone(&self.logger);
@@ -1044,8 +1052,7 @@ impl Node {
10441052
tokio::task::block_in_place(move || {
10451053
runtime.block_on(async move {
10461054
let res =
1047-
connect_peer_if_necessary(con_peer_pubkey, con_peer_addr, con_pm, con_logger)
1048-
.await;
1055+
connect_peer_if_necessary(con_node_id, con_addr, con_pm, con_logger).await;
10491056
con_success_cloned.store(res.is_ok(), Ordering::Release);
10501057
})
10511058
});
@@ -1054,7 +1061,7 @@ impl Node {
10541061
return Err(Error::ConnectionFailed);
10551062
}
10561063

1057-
log_info!(self.logger, "Connected to peer {}@{}. ", peer_info.pubkey, peer_info.address,);
1064+
log_info!(self.logger, "Connected to peer {}@{}. ", peer_info.node_id, peer_info.address);
10581065

10591066
if permanently {
10601067
self.peer_store.add_peer(peer_info)?;
@@ -1096,7 +1103,7 @@ impl Node {
10961103
///
10971104
/// Returns a temporary channel id.
10981105
pub fn connect_open_channel(
1099-
&self, node_id: PublicKey, address: SocketAddr, channel_amount_sats: u64,
1106+
&self, node_id: PublicKey, address: NetAddress, channel_amount_sats: u64,
11001107
push_to_counterparty_msat: Option<u64>, announce_channel: bool,
11011108
) -> Result<(), Error> {
11021109
let rt_lock = self.runtime.read().unwrap();
@@ -1111,10 +1118,10 @@ impl Node {
11111118
return Err(Error::InsufficientFunds);
11121119
}
11131120

1114-
let peer_info = PeerInfo { pubkey: node_id, address };
1121+
let peer_info = PeerInfo { node_id, address };
11151122

1116-
let con_peer_pubkey = peer_info.pubkey;
1117-
let con_peer_addr = peer_info.address;
1123+
let con_node_id = peer_info.node_id;
1124+
let con_addr = peer_info.address.clone();
11181125
let con_success = Arc::new(AtomicBool::new(false));
11191126
let con_success_cloned = Arc::clone(&con_success);
11201127
let con_logger = Arc::clone(&self.logger);
@@ -1123,8 +1130,7 @@ impl Node {
11231130
tokio::task::block_in_place(move || {
11241131
runtime.block_on(async move {
11251132
let res =
1126-
connect_peer_if_necessary(con_peer_pubkey, con_peer_addr, con_pm, con_logger)
1127-
.await;
1133+
connect_peer_if_necessary(con_node_id, con_addr, con_pm, con_logger).await;
11281134
con_success_cloned.store(res.is_ok(), Ordering::Release);
11291135
})
11301136
});
@@ -1150,7 +1156,7 @@ impl Node {
11501156
let user_channel_id: u128 = rand::thread_rng().gen::<u128>();
11511157

11521158
match self.channel_manager.create_channel(
1153-
peer_info.pubkey,
1159+
peer_info.node_id,
11541160
channel_amount_sats,
11551161
push_msat,
11561162
user_channel_id,
@@ -1160,7 +1166,7 @@ impl Node {
11601166
log_info!(
11611167
self.logger,
11621168
"Initiated channel creation with peer {}. ",
1163-
peer_info.pubkey
1169+
peer_info.node_id
11641170
);
11651171
self.peer_store.add_peer(peer_info)?;
11661172
Ok(())
@@ -1561,9 +1567,9 @@ impl Node {
15611567
.list_peers()
15621568
.iter()
15631569
.map(|p| PeerDetails {
1564-
node_id: p.pubkey,
1565-
address: p.address,
1566-
is_connected: active_connected_peers.contains(&p.pubkey),
1570+
node_id: p.node_id,
1571+
address: p.address.clone(),
1572+
is_connected: active_connected_peers.contains(&p.node_id),
15671573
})
15681574
.collect()
15691575
}
@@ -1592,44 +1598,55 @@ impl Drop for Node {
15921598
}
15931599

15941600
async fn connect_peer_if_necessary(
1595-
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager>,
1601+
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager>,
15961602
logger: Arc<FilesystemLogger>,
15971603
) -> Result<(), Error> {
1598-
for (node_pubkey, _addr) in peer_manager.get_peer_node_ids() {
1599-
if node_pubkey == pubkey {
1604+
for (pman_node_id, _pman_addr) in peer_manager.get_peer_node_ids() {
1605+
if node_id == pman_node_id {
16001606
return Ok(());
16011607
}
16021608
}
16031609

1604-
do_connect_peer(pubkey, peer_addr, peer_manager, logger).await
1610+
do_connect_peer(node_id, addr, peer_manager, logger).await
16051611
}
16061612

16071613
async fn do_connect_peer(
1608-
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager>,
1614+
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager>,
16091615
logger: Arc<FilesystemLogger>,
16101616
) -> Result<(), Error> {
1611-
log_info!(logger, "Connecting to peer: {}@{}", pubkey, peer_addr);
1612-
match lightning_net_tokio::connect_outbound(Arc::clone(&peer_manager), pubkey, peer_addr).await
1617+
log_info!(logger, "Connecting to peer: {}@{}", node_id, addr);
1618+
1619+
let socket_addr = addr
1620+
.to_socket_addrs()
1621+
.map_err(|e| {
1622+
log_error!(logger, "Failed to resolve network address: {}", e);
1623+
Error::InvalidNetAddress
1624+
})?
1625+
.next()
1626+
.ok_or(Error::ConnectionFailed)?;
1627+
1628+
match lightning_net_tokio::connect_outbound(Arc::clone(&peer_manager), node_id, socket_addr)
1629+
.await
16131630
{
16141631
Some(connection_closed_future) => {
16151632
let mut connection_closed_future = Box::pin(connection_closed_future);
16161633
loop {
16171634
match futures::poll!(&mut connection_closed_future) {
16181635
std::task::Poll::Ready(_) => {
1619-
log_info!(logger, "Peer connection closed: {}@{}", pubkey, peer_addr);
1636+
log_info!(logger, "Peer connection closed: {}@{}", node_id, addr);
16201637
return Err(Error::ConnectionFailed);
16211638
}
16221639
std::task::Poll::Pending => {}
16231640
}
16241641
// Avoid blocking the tokio context by sleeping a bit
1625-
match peer_manager.get_peer_node_ids().iter().find(|(id, _addr)| *id == pubkey) {
1642+
match peer_manager.get_peer_node_ids().iter().find(|(id, _addr)| *id == node_id) {
16261643
Some(_) => return Ok(()),
16271644
None => tokio::time::sleep(Duration::from_millis(10)).await,
16281645
}
16291646
}
16301647
}
16311648
None => {
1632-
log_error!(logger, "Failed to connect to peer: {}@{}", pubkey, peer_addr);
1649+
log_error!(logger, "Failed to connect to peer: {}@{}", node_id, addr);
16331650
Err(Error::ConnectionFailed)
16341651
}
16351652
}

0 commit comments

Comments
 (0)