Skip to content

Commit 6434712

Browse files
committed
Switch to use NetAddress for peer addresses
While we're still blocked on upstream changes, we now switch our peer info to use a newtype around `NetAddress` so that we won't have to break serialization compatibility when the upstream changes becom available post-0.1.
1 parent 8fd30e8 commit 6434712

File tree

7 files changed

+233
-122
lines changed

7 files changed

+233
-122
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 & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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,7 +152,7 @@ dictionary ChannelDetails {
152152

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

@@ -162,6 +162,9 @@ typedef string Txid;
162162
[Custom]
163163
typedef string SocketAddr;
164164

165+
[Custom]
166+
typedef string NetAddress;
167+
165168
[Custom]
166169
typedef string PublicKey;
167170

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: 43 additions & 32 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::{SocketAddr, ToSocketAddrs};
153155
use std::str::FromStr;
154156
use std::sync::atomic::{AtomicBool, Ordering};
155157
use std::sync::{Arc, Mutex, RwLock};
@@ -861,7 +863,7 @@ impl Node {
861863
{
862864
if let Some(peer_info) = connect_peer_store.get_peer(&node_id) {
863865
let _ = do_connect_peer(
864-
peer_info.pubkey,
866+
peer_info.node_id,
865867
peer_info.address,
866868
Arc::clone(&connect_pm),
867869
Arc::clone(&connect_logger),
@@ -1024,18 +1026,18 @@ impl Node {
10241026
///
10251027
/// If `permanently` is set to `true`, we'll remember the peer and reconnect to it on restart.
10261028
pub fn connect(
1027-
&self, node_id: PublicKey, address: SocketAddr, permanently: bool,
1029+
&self, node_id: PublicKey, address: NetAddress, permanently: bool,
10281030
) -> Result<(), Error> {
10291031
let rt_lock = self.runtime.read().unwrap();
10301032
if rt_lock.is_none() {
10311033
return Err(Error::NotRunning);
10321034
}
10331035
let runtime = rt_lock.as_ref().unwrap();
10341036

1035-
let peer_info = PeerInfo { pubkey: node_id, address };
1037+
let peer_info = PeerInfo { node_id, address };
10361038

1037-
let con_peer_pubkey = peer_info.pubkey;
1038-
let con_peer_addr = peer_info.address;
1039+
let con_node_id = peer_info.node_id;
1040+
let con_addr = peer_info.address.clone();
10391041
let con_success = Arc::new(AtomicBool::new(false));
10401042
let con_success_cloned = Arc::clone(&con_success);
10411043
let con_logger = Arc::clone(&self.logger);
@@ -1044,8 +1046,7 @@ impl Node {
10441046
tokio::task::block_in_place(move || {
10451047
runtime.block_on(async move {
10461048
let res =
1047-
connect_peer_if_necessary(con_peer_pubkey, con_peer_addr, con_pm, con_logger)
1048-
.await;
1049+
connect_peer_if_necessary(con_node_id, con_addr, con_pm, con_logger).await;
10491050
con_success_cloned.store(res.is_ok(), Ordering::Release);
10501051
})
10511052
});
@@ -1054,7 +1055,7 @@ impl Node {
10541055
return Err(Error::ConnectionFailed);
10551056
}
10561057

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

10591060
if permanently {
10601061
self.peer_store.add_peer(peer_info)?;
@@ -1096,7 +1097,7 @@ impl Node {
10961097
///
10971098
/// Returns a temporary channel id.
10981099
pub fn connect_open_channel(
1099-
&self, node_id: PublicKey, address: SocketAddr, channel_amount_sats: u64,
1100+
&self, node_id: PublicKey, address: NetAddress, channel_amount_sats: u64,
11001101
push_to_counterparty_msat: Option<u64>, announce_channel: bool,
11011102
) -> Result<(), Error> {
11021103
let rt_lock = self.runtime.read().unwrap();
@@ -1111,10 +1112,10 @@ impl Node {
11111112
return Err(Error::InsufficientFunds);
11121113
}
11131114

1114-
let peer_info = PeerInfo { pubkey: node_id, address };
1115+
let peer_info = PeerInfo { node_id, address };
11151116

1116-
let con_peer_pubkey = peer_info.pubkey;
1117-
let con_peer_addr = peer_info.address;
1117+
let con_node_id = peer_info.node_id;
1118+
let con_addr = peer_info.address.clone();
11181119
let con_success = Arc::new(AtomicBool::new(false));
11191120
let con_success_cloned = Arc::clone(&con_success);
11201121
let con_logger = Arc::clone(&self.logger);
@@ -1123,8 +1124,7 @@ impl Node {
11231124
tokio::task::block_in_place(move || {
11241125
runtime.block_on(async move {
11251126
let res =
1126-
connect_peer_if_necessary(con_peer_pubkey, con_peer_addr, con_pm, con_logger)
1127-
.await;
1127+
connect_peer_if_necessary(con_node_id, con_addr, con_pm, con_logger).await;
11281128
con_success_cloned.store(res.is_ok(), Ordering::Release);
11291129
})
11301130
});
@@ -1150,7 +1150,7 @@ impl Node {
11501150
let user_channel_id: u128 = rand::thread_rng().gen::<u128>();
11511151

11521152
match self.channel_manager.create_channel(
1153-
peer_info.pubkey,
1153+
peer_info.node_id,
11541154
channel_amount_sats,
11551155
push_msat,
11561156
user_channel_id,
@@ -1160,7 +1160,7 @@ impl Node {
11601160
log_info!(
11611161
self.logger,
11621162
"Initiated channel creation with peer {}. ",
1163-
peer_info.pubkey
1163+
peer_info.node_id
11641164
);
11651165
self.peer_store.add_peer(peer_info)?;
11661166
Ok(())
@@ -1561,9 +1561,9 @@ impl Node {
15611561
.list_peers()
15621562
.iter()
15631563
.map(|p| PeerDetails {
1564-
node_id: p.pubkey,
1565-
address: p.address,
1566-
is_connected: active_connected_peers.contains(&p.pubkey),
1564+
node_id: p.node_id,
1565+
address: p.address.clone(),
1566+
is_connected: active_connected_peers.contains(&p.node_id),
15671567
})
15681568
.collect()
15691569
}
@@ -1592,44 +1592,55 @@ impl Drop for Node {
15921592
}
15931593

15941594
async fn connect_peer_if_necessary(
1595-
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager>,
1595+
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager>,
15961596
logger: Arc<FilesystemLogger>,
15971597
) -> Result<(), Error> {
1598-
for (node_pubkey, _addr) in peer_manager.get_peer_node_ids() {
1599-
if node_pubkey == pubkey {
1598+
for (pman_node_id, _pman_addr) in peer_manager.get_peer_node_ids() {
1599+
if node_id == pman_node_id {
16001600
return Ok(());
16011601
}
16021602
}
16031603

1604-
do_connect_peer(pubkey, peer_addr, peer_manager, logger).await
1604+
do_connect_peer(node_id, addr, peer_manager, logger).await
16051605
}
16061606

16071607
async fn do_connect_peer(
1608-
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager>,
1608+
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager>,
16091609
logger: Arc<FilesystemLogger>,
16101610
) -> 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
1611+
log_info!(logger, "Connecting to peer: {}@{}", node_id, addr);
1612+
1613+
let socket_addr = addr
1614+
.to_socket_addrs()
1615+
.map_err(|e| {
1616+
log_error!(logger, "Failed to resolve network address: {}", e);
1617+
Error::InvalidNetAddress
1618+
})?
1619+
.next()
1620+
.ok_or(Error::ConnectionFailed)?;
1621+
1622+
match lightning_net_tokio::connect_outbound(Arc::clone(&peer_manager), node_id, socket_addr)
1623+
.await
16131624
{
16141625
Some(connection_closed_future) => {
16151626
let mut connection_closed_future = Box::pin(connection_closed_future);
16161627
loop {
16171628
match futures::poll!(&mut connection_closed_future) {
16181629
std::task::Poll::Ready(_) => {
1619-
log_info!(logger, "Peer connection closed: {}@{}", pubkey, peer_addr);
1630+
log_info!(logger, "Peer connection closed: {}@{}", node_id, addr);
16201631
return Err(Error::ConnectionFailed);
16211632
}
16221633
std::task::Poll::Pending => {}
16231634
}
16241635
// Avoid blocking the tokio context by sleeping a bit
1625-
match peer_manager.get_peer_node_ids().iter().find(|(id, _addr)| *id == pubkey) {
1636+
match peer_manager.get_peer_node_ids().iter().find(|(id, _addr)| *id == node_id) {
16261637
Some(_) => return Ok(()),
16271638
None => tokio::time::sleep(Duration::from_millis(10)).await,
16281639
}
16291640
}
16301641
}
16311642
None => {
1632-
log_error!(logger, "Failed to connect to peer: {}@{}", pubkey, peer_addr);
1643+
log_error!(logger, "Failed to connect to peer: {}@{}", node_id, addr);
16331644
Err(Error::ConnectionFailed)
16341645
}
16351646
}

0 commit comments

Comments
 (0)