Skip to content

multi: fix reliable re-processing+re-transmission of FundingLocked factoring in ChannelReestabilshment #457

Merged
Roasbeef merged 10 commits into
lightningnetwork:masterfrom
Roasbeef:funding-locked-fix
Dec 7, 2017
Merged

multi: fix reliable re-processing+re-transmission of FundingLocked factoring in ChannelReestabilshment #457
Roasbeef merged 10 commits into
lightningnetwork:masterfrom
Roasbeef:funding-locked-fix

Conversation

@Roasbeef
Copy link
Copy Markdown
Member

@Roasbeef Roasbeef commented Dec 6, 2017

This PR set out to remedy the issues that many users have reported surrounding their channels not being shown as "active" after the funding process has completed.

Existing Issue

The original logic surrounding process retransmitted FundingLocked message and also re-sending the message was written without mind for the requirements around re-sending the ChannelReestablishment message upon reconnect. This was drawn to my attention after realizing I had a flapping connection to a c-lightning node. The funding flow with the node didn't complete before I shutdown my local node. As a result, both nodes needed to retransmit the FundingLocked as we hadn't done any channel updates yet. However, my local lnd node was unable to do so for the following reasons:

Fix For Issue

In order to fix this, the following changes have been made:

  • We now always add an open channel to the link upon reconnection with an existing channel peer.
  • A new method EligibleToForward has been added to the ChannelLink interface. This should return true, iff, the link is fully able to cary and forward any incoming HTLC's. The current default implementation of this only returns true if we have already processed the FundingLocked message.
  • ListChannels now only marks a channel as "active", iff, it has fully processed the FundingLocked message.
  • In order to handle processing a retransmitted FundingLocked message for this first time, the channelManager will now detect if the newly sent channel (by the fundingManager) is more "up to date". The channel is more up-to-date if the old channel didn't have the remote next revocation set. If it's newer, then it'll re-send to the breachArbiter (to ensure it has the latest channel) and then update the revocation point in-place. After this is update, the EligibleToForward will now return true within the switch.

@Roasbeef Roasbeef requested a review from halseth December 6, 2017 02:13
Copy link
Copy Markdown
Contributor

@cfromknecht cfromknecht left a comment

Choose a reason for hiding this comment

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

LGTM 🚀

Comment thread rpcserver.go Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why doesn't this use link.EligibleToForward()?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It does now!

halseth
halseth previously approved these changes Dec 6, 2017
Copy link
Copy Markdown
Contributor

@halseth halseth left a comment

Choose a reason for hiding this comment

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

LGTM 🎄

Comment thread peer.go Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should closing of the newChanReq.done be moved to the end? In case the sender is synchronising on this and expects the breachArbiter to have the updated contract and revocation to be set up when it closes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Might have to close at each return/continue as well?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Atm, the caller (the funding manager) has already sent a channel to the breach arbiter. We then override that by sending out this newer channel who's pointer to the next revocation point will be updated in memory.

@Roasbeef
Copy link
Copy Markdown
Member Author

Roasbeef commented Dec 7, 2017

Pushed a few follow up commits to address #458

At a high level:

  • We'll now always send the chan sync message to the other peer upon reconnection
  • This means we'll now always load the channel into the switch even if it isn't confirmed yet
  • To ensure we can process this message, we'll now skip the channel barrier (for funding confirmation) if it's a chan sync message

I think this should address the items brought up in the issue, and also accomplish the original task set out.

@Roasbeef
Copy link
Copy Markdown
Member Author

Roasbeef commented Dec 7, 2017

Pushed a rebased version addressing conner's comment.

Tested this PR a good bit locally ensuring that we now properly handle the scenario pointed out in #458. This should fix a good bit of the issues people have been having when using ecliar's android app with lnd.

…rward

In this commit, we add a new method to the ChanneLink interface:
EligibleToForward. This method allows a link to be added to the switch,
but in an intermediate state which indicates that it isn’t yet ready to
forward any incoming HTLC’s.
…ing links

In this commit, when selecting a candidate link to forward a payment,
we’ll ensure that it’s actually able to take on the HTLC. Otherwise,
we’ll skip over the link itself. Currently, a link is only fully
eligible for forwarding, *after* we’ve received and fully processed the
FundingLocked message.
In this commit, we further constrain the candidacy for an “active”
channel. In addition to being present within the link, it *must* also
have the RemoteNextRevocation set. Otherwise, this indicates that we
haven’t yet processed a FundingLocked message for this channel.
In this commit we revert a prior change which was added after
FundingLocked retransmission was implemented. This prior change didn’t
factor in the fact that the FundingLocked message will *only* be
re-sent after both sides receive the ChannelReestablishment message.
With the prior code, as we never added the channel to the link, we’d
never re-send the ChannelReestablishment, meaning the other side would
never send the FundingLocked message.

By unconditionally adding the channel to the switch, we ensure that
we’ll always properly retransmit the FundingLocked message.
…r processed

In this commit, we modify the logic within the channelManager to be
able to process any retransmitted FundingLocked messages. Before this
commit, we would simply ignore any new channels sent to us, iff, we
already had an active channel with the same channel point. With the
recent change to the loadActiveChannels method in the peer, this is now
incorrect.

When a peer retransmits the FundingLocked message, it goes through to
the fundingManager. The fundingMgr will then (if we haven’t already
processed it), send the channel to the breach arbiter and also to the
peer’s channelManager. In order to handle this case properly, if we
already have the channel, we’ll check if our current channel *doesn’t*
already have the RemoteNextRevocation field set. If it doesn’t, then
this means that we haven’t yet processed the FundingLcoked message, so
we’ll process it for the first time.

This new logic will properly:
  * ensure that the breachArbiter still has the most up to date channel
  * allow us to update the state of the link has been added to the
switch at this point
      * this link will now be eligible for forwarding after this
sequence
…tablish

This will allow users to run in trace mode again, without having an
excessive amount of spam in their logs.
…h peer

In this commit, we modify the logic within loadActiveChannels to
*always* load a channel, even if it isn’t yet fully confirmed. With
this change, we ensure that we’ll always send a channel_reestablish
message upon reconnection.

Fixes lightningnetwork#458.
…nc message

This commit is a follow up to the prior commit: as it’s possible for
the channel_reestablish message to be sent *before* the channel has
been fully confirmed, we’ll now ensure that we process it to the link
even if the channel isn’t yet open.
The IsPending method will allow callers to determine if a channel has
been fully confirmed or not.
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.

3 participants