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