Skip to content

Commit 610b49b

Browse files
committed
Adds InboundChannelsConfig configuration
This commit aims to give two new configurations for node runners that want to control how inbound channels are requested. - `reject_announced_channels_requests`: Enable user to reject any request channel for announced channels. - `minimum_channel_size`: Permits node runner to set a minimum channel size for remote peers to open channels.
1 parent 0a2bccd commit 610b49b

File tree

5 files changed

+180
-4
lines changed

5 files changed

+180
-4
lines changed

bindings/ldk_node.udl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,19 @@ dictionary Config {
1313
u64 probing_liquidity_limit_multiplier;
1414
AnchorChannelsConfig? anchor_channels_config;
1515
SendingParameters? sending_parameters;
16+
InboundChannelsConfig inbound_channels_config;
1617
};
1718

1819
dictionary AnchorChannelsConfig {
1920
sequence<PublicKey> trusted_peers_no_reserve;
2021
u64 per_channel_reserve_sats;
2122
};
2223

24+
dictionary InboundChannelsConfig {
25+
boolean reject_announced_channel_requests;
26+
u64? minimum_channel_size;
27+
};
28+
2329
dictionary BackgroundSyncConfig {
2430
u64 onchain_wallet_sync_interval_secs;
2531
u64 lightning_wallet_sync_interval_secs;

src/config.rs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,12 @@ pub const WALLET_KEYS_SEED_LEN: usize = 64;
101101
/// | `trusted_peers_0conf` | [] |
102102
/// | `probing_liquidity_limit_multiplier` | 3 |
103103
/// | `log_level` | Debug |
104-
/// | `anchor_channels_config` | Some(..) |
104+
/// | `anchor_channels_config` | Some(..) |
105105
/// | `sending_parameters` | None |
106+
/// | `inbound_channels_config` . | ::Default |
106107
///
107-
/// See [`AnchorChannelsConfig`] and [`SendingParameters`] for more information regarding their
108-
/// respective default values.
108+
/// See [`AnchorChannelsConfig`], [`InboundChannelsConfig`] and [`SendingParameters`]
109+
/// for more information regarding their respective default values.
109110
///
110111
/// [`Node`]: crate::Node
111112
pub struct Config {
@@ -167,6 +168,11 @@ pub struct Config {
167168
/// **Note:** If unset, default parameters will be used, and you will be able to override the
168169
/// parameters on a per-payment basis in the corresponding method calls.
169170
pub sending_parameters: Option<SendingParameters>,
171+
/// Configuration options for inbound channels requests.
172+
///
173+
/// These options can be used to customize the behavior whenever a channel is requested by a
174+
/// remote peer.
175+
pub inbound_channels_config: InboundChannelsConfig,
170176
}
171177

172178
impl Default for Config {
@@ -181,10 +187,44 @@ impl Default for Config {
181187
anchor_channels_config: Some(AnchorChannelsConfig::default()),
182188
sending_parameters: None,
183189
node_alias: None,
190+
inbound_channels_config: InboundChannelsConfig::default(),
184191
}
185192
}
186193
}
187194

195+
/// Configuration options for inbound channels requests.
196+
///
197+
/// These options can be used to customize the behavior whenever a channel is requested by a
198+
/// remote peer.
199+
///
200+
/// ### Defaults
201+
///
202+
/// | Parameter | Value |
203+
/// |-------------------------------------|--------|
204+
/// | `reject_announced_channel_requests` | false |
205+
/// | `minimum_channel_size` | None |
206+
///
207+
208+
#[derive(Debug, Clone)]
209+
pub struct InboundChannelsConfig {
210+
/// Boolean flag indicating whether to reject announced channel requests.
211+
///
212+
/// If `true`, the node will reject any inbound channel requests with announced channel
213+
/// requests.
214+
pub reject_announced_channel_requests: bool,
215+
/// Optional minimum channel size in satoshis.
216+
///
217+
/// If set, the node will reject any inbound channel requests with a channel size smaller than
218+
/// the specified value.
219+
pub minimum_channel_size: Option<u64>,
220+
}
221+
222+
impl Default for InboundChannelsConfig {
223+
fn default() -> Self {
224+
Self { reject_announced_channel_requests: false, minimum_channel_size: None }
225+
}
226+
}
227+
188228
/// Configuration options pertaining to 'Anchor' channels, i.e., channels for which the
189229
/// `option_anchors_zero_fee_htlc_tx` channel type is negotiated.
190230
///

src/event.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,27 @@ where
10791079
is_announced,
10801080
params: _,
10811081
} => {
1082+
if is_announced
1083+
&& self.config.inbound_channels_config.reject_announced_channel_requests
1084+
{
1085+
log_error!(
1086+
self.logger,
1087+
"Rejecting inbound announced channel from peer {} due to reject_announced_channel_requests configuration",
1088+
counterparty_node_id
1089+
);
1090+
1091+
self.channel_manager
1092+
.force_close_without_broadcasting_txn(
1093+
&temporary_channel_id,
1094+
&counterparty_node_id,
1095+
"Channel request rejected".to_string(),
1096+
)
1097+
.unwrap_or_else(|e| {
1098+
log_error!(self.logger, "Failed to reject channel: {:?}", e)
1099+
});
1100+
return Ok(());
1101+
}
1102+
10821103
if is_announced {
10831104
if let Err(err) = may_announce_channel(&*self.config) {
10841105
log_error!(self.logger, "Rejecting inbound announced channel from peer {} due to missing configuration: {}", counterparty_node_id, err);
@@ -1096,6 +1117,29 @@ where
10961117
}
10971118
}
10981119

1120+
if funding_satoshis
1121+
< self.config.inbound_channels_config.minimum_channel_size.unwrap_or(0)
1122+
{
1123+
log_error!(
1124+
self.logger,
1125+
"Rejecting inbound announced channel from peer {} due to minimum channel size of {}sats",
1126+
counterparty_node_id,
1127+
self.config.inbound_channels_config.minimum_channel_size.unwrap_or(0),
1128+
);
1129+
1130+
self.channel_manager
1131+
.force_close_without_broadcasting_txn(
1132+
&temporary_channel_id,
1133+
&counterparty_node_id,
1134+
"Channel request rejected".to_string(),
1135+
)
1136+
.unwrap_or_else(|e| {
1137+
log_error!(self.logger, "Failed to reject channel: {:?}", e)
1138+
});
1139+
1140+
return Ok(());
1141+
}
1142+
10991143
let anchor_channel = channel_type.requires_anchors_zero_fee_htlc_tx();
11001144
if anchor_channel {
11011145
if let Some(anchor_channels_config) =

src/ffi/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
pub use crate::config::{
1414
default_config, AnchorChannelsConfig, BackgroundSyncConfig, ElectrumSyncConfig,
15-
EsploraSyncConfig, MaxDustHTLCExposure,
15+
EsploraSyncConfig, InboundChannelsConfig, MaxDustHTLCExposure,
1616
};
1717
pub use crate::graph::{ChannelInfo, ChannelUpdateInfo, NodeAnnouncementInfo, NodeInfo};
1818
pub use crate::liquidity::{LSPS1OrderStatus, LSPS2ServiceConfig, OnchainPaymentInfo, PaymentInfo};

tests/integration_tests_rust.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,92 @@ fn channel_open_fails_when_funds_insufficient() {
138138
);
139139
}
140140

141+
#[test]
142+
fn channel_open_fails_when_inbound_channels_config_rejects_announced_channels() {
143+
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
144+
let chain_source = TestChainSource::Esplora(&electrsd);
145+
let config_a = random_config(true);
146+
let node_a = setup_node(&chain_source, config_a, None);
147+
let mut config_b = random_config(true);
148+
config_b.node_config.inbound_channels_config.reject_announced_channel_requests = true;
149+
150+
let node_b = setup_node(&chain_source, config_b, None);
151+
152+
let addr_a = node_a.onchain_payment().new_address().unwrap();
153+
let addr_b = node_b.onchain_payment().new_address().unwrap();
154+
155+
let premine_amount_sat = 100_000;
156+
157+
premine_and_distribute_funds(
158+
&bitcoind.client,
159+
&electrsd.client,
160+
vec![addr_a, addr_b],
161+
Amount::from_sat(premine_amount_sat),
162+
);
163+
node_a.sync_wallets().unwrap();
164+
node_b.sync_wallets().unwrap();
165+
assert_eq!(node_a.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
166+
assert_eq!(node_b.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
167+
168+
println!("\nA -- open_channel -> B");
169+
node_a
170+
.open_announced_channel(
171+
node_b.node_id(),
172+
node_b.listening_addresses().unwrap().first().unwrap().clone(),
173+
20_000,
174+
None,
175+
None,
176+
)
177+
.unwrap();
178+
179+
assert_eq!(node_a.list_peers().first().unwrap().node_id, node_b.node_id());
180+
assert!(node_a.list_peers().first().unwrap().is_persisted);
181+
expect_event!(node_a, ChannelClosed);
182+
}
183+
184+
#[test]
185+
fn channel_open_fails_when_inbound_channels_config_has_min_channel_size() {
186+
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
187+
let chain_source = TestChainSource::Esplora(&electrsd);
188+
let config_a = random_config(true);
189+
let node_a = setup_node(&chain_source, config_a, None);
190+
let mut config_b = random_config(true);
191+
config_b.node_config.inbound_channels_config.minimum_channel_size = Some(100_000);
192+
193+
let node_b = setup_node(&chain_source, config_b, None);
194+
195+
let addr_a = node_a.onchain_payment().new_address().unwrap();
196+
let addr_b = node_b.onchain_payment().new_address().unwrap();
197+
198+
let premine_amount_sat = 100_000;
199+
200+
premine_and_distribute_funds(
201+
&bitcoind.client,
202+
&electrsd.client,
203+
vec![addr_a, addr_b],
204+
Amount::from_sat(premine_amount_sat),
205+
);
206+
node_a.sync_wallets().unwrap();
207+
node_b.sync_wallets().unwrap();
208+
assert_eq!(node_a.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
209+
assert_eq!(node_b.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
210+
211+
println!("\nA -- open_channel -> B");
212+
node_a
213+
.open_announced_channel(
214+
node_b.node_id(),
215+
node_b.listening_addresses().unwrap().first().unwrap().clone(),
216+
20_000,
217+
None,
218+
None,
219+
)
220+
.unwrap();
221+
222+
assert_eq!(node_a.list_peers().first().unwrap().node_id, node_b.node_id());
223+
assert!(node_a.list_peers().first().unwrap().is_persisted);
224+
expect_event!(node_a, ChannelClosed);
225+
}
226+
141227
#[test]
142228
fn multi_hop_sending() {
143229
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();

0 commit comments

Comments
 (0)