Skip to content

Commit 52af15c

Browse files
committed
Move ChannelError-handling logic down in channelmanager.rs
In the next commit we'll functionize some of the `ChannelError`-handling logic, requiring it have access to `handle_new_monitor_update_locked_actions_handled_by_caller!` which thus needs to be defined above it.
1 parent 3ada6f5 commit 52af15c

File tree

1 file changed

+170
-170
lines changed

1 file changed

+170
-170
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 170 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
34283258
macro_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]
37813781
macro_rules! process_events_body {
37823782
($self: expr, $event_to_handle: expr, $handle_event: expr) => {

0 commit comments

Comments
 (0)