-
Notifications
You must be signed in to change notification settings - Fork 385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor ShutdownResult type and construction #2613
Refactor ShutdownResult type and construction #2613
Conversation
Codecov ReportAttention:
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## main #2613 +/- ##
==========================================
+ Coverage 88.92% 88.98% +0.05%
==========================================
Files 112 112
Lines 87632 87650 +18
Branches 87632 87650 +18
==========================================
+ Hits 77929 77992 +63
+ Misses 7473 7422 -51
- Partials 2230 2236 +6
☔ View full report in Codecov by Sentry. |
Any reason this is marked as draft? |
@@ -5557,7 +5573,7 @@ impl<SP: Deref> Channel<SP> where | |||
/// [`ChannelMonitorUpdate`] will be returned). | |||
pub fn get_shutdown(&mut self, signer_provider: &SP, their_features: &InitFeatures, | |||
target_feerate_sats_per_kw: Option<u32>, override_shutdown_script: Option<ShutdownScript>) | |||
-> Result<(msgs::Shutdown, Option<ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>), APIError> | |||
-> Result<(msgs::Shutdown, Option<ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>, Option<ShutdownResult>), APIError> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if these Option<ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>
can be collapsed into Option<ShutdownResult>
although the use cases are slightly different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe? I think I'd rather keep them separate though. We'd want to handle the monitor update result on the non-shutdown case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, that was my main hesitation. It seems possible to branch on the update_id
of the ChannelMonitorUpdate
being equal to CLOSED_CHANNEL_UPDATE_ID
, but might not be something we want to unify.
Took another look, ready for review now. :) |
9c2ee48
to
6960cb8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple of comments here and there
lightning/src/ln/channelmanager.rs
Outdated
@@ -2700,7 +2700,7 @@ where | |||
} | |||
|
|||
let (monitor_update_option, mut failed_htlcs, unbroadcasted_batch_funding_txid) = shutdown_res; | |||
log_debug!(self.logger, "Finishing force-closure of channel with {} HTLCs to fail", failed_htlcs.len()); | |||
log_debug!(self.logger, "Finishing closure of channel with {} HTLCs to fail", failed_htlcs.len()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does force
here not give more context to anyone reading the logs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Problem is its not longer just force-closures, its all closures.
pub reason: Option<ClosureReason>, | ||
} | ||
|
||
impl Default for ExpectedCloseEvent { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it not make sense to derive Default instead of manually implementing it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely makes sense! Derived instead. :)
lightning/src/ln/channel.rs
Outdated
@@ -5626,11 +5642,19 @@ impl<SP: Deref> Channel<SP> where | |||
}; | |||
|
|||
// From here on out, we may not fail! | |||
let shutdown_result; | |||
let unbroadcasted_batch_funding_txid = self.context.unbroadcasted_batch_funding_txid(); | |||
self.context.target_closing_feerate_sats_per_kw = target_feerate_sats_per_kw; | |||
if self.context.channel_state & !STATE_FLAGS < ChannelState::FundingSent as u32 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of defining shutdown_result
on L5645 won't it be better to have this if/else expression return a ShutdownResult
and then capture it in the shutdown_result
variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, capturing shutdown_result
from if-else expressions in a couple places now.
Can you write more full commit messages that describe what we're doing (not just "refactor", but "refactor to do X") and why we're doing it? |
6960cb8
to
39e0b7d
Compare
I've rewritten the commit subjects and added explanations to the bodies following https://cbea.ms/git-commit/, let me know if anything can be reworded there though! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but I'd rather expand a few assertions and checks cause this is all pretty delicate code.
channel_capacity_sats, | ||
.. | ||
} if ( | ||
expected_event.channel_id.map(|expected| *channel_id == expected).unwrap_or(true) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't these all be unwrap_or(false)
? We don't want to match if the caller specified a channel id to match but the event didn't have it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The .map
function is called on the expected event field, so the unwrap_or(true)
call is meant to match if the caller left expectations unspecified. Does that sound correct? A ChannelClosed
event will always have a channel_id
.
pub fn check_closed_event(node: &Node, _events_count: usize, expected_reason: ClosureReason, is_check_discard_funding: bool, | ||
expected_counterparty_node_ids: &[PublicKey], expected_channel_capacity: u64) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
pub fn check_closed_event(node: &Node, _events_count: usize, expected_reason: ClosureReason, is_check_discard_funding: bool, | |
expected_counterparty_node_ids: &[PublicKey], expected_channel_capacity: u64) { | |
pub fn check_closed_event(node: &Node, events_count: usize, expected_reason: ClosureReason, is_check_discard_funding: bool, | |
expected_counterparty_node_ids: &[PublicKey], expected_channel_capacity: u64) { | |
assert_eq!(events_count, expected_counterparty_node_ids.len()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed to account for the DiscardFunding
events too but verified the events_count
here.
Option<Txid> | ||
); | ||
/// The result of a shutdown that should be handled. | ||
pub(crate) struct ShutdownResult { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pub(crate) struct ShutdownResult { | |
#[must_use] | |
pub(crate) struct ShutdownResult { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
chan.get_shutdown(&self.signer_provider, their_features, target_feerate_sats_per_1000_weight, override_shutdown_script)?; | ||
failed_htlcs = htlcs; | ||
shutdown_result = local_shutdown_result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's debug_assert our assumptions.
shutdown_result = local_shutdown_result; | |
shutdown_result = local_shutdown_result; | |
debug_assert_eq!(shutdown_result.is_some(), chan.is_shutdown()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added this assertion to all the cooperative closing paths.
39e0b7d
to
aa8a485
Compare
Ugh, sorry, this needs rebase due to a silent conflict with #2658. |
The check_closed_event function verified closure events against multiple counterparty nodes, but only a single closure reason and channel capacity. This commit introduces a check_closed_events function to verify events against descriptions of each expected event, and refactors check_closed_event in function of check_closed_events.
This refactors ShutdownResult as follows: - Makes ShutdownResult a struct instead of a tuple to represent individual results that need to be handled. This recently also includes funding batch closure propagations. - Makes Channel solely responsible for constructing ShutdownResult as it should own all channel-specific logic.
aa8a485
to
316a794
Compare
No problem! Rebased. :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
As a follow-up to #2486, this PR:
ShutdownResult
type and moves construction toChannel
methods.check_closed_event
to be able to share it for batch funding tests. The current implementation is not usable since there might be multipleClosureReason
s. Let me know if this is not worth it though.