Skip to content

Commit 3088c49

Browse files
committed
Make node's address optional when opening channel
Previously we always required providing the node's address when opening a channel, this made the api annoying in some cases as you may already be connected to the peer but still need to provide the socket address. Here we make it optional and will return a `ConnectionFailed` error when the socket address is not provided and we are not connected to the peer.
1 parent 804f00f commit 3088c49

File tree

7 files changed

+128
-51
lines changed

7 files changed

+128
-51
lines changed

bindings/ldk_node.udl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,13 @@ interface Node {
105105
[Throws=NodeError]
106106
void disconnect(PublicKey node_id);
107107
[Throws=NodeError]
108-
UserChannelId open_channel(PublicKey node_id, SocketAddress address, u64 channel_amount_sats, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
108+
UserChannelId open_channel(PublicKey node_id, SocketAddress? address, u64 channel_amount_sats, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
109109
[Throws=NodeError]
110-
UserChannelId open_announced_channel(PublicKey node_id, SocketAddress address, u64 channel_amount_sats, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
110+
UserChannelId open_announced_channel(PublicKey node_id, SocketAddress? address, u64 channel_amount_sats, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
111111
[Throws=NodeError]
112-
UserChannelId open_channel_with_all(PublicKey node_id, SocketAddress address, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
112+
UserChannelId open_channel_with_all(PublicKey node_id, SocketAddress? address, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
113113
[Throws=NodeError]
114-
UserChannelId open_announced_channel_with_all(PublicKey node_id, SocketAddress address, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
114+
UserChannelId open_announced_channel_with_all(PublicKey node_id, SocketAddress? address, u64? push_to_counterparty_msat, ChannelConfig? channel_config);
115115
[Throws=NodeError]
116116
void splice_in([ByRef]UserChannelId user_channel_id, PublicKey counterparty_node_id, u64 splice_amount_sats);
117117
[Throws=NodeError]
@@ -169,6 +169,7 @@ enum NodeError {
169169
"NotRunning",
170170
"OnchainTxCreationFailed",
171171
"ConnectionFailed",
172+
"NotConnected",
172173
"InvoiceCreationFailed",
173174
"InvoiceRequestCreationFailed",
174175
"OfferCreationFailed",

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
OnchainTxCreationFailed,
2626
/// A network connection has been closed.
2727
ConnectionFailed,
28+
/// The peer is not connected.
29+
NotConnected,
2830
/// Invoice creation failed.
2931
InvoiceCreationFailed,
3032
/// Invoice request creation failed.
@@ -148,6 +150,7 @@ impl fmt::Display for Error {
148150
write!(f, "On-chain transaction could not be created.")
149151
},
150152
Self::ConnectionFailed => write!(f, "Network connection closed."),
153+
Self::NotConnected => write!(f, "The peer is not connected."),
151154
Self::InvoiceCreationFailed => write!(f, "Failed to create invoice."),
152155
Self::InvoiceRequestCreationFailed => write!(f, "Failed to create invoice request."),
153156
Self::OfferCreationFailed => write!(f, "Failed to create offer."),

src/lib.rs

Lines changed: 64 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
//!
5555
//! let node_id = PublicKey::from_str("NODE_ID").unwrap();
5656
//! let node_addr = SocketAddress::from_str("IP_ADDR:PORT").unwrap();
57-
//! node.open_channel(node_id, node_addr, 10000, None, None).unwrap();
57+
//! node.open_channel(node_id, Some(node_addr), 10000, None, None).unwrap();
5858
//!
5959
//! let event = node.wait_next_event();
6060
//! println!("EVENT: {:?}", event);
@@ -1126,39 +1126,47 @@ impl Node {
11261126
}
11271127

11281128
fn open_channel_inner(
1129-
&self, node_id: PublicKey, address: SocketAddress, channel_amount_sats: FundingAmount,
1130-
push_to_counterparty_msat: Option<u64>, channel_config: Option<ChannelConfig>,
1131-
announce_for_forwarding: bool,
1129+
&self, node_id: PublicKey, address: Option<SocketAddress>,
1130+
channel_amount_sats: FundingAmount, push_to_counterparty_msat: Option<u64>,
1131+
channel_config: Option<ChannelConfig>, announce_for_forwarding: bool,
11321132
) -> Result<UserChannelId, Error> {
11331133
if !*self.is_running.read().unwrap() {
11341134
return Err(Error::NotRunning);
11351135
}
11361136

1137-
let peer_info = PeerInfo { node_id, address };
1138-
1139-
let con_node_id = peer_info.node_id;
1140-
let con_addr = peer_info.address.clone();
1141-
let con_cm = Arc::clone(&self.connection_manager);
1142-
1143-
// We need to use our main runtime here as a local runtime might not be around to poll
1144-
// connection futures going forward.
1145-
self.runtime.block_on(async move {
1146-
con_cm.connect_peer_if_necessary(con_node_id, con_addr).await
1147-
})?;
1137+
// if we don't have the socket address, check if we are already connected
1138+
let address = match address {
1139+
Some(address) => {
1140+
// We need to use our main runtime here as a local runtime might not be around to poll
1141+
// connection futures going forward.
1142+
let con_cm = Arc::clone(&self.connection_manager);
1143+
let con_addr = address.clone();
1144+
self.runtime.block_on(async move {
1145+
con_cm.connect_peer_if_necessary(node_id, con_addr).await
1146+
})?;
1147+
Some(address)
1148+
},
1149+
None => {
1150+
// If we are connected, grab the socket address as we need to make sure we have it persisted
1151+
// in our peer storage for future reconnections.
1152+
let peer =
1153+
self.peer_manager.peer_by_node_id(&node_id).ok_or(Error::NotConnected)?;
1154+
peer.socket_address
1155+
},
1156+
};
11481157

11491158
let channel_amount_sats = match channel_amount_sats {
11501159
FundingAmount::Exact { amount_sats } => {
11511160
// Check funds availability after connection (includes anchor reserve
11521161
// calculation).
1153-
self.check_sufficient_funds_for_channel(amount_sats, &peer_info.node_id)?;
1162+
self.check_sufficient_funds_for_channel(amount_sats, &node_id)?;
11541163
amount_sats
11551164
},
11561165
FundingAmount::Max => {
11571166
// Determine max funding amount from all available on-chain funds.
11581167
let cur_anchor_reserve_sats =
11591168
total_anchor_channels_reserve_sats(&self.channel_manager, &self.config);
1160-
let new_channel_reserve =
1161-
self.new_channel_anchor_reserve_sats(&peer_info.node_id)?;
1169+
let new_channel_reserve = self.new_channel_anchor_reserve_sats(&node_id)?;
11621170
let total_anchor_reserve_sats = cur_anchor_reserve_sats + new_channel_reserve;
11631171

11641172
let fee_rate =
@@ -1197,20 +1205,21 @@ impl Node {
11971205
);
11981206

11991207
match self.channel_manager.create_channel(
1200-
peer_info.node_id,
1208+
node_id,
12011209
channel_amount_sats,
12021210
push_msat,
12031211
user_channel_id,
12041212
None,
12051213
Some(user_config),
12061214
) {
12071215
Ok(_) => {
1208-
log_info!(
1209-
self.logger,
1210-
"Initiated channel creation with peer {}. ",
1211-
peer_info.node_id
1212-
);
1213-
self.peer_store.add_peer(peer_info)?;
1216+
log_info!(self.logger, "Initiated channel creation with peer {}. ", node_id);
1217+
1218+
if let Some(address) = address {
1219+
let peer_info = PeerInfo { node_id, address };
1220+
self.peer_store.add_peer(peer_info)?;
1221+
}
1222+
12141223
Ok(UserChannelId(user_channel_id))
12151224
},
12161225
Err(e) => {
@@ -1224,7 +1233,7 @@ impl Node {
12241233
let init_features = self
12251234
.peer_manager
12261235
.peer_by_node_id(peer_node_id)
1227-
.ok_or(Error::ConnectionFailed)?
1236+
.ok_or(Error::NotConnected)?
12281237
.init_features;
12291238
let anchor_channel = init_features.requires_anchors_zero_fee_htlc_tx();
12301239
Ok(new_channel_anchor_reserve_sats(&self.config, peer_node_id, anchor_channel))
@@ -1262,12 +1271,16 @@ impl Node {
12621271
Ok(())
12631272
}
12641273

1265-
/// Connect to a node and open a new unannounced channel.
1274+
/// Open a new unannounced channel with a node.
12661275
///
12671276
/// To open an announced channel, see [`Node::open_announced_channel`].
12681277
///
12691278
/// Disconnects and reconnects are handled automatically.
12701279
///
1280+
/// If `address` is provided, the node will connect to the peer at the given address before
1281+
/// opening the channel. If `address` is `None`, the node must already be connected to the
1282+
/// peer, otherwise [`Error::NotConnected`] will be returned.
1283+
///
12711284
/// If `push_to_counterparty_msat` is set, the given value will be pushed (read: sent) to the
12721285
/// channel counterparty on channel open. This can be useful to start out with the balance not
12731286
/// entirely shifted to one side, therefore allowing to receive payments from the getgo.
@@ -1280,7 +1293,7 @@ impl Node {
12801293
///
12811294
/// [`AnchorChannelsConfig::per_channel_reserve_sats`]: crate::config::AnchorChannelsConfig::per_channel_reserve_sats
12821295
pub fn open_channel(
1283-
&self, node_id: PublicKey, address: SocketAddress, channel_amount_sats: u64,
1296+
&self, node_id: PublicKey, address: Option<SocketAddress>, channel_amount_sats: u64,
12841297
push_to_counterparty_msat: Option<u64>, channel_config: Option<ChannelConfig>,
12851298
) -> Result<UserChannelId, Error> {
12861299
self.open_channel_inner(
@@ -1293,16 +1306,20 @@ impl Node {
12931306
)
12941307
}
12951308

1296-
/// Connect to a node and open a new announced channel.
1309+
/// Open a new announced channel with a node.
12971310
///
12981311
/// This will return an error if the node has not been sufficiently configured to operate as a
1299-
/// forwarding node that can properly announce its existence to the publip network graph, i.e.,
1312+
/// forwarding node that can properly announce its existence to the public network graph, i.e.,
13001313
/// [`Config::listening_addresses`] and [`Config::node_alias`] are unset.
13011314
///
13021315
/// To open an unannounced channel, see [`Node::open_channel`].
13031316
///
13041317
/// Disconnects and reconnects are handled automatically.
13051318
///
1319+
/// If `address` is provided, the node will connect to the peer at the given address before
1320+
/// opening the channel. If `address` is `None`, the node must already be connected to the
1321+
/// peer, otherwise [`Error::NotConnected`] will be returned.
1322+
///
13061323
/// If `push_to_counterparty_msat` is set, the given value will be pushed (read: sent) to the
13071324
/// channel counterparty on channel open. This can be useful to start out with the balance not
13081325
/// entirely shifted to one side, therefore allowing to receive payments from the getgo.
@@ -1315,7 +1332,7 @@ impl Node {
13151332
///
13161333
/// [`AnchorChannelsConfig::per_channel_reserve_sats`]: crate::config::AnchorChannelsConfig::per_channel_reserve_sats
13171334
pub fn open_announced_channel(
1318-
&self, node_id: PublicKey, address: SocketAddress, channel_amount_sats: u64,
1335+
&self, node_id: PublicKey, address: Option<SocketAddress>, channel_amount_sats: u64,
13191336
push_to_counterparty_msat: Option<u64>, channel_config: Option<ChannelConfig>,
13201337
) -> Result<UserChannelId, Error> {
13211338
if let Err(err) = may_announce_channel(&self.config) {
@@ -1333,13 +1350,17 @@ impl Node {
13331350
)
13341351
}
13351352

1336-
/// Connect to a node and open a new unannounced channel, using all available on-chain funds
1337-
/// minus fees and anchor reserves.
1353+
/// Open a new unannounced channel with a node, using all available on-chain funds minus fees
1354+
/// and anchor reserves.
13381355
///
13391356
/// To open an announced channel, see [`Node::open_announced_channel_with_all`].
13401357
///
13411358
/// Disconnects and reconnects are handled automatically.
13421359
///
1360+
/// If `address` is provided, the node will connect to the peer at the given address before
1361+
/// opening the channel. If `address` is `None`, the node must already be connected to the
1362+
/// peer, otherwise [`Error::NotConnected`] will be returned.
1363+
///
13431364
/// If `push_to_counterparty_msat` is set, the given value will be pushed (read: sent) to the
13441365
/// channel counterparty on channel open. This can be useful to start out with the balance not
13451366
/// entirely shifted to one side, therefore allowing to receive payments from the getgo.
@@ -1348,8 +1369,8 @@ impl Node {
13481369
///
13491370
/// [`AnchorChannelsConfig::per_channel_reserve_sats`]: crate::config::AnchorChannelsConfig::per_channel_reserve_sats
13501371
pub fn open_channel_with_all(
1351-
&self, node_id: PublicKey, address: SocketAddress, push_to_counterparty_msat: Option<u64>,
1352-
channel_config: Option<ChannelConfig>,
1372+
&self, node_id: PublicKey, address: Option<SocketAddress>,
1373+
push_to_counterparty_msat: Option<u64>, channel_config: Option<ChannelConfig>,
13531374
) -> Result<UserChannelId, Error> {
13541375
self.open_channel_inner(
13551376
node_id,
@@ -1361,8 +1382,8 @@ impl Node {
13611382
)
13621383
}
13631384

1364-
/// Connect to a node and open a new announced channel, using all available on-chain funds
1365-
/// minus fees and anchor reserves.
1385+
/// Open a new announced channel with a node, using all available on-chain funds minus fees
1386+
/// and anchor reserves.
13661387
///
13671388
/// This will return an error if the node has not been sufficiently configured to operate as a
13681389
/// forwarding node that can properly announce its existence to the public network graph, i.e.,
@@ -1372,6 +1393,10 @@ impl Node {
13721393
///
13731394
/// Disconnects and reconnects are handled automatically.
13741395
///
1396+
/// If `address` is provided, the node will connect to the peer at the given address before
1397+
/// opening the channel. If `address` is `None`, the node must already be connected to the
1398+
/// peer, otherwise [`Error::NotConnected`] will be returned.
1399+
///
13751400
/// If `push_to_counterparty_msat` is set, the given value will be pushed (read: sent) to the
13761401
/// channel counterparty on channel open. This can be useful to start out with the balance not
13771402
/// entirely shifted to one side, therefore allowing to receive payments from the getgo.
@@ -1380,8 +1405,8 @@ impl Node {
13801405
///
13811406
/// [`AnchorChannelsConfig::per_channel_reserve_sats`]: crate::config::AnchorChannelsConfig::per_channel_reserve_sats
13821407
pub fn open_announced_channel_with_all(
1383-
&self, node_id: PublicKey, address: SocketAddress, push_to_counterparty_msat: Option<u64>,
1384-
channel_config: Option<ChannelConfig>,
1408+
&self, node_id: PublicKey, address: Option<SocketAddress>,
1409+
push_to_counterparty_msat: Option<u64>, channel_config: Option<ChannelConfig>,
13851410
) -> Result<UserChannelId, Error> {
13861411
if let Err(err) = may_announce_channel(&self.config) {
13871412
log_error!(self.logger, "Failed to open announced channel as the node hasn't been sufficiently configured to act as a forwarding node: {err}");

tests/common/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ pub async fn open_channel_push_amt(
721721
node_a
722722
.open_announced_channel(
723723
node_b.node_id(),
724-
node_b.listening_addresses().unwrap().first().unwrap().clone(),
724+
node_b.listening_addresses().unwrap().first().cloned(),
725725
funding_amount_sat,
726726
push_amount_msat,
727727
None,
@@ -731,7 +731,7 @@ pub async fn open_channel_push_amt(
731731
node_a
732732
.open_channel(
733733
node_b.node_id(),
734-
node_b.listening_addresses().unwrap().first().unwrap().clone(),
734+
node_b.listening_addresses().unwrap().first().cloned(),
735735
funding_amount_sat,
736736
push_amount_msat,
737737
None,
@@ -755,7 +755,7 @@ pub async fn open_channel_with_all(
755755
node_a
756756
.open_announced_channel_with_all(
757757
node_b.node_id(),
758-
node_b.listening_addresses().unwrap().first().unwrap().clone(),
758+
node_b.listening_addresses().unwrap().first().cloned(),
759759
None,
760760
None,
761761
)
@@ -764,7 +764,7 @@ pub async fn open_channel_with_all(
764764
node_a
765765
.open_channel_with_all(
766766
node_b.node_id(),
767-
node_b.listening_addresses().unwrap().first().unwrap().clone(),
767+
node_b.listening_addresses().unwrap().first().cloned(),
768768
None,
769769
None,
770770
)
@@ -851,7 +851,7 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
851851
node_a
852852
.open_announced_channel(
853853
node_b.node_id(),
854-
node_b.listening_addresses().unwrap().first().unwrap().clone(),
854+
node_b.listening_addresses().unwrap().first().cloned(),
855855
funding_amount_sat,
856856
Some(push_msat),
857857
None,

tests/integration_tests_cln.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ async fn test_cln() {
8989
// Open the channel
9090
let funding_amount_sat = 1_000_000;
9191

92-
node.open_channel(cln_node_id, cln_address, funding_amount_sat, Some(500_000_000), None)
92+
node.open_channel(cln_node_id, Some(cln_address), funding_amount_sat, Some(500_000_000), None)
9393
.unwrap();
9494

9595
let funding_txo = common::expect_channel_pending_event!(node, cln_node_id);

tests/integration_tests_lnd.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ async fn test_lnd() {
7070
// Open the channel
7171
let funding_amount_sat = 1_000_000;
7272

73-
node.open_channel(lnd_node_id, lnd_address, funding_amount_sat, Some(500_000_000), None)
73+
node.open_channel(lnd_node_id, Some(lnd_address), funding_amount_sat, Some(500_000_000), None)
7474
.unwrap();
7575

7676
let funding_txo = common::expect_channel_pending_event!(node, lnd_node_id);

0 commit comments

Comments
 (0)