Skip to content

Commit 04032ec

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 7c067a7 commit 04032ec

File tree

7 files changed

+231
-113
lines changed

7 files changed

+231
-113
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: 6 additions & 2 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]
@@ -69,6 +69,7 @@ enum NodeError {
6969
"InvoiceCreationFailed",
7070
"PaymentFailed",
7171
"PeerInfoParseFailed",
72+
"PeerInfoNotFound",
7273
"ChannelCreationFailed",
7374
"ChannelClosingFailed",
7475
"PersistenceFailed",
@@ -129,6 +130,9 @@ typedef string Txid;
129130
[Custom]
130131
typedef string SocketAddr;
131132

133+
[Custom]
134+
typedef string NetAddress;
135+
132136
[Custom]
133137
typedef string PublicKey;
134138

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.
@@ -65,6 +67,7 @@ impl fmt::Display for Error {
6567
Self::InvoiceCreationFailed => write!(f, "Failed to create invoice."),
6668
Self::PaymentFailed => write!(f, "Failed to send the given payment."),
6769
Self::PeerInfoParseFailed => write!(f, "Failed to parse the given peer information."),
70+
Self::PeerInfoNotFound => write!(f, "Failed to resolve the given peer information."),
6871
Self::ChannelCreationFailed => write!(f, "Failed to create channel."),
6972
Self::ChannelClosingFailed => write!(f, "Failed to close channel."),
7073
Self::PersistenceFailed => write!(f, "Failed to persist data."),

src/lib.rs

Lines changed: 38 additions & 30 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();
@@ -95,6 +95,8 @@ pub use error::Error as NodeError;
9595
use error::Error;
9696

9797
pub use event::Event;
98+
pub use types::NetAddress;
99+
98100
use event::{EventHandler, EventQueue};
99101
use io::fs_store::FilesystemStore;
100102
use io::{KVStore, CHANNEL_MANAGER_PERSISTENCE_KEY, CHANNEL_MANAGER_PERSISTENCE_NAMESPACE};
@@ -150,11 +152,11 @@ use rand::Rng;
150152
use std::convert::TryInto;
151153
use std::default::Default;
152154
use std::fs;
153-
use std::net::SocketAddr;
154-
use std::str::FromStr;
155+
use std::net::{SocketAddr, ToSocketAddrs};
155156
use std::sync::atomic::{AtomicBool, Ordering};
156157
use std::sync::{Arc, Mutex, RwLock};
157158
use std::time::{Duration, Instant, SystemTime};
159+
use std::str::FromStr;
158160

159161
uniffi::include_scaffolding!("ldk_node");
160162

@@ -758,7 +760,7 @@ impl Node {
758760
{
759761
if let Some(peer_info) = connect_peer_store.get_peer(&node_id) {
760762
let _ = do_connect_peer(
761-
peer_info.pubkey,
763+
peer_info.node_id,
762764
peer_info.address,
763765
Arc::clone(&connect_pm),
764766
Arc::clone(&connect_logger),
@@ -910,18 +912,18 @@ impl Node {
910912
///
911913
/// If `permanently` is set to `true`, we'll remember the peer and reconnect to it on restart.
912914
pub fn connect(
913-
&self, node_id: PublicKey, address: SocketAddr, permanently: bool,
915+
&self, node_id: PublicKey, address: NetAddress, permanently: bool,
914916
) -> Result<(), Error> {
915917
let rt_lock = self.runtime.read().unwrap();
916918
if rt_lock.is_none() {
917919
return Err(Error::NotRunning);
918920
}
919921
let runtime = rt_lock.as_ref().unwrap();
920922

921-
let peer_info = PeerInfo { pubkey: node_id, address };
923+
let peer_info = PeerInfo { node_id, address };
922924

923-
let con_peer_pubkey = peer_info.pubkey;
924-
let con_peer_addr = peer_info.address;
925+
let con_node_id = peer_info.node_id;
926+
let con_addr = peer_info.address.clone();
925927
let con_success = Arc::new(AtomicBool::new(false));
926928
let con_success_cloned = Arc::clone(&con_success);
927929
let con_logger = Arc::clone(&self.logger);
@@ -930,8 +932,7 @@ impl Node {
930932
tokio::task::block_in_place(move || {
931933
runtime.block_on(async move {
932934
let res =
933-
connect_peer_if_necessary(con_peer_pubkey, con_peer_addr, con_pm, con_logger)
934-
.await;
935+
connect_peer_if_necessary(con_node_id, con_addr, con_pm, con_logger).await;
935936
con_success_cloned.store(res.is_ok(), Ordering::Release);
936937
})
937938
});
@@ -940,7 +941,7 @@ impl Node {
940941
return Err(Error::ConnectionFailed);
941942
}
942943

943-
log_info!(self.logger, "Connected to peer {}@{}. ", peer_info.pubkey, peer_info.address,);
944+
log_info!(self.logger, "Connected to peer {}@{}. ", peer_info.node_id, peer_info.address);
944945

945946
if permanently {
946947
self.peer_store.add_peer(peer_info)?;
@@ -982,7 +983,7 @@ impl Node {
982983
///
983984
/// Returns a temporary channel id.
984985
pub fn connect_open_channel(
985-
&self, node_id: PublicKey, address: SocketAddr, channel_amount_sats: u64,
986+
&self, node_id: PublicKey, address: NetAddress, channel_amount_sats: u64,
986987
push_to_counterparty_msat: Option<u64>, announce_channel: bool,
987988
) -> Result<(), Error> {
988989
let rt_lock = self.runtime.read().unwrap();
@@ -997,10 +998,10 @@ impl Node {
997998
return Err(Error::InsufficientFunds);
998999
}
9991000

1000-
let peer_info = PeerInfo { pubkey: node_id, address };
1001+
let peer_info = PeerInfo { node_id, address };
10011002

1002-
let con_peer_pubkey = peer_info.pubkey;
1003-
let con_peer_addr = peer_info.address;
1003+
let con_node_id = peer_info.node_id;
1004+
let con_addr = peer_info.address.clone();
10041005
let con_success = Arc::new(AtomicBool::new(false));
10051006
let con_success_cloned = Arc::clone(&con_success);
10061007
let con_logger = Arc::clone(&self.logger);
@@ -1009,8 +1010,7 @@ impl Node {
10091010
tokio::task::block_in_place(move || {
10101011
runtime.block_on(async move {
10111012
let res =
1012-
connect_peer_if_necessary(con_peer_pubkey, con_peer_addr, con_pm, con_logger)
1013-
.await;
1013+
connect_peer_if_necessary(con_node_id, con_addr, con_pm, con_logger).await;
10141014
con_success_cloned.store(res.is_ok(), Ordering::Release);
10151015
})
10161016
});
@@ -1036,7 +1036,7 @@ impl Node {
10361036
let user_channel_id: u128 = rand::thread_rng().gen::<u128>();
10371037

10381038
match self.channel_manager.create_channel(
1039-
peer_info.pubkey,
1039+
peer_info.node_id,
10401040
channel_amount_sats,
10411041
push_msat,
10421042
user_channel_id,
@@ -1046,7 +1046,7 @@ impl Node {
10461046
log_info!(
10471047
self.logger,
10481048
"Initiated channel creation with peer {}. ",
1049-
peer_info.pubkey
1049+
peer_info.node_id
10501050
);
10511051
self.peer_store.add_peer(peer_info)?;
10521052
Ok(())
@@ -1447,44 +1447,52 @@ impl Drop for Node {
14471447
}
14481448

14491449
async fn connect_peer_if_necessary(
1450-
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager>,
1450+
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager>,
14511451
logger: Arc<FilesystemLogger>,
14521452
) -> Result<(), Error> {
1453-
for (node_pubkey, _addr) in peer_manager.get_peer_node_ids() {
1454-
if node_pubkey == pubkey {
1453+
for (pman_node_id, _pman_addr) in peer_manager.get_peer_node_ids() {
1454+
if node_id == pman_node_id {
14551455
return Ok(());
14561456
}
14571457
}
14581458

1459-
do_connect_peer(pubkey, peer_addr, peer_manager, logger).await
1459+
do_connect_peer(node_id, addr, peer_manager, logger).await
14601460
}
14611461

14621462
async fn do_connect_peer(
1463-
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager>,
1463+
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager>,
14641464
logger: Arc<FilesystemLogger>,
14651465
) -> Result<(), Error> {
1466-
log_info!(logger, "Connecting to peer: {}@{}", pubkey, peer_addr);
1467-
match lightning_net_tokio::connect_outbound(Arc::clone(&peer_manager), pubkey, peer_addr).await
1466+
log_info!(logger, "Connecting to peer: {}@{}", node_id, addr);
1467+
1468+
let socket_addr = addr
1469+
.to_socket_addrs()
1470+
.map_err(|_| Error::PeerInfoNotFound)?
1471+
.next()
1472+
.ok_or(Error::ConnectionFailed)?;
1473+
1474+
match lightning_net_tokio::connect_outbound(Arc::clone(&peer_manager), node_id, socket_addr)
1475+
.await
14681476
{
14691477
Some(connection_closed_future) => {
14701478
let mut connection_closed_future = Box::pin(connection_closed_future);
14711479
loop {
14721480
match futures::poll!(&mut connection_closed_future) {
14731481
std::task::Poll::Ready(_) => {
1474-
log_info!(logger, "Peer connection closed: {}@{}", pubkey, peer_addr);
1482+
log_info!(logger, "Peer connection closed: {}@{}", node_id, addr);
14751483
return Err(Error::ConnectionFailed);
14761484
}
14771485
std::task::Poll::Pending => {}
14781486
}
14791487
// Avoid blocking the tokio context by sleeping a bit
1480-
match peer_manager.get_peer_node_ids().iter().find(|(id, _addr)| *id == pubkey) {
1488+
match peer_manager.get_peer_node_ids().iter().find(|(id, _addr)| *id == node_id) {
14811489
Some(_) => return Ok(()),
14821490
None => tokio::time::sleep(Duration::from_millis(10)).await,
14831491
}
14841492
}
14851493
}
14861494
None => {
1487-
log_error!(logger, "Failed to connect to peer: {}@{}", pubkey, peer_addr);
1495+
log_error!(logger, "Failed to connect to peer: {}@{}", node_id, addr);
14881496
Err(Error::ConnectionFailed)
14891497
}
14901498
}

0 commit comments

Comments
 (0)