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

multi: store bool to determine retransmission ordering #4915

Merged
merged 2 commits into from
Feb 4, 2021

Conversation

Crypt-iQ
Copy link
Collaborator

@Crypt-iQ Crypt-iQ commented Jan 13, 2021

With this pull request, we store a boolean per channel under the new lastWasRevokeKey. This key determines if the last material update our channel sent was a CommitSig or RevokeAndAck. When the link calls SignNextCommitment, false is stored under the key. When the link calls RevokeAndAck, true is stored under the key.

For new channels with no updates yet exchanged, nothing is stored and so the key contains nil.

For existing channels updating to this patch, the default nil is also stored. The next update sent will store something under the key.

Fixes #4799
Fixes #4613

@Crypt-iQ Crypt-iQ added this to the 0.13.0 milestone Jan 13, 2021
@Crypt-iQ Crypt-iQ requested a review from cfromknecht January 13, 2021 20:39
Copy link
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.

first pass looks solid! nice to see that the fix was straightforward. a few nits but otherwise looks good

channeldb/channel.go Outdated Show resolved Hide resolved
htlcswitch/link_test.go Outdated Show resolved Hide resolved
lnwallet/channel.go Show resolved Hide resolved
updates = append(updates, commitDiff.CommitSig)
commitUpdates = append(commitUpdates, commitDiff.CommitSig)

if lastWasRevoke {
Copy link
Contributor

Choose a reason for hiding this comment

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

a comment here would be useful to explain how these two orderings differ

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Comment added

@halseth halseth self-requested a review January 19, 2021 13:01
channeldb/channel.go Show resolved Hide resolved
htlcswitch/link_test.go Show resolved Hide resolved
ctx.receiveRevAndAckAliceToBob()

// ------add---->
// We don't send this to Bob as his channel state already contains this,
Copy link
Contributor

Choose a reason for hiding this comment

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

why is this? Since Bob was not restarted?

Shouldn't bob handle receiving this from Alice?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We'll get a duplicate htlc id if Bob accepts (0) while Bob is expecting 1. It's because Bob is represented as LightningChannel

Copy link
Contributor

Choose a reason for hiding this comment

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

I see. Would i make sense to also restart Bob?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, restarting Bob now. Makes the tests cleaner

htlcswitch/link_test.go Show resolved Hide resolved
@Crypt-iQ Crypt-iQ force-pushed the revsigbool_01132021 branch from a11317a to 29271b0 Compare January 26, 2021 17:06
// If lastWasRevoke is set to true, a revocation was last and we
// need to reorder the updates so that the revocation stored in
// updates comes after the LogUpdates+CommitSig.
updates = append(commitUpdates, updates...)
Copy link
Contributor

Choose a reason for hiding this comment

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

I find this a bit hard to follow, possibly because we are assuming something about the updates that have been added in an earlier switch statement.

Could an alternative be to split this up

var owedRevocation, owedCommitUpdates []lnwire.Message

switch {
case ...:
    owedRevocation = append(owedRevocation, revokeAndAck)
}

switch {
case ...:
    owedCommitUpdates = append(owedCommitUpdates, commitSig)
}

var updates []lnwire.Message
if lastWasRevoke {
    updates = append(owedCommitUpdates, owedRevocation)
else {
    updates = append(owedRevocation, owedCommitUpdates) 
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I chose this way because this does not account for OweCommitment. Would it then be added to owedRevocation? - Then the name doesn't describe what it does. The switch case msg.NextLocalCommitHeight == remoteTipHeight cannot be called if OweCommitment is called so that doesn't change our current logic if a revocation exists or not.

Copy link
Member

Choose a reason for hiding this comment

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

I chose this way because this does not account for OweCommitment

So won't this end up re ordering the OweCommitment sig if we need to generate+send it?

Copy link
Member

Choose a reason for hiding this comment

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

The switch case msg.NextLocalCommitHeight == remoteTipHeight cannot be called if OweCommitment is called so that doesn't change our current logic if a revocation exists or not.

Ah ok, make sense.

@@ -3892,16 +3892,30 @@ func (lc *LightningChannel) ProcessChanSyncMsg(
return nil, nil, nil, err
}

var commitUpdates []lnwire.Message
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we could also encode the OweCommitment case above using this new key?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If OweCommitment is called, then this block of code cannot be called

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sorry, I don't understand the suggestion

Copy link
Member

Choose a reason for hiding this comment

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

I think he means modify the logic above that determines if we need to send a new sig to use the new value added in the change. IMO we should just try to make the smallest change here, so we can isolate the impact of the diff itself.

ctx.receiveRevAndAckAliceToBob()

// ------add---->
// We don't send this to Bob as his channel state already contains this,
Copy link
Contributor

Choose a reason for hiding this comment

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

I see. Would i make sense to also restart Bob?

@Roasbeef Roasbeef added the P1 MUST be fixed or reviewed label Jan 28, 2021
@Crypt-iQ Crypt-iQ force-pushed the revsigbool_01132021 branch from 172e5d6 to 1c407f4 Compare February 3, 2021 21:48
Copy link
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, nice find on this being absent from the spec and a simple fix 🥂

Copy link
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

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

Excellent find and fix!

To our knowledge, there's just one lingering issue in this area. However, we know this PR in itself improves the situation, so it makes sense to move forward with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
htlcswitch P1 MUST be fixed or reviewed spec v0.13
Projects
None yet
4 participants