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

Handle fallible per commitment point in channel establishment #3109

Open
wants to merge 22 commits into
base: main
Choose a base branch
from

Conversation

alecchendev
Copy link
Contributor

@alecchendev alecchendev commented Jun 6, 2024

Builds on #3086, #3096, #3115. First PR to handle fallible get_per_commitment_point signer method.

We make get_per_commitment_point return a result type so that in the Err case, we (LDK) can resume operation while an async signer fetches the commitment point. This will typically block sending out a message, but otherwise most state updates will occur. When the signature arrives, the user is expected to call ChannelManager::signer_unblocked and we will retry get_per_commitment_point however this time the signer will return the commitment point with Ok, and we'll send out our message.

This PR implements this flow for channel establishment, i.e. open_channel, accept_channel, and channel_ready.

Rough outline of how our HolderCommitmentPoint advances and gets new signatures:

  • sending open_channel - creates new outbound channel, immediately requests the first commit point, waits to have the first 2 commit points to be unblocked to send the message
  • sending accept_channel - same ^
  • sending funding_created - no op regarding commit points
  • receiving funding_created - uses point to verify first commitment, then advances commitment, requesting next point
  • sending funding_signed - no op
  • receiving funding_signed - same as above, verifies, advances, requests next point
  • sending channel_ready - waits to have the next commit point ready, then once unblocked sends the current point in the channel_ready message

To do

@codecov-commenter
Copy link

codecov-commenter commented Jun 10, 2024

Codecov Report

Attention: Patch coverage is 70.88123% with 76 lines in your changes missing coverage. Please review.

Project coverage is 89.78%. Comparing base (f2237a7) to head (744f2ca).

Files Patch % Lines
lightning/src/util/test_channel_signer.rs 36.53% 33 Missing ⚠️
lightning/src/ln/channel.rs 80.37% 29 Missing and 2 partials ⚠️
lightning/src/ln/functional_test_utils.rs 0.00% 6 Missing ⚠️
lightning/src/ln/channelmanager.rs 87.87% 0 Missing and 4 partials ⚠️
lightning/src/util/test_utils.rs 50.00% 0 Missing and 2 partials ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3109      +/-   ##
==========================================
- Coverage   89.79%   89.78%   -0.02%     
==========================================
  Files         119      119              
  Lines       97884    97966      +82     
  Branches    97884    97966      +82     
==========================================
+ Hits        87894    87955      +61     
- Misses       7415     7435      +20     
- Partials     2575     2576       +1     

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

@alecchendev alecchendev force-pushed the 2024-06-async-commit-point-funding branch from 1e5b210 to 07991fa Compare June 10, 2024 01:16
@alecchendev
Copy link
Contributor Author

alecchendev commented Jun 11, 2024

the commits from #3115 are second from the end, will rebase on top later this week, but generally most of the stuff here is in place

@alecchendev alecchendev force-pushed the 2024-06-async-commit-point-funding branch from 07991fa to 744f2ca Compare June 11, 2024 01:22
@@ -995,9 +1003,12 @@ impl HolderCommitmentPoint {
}

if let HolderCommitmentPoint::PendingNext { transaction_number, current } = self {
let next = signer.as_ref().get_per_commitment_point(*transaction_number - 1, secp_ctx);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually, looking at this again this API is super weird - advance may reduce the commitment transaction number by one....or it may not. ISTM the callsites mostly want it to actually advance, and are wrong in cases where we're PendingNext or otherwise don't advance here. Should this return a Result?

Copy link
Contributor Author

@alecchendev alecchendev Jun 11, 2024

Choose a reason for hiding this comment

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

there's the callsites 1. in funding_created/signed + commitment update where it wants to advance and is expected to be Available and go to PendingNext and then there are the callsites 2. in signer_unblocked where we call advance to try to go from PendingNext to Available if the signer has the commitment point. Not sure how to best enforce this. Maybe should these be two separate functions to distinguish what we're trying to do at each of these?

if advance returned Result, what would be an example of how we'd want to handle the err case at a callsite?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure about this PR, but in git HEAD (after the previous PR was merged) all callsites currently want to move to the next point. The current code always first sees that we're Available, then sets us to PendingNext with the number one lower, then also checks and sees that we're now PendingNext (cause we just set it), and sets us to Available at the same number. Thus, the net result of the method today is we always transition from Available to Available with a tx number one lower and the correct points.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

split into different functions, advance and try_resolve_pending (not sure if its the best name), and made advance return a Result and just defaulted to returning a closing error if we failed to advance the commitment number.

@alecchendev alecchendev force-pushed the 2024-06-async-commit-point-funding branch 2 times, most recently from e053af5 to 73583e7 Compare June 18, 2024 22:12
- Remove unused unavailable signers in TestKeysInterface
- Remove unnecessary display implementation for SignerOp
- Move set of test disabled signer ops to EnforcementState
This makes things more consistent with the overall style we use for
async signing. We try to generate a signature for a message, if it's not
there, we set a pending flag, and only in `signer_unblocked` we clear
the flag and retry the signature/message.
Includes simple changes to test util signers and tests, as well as
handling the error case for get_per_commitment_point in
HolderCommitmentPoint. This leaves an `.expect("TODO")` in places
that will be addressed in upcoming commits.
@alecchendev alecchendev force-pushed the 2024-06-async-commit-point-funding branch from 73583e7 to b798ffa Compare June 18, 2024 22:24
@alecchendev alecchendev marked this pull request as ready for review June 18, 2024 22:27
// TODO: add a variant for before our first commitment point is retrieved
/// We have just created or accepted a channel and are pending our very
/// first commitment point.
Uninitialized { transaction_number: u64 },
Copy link
Collaborator

Choose a reason for hiding this comment

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

I thought we were going to first handle all the async cases post-funding and then add support for handling the async case during initial channel bring up in a separate PR?

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.

None yet

3 participants