Skip to content

Commit b59e86d

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 e104c21 commit b59e86d

File tree

7 files changed

+235
-117
lines changed

7 files changed

+235
-117
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 & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ interface Node {
3636
[Throws=NodeError]
3737
u64 total_onchain_balance_sats();
3838
[Throws=NodeError]
39-
void connect(PublicKey node_id, SocketAddr address, boolean permanently);
39+
void connect(PublicKey node_id, NetAddress address, boolean permanently);
4040
[Throws=NodeError]
4141
void disconnect(PublicKey node_id);
4242
[Throws=NodeError]
43-
void connect_open_channel(PublicKey node_id, SocketAddr address, u64 channel_amount_sats, u64? push_to_counterparty_msat, boolean announce_channel);
43+
void connect_open_channel(PublicKey node_id, NetAddress address, u64 channel_amount_sats, u64? push_to_counterparty_msat, boolean announce_channel);
4444
[Throws=NodeError]
4545
void close_channel([ByRef]ChannelId channel_id, PublicKey counterparty_node_id);
4646
[Throws=NodeError]
@@ -71,6 +71,7 @@ enum NodeError {
7171
"InvoiceCreationFailed",
7272
"PaymentFailed",
7373
"PeerInfoParseFailed",
74+
"PeerInfoNotFound",
7475
"ChannelCreationFailed",
7576
"ChannelClosingFailed",
7677
"PersistenceFailed",
@@ -147,7 +148,7 @@ dictionary ChannelDetails {
147148

148149
dictionary PeerDetails {
149150
PublicKey node_id;
150-
SocketAddr address;
151+
NetAddress address;
151152
boolean is_connected;
152153
};
153154

@@ -157,6 +158,9 @@ typedef string Txid;
157158
[Custom]
158159
typedef string SocketAddr;
159160

161+
[Custom]
162+
typedef string NetAddress;
163+
160164
[Custom]
161165
typedef string PublicKey;
162166

src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ pub enum Error {
1717
PaymentFailed,
1818
/// A given peer info could not be parsed.
1919
PeerInfoParseFailed,
20+
/// A given peer info could not be found.
21+
PeerInfoNotFound,
2022
/// A channel could not be opened.
2123
ChannelCreationFailed,
2224
/// A channel could not be closed.
@@ -67,6 +69,7 @@ impl fmt::Display for Error {
6769
Self::InvoiceCreationFailed => write!(f, "Failed to create invoice."),
6870
Self::PaymentFailed => write!(f, "Failed to send the given payment."),
6971
Self::PeerInfoParseFailed => write!(f, "Failed to parse the given peer information."),
72+
Self::PeerInfoNotFound => write!(f, "Failed to resolve the given peer information."),
7073
Self::ChannelCreationFailed => write!(f, "Failed to create channel."),
7174
Self::ChannelClosingFailed => write!(f, "Failed to close channel."),
7275
Self::PersistenceFailed => write!(f, "Failed to persist data."),

src/lib.rs

Lines changed: 40 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),
@@ -1013,18 +1015,18 @@ impl Node {
10131015
///
10141016
/// If `permanently` is set to `true`, we'll remember the peer and reconnect to it on restart.
10151017
pub fn connect(
1016-
&self, node_id: PublicKey, address: SocketAddr, permanently: bool,
1018+
&self, node_id: PublicKey, address: NetAddress, permanently: bool,
10171019
) -> Result<(), Error> {
10181020
let rt_lock = self.runtime.read().unwrap();
10191021
if rt_lock.is_none() {
10201022
return Err(Error::NotRunning);
10211023
}
10221024
let runtime = rt_lock.as_ref().unwrap();
10231025

1024-
let peer_info = PeerInfo { pubkey: node_id, address };
1026+
let peer_info = PeerInfo { node_id, address };
10251027

1026-
let con_peer_pubkey = peer_info.pubkey;
1027-
let con_peer_addr = peer_info.address;
1028+
let con_node_id = peer_info.node_id;
1029+
let con_addr = peer_info.address.clone();
10281030
let con_success = Arc::new(AtomicBool::new(false));
10291031
let con_success_cloned = Arc::clone(&con_success);
10301032
let con_logger = Arc::clone(&self.logger);
@@ -1033,8 +1035,7 @@ impl Node {
10331035
tokio::task::block_in_place(move || {
10341036
runtime.block_on(async move {
10351037
let res =
1036-
connect_peer_if_necessary(con_peer_pubkey, con_peer_addr, con_pm, con_logger)
1037-
.await;
1038+
connect_peer_if_necessary(con_node_id, con_addr, con_pm, con_logger).await;
10381039
con_success_cloned.store(res.is_ok(), Ordering::Release);
10391040
})
10401041
});
@@ -1043,7 +1044,7 @@ impl Node {
10431044
return Err(Error::ConnectionFailed);
10441045
}
10451046

1046-
log_info!(self.logger, "Connected to peer {}@{}. ", peer_info.pubkey, peer_info.address,);
1047+
log_info!(self.logger, "Connected to peer {}@{}. ", peer_info.node_id, peer_info.address);
10471048

10481049
if permanently {
10491050
self.peer_store.add_peer(peer_info)?;
@@ -1085,7 +1086,7 @@ impl Node {
10851086
///
10861087
/// Returns a temporary channel id.
10871088
pub fn connect_open_channel(
1088-
&self, node_id: PublicKey, address: SocketAddr, channel_amount_sats: u64,
1089+
&self, node_id: PublicKey, address: NetAddress, channel_amount_sats: u64,
10891090
push_to_counterparty_msat: Option<u64>, announce_channel: bool,
10901091
) -> Result<(), Error> {
10911092
let rt_lock = self.runtime.read().unwrap();
@@ -1100,10 +1101,10 @@ impl Node {
11001101
return Err(Error::InsufficientFunds);
11011102
}
11021103

1103-
let peer_info = PeerInfo { pubkey: node_id, address };
1104+
let peer_info = PeerInfo { node_id, address };
11041105

1105-
let con_peer_pubkey = peer_info.pubkey;
1106-
let con_peer_addr = peer_info.address;
1106+
let con_node_id = peer_info.node_id;
1107+
let con_addr = peer_info.address.clone();
11071108
let con_success = Arc::new(AtomicBool::new(false));
11081109
let con_success_cloned = Arc::clone(&con_success);
11091110
let con_logger = Arc::clone(&self.logger);
@@ -1112,8 +1113,7 @@ impl Node {
11121113
tokio::task::block_in_place(move || {
11131114
runtime.block_on(async move {
11141115
let res =
1115-
connect_peer_if_necessary(con_peer_pubkey, con_peer_addr, con_pm, con_logger)
1116-
.await;
1116+
connect_peer_if_necessary(con_node_id, con_addr, con_pm, con_logger).await;
11171117
con_success_cloned.store(res.is_ok(), Ordering::Release);
11181118
})
11191119
});
@@ -1139,7 +1139,7 @@ impl Node {
11391139
let user_channel_id: u128 = rand::thread_rng().gen::<u128>();
11401140

11411141
match self.channel_manager.create_channel(
1142-
peer_info.pubkey,
1142+
peer_info.node_id,
11431143
channel_amount_sats,
11441144
push_msat,
11451145
user_channel_id,
@@ -1149,7 +1149,7 @@ impl Node {
11491149
log_info!(
11501150
self.logger,
11511151
"Initiated channel creation with peer {}. ",
1152-
peer_info.pubkey
1152+
peer_info.node_id
11531153
);
11541154
self.peer_store.add_peer(peer_info)?;
11551155
Ok(())
@@ -1550,9 +1550,9 @@ impl Node {
15501550
.list_peers()
15511551
.iter()
15521552
.map(|p| PeerDetails {
1553-
node_id: p.pubkey,
1554-
address: p.address,
1555-
is_connected: active_connected_peers.contains(&p.pubkey),
1553+
node_id: p.node_id,
1554+
address: p.address.clone(),
1555+
is_connected: active_connected_peers.contains(&p.node_id),
15561556
})
15571557
.collect()
15581558
}
@@ -1565,44 +1565,52 @@ impl Drop for Node {
15651565
}
15661566

15671567
async fn connect_peer_if_necessary(
1568-
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager>,
1568+
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager>,
15691569
logger: Arc<FilesystemLogger>,
15701570
) -> Result<(), Error> {
1571-
for (node_pubkey, _addr) in peer_manager.get_peer_node_ids() {
1572-
if node_pubkey == pubkey {
1571+
for (pman_node_id, _pman_addr) in peer_manager.get_peer_node_ids() {
1572+
if node_id == pman_node_id {
15731573
return Ok(());
15741574
}
15751575
}
15761576

1577-
do_connect_peer(pubkey, peer_addr, peer_manager, logger).await
1577+
do_connect_peer(node_id, addr, peer_manager, logger).await
15781578
}
15791579

15801580
async fn do_connect_peer(
1581-
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager>,
1581+
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager>,
15821582
logger: Arc<FilesystemLogger>,
15831583
) -> Result<(), Error> {
1584-
log_info!(logger, "Connecting to peer: {}@{}", pubkey, peer_addr);
1585-
match lightning_net_tokio::connect_outbound(Arc::clone(&peer_manager), pubkey, peer_addr).await
1584+
log_info!(logger, "Connecting to peer: {}@{}", node_id, addr);
1585+
1586+
let socket_addr = addr
1587+
.to_socket_addrs()
1588+
.map_err(|_| Error::PeerInfoNotFound)?
1589+
.next()
1590+
.ok_or(Error::ConnectionFailed)?;
1591+
1592+
match lightning_net_tokio::connect_outbound(Arc::clone(&peer_manager), node_id, socket_addr)
1593+
.await
15861594
{
15871595
Some(connection_closed_future) => {
15881596
let mut connection_closed_future = Box::pin(connection_closed_future);
15891597
loop {
15901598
match futures::poll!(&mut connection_closed_future) {
15911599
std::task::Poll::Ready(_) => {
1592-
log_info!(logger, "Peer connection closed: {}@{}", pubkey, peer_addr);
1600+
log_info!(logger, "Peer connection closed: {}@{}", node_id, addr);
15931601
return Err(Error::ConnectionFailed);
15941602
}
15951603
std::task::Poll::Pending => {}
15961604
}
15971605
// Avoid blocking the tokio context by sleeping a bit
1598-
match peer_manager.get_peer_node_ids().iter().find(|(id, _addr)| *id == pubkey) {
1606+
match peer_manager.get_peer_node_ids().iter().find(|(id, _addr)| *id == node_id) {
15991607
Some(_) => return Ok(()),
16001608
None => tokio::time::sleep(Duration::from_millis(10)).await,
16011609
}
16021610
}
16031611
}
16041612
None => {
1605-
log_error!(logger, "Failed to connect to peer: {}@{}", pubkey, peer_addr);
1613+
log_error!(logger, "Failed to connect to peer: {}@{}", node_id, addr);
16061614
Err(Error::ConnectionFailed)
16071615
}
16081616
}

0 commit comments

Comments
 (0)