Skip to content

Commit a6665dc

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 9ed5ae7 commit a6665dc

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() {
@@ -3756,6 +3586,176 @@ macro_rules! handle_new_monitor_update {
37563586
}};
37573587
}
37583588

3589+
/// Do not call this directly, use `convert_channel_err` instead.
3590+
#[rustfmt::skip]
3591+
macro_rules! locked_close_channel {
3592+
($self: ident, $chan_context: expr, UNFUNDED) => {{
3593+
$self.short_to_chan_info.write().unwrap().remove(&$chan_context.outbound_scid_alias());
3594+
// If the channel was never confirmed on-chain prior to its closure, remove the
3595+
// outbound SCID alias we used for it from the collision-prevention set. While we
3596+
// generally want to avoid ever re-using an outbound SCID alias across all channels, we
3597+
// also don't want a counterparty to be able to trivially cause a memory leak by simply
3598+
// opening a million channels with us which are closed before we ever reach the funding
3599+
// stage.
3600+
let alias_removed = $self.outbound_scid_aliases.lock().unwrap().remove(&$chan_context.outbound_scid_alias());
3601+
debug_assert!(alias_removed);
3602+
}};
3603+
($self: ident, $peer_state: expr, $funded_chan: expr, $shutdown_res_mut: expr, FUNDED) => {{
3604+
if let Some((_, funding_txo, _, update)) = $shutdown_res_mut.monitor_update.take() {
3605+
handle_new_monitor_update_locked_actions_handled_by_caller!(
3606+
$self, funding_txo, update, $peer_state, $funded_chan.context
3607+
);
3608+
}
3609+
// If there's a possibility that we need to generate further monitor updates for this
3610+
// channel, we need to store the last update_id of it. However, we don't want to insert
3611+
// into the map (which prevents the `PeerState` from being cleaned up) for channels that
3612+
// never even got confirmations (which would open us up to DoS attacks).
3613+
let update_id = $funded_chan.context.get_latest_monitor_update_id();
3614+
if $funded_chan.funding.get_funding_tx_confirmation_height().is_some() || $funded_chan.context.minimum_depth(&$funded_chan.funding) == Some(0) || update_id > 1 {
3615+
let chan_id = $funded_chan.context.channel_id();
3616+
$peer_state.closed_channel_monitor_update_ids.insert(chan_id, update_id);
3617+
}
3618+
let mut short_to_chan_info = $self.short_to_chan_info.write().unwrap();
3619+
if let Some(short_id) = $funded_chan.funding.get_short_channel_id() {
3620+
short_to_chan_info.remove(&short_id);
3621+
} else {
3622+
// If the channel was never confirmed on-chain prior to its closure, remove the
3623+
// outbound SCID alias we used for it from the collision-prevention set. While we
3624+
// generally want to avoid ever re-using an outbound SCID alias across all channels, we
3625+
// also don't want a counterparty to be able to trivially cause a memory leak by simply
3626+
// opening a million channels with us which are closed before we ever reach the funding
3627+
// stage.
3628+
let alias_removed = $self.outbound_scid_aliases.lock().unwrap().remove(&$funded_chan.context.outbound_scid_alias());
3629+
debug_assert!(alias_removed);
3630+
}
3631+
short_to_chan_info.remove(&$funded_chan.context.outbound_scid_alias());
3632+
for scid in $funded_chan.context.historical_scids() {
3633+
short_to_chan_info.remove(scid);
3634+
}
3635+
}}
3636+
}
3637+
3638+
/// When a channel is removed, two things need to happen:
3639+
/// (a) This must be called in the same `per_peer_state` lock as the channel-closing action,
3640+
/// (b) [`handle_error`] needs to be called without holding any locks (except
3641+
/// [`ChannelManager::total_consistency_lock`]), which then calls
3642+
/// [`ChannelManager::finish_close_channel`].
3643+
///
3644+
/// Note that this step can be skipped if the channel was never opened (through the creation of a
3645+
/// [`ChannelMonitor`]/channel funding transaction) to begin with.
3646+
///
3647+
/// Returns `(boolean indicating if we should remove the Channel object from memory, a mapped
3648+
/// error)`, except in the `COOP_CLOSE` case, where the bool is elided (it is always implicitly
3649+
/// true).
3650+
#[rustfmt::skip]
3651+
macro_rules! convert_channel_err {
3652+
($self: ident, $peer_state: expr, $err: expr, $chan: expr, $close: expr, $locked_close: expr, $channel_id: expr, _internal) => { {
3653+
match $err {
3654+
ChannelError::Warn(msg) => {
3655+
(false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Warn(msg), $channel_id))
3656+
},
3657+
ChannelError::WarnAndDisconnect(msg) => {
3658+
(false, MsgHandleErrInternal::from_chan_no_close(ChannelError::WarnAndDisconnect(msg), $channel_id))
3659+
},
3660+
ChannelError::Ignore(msg) => {
3661+
(false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore(msg), $channel_id))
3662+
},
3663+
ChannelError::Abort(reason) => {
3664+
(false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Abort(reason), $channel_id))
3665+
},
3666+
ChannelError::Close((msg, reason)) => {
3667+
let (mut shutdown_res, chan_update) = $close(reason);
3668+
let logger = WithChannelContext::from(&$self.logger, &$chan.context(), None);
3669+
log_error!(logger, "Closed channel {} due to close-required error: {}", $channel_id, msg);
3670+
$locked_close(&mut shutdown_res, $chan);
3671+
let err =
3672+
MsgHandleErrInternal::from_finish_shutdown(msg, $channel_id, shutdown_res, chan_update);
3673+
(true, err)
3674+
},
3675+
ChannelError::SendError(msg) => {
3676+
(false, MsgHandleErrInternal::from_chan_no_close(ChannelError::SendError(msg), $channel_id))
3677+
},
3678+
}
3679+
} };
3680+
($self: ident, $peer_state: expr, $shutdown_result: expr, $funded_channel: expr, COOP_CLOSED) => { {
3681+
let chan_id = $funded_channel.context.channel_id();
3682+
let reason = ChannelError::Close(("Coop Closed".to_owned(), $shutdown_result.closure_reason.clone()));
3683+
let do_close = |_| {
3684+
(
3685+
$shutdown_result,
3686+
$self.get_channel_update_for_broadcast(&$funded_channel).ok(),
3687+
)
3688+
};
3689+
let mut locked_close = |shutdown_res_mut: &mut ShutdownResult, funded_channel: &mut FundedChannel<_>| {
3690+
locked_close_channel!($self, $peer_state, funded_channel, shutdown_res_mut, FUNDED);
3691+
};
3692+
let (close, mut err) =
3693+
convert_channel_err!($self, $peer_state, reason, $funded_channel, do_close, locked_close, chan_id, _internal);
3694+
err.dont_send_error_message();
3695+
debug_assert!(close);
3696+
err
3697+
} };
3698+
($self: ident, $peer_state: expr, $err: expr, $funded_channel: expr, FUNDED_CHANNEL) => { {
3699+
let chan_id = $funded_channel.context.channel_id();
3700+
let mut do_close = |reason| {
3701+
(
3702+
$funded_channel.force_shutdown(reason),
3703+
$self.get_channel_update_for_broadcast(&$funded_channel).ok(),
3704+
)
3705+
};
3706+
let mut locked_close = |shutdown_res_mut: &mut ShutdownResult, funded_channel: &mut FundedChannel<_>| {
3707+
locked_close_channel!($self, $peer_state, funded_channel, shutdown_res_mut, FUNDED);
3708+
};
3709+
convert_channel_err!($self, $peer_state, $err, $funded_channel, do_close, locked_close, chan_id, _internal)
3710+
} };
3711+
($self: ident, $peer_state: expr, $err: expr, $channel: expr, UNFUNDED_CHANNEL) => { {
3712+
let chan_id = $channel.context().channel_id();
3713+
let mut do_close = |reason| { ($channel.force_shutdown(reason), None) };
3714+
let locked_close = |_, chan: &mut Channel<_>| { locked_close_channel!($self, chan.context(), UNFUNDED); };
3715+
convert_channel_err!($self, $peer_state, $err, $channel, do_close, locked_close, chan_id, _internal)
3716+
} };
3717+
($self: ident, $peer_state: expr, $err: expr, $channel: expr) => {
3718+
match $channel.as_funded_mut() {
3719+
Some(funded_channel) => {
3720+
convert_channel_err!($self, $peer_state, $err, funded_channel, FUNDED_CHANNEL)
3721+
},
3722+
None => {
3723+
convert_channel_err!($self, $peer_state, $err, $channel, UNFUNDED_CHANNEL)
3724+
},
3725+
}
3726+
};
3727+
}
3728+
3729+
macro_rules! break_channel_entry {
3730+
($self: ident, $peer_state: expr, $res: expr, $entry: expr) => {
3731+
match $res {
3732+
Ok(res) => res,
3733+
Err(e) => {
3734+
let (drop, res) = convert_channel_err!($self, $peer_state, e, $entry.get_mut());
3735+
if drop {
3736+
$entry.remove_entry();
3737+
}
3738+
break Err(res);
3739+
},
3740+
}
3741+
};
3742+
}
3743+
3744+
macro_rules! try_channel_entry {
3745+
($self: ident, $peer_state: expr, $res: expr, $entry: expr) => {
3746+
match $res {
3747+
Ok(res) => res,
3748+
Err(e) => {
3749+
let (drop, res) = convert_channel_err!($self, $peer_state, e, $entry.get_mut());
3750+
if drop {
3751+
$entry.remove_entry();
3752+
}
3753+
return Err(res);
3754+
},
3755+
}
3756+
};
3757+
}
3758+
37593759
#[rustfmt::skip]
37603760
macro_rules! process_events_body {
37613761
($self: expr, $event_to_handle: expr, $handle_event: expr) => {

0 commit comments

Comments
 (0)