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

Reset the channel state before restarting the channel establishment process. #2983

Closed
wants to merge 4 commits into from

Conversation

shaavan
Copy link
Contributor

@shaavan shaavan commented Apr 8, 2024

Fixes #2982

When our counterparty disconnects during channel creation, we could have progressed along the channel creation process.
In such cases, retrying to send the OpenChannel message would fail because the channel state had progressed, leading to a panic in the get_open_channel.
To prevent this issue, introduce a new function, reset_channel_state, which resets the channel state to its initial state and uses it before regenerating the OpenChannel message for an Unfunded Outbound channel.

@codecov-commenter
Copy link

codecov-commenter commented Apr 8, 2024

Codecov Report

Attention: Patch coverage is 50.00000% with 40 lines in your changes are missing coverage. Please review.

Project coverage is 89.18%. Comparing base (d25d55a) to head (3dfc379).
Report is 8 commits behind head on main.

Files Patch % Lines
lightning/src/ln/channel.rs 48.00% 33 Missing and 6 partials ⚠️
lightning/src/ln/functional_tests.rs 50.00% 0 Missing and 1 partial ⚠️

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

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2983      +/-   ##
==========================================
+ Coverage   89.15%   89.18%   +0.03%     
==========================================
  Files         118      118              
  Lines       97521    98325     +804     
  Branches    97521    98325     +804     
==========================================
+ Hits        86941    87690     +749     
- Misses       8343     8398      +55     
  Partials     2237     2237              

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

@TheBlueMatt
Copy link
Collaborator

I don't think this is the right approach - from the user's perspective they created a channel, funded it, and then suddenly get told to generate a new funding transaction?

@shaavan
Copy link
Contributor Author

shaavan commented Apr 11, 2024

Updated from pr2983.01 to pr2983.02 (diff):
Addressed @TheBlueMatt comment

Updates:

  1. Introduce logic to get funding_transaction, funding_txo, and is_batch_funding info from context if available in get_funding_created.
  2. This logic is introduced so that users don't need to create another funding transaction if they created once for an OutboundChannel, and the channel handshake got disrupted in between because of disconnection.

@TheBlueMatt

As we discussed on Discord, I have introduced logic to get funding from context if present. And I would love to get some views on the approach and to confirm if it's the right way. I will soon update the PR with a doc update, and introduce tests as soon as I get a rough Approach ACK. Thanks!

@@ -2123,6 +2123,10 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
self.channel_state > ChannelState::NegotiatingFunding(NegotiatingFundingFlags::OUR_INIT_SENT)
}

pub(super) fn reset_state(&mut self) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the point of fetching the funding info from the channel is so we dont have to reset the state and can just repeat the messages when the peer comes online.

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 agree with your point.
But my idea was to use channel_state as a syncing parameter between us and the counterparty’s knowledge of the outbound channel.

Also, resetting channel_state allows for preserving the current flow of checks including the have_received_message check that causes the panic in #2982.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, resetting channel_state allows for preserving the current flow of checks including the have_received_message check that causes the panic in #2982.

I'm not sure why we want to preserve the current checks, though? Re-opening a channel after the peer disconnected is a fundamentally different flow from the normal one. eg we'll need to check that the AcceptChannel we received is the same as the one we previously received, not set fields based on 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.

I think that makes sense. Having a parallel but distinct flow to handle "retries" sounds like a more correct way to go forward with it.
Let me try to come up with an approach. Thanks for the pointer!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Created a new flow to handle the outbound channel handshake post disconnection/reconnection in 3dfc379

Thanks a lot for all the pointers & suggestions!

1. This field saves info about the previously received AcceptChannel
   and previously created FundingTransaction.
- If our channel_state has moved forward, we check if it is at the
  negotiation stage, and that we have access to previously received
  accept_channel_msg. We panic only when both conditions fail.
1. If we had an acceptchannel earlier, we check if it matches the one
   received just now. If not we error, because the channel parameters
   have changed and that warrants renegotiating parameters again.
2. If they do match we simply skip the rest of the function because we
   had updated those values already.
- Introduce a new enum that tracks if the Funding Transaction is a
  previously received transaction or a newly created one.
- Update the flow and sanity checks accordingly to allow using
  previously used transaction if present.
@shaavan
Copy link
Contributor Author

shaavan commented Apr 24, 2024

Updated from pr2983.02 to pr2983.03 (diff):
Addressed @TheBlueMatt comment

Updates:

  1. Rebase on main.
  2. Approach update.

Instead of resetting channel_state, this new approach tries to create an alternative flow to handle the case where the counterparty disconnects midway through the outbound channel handshake.

The approach and subsequent changes are explained in depth in the commit messages.

@TheBlueMatt
Let me know if the new approach seems sound. Would love to get the tests in as soon as I get a rough approach ACK. Thanks!

@TheBlueMatt TheBlueMatt added this to the 0.0.123 milestone Apr 26, 2024
@TheBlueMatt
Copy link
Collaborator

Can you add a test which demonstrates the panic and also exercises the new flow to retry messages?

@TheBlueMatt
Copy link
Collaborator

Looks like this still will at a minimum generate a FundingGenerationReady event for a replayed channel which we don't want.

@TheBlueMatt
Copy link
Collaborator

Dropping from 0.0.123 as this didn't finish nearly in time, we can do #3034 for 0.0.123.

@shaavan
Copy link
Contributor Author

shaavan commented May 6, 2024

Closing this PR in favor of #3034, which addresses issue #2982 by removing the OutboundChannel for which the peer was disconnected after messages were exchanged and a funding transaction was created.

Rationale:

During each channel handshake (involving messages like OpenChannel, AcceptChannel, FundingCreated, etc.), the Pubkeys in these messages change. Consequently, previous messages and their associated funding transactions become obsolete.

This means that even if a funding transaction was previously created for an outbound channel, if the peer gets disconnected, creating a new funding transaction becomes necessary. However, this process offers no advantage over simply removing the disconnected channel and initiating a new Channel handshake flow later when needed.

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.

ddf75afd16 introduced a reachable panic
3 participants