Skip to content
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

Merged
merged 3 commits into from
Oct 29, 2023

Conversation

wvanlint
Copy link
Contributor

@wvanlint wvanlint commented Sep 28, 2023

As a follow-up to #2486, this PR:

  • Refactors the ShutdownResult type and moves construction to Channel methods.
  • Cleans up typos and unused variables/imports.
  • Refactors check_closed_event to be able to share it for batch funding tests. The current implementation is not usable since there might be multiple ClosureReasons. Let me know if this is not worth it though.

@wvanlint wvanlint mentioned this pull request Sep 28, 2023
@codecov-commenter
Copy link

codecov-commenter commented Sep 28, 2023

Codecov Report

Attention: 11 lines in your changes are missing coverage. Please review.

Comparison is base (1852715) 88.92% compared to head (316a794) 88.98%.

❗ 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     
Files Coverage Δ
lightning/src/ln/functional_tests.rs 97.25% <100.00%> (+0.01%) ⬆️
lightning/src/ln/functional_test_utils.rs 91.10% <97.36%> (+0.25%) ⬆️
lightning/src/ln/channelmanager.rs 81.28% <84.00%> (-0.03%) ⬇️
lightning/src/ln/channel.rs 88.38% <77.77%> (-0.01%) ⬇️

... and 8 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@wpaulino
Copy link
Contributor

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>
Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

@wvanlint wvanlint marked this pull request as ready for review September 28, 2023 18:09
@wvanlint
Copy link
Contributor Author

Any reason this is marked as draft?

Took another look, ready for review now. :)

@wvanlint wvanlint force-pushed the batch_funding_fix_up branch from 9c2ee48 to 6960cb8 Compare October 2, 2023 17:53
Copy link
Contributor

@vladimirfomene vladimirfomene left a 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

@@ -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());
Copy link
Contributor

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?

Copy link
Collaborator

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 {
Copy link
Contributor

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?

Copy link
Contributor Author

@wvanlint wvanlint Oct 11, 2023

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. :)

@@ -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 {
Copy link
Contributor

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.

Copy link
Contributor Author

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.

@TheBlueMatt
Copy link
Collaborator

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?

@wvanlint wvanlint force-pushed the batch_funding_fix_up branch from 6960cb8 to 39e0b7d Compare October 11, 2023 00:22
@wvanlint
Copy link
Contributor Author

wvanlint commented Oct 11, 2023

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?

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!

wpaulino
wpaulino previously approved these changes Oct 12, 2023
Copy link
Collaborator

@TheBlueMatt TheBlueMatt left a 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) &&
Copy link
Collaborator

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.

Copy link
Contributor Author

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.

Comment on lines 1509 to 1521
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) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Suggested change
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());

Copy link
Contributor Author

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 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub(crate) struct ShutdownResult {
#[must_use]
pub(crate) struct ShutdownResult {

Copy link
Contributor Author

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;
Copy link
Collaborator

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.

Suggested change
shutdown_result = local_shutdown_result;
shutdown_result = local_shutdown_result;
debug_assert_eq!(shutdown_result.is_some(), chan.is_shutdown());

Copy link
Contributor Author

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.

@TheBlueMatt
Copy link
Collaborator

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.
@wvanlint wvanlint force-pushed the batch_funding_fix_up branch from aa8a485 to 316a794 Compare October 19, 2023 03:52
@wvanlint
Copy link
Contributor Author

Ugh, sorry, this needs rebase due to a silent conflict with #2658.

No problem! Rebased. :)

Copy link
Collaborator

@TheBlueMatt TheBlueMatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@TheBlueMatt TheBlueMatt merged commit 8f308f9 into lightningdevkit:main Oct 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants