Skip to content

Commit 2a65025

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 4e4e34e commit 2a65025

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: {}", 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() {
@@ -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]
37823782
macro_rules! process_events_body {
37833783
($self: expr, $event_to_handle: expr, $handle_event: expr) => {

0 commit comments

Comments
 (0)