Skip to content

Commit 90e6a9b

Browse files
committed
Tighten requirements to unset anchor channels conf
We previously allowed users to unset the anchor channels config while they still had anchor channels open or unresolved. This allowed our users to drain their anchor reserves while still having anchor channels open. This is particularly dangerous for 0FC channels, as these rely entirely on anchor bumps to force-close the channel. Here, we require that a user first close and resolve all their existing anchor channels before unsetting their anchor channels config to disable the opening of fresh anchor channels.
1 parent 5eab461 commit 90e6a9b

1 file changed

Lines changed: 26 additions & 11 deletions

File tree

‎src/lib.rs‎

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ use lightning_background_processor::process_events_async;
161161
pub use lightning_invoice;
162162
pub use lightning_liquidity;
163163
pub use lightning_types;
164-
use lightning_types::features::NodeFeatures as LdkNodeFeatures;
164+
use lightning_types::features::{ChannelTypeFeatures, NodeFeatures as LdkNodeFeatures};
165165
use liquidity::LiquiditySource;
166166
use lnurl_auth::LnurlAuth;
167167
use logger::{log_debug, log_error, log_info, log_trace, LdkLogger, Logger};
@@ -214,6 +214,11 @@ impl LeakChecker {
214214
}
215215
}
216216

217+
pub(crate) fn requires_anchor_channel_type(channel_type: &ChannelTypeFeatures) -> bool {
218+
channel_type.requires_anchors_zero_fee_htlc_tx()
219+
|| channel_type.requires_anchor_zero_fee_commitments()
220+
}
221+
217222
/// The main interface object of LDK Node, wrapping the necessary LDK and BDK functionalities.
218223
///
219224
/// Needs to be initialized and instantiated through [`Builder::build`].
@@ -285,16 +290,29 @@ impl Node {
285290
e
286291
})?;
287292

288-
let any_current_0fc_channels =
289-
self.chain_monitor.list_monitors().into_iter().any(|channel_id| {
293+
let any_current_anchor_channels =
294+
self.channel_manager.list_channels().into_iter().any(|channel| {
295+
channel
296+
.channel_shutdown_state
297+
.map_or(true, |s| s != ChannelShutdownState::ShutdownComplete)
298+
&& channel.channel_type.as_ref().map_or(false, requires_anchor_channel_type)
299+
}) || self.chain_monitor.list_monitors().into_iter().any(|channel_id| {
290300
self.chain_monitor
291301
.get_monitor(channel_id)
292-
.map(|monitor| {
293-
monitor.channel_type_features().requires_anchor_zero_fee_commitments()
294-
})
302+
.map(|monitor| requires_anchor_channel_type(&monitor.channel_type_features()))
295303
.unwrap_or(false)
296304
});
297305

306+
if any_current_anchor_channels && self.config.anchor_channels_config.is_none() {
307+
log_error!(
308+
self.logger,
309+
"Cannot remove the anchor channels config while anchor channels \
310+
are still open or unresolved. You must close and resolve all anchor \
311+
channels before disabling anchor channels."
312+
);
313+
return Err(Error::ChannelConfigUpdateFailed);
314+
}
315+
298316
// Block to ensure we update our fee rate cache once on startup.
299317
// Also take this opportunity to make sure our chain source supports any current or
300318
// future 0FC channels.
@@ -303,7 +321,7 @@ impl Node {
303321
tokio::try_join!(
304322
chain_source.update_fee_rate_estimates(),
305323
chain_source.validate_zero_fee_commitments_support_if_required(
306-
any_current_0fc_channels || self.config.anchor_channels_config.is_some()
324+
self.config.anchor_channels_config.is_some()
307325
)
308326
)
309327
})?;
@@ -2334,10 +2352,7 @@ pub(crate) fn total_anchor_channels_reserve_sats(
23342352
!anchor_channels_config.trusted_peers_no_reserve.contains(&c.counterparty.node_id)
23352353
&& c.channel_shutdown_state
23362354
.map_or(true, |s| s != ChannelShutdownState::ShutdownComplete)
2337-
&& c.channel_type.as_ref().map_or(false, |t| {
2338-
t.requires_anchors_zero_fee_htlc_tx()
2339-
|| t.requires_anchor_zero_fee_commitments()
2340-
})
2355+
&& c.channel_type.as_ref().map_or(false, requires_anchor_channel_type)
23412356
})
23422357
.count() as u64
23432358
* anchor_channels_config.per_channel_reserve_sats

0 commit comments

Comments
 (0)