Skip to content

Commit ba818f2

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 feda4b4 commit ba818f2

File tree

6 files changed

+196
-90
lines changed

6 files changed

+196
-90
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();

src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub enum Error {
2525
PaymentFailed,
2626
/// A given peer info could not be parsed.
2727
PeerInfoParseFailed,
28+
/// A given peer info could not be found.
29+
PeerInfoNotFound,
2830
/// A channel could not be opened.
2931
ChannelCreationFailed,
3032
/// A channel could not be closed.
@@ -57,6 +59,7 @@ impl fmt::Display for Error {
5759
}
5860
Self::PaymentFailed => write!(f, "Failed to send the given payment."),
5961
Self::PeerInfoParseFailed => write!(f, "Failed to parse the given peer information."),
62+
Self::PeerInfoNotFound => write!(f, "Failed to resolve the given peer information."),
6063
Self::ChannelCreationFailed => write!(f, "Failed to create channel."),
6164
Self::ChannelClosingFailed => write!(f, "Failed to close channel."),
6265
Self::PersistenceFailed => write!(f, "Failed to persist data."),

src/lib.rs

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ pub use lightning_invoice;
8888

8989
pub use error::Error;
9090
pub use event::Event;
91+
pub use types::NetAddress;
92+
9193
use event::{EventHandler, EventQueue};
9294
use io::fs_store::FilesystemStore;
9395
use io::{KVStore, CHANNEL_MANAGER_PERSISTENCE_KEY, CHANNEL_MANAGER_PERSISTENCE_NAMESPACE};
@@ -140,7 +142,7 @@ use rand::Rng;
140142
use std::convert::TryInto;
141143
use std::default::Default;
142144
use std::fs;
143-
use std::net::SocketAddr;
145+
use std::net::{SocketAddr, ToSocketAddrs};
144146
use std::sync::atomic::{AtomicBool, Ordering};
145147
use std::sync::{Arc, Mutex, RwLock};
146148
use std::time::{Duration, Instant, SystemTime};
@@ -754,7 +756,7 @@ impl Node {
754756
{
755757
if let Some(peer_info) = connect_peer_store.get_peer(&node_id) {
756758
let _ = do_connect_peer(
757-
peer_info.pubkey,
759+
peer_info.node_id,
758760
peer_info.address,
759761
Arc::clone(&connect_pm),
760762
Arc::clone(&connect_logger),
@@ -896,18 +898,18 @@ impl Node {
896898
///
897899
/// If `permanently` is set to `true`, we'll remember the peer and reconnect to it on restart.
898900
pub fn connect(
899-
&self, node_id: PublicKey, address: SocketAddr, permanently: bool,
901+
&self, node_id: PublicKey, address: NetAddress, permanently: bool,
900902
) -> Result<(), Error> {
901903
let rt_lock = self.runtime.read().unwrap();
902904
if rt_lock.is_none() {
903905
return Err(Error::NotRunning);
904906
}
905907
let runtime = rt_lock.as_ref().unwrap();
906908

907-
let peer_info = PeerInfo { pubkey: node_id, address };
909+
let peer_info = PeerInfo { node_id, address };
908910

909-
let con_peer_pubkey = peer_info.pubkey;
910-
let con_peer_addr = peer_info.address;
911+
let con_node_id = peer_info.node_id;
912+
let con_addr = peer_info.address.clone();
911913
let con_success = Arc::new(AtomicBool::new(false));
912914
let con_success_cloned = Arc::clone(&con_success);
913915
let con_logger = Arc::clone(&self.logger);
@@ -916,8 +918,7 @@ impl Node {
916918
tokio::task::block_in_place(move || {
917919
runtime.block_on(async move {
918920
let res =
919-
connect_peer_if_necessary(con_peer_pubkey, con_peer_addr, con_pm, con_logger)
920-
.await;
921+
connect_peer_if_necessary(con_node_id, con_addr, con_pm, con_logger).await;
921922
con_success_cloned.store(res.is_ok(), Ordering::Release);
922923
})
923924
});
@@ -926,7 +927,7 @@ impl Node {
926927
return Err(Error::ConnectionFailed);
927928
}
928929

929-
log_info!(self.logger, "Connected to peer {}@{}. ", peer_info.pubkey, peer_info.address,);
930+
log_info!(self.logger, "Connected to peer {}@{}. ", peer_info.node_id, peer_info.address);
930931

931932
if permanently {
932933
self.peer_store.add_peer(peer_info)?;
@@ -968,7 +969,7 @@ impl Node {
968969
///
969970
/// Returns a temporary channel id.
970971
pub fn connect_open_channel(
971-
&self, node_id: PublicKey, address: SocketAddr, channel_amount_sats: u64,
972+
&self, node_id: PublicKey, address: NetAddress, channel_amount_sats: u64,
972973
push_to_counterparty_msat: Option<u64>, announce_channel: bool,
973974
) -> Result<(), Error> {
974975
let rt_lock = self.runtime.read().unwrap();
@@ -983,10 +984,10 @@ impl Node {
983984
return Err(Error::InsufficientFunds);
984985
}
985986

986-
let peer_info = PeerInfo { pubkey: node_id, address };
987+
let peer_info = PeerInfo { node_id, address };
987988

988-
let con_peer_pubkey = peer_info.pubkey;
989-
let con_peer_addr = peer_info.address;
989+
let con_node_id = peer_info.node_id;
990+
let con_addr = peer_info.address.clone();
990991
let con_success = Arc::new(AtomicBool::new(false));
991992
let con_success_cloned = Arc::clone(&con_success);
992993
let con_logger = Arc::clone(&self.logger);
@@ -995,8 +996,7 @@ impl Node {
995996
tokio::task::block_in_place(move || {
996997
runtime.block_on(async move {
997998
let res =
998-
connect_peer_if_necessary(con_peer_pubkey, con_peer_addr, con_pm, con_logger)
999-
.await;
999+
connect_peer_if_necessary(con_node_id, con_addr, con_pm, con_logger).await;
10001000
con_success_cloned.store(res.is_ok(), Ordering::Release);
10011001
})
10021002
});
@@ -1022,7 +1022,7 @@ impl Node {
10221022
let user_channel_id: u128 = rand::thread_rng().gen::<u128>();
10231023

10241024
match self.channel_manager.create_channel(
1025-
peer_info.pubkey,
1025+
peer_info.node_id,
10261026
channel_amount_sats,
10271027
push_msat,
10281028
user_channel_id,
@@ -1032,7 +1032,7 @@ impl Node {
10321032
log_info!(
10331033
self.logger,
10341034
"Initiated channel creation with peer {}. ",
1035-
peer_info.pubkey
1035+
peer_info.node_id
10361036
);
10371037
self.peer_store.add_peer(peer_info)?;
10381038
Ok(())
@@ -1438,44 +1438,52 @@ impl Drop for Node {
14381438
}
14391439

14401440
async fn connect_peer_if_necessary(
1441-
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager>,
1441+
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager>,
14421442
logger: Arc<FilesystemLogger>,
14431443
) -> Result<(), Error> {
1444-
for (node_pubkey, _addr) in peer_manager.get_peer_node_ids() {
1445-
if node_pubkey == pubkey {
1444+
for (pman_node_id, _pman_addr) in peer_manager.get_peer_node_ids() {
1445+
if node_id == pman_node_id {
14461446
return Ok(());
14471447
}
14481448
}
14491449

1450-
do_connect_peer(pubkey, peer_addr, peer_manager, logger).await
1450+
do_connect_peer(node_id, addr, peer_manager, logger).await
14511451
}
14521452

14531453
async fn do_connect_peer(
1454-
pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager>,
1454+
node_id: PublicKey, addr: NetAddress, peer_manager: Arc<PeerManager>,
14551455
logger: Arc<FilesystemLogger>,
14561456
) -> Result<(), Error> {
1457-
log_info!(logger, "Connecting to peer: {}@{}", pubkey, peer_addr);
1458-
match lightning_net_tokio::connect_outbound(Arc::clone(&peer_manager), pubkey, peer_addr).await
1457+
log_info!(logger, "Connecting to peer: {}@{}", node_id, addr);
1458+
1459+
let socket_addr = addr
1460+
.to_socket_addrs()
1461+
.map_err(|_| Error::PeerInfoNotFound)?
1462+
.next()
1463+
.ok_or(Error::ConnectionFailed)?;
1464+
1465+
match lightning_net_tokio::connect_outbound(Arc::clone(&peer_manager), node_id, socket_addr)
1466+
.await
14591467
{
14601468
Some(connection_closed_future) => {
14611469
let mut connection_closed_future = Box::pin(connection_closed_future);
14621470
loop {
14631471
match futures::poll!(&mut connection_closed_future) {
14641472
std::task::Poll::Ready(_) => {
1465-
log_info!(logger, "Peer connection closed: {}@{}", pubkey, peer_addr);
1473+
log_info!(logger, "Peer connection closed: {}@{}", node_id, addr);
14661474
return Err(Error::ConnectionFailed);
14671475
}
14681476
std::task::Poll::Pending => {}
14691477
}
14701478
// Avoid blocking the tokio context by sleeping a bit
1471-
match peer_manager.get_peer_node_ids().iter().find(|(id, _addr)| *id == pubkey) {
1479+
match peer_manager.get_peer_node_ids().iter().find(|(id, _addr)| *id == node_id) {
14721480
Some(_) => return Ok(()),
14731481
None => tokio::time::sleep(Duration::from_millis(10)).await,
14741482
}
14751483
}
14761484
}
14771485
None => {
1478-
log_error!(logger, "Failed to connect to peer: {}@{}", pubkey, peer_addr);
1486+
log_error!(logger, "Failed to connect to peer: {}@{}", node_id, addr);
14791487
Err(Error::ConnectionFailed)
14801488
}
14811489
}

src/peer_store.rs

Lines changed: 17 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ use crate::io::{
22
KVStore, TransactionalWrite, PEER_INFO_PERSISTENCE_KEY, PEER_INFO_PERSISTENCE_NAMESPACE,
33
};
44
use crate::logger::{log_error, Logger};
5-
use crate::Error;
5+
use crate::{Error, NetAddress};
66

7+
use lightning::impl_writeable_tlv_based;
78
use lightning::util::ser::{Readable, ReadableArgs, Writeable, Writer};
89

910
use bitcoin::secp256k1::PublicKey;
1011

1112
use std::collections::HashMap;
12-
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
1313
use std::ops::Deref;
1414
use std::sync::RwLock;
1515

@@ -36,23 +36,23 @@ where
3636
pub(crate) fn add_peer(&self, peer_info: PeerInfo) -> Result<(), Error> {
3737
let mut locked_peers = self.peers.write().unwrap();
3838

39-
locked_peers.insert(peer_info.pubkey, peer_info);
39+
locked_peers.insert(peer_info.node_id, peer_info);
4040
self.write_peers_and_commit(&*locked_peers)
4141
}
4242

43-
pub(crate) fn remove_peer(&self, peer_pubkey: &PublicKey) -> Result<(), Error> {
43+
pub(crate) fn remove_peer(&self, node_id: &PublicKey) -> Result<(), Error> {
4444
let mut locked_peers = self.peers.write().unwrap();
4545

46-
locked_peers.remove(peer_pubkey);
46+
locked_peers.remove(node_id);
4747
self.write_peers_and_commit(&*locked_peers)
4848
}
4949

5050
pub(crate) fn list_peers(&self) -> Vec<PeerInfo> {
5151
self.peers.read().unwrap().values().cloned().collect()
5252
}
5353

54-
pub(crate) fn get_peer(&self, peer_pubkey: &PublicKey) -> Option<PeerInfo> {
55-
self.peers.read().unwrap().get(peer_pubkey).cloned()
54+
pub(crate) fn get_peer(&self, node_id: &PublicKey) -> Option<PeerInfo> {
55+
self.peers.read().unwrap().get(node_id).cloned()
5656
}
5757

5858
fn write_peers_and_commit(
@@ -143,56 +143,14 @@ impl Writeable for PeerStoreSerWrapper<'_> {
143143

144144
#[derive(Clone, Debug, PartialEq, Eq)]
145145
pub(crate) struct PeerInfo {
146-
pub pubkey: PublicKey,
147-
pub address: SocketAddr,
146+
pub node_id: PublicKey,
147+
pub address: NetAddress,
148148
}
149149

150-
impl Readable for PeerInfo {
151-
fn read<R: lightning::io::Read>(
152-
reader: &mut R,
153-
) -> Result<Self, lightning::ln::msgs::DecodeError> {
154-
let pubkey = Readable::read(reader)?;
155-
156-
let ip_type: u8 = Readable::read(reader)?;
157-
158-
let ip_addr = if ip_type == 0 {
159-
let v4bytes: u32 = Readable::read(reader)?;
160-
let v4addr = Ipv4Addr::from(v4bytes);
161-
IpAddr::from(v4addr)
162-
} else {
163-
let v6bytes: u128 = Readable::read(reader)?;
164-
let v6addr = Ipv6Addr::from(v6bytes);
165-
IpAddr::from(v6addr)
166-
};
167-
168-
let port: u16 = Readable::read(reader)?;
169-
170-
let address = SocketAddr::new(ip_addr, port);
171-
172-
Ok(PeerInfo { pubkey, address })
173-
}
174-
}
175-
176-
impl Writeable for PeerInfo {
177-
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), lightning::io::Error> {
178-
self.pubkey.write(writer)?;
179-
180-
match self.address.ip() {
181-
IpAddr::V4(v4addr) => {
182-
0u8.write(writer)?;
183-
u32::from(v4addr).write(writer)?;
184-
}
185-
IpAddr::V6(v6addr) => {
186-
1u8.write(writer)?;
187-
u128::from(v6addr).write(writer)?;
188-
}
189-
}
190-
191-
self.address.port().write(writer)?;
192-
193-
Ok(())
194-
}
195-
}
150+
impl_writeable_tlv_based!(PeerInfo, {
151+
(0, node_id, required),
152+
(2, address, required),
153+
});
196154

197155
#[cfg(test)]
198156
mod tests {
@@ -207,12 +165,12 @@ mod tests {
207165
let logger = Arc::new(TestLogger::new());
208166
let peer_store = PeerStore::new(Arc::clone(&store), Arc::clone(&logger));
209167

210-
let pubkey = PublicKey::from_str(
168+
let node_id = PublicKey::from_str(
211169
"0276607124ebe6a6c9338517b6f485825b27c2dcc0b9fc2aa6a4c0df91194e5993",
212170
)
213171
.unwrap();
214-
let address: SocketAddr = "127.0.0.1:9738".parse().unwrap();
215-
let expected_peer_info = PeerInfo { pubkey, address };
172+
let address = NetAddress::from_str("127.0.0.1:9738").unwrap();
173+
let expected_peer_info = PeerInfo { node_id, address };
216174
peer_store.add_peer(expected_peer_info.clone()).unwrap();
217175
assert!(store.get_and_clear_did_persist());
218176

@@ -226,7 +184,7 @@ mod tests {
226184
let peers = deser_peer_store.list_peers();
227185
assert_eq!(peers.len(), 1);
228186
assert_eq!(peers[0], expected_peer_info);
229-
assert_eq!(deser_peer_store.get_peer(&pubkey), Some(expected_peer_info));
187+
assert_eq!(deser_peer_store.get_peer(&node_id), Some(expected_peer_info));
230188
assert!(!store.get_and_clear_did_persist());
231189
}
232190
}

src/test/functional_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn channel_full_cycle() {
3939
node_a
4040
.connect_open_channel(
4141
node_b.node_id(),
42-
node_b.listening_address().unwrap(),
42+
node_b.listening_address().unwrap().into(),
4343
funding_amount_sat,
4444
Some(push_msat),
4545
true,
@@ -240,7 +240,7 @@ fn channel_open_fails_when_funds_insufficient() {
240240
Err(Error::InsufficientFunds),
241241
node_a.connect_open_channel(
242242
node_b.node_id(),
243-
node_b.listening_address().unwrap(),
243+
node_b.listening_address().unwrap().into(),
244244
120000,
245245
None,
246246
true

0 commit comments

Comments
 (0)