@@ -3255,176 +3255,6 @@ macro_rules! handle_error {
32553255 } };
32563256}
32573257
3258- /// Do not call this directly, use `convert_channel_err` instead.
3259- #[rustfmt::skip]
3260- macro_rules! locked_close_channel {
3261- ($self: ident, $chan_context: expr, UNFUNDED) => {{
3262- $self.short_to_chan_info.write().unwrap().remove(&$chan_context.outbound_scid_alias());
3263- // If the channel was never confirmed on-chain prior to its closure, remove the
3264- // outbound SCID alias we used for it from the collision-prevention set. While we
3265- // generally want to avoid ever re-using an outbound SCID alias across all channels, we
3266- // also don't want a counterparty to be able to trivially cause a memory leak by simply
3267- // opening a million channels with us which are closed before we ever reach the funding
3268- // stage.
3269- let alias_removed = $self.outbound_scid_aliases.lock().unwrap().remove(&$chan_context.outbound_scid_alias());
3270- debug_assert!(alias_removed);
3271- }};
3272- ($self: ident, $peer_state: expr, $funded_chan: expr, $shutdown_res_mut: expr, FUNDED) => {{
3273- if let Some((_, funding_txo, _, update)) = $shutdown_res_mut.monitor_update.take() {
3274- handle_new_monitor_update_locked_actions_handled_by_caller!(
3275- $self, funding_txo, update, $peer_state, $funded_chan.context
3276- );
3277- }
3278- // If there's a possibility that we need to generate further monitor updates for this
3279- // channel, we need to store the last update_id of it. However, we don't want to insert
3280- // into the map (which prevents the `PeerState` from being cleaned up) for channels that
3281- // never even got confirmations (which would open us up to DoS attacks).
3282- let update_id = $funded_chan.context.get_latest_monitor_update_id();
3283- if $funded_chan.funding.get_funding_tx_confirmation_height().is_some() || $funded_chan.context.minimum_depth(&$funded_chan.funding) == Some(0) || update_id > 1 {
3284- let chan_id = $funded_chan.context.channel_id();
3285- $peer_state.closed_channel_monitor_update_ids.insert(chan_id, update_id);
3286- }
3287- let mut short_to_chan_info = $self.short_to_chan_info.write().unwrap();
3288- if let Some(short_id) = $funded_chan.funding.get_short_channel_id() {
3289- short_to_chan_info.remove(&short_id);
3290- } else {
3291- // If the channel was never confirmed on-chain prior to its closure, remove the
3292- // outbound SCID alias we used for it from the collision-prevention set. While we
3293- // generally want to avoid ever re-using an outbound SCID alias across all channels, we
3294- // also don't want a counterparty to be able to trivially cause a memory leak by simply
3295- // opening a million channels with us which are closed before we ever reach the funding
3296- // stage.
3297- let alias_removed = $self.outbound_scid_aliases.lock().unwrap().remove(&$funded_chan.context.outbound_scid_alias());
3298- debug_assert!(alias_removed);
3299- }
3300- short_to_chan_info.remove(&$funded_chan.context.outbound_scid_alias());
3301- for scid in $funded_chan.context.historical_scids() {
3302- short_to_chan_info.remove(scid);
3303- }
3304- }}
3305- }
3306-
3307- /// When a channel is removed, two things need to happen:
3308- /// (a) This must be called in the same `per_peer_state` lock as the channel-closing action,
3309- /// (b) [`handle_error`] needs to be called without holding any locks (except
3310- /// [`ChannelManager::total_consistency_lock`]), which then calls
3311- /// [`ChannelManager::finish_close_channel`].
3312- ///
3313- /// Note that this step can be skipped if the channel was never opened (through the creation of a
3314- /// [`ChannelMonitor`]/channel funding transaction) to begin with.
3315- ///
3316- /// Returns `(boolean indicating if we should remove the Channel object from memory, a mapped
3317- /// error)`, except in the `COOP_CLOSE` case, where the bool is elided (it is always implicitly
3318- /// true).
3319- #[rustfmt::skip]
3320- macro_rules! convert_channel_err {
3321- ($self: ident, $peer_state: expr, $err: expr, $chan: expr, $close: expr, $locked_close: expr, $channel_id: expr, _internal) => { {
3322- match $err {
3323- ChannelError::Warn(msg) => {
3324- (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Warn(msg), $channel_id))
3325- },
3326- ChannelError::WarnAndDisconnect(msg) => {
3327- (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::WarnAndDisconnect(msg), $channel_id))
3328- },
3329- ChannelError::Ignore(msg) => {
3330- (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore(msg), $channel_id))
3331- },
3332- ChannelError::Abort(reason) => {
3333- (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Abort(reason), $channel_id))
3334- },
3335- ChannelError::Close((msg, reason)) => {
3336- let (mut shutdown_res, chan_update) = $close(reason);
3337- let logger = WithChannelContext::from(&$self.logger, &$chan.context(), None);
3338- log_error!(logger, "Closed channel due to close-required error: {}", msg);
3339- $locked_close(&mut shutdown_res, $chan);
3340- let err =
3341- MsgHandleErrInternal::from_finish_shutdown(msg, $channel_id, shutdown_res, chan_update);
3342- (true, err)
3343- },
3344- ChannelError::SendError(msg) => {
3345- (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::SendError(msg), $channel_id))
3346- },
3347- }
3348- } };
3349- ($self: ident, $peer_state: expr, $shutdown_result: expr, $funded_channel: expr, COOP_CLOSED) => { {
3350- let chan_id = $funded_channel.context.channel_id();
3351- let reason = ChannelError::Close(("Coop Closed".to_owned(), $shutdown_result.closure_reason.clone()));
3352- let do_close = |_| {
3353- (
3354- $shutdown_result,
3355- $self.get_channel_update_for_broadcast(&$funded_channel).ok(),
3356- )
3357- };
3358- let mut locked_close = |shutdown_res_mut: &mut ShutdownResult, funded_channel: &mut FundedChannel<_>| {
3359- locked_close_channel!($self, $peer_state, funded_channel, shutdown_res_mut, FUNDED);
3360- };
3361- let (close, mut err) =
3362- convert_channel_err!($self, $peer_state, reason, $funded_channel, do_close, locked_close, chan_id, _internal);
3363- err.dont_send_error_message();
3364- debug_assert!(close);
3365- err
3366- } };
3367- ($self: ident, $peer_state: expr, $err: expr, $funded_channel: expr, FUNDED_CHANNEL) => { {
3368- let chan_id = $funded_channel.context.channel_id();
3369- let mut do_close = |reason| {
3370- (
3371- $funded_channel.force_shutdown(reason),
3372- $self.get_channel_update_for_broadcast(&$funded_channel).ok(),
3373- )
3374- };
3375- let mut locked_close = |shutdown_res_mut: &mut ShutdownResult, funded_channel: &mut FundedChannel<_>| {
3376- locked_close_channel!($self, $peer_state, funded_channel, shutdown_res_mut, FUNDED);
3377- };
3378- convert_channel_err!($self, $peer_state, $err, $funded_channel, do_close, locked_close, chan_id, _internal)
3379- } };
3380- ($self: ident, $peer_state: expr, $err: expr, $channel: expr, UNFUNDED_CHANNEL) => { {
3381- let chan_id = $channel.context().channel_id();
3382- let mut do_close = |reason| { ($channel.force_shutdown(reason), None) };
3383- let locked_close = |_, chan: &mut Channel<_>| { locked_close_channel!($self, chan.context(), UNFUNDED); };
3384- convert_channel_err!($self, $peer_state, $err, $channel, do_close, locked_close, chan_id, _internal)
3385- } };
3386- ($self: ident, $peer_state: expr, $err: expr, $channel: expr) => {
3387- match $channel.as_funded_mut() {
3388- Some(funded_channel) => {
3389- convert_channel_err!($self, $peer_state, $err, funded_channel, FUNDED_CHANNEL)
3390- },
3391- None => {
3392- convert_channel_err!($self, $peer_state, $err, $channel, UNFUNDED_CHANNEL)
3393- },
3394- }
3395- };
3396- }
3397-
3398- macro_rules! break_channel_entry {
3399- ($self: ident, $peer_state: expr, $res: expr, $entry: expr) => {
3400- match $res {
3401- Ok(res) => res,
3402- Err(e) => {
3403- let (drop, res) = convert_channel_err!($self, $peer_state, e, $entry.get_mut());
3404- if drop {
3405- $entry.remove_entry();
3406- }
3407- break Err(res);
3408- },
3409- }
3410- };
3411- }
3412-
3413- macro_rules! try_channel_entry {
3414- ($self: ident, $peer_state: expr, $res: expr, $entry: expr) => {
3415- match $res {
3416- Ok(res) => res,
3417- Err(e) => {
3418- let (drop, res) = convert_channel_err!($self, $peer_state, e, $entry.get_mut());
3419- if drop {
3420- $entry.remove_entry();
3421- }
3422- return Err(res);
3423- },
3424- }
3425- };
3426- }
3427-
34283258macro_rules! send_channel_ready {
34293259 ($self: ident, $pending_msg_events: expr, $channel: expr, $channel_ready_msg: expr) => {{
34303260 if $channel.context.is_connected() {
@@ -3778,6 +3608,176 @@ macro_rules! handle_new_monitor_update {
37783608 }};
37793609}
37803610
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, $peer_state: 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, $peer_state, $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+ $peer_state.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+
3660+ /// When a channel is removed, two things need to happen:
3661+ /// (a) This must be called in the same `per_peer_state` lock as the channel-closing action,
3662+ /// (b) [`handle_error`] needs to be called without holding any locks (except
3663+ /// [`ChannelManager::total_consistency_lock`]), which then calls
3664+ /// [`ChannelManager::finish_close_channel`].
3665+ ///
3666+ /// Note that this step can be skipped if the channel was never opened (through the creation of a
3667+ /// [`ChannelMonitor`]/channel funding transaction) to begin with.
3668+ ///
3669+ /// Returns `(boolean indicating if we should remove the Channel object from memory, a mapped
3670+ /// error)`, except in the `COOP_CLOSE` case, where the bool is elided (it is always implicitly
3671+ /// true).
3672+ #[rustfmt::skip]
3673+ macro_rules! convert_channel_err {
3674+ ($self: ident, $peer_state: expr, $err: expr, $chan: expr, $close: expr, $locked_close: expr, $channel_id: expr, _internal) => { {
3675+ match $err {
3676+ ChannelError::Warn(msg) => {
3677+ (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Warn(msg), $channel_id))
3678+ },
3679+ ChannelError::WarnAndDisconnect(msg) => {
3680+ (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::WarnAndDisconnect(msg), $channel_id))
3681+ },
3682+ ChannelError::Ignore(msg) => {
3683+ (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore(msg), $channel_id))
3684+ },
3685+ ChannelError::Abort(reason) => {
3686+ (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Abort(reason), $channel_id))
3687+ },
3688+ ChannelError::Close((msg, reason)) => {
3689+ let (mut shutdown_res, chan_update) = $close(reason);
3690+ let logger = WithChannelContext::from(&$self.logger, &$chan.context(), None);
3691+ log_error!(logger, "Closed channel due to close-required error: {}", msg);
3692+ $locked_close(&mut shutdown_res, $chan);
3693+ let err =
3694+ MsgHandleErrInternal::from_finish_shutdown(msg, $channel_id, shutdown_res, chan_update);
3695+ (true, err)
3696+ },
3697+ ChannelError::SendError(msg) => {
3698+ (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::SendError(msg), $channel_id))
3699+ },
3700+ }
3701+ } };
3702+ ($self: ident, $peer_state: expr, $shutdown_result: expr, $funded_channel: expr, COOP_CLOSED) => { {
3703+ let chan_id = $funded_channel.context.channel_id();
3704+ let reason = ChannelError::Close(("Coop Closed".to_owned(), $shutdown_result.closure_reason.clone()));
3705+ let do_close = |_| {
3706+ (
3707+ $shutdown_result,
3708+ $self.get_channel_update_for_broadcast(&$funded_channel).ok(),
3709+ )
3710+ };
3711+ let mut locked_close = |shutdown_res_mut: &mut ShutdownResult, funded_channel: &mut FundedChannel<_>| {
3712+ locked_close_channel!($self, $peer_state, funded_channel, shutdown_res_mut, FUNDED);
3713+ };
3714+ let (close, mut err) =
3715+ convert_channel_err!($self, $peer_state, reason, $funded_channel, do_close, locked_close, chan_id, _internal);
3716+ err.dont_send_error_message();
3717+ debug_assert!(close);
3718+ err
3719+ } };
3720+ ($self: ident, $peer_state: expr, $err: expr, $funded_channel: expr, FUNDED_CHANNEL) => { {
3721+ let chan_id = $funded_channel.context.channel_id();
3722+ let mut do_close = |reason| {
3723+ (
3724+ $funded_channel.force_shutdown(reason),
3725+ $self.get_channel_update_for_broadcast(&$funded_channel).ok(),
3726+ )
3727+ };
3728+ let mut locked_close = |shutdown_res_mut: &mut ShutdownResult, funded_channel: &mut FundedChannel<_>| {
3729+ locked_close_channel!($self, $peer_state, funded_channel, shutdown_res_mut, FUNDED);
3730+ };
3731+ convert_channel_err!($self, $peer_state, $err, $funded_channel, do_close, locked_close, chan_id, _internal)
3732+ } };
3733+ ($self: ident, $peer_state: expr, $err: expr, $channel: expr, UNFUNDED_CHANNEL) => { {
3734+ let chan_id = $channel.context().channel_id();
3735+ let mut do_close = |reason| { ($channel.force_shutdown(reason), None) };
3736+ let locked_close = |_, chan: &mut Channel<_>| { locked_close_channel!($self, chan.context(), UNFUNDED); };
3737+ convert_channel_err!($self, $peer_state, $err, $channel, do_close, locked_close, chan_id, _internal)
3738+ } };
3739+ ($self: ident, $peer_state: expr, $err: expr, $channel: expr) => {
3740+ match $channel.as_funded_mut() {
3741+ Some(funded_channel) => {
3742+ convert_channel_err!($self, $peer_state, $err, funded_channel, FUNDED_CHANNEL)
3743+ },
3744+ None => {
3745+ convert_channel_err!($self, $peer_state, $err, $channel, UNFUNDED_CHANNEL)
3746+ },
3747+ }
3748+ };
3749+ }
3750+
3751+ macro_rules! break_channel_entry {
3752+ ($self: ident, $peer_state: expr, $res: expr, $entry: expr) => {
3753+ match $res {
3754+ Ok(res) => res,
3755+ Err(e) => {
3756+ let (drop, res) = convert_channel_err!($self, $peer_state, e, $entry.get_mut());
3757+ if drop {
3758+ $entry.remove_entry();
3759+ }
3760+ break Err(res);
3761+ },
3762+ }
3763+ };
3764+ }
3765+
3766+ macro_rules! try_channel_entry {
3767+ ($self: ident, $peer_state: expr, $res: expr, $entry: expr) => {
3768+ match $res {
3769+ Ok(res) => res,
3770+ Err(e) => {
3771+ let (drop, res) = convert_channel_err!($self, $peer_state, e, $entry.get_mut());
3772+ if drop {
3773+ $entry.remove_entry();
3774+ }
3775+ return Err(res);
3776+ },
3777+ }
3778+ };
3779+ }
3780+
37813781#[rustfmt::skip]
37823782macro_rules! process_events_body {
37833783 ($self: expr, $event_to_handle: expr, $handle_event: expr) => {
0 commit comments