@@ -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: {}", $channel_id, 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() {
@@ -3777,6 +3607,176 @@ macro_rules! handle_new_monitor_update {
37773607 }};
37783608}
37793609
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, $peer_state: 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, $peer_state, $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+ $peer_state.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+
3659+ /// When a channel is removed, two things need to happen:
3660+ /// (a) This must be called in the same `per_peer_state` lock as the channel-closing action,
3661+ /// (b) [`handle_error`] needs to be called without holding any locks (except
3662+ /// [`ChannelManager::total_consistency_lock`]), which then calls
3663+ /// [`ChannelManager::finish_close_channel`].
3664+ ///
3665+ /// Note that this step can be skipped if the channel was never opened (through the creation of a
3666+ /// [`ChannelMonitor`]/channel funding transaction) to begin with.
3667+ ///
3668+ /// Returns `(boolean indicating if we should remove the Channel object from memory, a mapped
3669+ /// error)`, except in the `COOP_CLOSE` case, where the bool is elided (it is always implicitly
3670+ /// true).
3671+ #[rustfmt::skip]
3672+ macro_rules! convert_channel_err {
3673+ ($self: ident, $peer_state: expr, $err: expr, $chan: expr, $close: expr, $locked_close: expr, $channel_id: expr, _internal) => { {
3674+ match $err {
3675+ ChannelError::Warn(msg) => {
3676+ (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Warn(msg), $channel_id))
3677+ },
3678+ ChannelError::WarnAndDisconnect(msg) => {
3679+ (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::WarnAndDisconnect(msg), $channel_id))
3680+ },
3681+ ChannelError::Ignore(msg) => {
3682+ (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore(msg), $channel_id))
3683+ },
3684+ ChannelError::Abort(reason) => {
3685+ (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Abort(reason), $channel_id))
3686+ },
3687+ ChannelError::Close((msg, reason)) => {
3688+ let (mut shutdown_res, chan_update) = $close(reason);
3689+ let logger = WithChannelContext::from(&$self.logger, &$chan.context(), None);
3690+ log_error!(logger, "Closed channel {} due to close-required error: {}", $channel_id, msg);
3691+ $locked_close(&mut shutdown_res, $chan);
3692+ let err =
3693+ MsgHandleErrInternal::from_finish_shutdown(msg, $channel_id, shutdown_res, chan_update);
3694+ (true, err)
3695+ },
3696+ ChannelError::SendError(msg) => {
3697+ (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::SendError(msg), $channel_id))
3698+ },
3699+ }
3700+ } };
3701+ ($self: ident, $peer_state: expr, $shutdown_result: expr, $funded_channel: expr, COOP_CLOSED) => { {
3702+ let chan_id = $funded_channel.context.channel_id();
3703+ let reason = ChannelError::Close(("Coop Closed".to_owned(), $shutdown_result.closure_reason.clone()));
3704+ let do_close = |_| {
3705+ (
3706+ $shutdown_result,
3707+ $self.get_channel_update_for_broadcast(&$funded_channel).ok(),
3708+ )
3709+ };
3710+ let mut locked_close = |shutdown_res_mut: &mut ShutdownResult, funded_channel: &mut FundedChannel<_>| {
3711+ locked_close_channel!($self, $peer_state, funded_channel, shutdown_res_mut, FUNDED);
3712+ };
3713+ let (close, mut err) =
3714+ convert_channel_err!($self, $peer_state, reason, $funded_channel, do_close, locked_close, chan_id, _internal);
3715+ err.dont_send_error_message();
3716+ debug_assert!(close);
3717+ err
3718+ } };
3719+ ($self: ident, $peer_state: expr, $err: expr, $funded_channel: expr, FUNDED_CHANNEL) => { {
3720+ let chan_id = $funded_channel.context.channel_id();
3721+ let mut do_close = |reason| {
3722+ (
3723+ $funded_channel.force_shutdown(reason),
3724+ $self.get_channel_update_for_broadcast(&$funded_channel).ok(),
3725+ )
3726+ };
3727+ let mut locked_close = |shutdown_res_mut: &mut ShutdownResult, funded_channel: &mut FundedChannel<_>| {
3728+ locked_close_channel!($self, $peer_state, funded_channel, shutdown_res_mut, FUNDED);
3729+ };
3730+ convert_channel_err!($self, $peer_state, $err, $funded_channel, do_close, locked_close, chan_id, _internal)
3731+ } };
3732+ ($self: ident, $peer_state: expr, $err: expr, $channel: expr, UNFUNDED_CHANNEL) => { {
3733+ let chan_id = $channel.context().channel_id();
3734+ let mut do_close = |reason| { ($channel.force_shutdown(reason), None) };
3735+ let locked_close = |_, chan: &mut Channel<_>| { locked_close_channel!($self, chan.context(), UNFUNDED); };
3736+ convert_channel_err!($self, $peer_state, $err, $channel, do_close, locked_close, chan_id, _internal)
3737+ } };
3738+ ($self: ident, $peer_state: expr, $err: expr, $channel: expr) => {
3739+ match $channel.as_funded_mut() {
3740+ Some(funded_channel) => {
3741+ convert_channel_err!($self, $peer_state, $err, funded_channel, FUNDED_CHANNEL)
3742+ },
3743+ None => {
3744+ convert_channel_err!($self, $peer_state, $err, $channel, UNFUNDED_CHANNEL)
3745+ },
3746+ }
3747+ };
3748+ }
3749+
3750+ macro_rules! break_channel_entry {
3751+ ($self: ident, $peer_state: expr, $res: expr, $entry: expr) => {
3752+ match $res {
3753+ Ok(res) => res,
3754+ Err(e) => {
3755+ let (drop, res) = convert_channel_err!($self, $peer_state, e, $entry.get_mut());
3756+ if drop {
3757+ $entry.remove_entry();
3758+ }
3759+ break Err(res);
3760+ },
3761+ }
3762+ };
3763+ }
3764+
3765+ macro_rules! try_channel_entry {
3766+ ($self: ident, $peer_state: expr, $res: expr, $entry: expr) => {
3767+ match $res {
3768+ Ok(res) => res,
3769+ Err(e) => {
3770+ let (drop, res) = convert_channel_err!($self, $peer_state, e, $entry.get_mut());
3771+ if drop {
3772+ $entry.remove_entry();
3773+ }
3774+ return Err(res);
3775+ },
3776+ }
3777+ };
3778+ }
3779+
37803780#[rustfmt::skip]
37813781macro_rules! process_events_body {
37823782 ($self: expr, $event_to_handle: expr, $handle_event: expr) => {
0 commit comments