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: implement new safu commitment format #3365

Open
wants to merge 18 commits into
base: master
from

Conversation

@Roasbeef
Copy link
Member

commented Aug 1, 2019

In this PR, we implement the current working draft of the new safu commitment format (has no tweak for the remote party's output in your commitment transaction). In short, once we roll this out, once a channel is closed by the remote party, the funds will go directly into an output that you control, so there's no need for any additional action. This essentially replaces the existing DLP protocol (we still need to understand it for old nodes though), as we no longer need the remote party's last unrevoked commitment point.

This is still labeled as WIP, as the current spec draft is missing some necessary signalling cut outs. Beyond that, I still need to update the integration tests to cover the new format (and still the old), and possibly a debug build flag guarded RPC to force the old format.

On the topic of how this affects our current SCB scheme, the short answer is that it only kinda does. With the change in this PR, the existing SCB files in the wild can be used with new channels, with the caveat that we'll still sweep the funds into our wallet, although we don't need to. In order to cut down on this extra transaction, we can instead add the commitment key (as an address) into a sort of look aside while we undergo our regular scan for keys on chain during the recovery process. I say "look aside" as we don't generate keys from the key family we use to generate commitment keys in the normal process, and it isn't expected that they'll be used in order. Therefore, we'll provide these addresses as hints, distinct from the normal look ahead process. This allows us to pick up these funds during the normal recovery process.

At a later time, we can then update the regular on-chain recovery process to also scan for these commitment keys as normal. However, it's likely that it won't locate all the funds since we can't really expect them to be used in order (you don't FIFO close your channels, it's more arbitrary).

NOTE: the PR as a whole mostly calls this new format "tweakless" commitments, but upon reflection I find that it isn't very descriptive since it requires you to know low level details w.r.t how the scripts are constructed. IMO "safu commitments" is gets the point across a bit better, and it's more meme-y to boot, which may promote users to update sooner to this new version: "dude, you're not using safu commitments?! wot??".

@Roasbeef

This comment has been minimized.

Copy link
Member Author

commented Aug 1, 2019

Also the commits were crafted knowing that some of them don't build in isolation, as otherwise I would've had to commit the bulk of the PR in a single commit. IMO this is undesirable, as there're portions that need to be reviewed in isolation, and having them be distinct commits creates a guide for the reviewer.

Also the bulk of this diff is updating the existing tests, the final diff will also do a similar update for our set of integration tests.

@joostjager
Copy link
Collaborator

left a comment

Not so easy to review for me, as I am not very familiar with the funding flow and dlp. Just some low level comments, but the changes look straight forward.

One thing I was wondering: what would be the consequences if we'd not negotiate the new format in the open channel flow, but add the commitment format to commitment_signed? so that existing channels can change over to the new format when they signal the global feature bit. For the next next version of the commitment txes (with the anchor point?), it could upgrade in the same way.

// value to be combined.
case true:
witness[1] = signDesc.KeyDesc.PubKey.SerializeCompressed()
}

This comment has been minimized.

Copy link
@joostjager

joostjager Aug 1, 2019

Collaborator

Is this 2019-style if/then/else?

This comment has been minimized.

Copy link
@Roasbeef

Roasbeef Aug 6, 2019

Author Member

😂

I prefer this over if/else due to the way that gofmt handles indenting comments that are above the else case. Usually, it'll indent them to the right, when I prefer for them to read linearly. As a personal preference, I think switch statements are more visually appealing, since they're more linear, and let you pick up the information quickly at a glance.

lnwallet/transactions_test.go Show resolved Hide resolved
aliceCommitTx, bobCommitTx, err := lnwallet.CreateCommitmentTxns(
channelBal, channelBal, &aliceCfg, &bobCfg, aliceCommitPoint,
bobCommitPoint, *fundingTxIn, true,
)

This comment has been minimized.

Copy link
@joostjager

joostjager Aug 1, 2019

Collaborator

Shouldn't the legacy commitment txes remain covered?

This comment has been minimized.

Copy link
@Roasbeef

Roasbeef Aug 8, 2019

Author Member

There's no actual signature validation here, no are the keys checked. However, I've gone and updated the breach arb to be aware of the new commitment format, and added a new test case for serialization (for the new format, the SingleTweak is no longer needed). State transitions (of the channel), happen in the test, but this is tested more comprehensively in lnwallet.

The integration tests will cover all these cases in detail, as along the way it verifies the script change, as if all areas aren't updated, then funds won't be able to be swept, as the commitment will be invalid.

lnwallet/channel_test.go Outdated Show resolved Hide resolved
lnwallet/channel.go Show resolved Hide resolved

// If this is a tweakless commitment, then we can safely blank
// out the SingleTweak value as it isn't needed.
if tweaklessCommit {

This comment has been minimized.

Copy link
@joostjager

joostjager Aug 1, 2019

Collaborator

I think not setting it above and only setting the tweak in case of !tweaklessCommit is clearer. Then the legacy flow is the exception.

@cfromknecht
Copy link
Collaborator

left a comment

nice work @Roasbeef! diff is pretty straight forward and contained. only other area i can think of that needs changing is in the wtclient where we sign the justice transactions. no changes are needed on the tower side, since it doesn't care whether the input was tweaked or not, only that the signature is valid.

lnwallet/channel.go Outdated Show resolved Hide resolved
@@ -3513,7 +3537,11 @@ func (lc *LightningChannel) ProcessChanSyncMsg(
commitPoint = lc.channelState.RemoteNextRevocation
}

if commitPoint != nil &&
// We only need to check the unrevoked commitment point value if this
// isn't a tweakless commit, as otherwise, it'll be zero.

This comment has been minimized.

Copy link
@cfromknecht

cfromknecht Aug 2, 2019

Collaborator

we're still setting it in ChanSyncMsg()

This comment has been minimized.

Copy link
@Roasbeef

Roasbeef Aug 8, 2019

Author Member

Ah yeah you're right, will wait until we fix the issue in the current spec draft re removing it all together. Also FWIW, there's no harm in still setting it (other than the extra CPU cycles to compute the point from the secret).

@cfromknecht

This comment has been minimized.

Copy link
Collaborator

commented Aug 2, 2019

we may also need a way of signaling to the client whether the channel is tweakless or not, since we assume that it's tweaked here

input.CommitmentNoDelay,

@Roasbeef

This comment has been minimized.

Copy link
Member Author

commented Aug 8, 2019

Responded to the initial set of comments, and added commits to update the brar logic, as well as the tower logic. Still need to update the itests (I have a format I used in #3362 that I think will work well), and then also add a new funding flag to allow negotiation at funding flow time.

@Roasbeef Roasbeef force-pushed the Roasbeef:safu-commitments branch from 0821d25 to e428333 Sep 11, 2019

@Roasbeef Roasbeef requested a review from wpaulino as a code owner Sep 11, 2019

@Roasbeef Roasbeef changed the title [WIP] multi: implement new safu commitment format multi: implement new safu commitment format Sep 11, 2019

@wpaulino wpaulino removed their request for review Sep 11, 2019

Roasbeef added 11 commits Aug 1, 2019
channeldb: define new channel type, SingleFunderTweakless
In this commit, we define a new channel type: SingleFunderTweakless.
We'll use this channel type to denote channels with commitments that
don't tweak the remote party's key in their non-delay output.
input: update CommitSpendNoDelay to be aware of tweakless commits, ad…
…d new witness type

In this commit, we update the `CommitSpendNoDelay` method to be aware of
the alternate spending mechanism for commitments that don't have a tweak
for the remote party's non-delay output. We also add a new witness type
so callers can convey their expected signing path.
lnwallet: update channel state machine to be aware of tweakless commits
In this commit, we update the channel state machine to be aware of
tweakless commits. In several areas, we'll now check the channel's type
to see if it's `SingleFunderTweakless`. If so, then we'll opt to use the
remote party's non-delay based point directly in the script, skipping
any additional cryptographic operations.

Notably, within the `NewUnilateralCloseSummary` method, we'll now _blank
out_ the `SingleTweak` value if the commitment is tweakless. This
indicates to callers the witness type they should map to, as the value
isn't needed at all any longer when sweeping a non-delay output.
multi: update funding workflow to be aware of new tweakless commits
In this commit, we update the funding workflow to be aware of the new
channel type that doesn't tweak the remote party's output within the
non-delay script on their commitment transaction. To do this, we now
allow the caller of `InnitChannelReservation` to to signal if they want
to old or new (tweakless) commitment style.

The funding tests are also updated to test both funding variants, as
we'll still need to understand the legacy format for older nodes.
lnwallet: update signing+verification tests to also test tweakless co…
…mmitments

In this commit, we update the signing+verification tests to also test
that we're able to properly generate a valid witness for the new
tweakless commitment format.
contractcourt: update the commitSweepResolver to be aware of tweakles…
…s commits

In this commit, we update the `commitSweepResolver` to be aware of
tweakless commitments. We'll now use the new behavior of the uni close
summary (leaving out the single tweak) to detect if we're dealing with a
new, or modern commitment. Depending on the commitment type, we'll then
set the witness type accordingly so we can generate the proper signature
within the sweeper.
contractcourt: don't wait for DLP point if commit is tweakless on rem…
…ote close

In this commit, we update the logic in the `chainWatcher` to no longer
wait until the DLP point has been populated in the database before we
dispatch the force close summary to any registered clients. Instead, we
can sweep immediately, as we have all the information we need to sweep
the funds (just our key).
watchtower+htlcswitch: update client tower logic to recognize safu co…
…mmitments

In this commit, we update the tower+link logic to tag a commitment as
the new (tweakless) format if it applies. In order to do this, the
BackupTask method has gained an additional parameter to indicate the
type of commitment that we're attempting to upload. This new tweakless
bool is then threaded through all the way to back up task creation to
ensure that we make the proper input.Input.

Finally, we've added a new test case for each existing test case to test
each case w/ and w/o the tweakless modifier.
lnwallet+breacharbiter: update breach logic to be aware of new commit…
…ment format

In this commit, we update the brar logic in the channel state machine,
and also the brar itself to be aware of the new commitment format.
Similar to the unilateral close summary, we'll now blank out the
SingleTweak field in `NewBreachRetribution` if it's a tweakless
commitment. The brar will then use this to properly identify the
commitment type, to ensure we use the proper witness generation function
when we're handling our own breach.
Roasbeef added 5 commits Aug 8, 2019
lncfg+lnd: gate usage of tweakless commitments based on local/global …
…feature bits

In this commit, we add a new legacy protocol command line flag:
`committweak`. When set, this forces the node to NOT signal usage of the
new commitment format. This allows us to test that we're able to
properly establish channels with legacy nodes. Within the server, we'll
now gate our signalling of this new feature based on the legacy protocol
config. Finally, when accepting/initiating a new channel funding, we'll
now check both the local and remote global feature bits, only using the
new commitment format if both signal the global feature bit.

@Roasbeef Roasbeef force-pushed the Roasbeef:safu-commitments branch from e428333 to 853edca Sep 14, 2019

Roasbeef added 2 commits Sep 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.