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

[7/?] - funding: update funding manager w/ new musig2+taproot funding flow #7346

Conversation

Roasbeef
Copy link
Member

Change Description

Depends on #7345.

Only the last 6 commits are new.

In this PR, we build on the prior PR that updated the channel state machine to update the funding manager to be aware of the new funding flow.

This flow is identical to the existing flow, but both sides need to exchange local nonces up front, and then signatures sent are now partial signatures instead of regular signatures.

The funding manager also gains some new state of the local nonces it needs to generate in order to send the funding locked message, and also process the funding locked message from the remote party.

In order to allow the funding manger to generate the nonces that need to be applied to each channel, then AddNewChannel method has been modified to accept a set of options that the peer will then use to bind the nonces to a new channel.

We also update the link+peer interaction to know how to initialize the new channel, as well as the extra information that needs to be sent in funding locked and the channel reest message.

As a stop gap before Gossip 1.5, we need to set a new feature bit in the channel announcement itself. Otherwise, the router won't know how to validate the funding script of the newly created channel.

Steps to Test

Steps for reviewers to follow to test the change.

Pull Request Checklist

Testing

  • Your PR passes all CI checks.
  • Tests covering the positive and negative (error paths) are included.
  • Bug fixes contain tests triggering the bug to prevent regressions.

Code Style and Documentation

📝 Please see our Contribution Guidelines for further guidance.

log.Debugf("Applying taproot feature bit to "+
"ChannelAnnouncement for %v", chanID)

chanAnn.Features.Set(lnwire.SimpleTaprootChannelsRequired)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you expect the same feature bit to be used eventually for public channels?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this modify the feature bit dependency mapping to use "INC+" instead of "IN"?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, this is a temp hack so we're able to signal to the gossiper exactly what type of channel this is. When things get to the router, we'll still verify the channel on-chain (compared the output to the expected script), so we need this in order to signal that this is a different type of channel.

Copy link
Collaborator

@joostjager joostjager left a comment

Choose a reason for hiding this comment

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

Shallow-reviewed all the PRs in the series and overall the addition of simple taproot channels does not look too involved at all! Of course relative to the expectation, because obviously it is still a large diff.

General comments:

  • Perhaps it is good to make the changes so that taproot channels follow the default flow instead of being the exception. So if !taproot { ... } rather than if taproot { ...}
  • Related to the first point: would it be feasible to take a more object-oriented approach for adding taproot channels? More grouping of taproot-channel-specific code in a single location and fewer selects on chan type could possibly improve code quality.
  • For public channels, gossip needs to change. Is there already anything concrete in terms of spec for that? Would be helpful to complete the mental model, even if not implemented.
  • To reduce complexity, it would be great if all non-taproot channels would just go away 😬

@saubyk saubyk modified the milestones: v0.16.0, v0.16.1 Feb 14, 2023
@saubyk saubyk modified the milestones: v0.16.1, v0.17.0 Mar 13, 2023
@Roasbeef Roasbeef changed the base branch from master to simple-taproot-chans-channel-statemachine April 27, 2023 00:10
@Roasbeef Roasbeef force-pushed the simple-taproot-chans-funding-mgr branch from ff09526 to 3ccb4e1 Compare April 27, 2023 00:12
Copy link
Collaborator

@ellemouton ellemouton left a comment

Choose a reason for hiding this comment

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

Did first pass - looks good! Sooo cool how the funding manager could be made taproot-chan-ready with such a slim diff 🔥

funding/manager.go Show resolved Hide resolved
funding/manager.go Outdated Show resolved Hide resolved
if !ok {
// If there's no pending nonce for this channel ID,
// then we'll generate one now.
verNonce, err := lnwallet.NewMusigVerificationNonce(
Copy link
Collaborator

Choose a reason for hiding this comment

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

can use channel.GenMusigNonces() as is done for createFundingLocked

Copy link
Collaborator

Choose a reason for hiding this comment

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

agree

Copy link
Member Author

Choose a reason for hiding this comment

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

So can't use it here as we don't yet have the full channel state machine created. So instead we need to call the function manually. Also spotted a bug here (will be covered by the eventual itests): it uses the current commitment height, but should actually use the next commitment height. I think @ellemouton ran into this in the past.

funding/manager.go Show resolved Hide resolved
feature/deps.go Outdated Show resolved Hide resolved
@@ -2383,14 +2384,17 @@ out:
continue
}

// TODO(roasbeef): don't also need to apply
// nonces here? get from chan reest
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 it gets confusing because they may send a channel_ready and channel_reestablish

Copy link
Member Author

Choose a reason for hiding this comment

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

Goa here is to have the "last" one override the nonce that we'll store for them.

Copy link
Member Author

Choose a reason for hiding this comment

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

Goal here is to have the "last" one override the nonce that we'll store for them.

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 that means that the channel_ready will override the nonces previously set in channel_reestablish? IMO if channel_reestablish has been exchanged, we should ignore nonces in channel_ready and then we never need to worry about overriding nonces with scid alias rotation

log.Debugf("Applying taproot feature bit to "+
"ChannelAnnouncement for %v", chanID)

chanAnn.Features.Set(lnwire.SimpleTaprootChannelsRequired)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this modify the feature bit dependency mapping to use "INC+" instead of "IN"?

routing/router.go Show resolved Hide resolved
htlcswitch/link.go Show resolved Hide resolved
funding/manager.go Show resolved Hide resolved
funding/manager.go Show resolved Hide resolved
funding/manager.go Outdated Show resolved Hide resolved
htlcswitch/link.go Show resolved Hide resolved
htlcswitch/link.go Show resolved Hide resolved
@Roasbeef Roasbeef force-pushed the simple-taproot-chans-channel-statemachine branch from 717c9a3 to 4a43a07 Compare May 12, 2023 20:52
@Roasbeef Roasbeef force-pushed the simple-taproot-chans-funding-mgr branch 2 times, most recently from 7b91e27 to a9dd0f4 Compare May 12, 2023 20:57
Copy link
Collaborator

@positiveblue positiveblue 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 done.

The code looks good and the changes are pretty straight forward 🎉

There are some issues to resolve before merging (like make it panic proof). I also did not see any tests in the commits, are they added later in the PR chain?

funding/manager.go Show resolved Hide resolved
funding/manager.go Outdated Show resolved Hide resolved
funding/manager.go Show resolved Hide resolved
funding/manager.go Show resolved Hide resolved
funding/manager.go Show resolved Hide resolved
@Roasbeef Roasbeef force-pushed the simple-taproot-chans-channel-statemachine branch from 4a43a07 to 763d774 Compare July 3, 2023 01:25
@Roasbeef Roasbeef force-pushed the simple-taproot-chans-funding-mgr branch 2 times, most recently from 138c6c5 to c8e9287 Compare July 3, 2023 02:18
@Roasbeef Roasbeef force-pushed the simple-taproot-chans-channel-statemachine branch 4 times, most recently from b3a68b0 to 07d8f36 Compare July 14, 2023 02:22
@lightninglabs-deploy
Copy link

@Roasbeef, remember to re-request review from reviewers when ready

@levmi levmi requested a review from positiveblue July 17, 2023 11:11
Copy link
Collaborator

@Crypt-iQ Crypt-iQ left a comment

Choose a reason for hiding this comment

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

I think that this might be an outdated branch because there are three panics?

  • msg.LocalNonce in handleFundingOpen
  • msg.LocalNonce in handleFundingAccept
  • sig.Nonce in VerifyCommitSig

funding/manager.go Show resolved Hide resolved
@@ -3517,6 +3674,8 @@ func (f *Manager) handleFundingLocked(peer lnpeer.Peer,
return
}

// TODO(roasbeef): call sendFundingLocked here?

Copy link
Collaborator

Choose a reason for hiding this comment

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

think we need to include nonces here. Also think the spec needs to clarify what to do when we receive another FundingLocked that rotates the alias, do we ignore the nonces?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes as is we'll ignore the second one (existing logic). We'll use the same nonce each time until the channel state has moved forward one.

funding/manager.go Show resolved Hide resolved
@@ -2383,14 +2384,17 @@ out:
continue
}

// TODO(roasbeef): don't also need to apply
// nonces here? get from chan reest
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 that means that the channel_ready will override the nonces previously set in channel_reestablish? IMO if channel_reestablish has been exchanged, we should ignore nonces in channel_ready and then we never need to worry about overriding nonces with scid alias rotation

htlcswitch/link.go Outdated Show resolved Hide resolved
htlcswitch/link.go Outdated Show resolved Hide resolved
htlcswitch/link.go Show resolved Hide resolved
contractcourt/chain_watcher.go Show resolved Hide resolved
contractcourt/chain_watcher.go Show resolved Hide resolved
funding/manager.go Outdated Show resolved Hide resolved
@Roasbeef Roasbeef force-pushed the simple-taproot-chans-channel-statemachine branch from 07d8f36 to 5c09d61 Compare July 21, 2023 17:09
@Roasbeef Roasbeef changed the base branch from simple-taproot-chans-channel-statemachine to simple-taproot-chans-staging July 23, 2023 16:11
@Roasbeef Roasbeef force-pushed the simple-taproot-chans-funding-mgr branch from c8e9287 to 171e993 Compare July 23, 2023 16:13
lnwallet/transactions.go Outdated Show resolved Hide resolved
lnwallet/transactions.go Outdated Show resolved Hide resolved
lnwallet/channel.go Outdated Show resolved Hide resolved
lnwallet/channel.go Outdated Show resolved Hide resolved
lnwallet/channel.go Outdated Show resolved Hide resolved
feature/default_sets.go Show resolved Hide resolved
funding/commitment_type_negotiation.go Show resolved Hide resolved
funding/manager.go Show resolved Hide resolved
routing/router.go Show resolved Hide resolved
htlcswitch/link.go Outdated Show resolved Hide resolved
@Roasbeef
Copy link
Member Author

sig.Nonce in VerifyCommitSig

sig.Nonce isn't a pointer here.

@Roasbeef Roasbeef force-pushed the simple-taproot-chans-funding-mgr branch 2 times, most recently from af2fe2b to e47cced Compare July 24, 2023 19:25
Copy link
Collaborator

@ellemouton ellemouton left a comment

Choose a reason for hiding this comment

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

LGTM pending resolution on @Crypt-iQ's comment re RegisterSpendNtfn & CI fixes.
Left one comment re allowing unsetting of the new feature bit.

feature/deps.go Show resolved Hide resolved
funding/commitment_type_negotiation.go Outdated Show resolved Hide resolved
funding/manager.go Show resolved Hide resolved
funding/manager.go Show resolved Hide resolved
@Crypt-iQ
Copy link
Collaborator

Crypt-iQ commented Jul 25, 2023

sig.Nonce in VerifyCommitSig

sig.Nonce isn't a pointer here.

if sig is nil then it will be nil-ptr-dereference

@Roasbeef Roasbeef force-pushed the simple-taproot-chans-funding-mgr branch 2 times, most recently from 8cfdf30 to a1b6a0d Compare July 26, 2023 00:54
Copy link
Collaborator

@yyforyongyu yyforyongyu left a comment

Choose a reason for hiding this comment

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

Think it's very close. Got one question - should we update the commit weight and fee here when calling NewChannelReservation?

@@ -1965,6 +2021,20 @@ func (f *Manager) handleFundingAccept(peer lnpeer.Peer,
},
UpfrontShutdown: msg.UpfrontShutdownScript,
}

if resCtx.reservation.IsTaproot() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: would put this check after L1968 to align with other checks such as if !resCtx.reservation.IsZeroConf() && msg.MinAcceptDepth == 0 { .

fundingSigned.CommitSig, err = lnwire.NewSigFromSignature(sig)
if err != nil {
log.Errorf("unable to parse signature: %v", err)
f.failFundingFlow(peer, pendingChanID, err)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is probably a bug, not introduced from this PR tho. At L2320 we already called f.deleteReservationCtx which removes the channel from f.activeReservations. Hence when we call failFundingFlow here, it will error out because f.cancelReservationCtx won't find the reservation.

funding/manager.go Show resolved Hide resolved
funding/manager.go Show resolved Hide resolved
@ellemouton
Copy link
Collaborator

should we update the commit weight and fee here when calling NewChannelReservation?

I think we can just change that to use the lnwallet.CommitWeight method instead which is updated with a taproot case here

Copy link
Collaborator

@Crypt-iQ Crypt-iQ left a comment

Choose a reason for hiding this comment

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

In this commit, we add support for the new musig2 channel funding flow.
This flow is identical to the existing flow, but not both sides need to
exchange local nonces up front, and then signatures sent are now partial
signatures instead of regular signatures.

The funding manager also gains some new state of the local nonces it
needs to generate in order to send the funding locked message, and also
process the funding locked message from the remote party.

In order to allow the funding manger to generate the nonces that need to
be applied to each channel, then AddNewChannel method has been modified
to accept a set of options that the peer will then use to bind the
nonces to a new channel.
… channels

In this commit, we start to set _internally_ a new feature bit in the
channel announcements we generate. As these taproot channels can only be
unadvertised, this will never actually leak to the public network. The
funding manager will then set this field to allow the router to properly
validate these channels.
In this commit, we update the chain watcher to be able to generate the
correct pkScript so it can register for confirmation and spend
notifications for taproot channels.
This ensures that when loading the channel again after a normal chan
reest, we generate the local nonces, which ensures we can then process
nonces the remote party sends us in their chan reest message.
This ensures that we end up playing the target output on chain for
taproot channels.
@Roasbeef Roasbeef force-pushed the simple-taproot-chans-funding-mgr branch from a1b6a0d to ea25054 Compare July 27, 2023 00:04
@Roasbeef
Copy link
Member Author

Pushed up a final set of commits adding unit test coverage for the new funding manager flows, cc @positiveblue

@Roasbeef Roasbeef merged commit dd8820d into lightningnetwork:simple-taproot-chans-staging Jul 27, 2023
19 of 24 checks passed
@Crypt-iQ
Copy link
Collaborator

@ellemouton comment was that channelFeatures.OnlyContains can be called with ZeroConfRequired and ScidAliasRequired, but then hasFeatures doesn't contain ScidAliasOptional. I think that the ZeroConfRequired+ScidAliasRequired case is missing from this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: High Priority
Status: Done
Development

Successfully merging this pull request may close these issues.

None yet

9 participants