@@ -3586,55 +3586,6 @@ macro_rules! handle_new_monitor_update {
35863586 }};
35873587}
35883588
3589- /// Do not call this directly, use `convert_channel_err` instead.
3590- #[rustfmt::skip]
3591- macro_rules! locked_close_channel {
3592- ($self: ident, $chan_context: expr, UNFUNDED) => {{
3593- $self.short_to_chan_info.write().unwrap().remove(&$chan_context.outbound_scid_alias());
3594- // If the channel was never confirmed on-chain prior to its closure, remove the
3595- // outbound SCID alias we used for it from the collision-prevention set. While we
3596- // generally want to avoid ever re-using an outbound SCID alias across all channels, we
3597- // also don't want a counterparty to be able to trivially cause a memory leak by simply
3598- // opening a million channels with us which are closed before we ever reach the funding
3599- // stage.
3600- let alias_removed = $self.outbound_scid_aliases.lock().unwrap().remove(&$chan_context.outbound_scid_alias());
3601- debug_assert!(alias_removed);
3602- }};
3603- ($self: ident, $closed_channel_monitor_update_ids: expr, $in_flight_monitor_updates: expr, $funded_chan: expr, $shutdown_res_mut: expr, FUNDED) => {{
3604- if let Some((_, funding_txo, _, update)) = $shutdown_res_mut.monitor_update.take() {
3605- handle_new_monitor_update_locked_actions_handled_by_caller!(
3606- $self, funding_txo, update, $in_flight_monitor_updates, $funded_chan.context
3607- );
3608- }
3609- // If there's a possibility that we need to generate further monitor updates for this
3610- // channel, we need to store the last update_id of it. However, we don't want to insert
3611- // into the map (which prevents the `PeerState` from being cleaned up) for channels that
3612- // never even got confirmations (which would open us up to DoS attacks).
3613- let update_id = $funded_chan.context.get_latest_monitor_update_id();
3614- if $funded_chan.funding.get_funding_tx_confirmation_height().is_some() || $funded_chan.context.minimum_depth(&$funded_chan.funding) == Some(0) || update_id > 1 {
3615- let chan_id = $funded_chan.context.channel_id();
3616- $closed_channel_monitor_update_ids.insert(chan_id, update_id);
3617- }
3618- let mut short_to_chan_info = $self.short_to_chan_info.write().unwrap();
3619- if let Some(short_id) = $funded_chan.funding.get_short_channel_id() {
3620- short_to_chan_info.remove(&short_id);
3621- } else {
3622- // If the channel was never confirmed on-chain prior to its closure, remove the
3623- // outbound SCID alias we used for it from the collision-prevention set. While we
3624- // generally want to avoid ever re-using an outbound SCID alias across all channels, we
3625- // also don't want a counterparty to be able to trivially cause a memory leak by simply
3626- // opening a million channels with us which are closed before we ever reach the funding
3627- // stage.
3628- let alias_removed = $self.outbound_scid_aliases.lock().unwrap().remove(&$funded_chan.context.outbound_scid_alias());
3629- debug_assert!(alias_removed);
3630- }
3631- short_to_chan_info.remove(&$funded_chan.context.outbound_scid_alias());
3632- for scid in $funded_chan.context.historical_scids() {
3633- short_to_chan_info.remove(scid);
3634- }
3635- }}
3636- }
3637-
36383589fn convert_channel_err_internal<Close: FnOnce(ClosureReason, &str) -> (ShutdownResult, Option<(msgs::ChannelUpdate, NodeId, NodeId)>)>(
36393590 err: ChannelError, chan_id: ChannelId, close: Close,
36403591) -> (bool, MsgHandleErrInternal) {
@@ -3686,7 +3637,38 @@ where
36863637 let chan_update = cm.get_channel_update_for_broadcast(chan).ok();
36873638
36883639 log_error!(logger, "Closed channel {} due to close-required error: {}", chan_id, msg);
3689- locked_close_channel!(cm, closed_channel_monitor_update_ids, in_flight_monitor_updates, chan, shutdown_res, FUNDED);
3640+
3641+ if let Some((_, funding_txo, _, update)) = shutdown_res.monitor_update.take() {
3642+ handle_new_monitor_update_locked_actions_handled_by_caller!(
3643+ cm, funding_txo, update, in_flight_monitor_updates, chan.context
3644+ );
3645+ }
3646+ // If there's a possibility that we need to generate further monitor updates for this
3647+ // channel, we need to store the last update_id of it. However, we don't want to insert
3648+ // into the map (which prevents the `PeerState` from being cleaned up) for channels that
3649+ // never even got confirmations (which would open us up to DoS attacks).
3650+ let update_id = chan.context.get_latest_monitor_update_id();
3651+ if chan.funding.get_funding_tx_confirmation_height().is_some() || chan.context.minimum_depth(&chan.funding) == Some(0) || update_id > 1 {
3652+ closed_channel_monitor_update_ids.insert(chan_id, update_id);
3653+ }
3654+ let mut short_to_chan_info = cm.short_to_chan_info.write().unwrap();
3655+ if let Some(short_id) = chan.funding.get_short_channel_id() {
3656+ short_to_chan_info.remove(&short_id);
3657+ } else {
3658+ // If the channel was never confirmed on-chain prior to its closure, remove the
3659+ // outbound SCID alias we used for it from the collision-prevention set. While we
3660+ // generally want to avoid ever re-using an outbound SCID alias across all channels, we
3661+ // also don't want a counterparty to be able to trivially cause a memory leak by simply
3662+ // opening a million channels with us which are closed before we ever reach the funding
3663+ // stage.
3664+ let alias_removed = cm.outbound_scid_aliases.lock().unwrap().remove(&chan.context.outbound_scid_alias());
3665+ debug_assert!(alias_removed);
3666+ }
3667+ short_to_chan_info.remove(&chan.context.outbound_scid_alias());
3668+ for scid in chan.context.historical_scids() {
3669+ short_to_chan_info.remove(scid);
3670+ }
3671+
36903672 (shutdown_res, chan_update)
36913673 })
36923674}
@@ -3707,7 +3689,15 @@ where
37073689
37083690 let shutdown_res = chan.force_shutdown(reason);
37093691 log_error!(logger, "Closed channel {} due to close-required error: {}", chan_id, msg);
3710- locked_close_channel!(cm, chan.context(), UNFUNDED);
3692+ cm.short_to_chan_info.write().unwrap().remove(&chan.context().outbound_scid_alias());
3693+ // If the channel was never confirmed on-chain prior to its closure, remove the
3694+ // outbound SCID alias we used for it from the collision-prevention set. While we
3695+ // generally want to avoid ever re-using an outbound SCID alias across all channels, we
3696+ // also don't want a counterparty to be able to trivially cause a memory leak by simply
3697+ // opening a million channels with us which are closed before we ever reach the funding
3698+ // stage.
3699+ let alias_removed = cm.outbound_scid_aliases.lock().unwrap().remove(&chan.context().outbound_scid_alias());
3700+ debug_assert!(alias_removed);
37113701 (shutdown_res, None)
37123702 })
37133703}
@@ -4495,15 +4485,15 @@ where
44954485 self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver, None);
44964486 }
44974487 if let Some((_, funding_txo, _channel_id, monitor_update)) = shutdown_res.monitor_update {
4498- debug_assert!(false, "This should have been handled in `locked_close_channel `");
4488+ debug_assert!(false, "This should have been handled in `convert_channel_err `");
44994489 self.apply_post_close_monitor_update(shutdown_res.counterparty_node_id, shutdown_res.channel_id, funding_txo, monitor_update);
45004490 }
45014491 if self.background_events_processed_since_startup.load(Ordering::Acquire) {
45024492 // If a `ChannelMonitorUpdate` was applied (i.e. any time we have a funding txo and are
45034493 // not in the startup sequence) check if we need to handle any
45044494 // `MonitorUpdateCompletionAction`s.
45054495 // TODO: If we do the `in_flight_monitor_updates.is_empty()` check in
4506- // `locked_close_channel ` we can skip the locks here.
4496+ // `convert_channel_err ` we can skip the locks here.
45074497 if shutdown_res.channel_funding_txo.is_some() {
45084498 self.channel_monitor_updated(&shutdown_res.channel_id, None, &shutdown_res.counterparty_node_id);
45094499 }
@@ -10335,10 +10325,9 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1033510325 let funded_channel_id = chan.context.channel_id();
1033610326
1033710327 macro_rules! fail_chan { ($err: expr) => { {
10338- // Note that at this point we've filled in the funding outpoint on our
10339- // channel, but its actually in conflict with another channel. Thus, if
10340- // we call `convert_channel_err` immediately (thus calling
10341- // `locked_close_channel`), we'll remove the existing channel from `outpoint_to_peer`.
10328+ // Note that at this point we've filled in the funding outpoint on our channel, but its
10329+ // actually in conflict with another channel. Thus, if we call `convert_channel_err`
10330+ // immediately, we'll remove the existing channel from `outpoint_to_peer`.
1034210331 // Thus, we must first unset the funding outpoint on the channel.
1034310332 let err = ChannelError::close($err.to_owned());
1034410333 chan.unset_funding_info();
0 commit comments