@@ -3608,55 +3608,6 @@ macro_rules! handle_new_monitor_update {
36083608 }};
36093609}
36103610
3611- /// Do not call this directly, use `convert_channel_err` instead.
3612- #[rustfmt::skip]
3613- macro_rules! locked_close_channel {
3614- ($self: ident, $chan_context: expr, UNFUNDED) => {{
3615- $self.short_to_chan_info.write().unwrap().remove(&$chan_context.outbound_scid_alias());
3616- // If the channel was never confirmed on-chain prior to its closure, remove the
3617- // outbound SCID alias we used for it from the collision-prevention set. While we
3618- // generally want to avoid ever re-using an outbound SCID alias across all channels, we
3619- // also don't want a counterparty to be able to trivially cause a memory leak by simply
3620- // opening a million channels with us which are closed before we ever reach the funding
3621- // stage.
3622- let alias_removed = $self.outbound_scid_aliases.lock().unwrap().remove(&$chan_context.outbound_scid_alias());
3623- debug_assert!(alias_removed);
3624- }};
3625- ($self: ident, $closed_channel_monitor_update_ids: expr, $in_flight_monitor_updates: expr, $funded_chan: expr, $shutdown_res_mut: expr, FUNDED) => {{
3626- if let Some((_, funding_txo, _, update)) = $shutdown_res_mut.monitor_update.take() {
3627- handle_new_monitor_update_locked_actions_handled_by_caller!(
3628- $self, funding_txo, update, $in_flight_monitor_updates, $funded_chan.context
3629- );
3630- }
3631- // If there's a possibility that we need to generate further monitor updates for this
3632- // channel, we need to store the last update_id of it. However, we don't want to insert
3633- // into the map (which prevents the `PeerState` from being cleaned up) for channels that
3634- // never even got confirmations (which would open us up to DoS attacks).
3635- let update_id = $funded_chan.context.get_latest_monitor_update_id();
3636- if $funded_chan.funding.get_funding_tx_confirmation_height().is_some() || $funded_chan.context.minimum_depth(&$funded_chan.funding) == Some(0) || update_id > 1 {
3637- let chan_id = $funded_chan.context.channel_id();
3638- $closed_channel_monitor_update_ids.insert(chan_id, update_id);
3639- }
3640- let mut short_to_chan_info = $self.short_to_chan_info.write().unwrap();
3641- if let Some(short_id) = $funded_chan.funding.get_short_channel_id() {
3642- short_to_chan_info.remove(&short_id);
3643- } else {
3644- // If the channel was never confirmed on-chain prior to its closure, remove the
3645- // outbound SCID alias we used for it from the collision-prevention set. While we
3646- // generally want to avoid ever re-using an outbound SCID alias across all channels, we
3647- // also don't want a counterparty to be able to trivially cause a memory leak by simply
3648- // opening a million channels with us which are closed before we ever reach the funding
3649- // stage.
3650- let alias_removed = $self.outbound_scid_aliases.lock().unwrap().remove(&$funded_chan.context.outbound_scid_alias());
3651- debug_assert!(alias_removed);
3652- }
3653- short_to_chan_info.remove(&$funded_chan.context.outbound_scid_alias());
3654- for scid in $funded_chan.context.historical_scids() {
3655- short_to_chan_info.remove(scid);
3656- }
3657- }}
3658- }
3659-
36603611fn convert_channel_err_internal<
36613612 Close: FnOnce(ClosureReason, &str) -> (ShutdownResult, Option<(msgs::ChannelUpdate, NodeId, NodeId)>),
36623613>(
@@ -3687,8 +3638,8 @@ fn convert_channel_err_internal<
36873638}
36883639
36893640fn convert_funded_channel_err_internal<SP: Deref, CM: AChannelManager<SP = SP>>(
3690- cm: &CM, closed_update_ids : &mut BTreeMap<ChannelId, u64>,
3691- in_flight_updates : &mut BTreeMap<ChannelId, (OutPoint, Vec<ChannelMonitorUpdate>)>,
3641+ cm: &CM, closed_channel_monitor_update_ids : &mut BTreeMap<ChannelId, u64>,
3642+ in_flight_monitor_updates : &mut BTreeMap<ChannelId, (OutPoint, Vec<ChannelMonitorUpdate>)>,
36923643 coop_close_shutdown_res: Option<ShutdownResult>, err: ChannelError,
36933644 chan: &mut FundedChannel<SP>,
36943645) -> (bool, MsgHandleErrInternal)
@@ -3706,7 +3657,38 @@ where
37063657 let chan_update = cm.get_channel_update_for_broadcast(chan).ok();
37073658
37083659 log_error!(logger, "Closed channel due to close-required error: {}", msg);
3709- locked_close_channel!(cm, closed_update_ids, in_flight_updates, chan, shutdown_res, FUNDED);
3660+
3661+ if let Some((_, funding_txo, _, update)) = shutdown_res.monitor_update.take() {
3662+ handle_new_monitor_update_locked_actions_handled_by_caller!(
3663+ cm, funding_txo, update, in_flight_monitor_updates, chan.context
3664+ );
3665+ }
3666+ // If there's a possibility that we need to generate further monitor updates for this
3667+ // channel, we need to store the last update_id of it. However, we don't want to insert
3668+ // into the map (which prevents the `PeerState` from being cleaned up) for channels that
3669+ // never even got confirmations (which would open us up to DoS attacks).
3670+ let update_id = chan.context.get_latest_monitor_update_id();
3671+ if chan.funding.get_funding_tx_confirmation_height().is_some() || chan.context.minimum_depth(&chan.funding) == Some(0) || update_id > 1 {
3672+ closed_channel_monitor_update_ids.insert(chan_id, update_id);
3673+ }
3674+ let mut short_to_chan_info = cm.short_to_chan_info.write().unwrap();
3675+ if let Some(short_id) = chan.funding.get_short_channel_id() {
3676+ short_to_chan_info.remove(&short_id);
3677+ } else {
3678+ // If the channel was never confirmed on-chain prior to its closure, remove the
3679+ // outbound SCID alias we used for it from the collision-prevention set. While we
3680+ // generally want to avoid ever re-using an outbound SCID alias across all channels, we
3681+ // also don't want a counterparty to be able to trivially cause a memory leak by simply
3682+ // opening a million channels with us which are closed before we ever reach the funding
3683+ // stage.
3684+ let alias_removed = cm.outbound_scid_aliases.lock().unwrap().remove(&chan.context.outbound_scid_alias());
3685+ debug_assert!(alias_removed);
3686+ }
3687+ short_to_chan_info.remove(&chan.context.outbound_scid_alias());
3688+ for scid in chan.context.historical_scids() {
3689+ short_to_chan_info.remove(scid);
3690+ }
3691+
37103692 (shutdown_res, chan_update)
37113693 })
37123694}
@@ -3724,7 +3706,15 @@ where
37243706
37253707 let shutdown_res = chan.force_shutdown(reason);
37263708 log_error!(logger, "Closed channel due to close-required error: {}", msg);
3727- locked_close_channel!(cm, chan.context(), UNFUNDED);
3709+ cm.short_to_chan_info.write().unwrap().remove(&chan.context().outbound_scid_alias());
3710+ // If the channel was never confirmed on-chain prior to its closure, remove the
3711+ // outbound SCID alias we used for it from the collision-prevention set. While we
3712+ // generally want to avoid ever re-using an outbound SCID alias across all channels, we
3713+ // also don't want a counterparty to be able to trivially cause a memory leak by simply
3714+ // opening a million channels with us which are closed before we ever reach the funding
3715+ // stage.
3716+ let alias_removed = cm.outbound_scid_aliases.lock().unwrap().remove(&chan.context().outbound_scid_alias());
3717+ debug_assert!(alias_removed);
37283718 (shutdown_res, None)
37293719 })
37303720}
@@ -4512,15 +4502,15 @@ where
45124502 self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver, None);
45134503 }
45144504 if let Some((_, funding_txo, _channel_id, monitor_update)) = shutdown_res.monitor_update {
4515- debug_assert!(false, "This should have been handled in `locked_close_channel `");
4505+ debug_assert!(false, "This should have been handled in `convert_channel_err `");
45164506 self.apply_post_close_monitor_update(shutdown_res.counterparty_node_id, shutdown_res.channel_id, funding_txo, monitor_update);
45174507 }
45184508 if self.background_events_processed_since_startup.load(Ordering::Acquire) {
45194509 // If a `ChannelMonitorUpdate` was applied (i.e. any time we have a funding txo and are
45204510 // not in the startup sequence) check if we need to handle any
45214511 // `MonitorUpdateCompletionAction`s.
45224512 // TODO: If we do the `in_flight_monitor_updates.is_empty()` check in
4523- // `locked_close_channel ` we can skip the locks here.
4513+ // `convert_channel_err ` we can skip the locks here.
45244514 if shutdown_res.channel_funding_txo.is_some() {
45254515 self.channel_monitor_updated(&shutdown_res.channel_id, None, &shutdown_res.counterparty_node_id);
45264516 }
@@ -10357,10 +10347,9 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1035710347 let funded_channel_id = chan.context.channel_id();
1035810348
1035910349 macro_rules! fail_chan { ($err: expr) => { {
10360- // Note that at this point we've filled in the funding outpoint on our
10361- // channel, but its actually in conflict with another channel. Thus, if
10362- // we call `convert_channel_err` immediately (thus calling
10363- // `locked_close_channel`), we'll remove the existing channel from `outpoint_to_peer`.
10350+ // Note that at this point we've filled in the funding outpoint on our channel, but its
10351+ // actually in conflict with another channel. Thus, if we call `convert_channel_err`
10352+ // immediately, we'll remove the existing channel from `outpoint_to_peer`.
1036410353 // Thus, we must first unset the funding outpoint on the channel.
1036510354 let err = ChannelError::close($err.to_owned());
1036610355 chan.unset_funding_info();
0 commit comments