Skip to content

Commit 078f756

Browse files
Roasbeefguggero
authored andcommitted
funding+lnwallet: only blind tapscript root early in funding flow
In this commit, we modify the aux funding work flow slightly. We won't be able to generate the full AuxFundingDesc until both sides has sent+received funding params. So we'll now only attempt to bind the tapscript root as soon as we send+recv the open_channel message. We'll now also make sure that we pass the tapscript root all the way down into the musig2 session creation.
1 parent cd34dbb commit 078f756

File tree

5 files changed

+53
-60
lines changed

5 files changed

+53
-60
lines changed

funding/aux_funding.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package funding
22

33
import (
4+
"github.com/btcsuite/btcd/chaincfg/chainhash"
45
"github.com/lightningnetwork/lnd/fn"
56
"github.com/lightningnetwork/lnd/lnwallet"
67
"github.com/lightningnetwork/lnd/protofsm"
@@ -23,4 +24,9 @@ type AuxFundingController interface {
2324
// TODO(roasbeef): erorr on validation if fail due to invalid root
2425
// match?
2526
DescFromPendingChanID(PendingChanID) fn.Option[lnwallet.AuxFundingDesc]
27+
28+
// DeriveTapscriptRoot takes a pending channel ID and maybe returns a
29+
// tapscript root that should be used when creating any musig2 sessions
30+
// for a channel.
31+
DeriveTapscriptRoot(PendingChanID) fn.Option[chainhash.Hash]
2632
}

funding/manager.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1620,11 +1620,11 @@ func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
16201620
}
16211621

16221622
// At this point, if we have an AuxFundingController active, we'll
1623-
// check to see if we have any aux info that we should carry along for
1624-
// this pid.
1625-
auxFundingDesc := fn.MapOption(
1626-
func(a AuxFundingController) fn.Option[lnwallet.AuxFundingDesc] {
1627-
return a.DescFromPendingChanID(msg.PendingChannelID)
1623+
// check to see if we have a special tapscript root to use in our
1624+
// musig2 funding output.
1625+
tapscriptRoot := fn.MapOption(
1626+
func(a AuxFundingController) fn.Option[chainhash.Hash] {
1627+
return a.DeriveTapscriptRoot(msg.PendingChannelID)
16281628
},
16291629
)(f.cfg.AuxFundingController)
16301630

@@ -1644,7 +1644,7 @@ func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
16441644
ZeroConf: zeroConf,
16451645
OptionScidAlias: scid,
16461646
ScidAliasFeature: scidFeatureVal,
1647-
AuxFundingDesc: fn.FlattenOption(auxFundingDesc),
1647+
TapscriptRoot: fn.FlattenOption(tapscriptRoot),
16481648
}
16491649

16501650
reservation, err := f.cfg.Wallet.InitChannelReservation(req)
@@ -4620,11 +4620,11 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
46204620
}
46214621

46224622
// At this point, if we have an AuxFundingController active, we'll
4623-
// check to see if we have any aux info that we should carry along for
4624-
// this pid.
4625-
auxFundingDesc := fn.MapOption(
4626-
func(a AuxFundingController) fn.Option[lnwallet.AuxFundingDesc] {
4627-
return a.DescFromPendingChanID(chanID)
4623+
// check to see if we have a special tapscript root to use in our
4624+
// musig2 funding output.
4625+
tapscriptRoot := fn.MapOption(
4626+
func(a AuxFundingController) fn.Option[chainhash.Hash] {
4627+
return a.DeriveTapscriptRoot(chanID)
46284628
},
46294629
)(f.cfg.AuxFundingController)
46304630

@@ -4651,7 +4651,7 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
46514651
OptionScidAlias: scid,
46524652
ScidAliasFeature: scidFeatureVal,
46534653
Memo: msg.Memo,
4654-
AuxFundingDesc: fn.FlattenOption(auxFundingDesc),
4654+
TapscriptRoot: fn.FlattenOption(tapscriptRoot),
46554655
}
46564656

46574657
reservation, err := f.cfg.Wallet.InitChannelReservation(req)

lnwallet/chanfunding/psbt_assembler.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/btcsuite/btcd/btcutil"
1111
"github.com/btcsuite/btcd/btcutil/psbt"
1212
"github.com/btcsuite/btcd/chaincfg"
13+
"github.com/btcsuite/btcd/chaincfg/chainhash"
1314
"github.com/btcsuite/btcd/txscript"
1415
"github.com/btcsuite/btcd/wire"
1516
"github.com/lightningnetwork/lnd/fn"
@@ -164,6 +165,13 @@ func (i *PsbtIntent) BindKeys(localKey *keychain.KeyDescriptor,
164165
i.State = PsbtOutputKnown
165166
}
166167

168+
// BindTapscriptRoot takes an optional tapscript root and binds it to the
169+
// underlying funding intent. This only applies to musig2 channels, and will be
170+
// used to make the musig2 funding output.
171+
func (i *PsbtIntent) BindTapscriptRoot(root fn.Option[chainhash.Hash]) {
172+
i.tapscriptRoot = root
173+
}
174+
167175
// FundingParams returns the parameters that are necessary to start funding the
168176
// channel output this intent was created for. It returns the P2WSH funding
169177
// address, the exact funding amount and a PSBT packet that contains exactly one

lnwallet/reservation.go

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"github.com/lightningnetwork/lnd/keychain"
1717
"github.com/lightningnetwork/lnd/lnwallet/chanfunding"
1818
"github.com/lightningnetwork/lnd/lnwire"
19-
"github.com/lightningnetwork/lnd/tlv"
2019
)
2120

2221
// CommitmentType is an enum indicating the commitment type we should use for
@@ -419,7 +418,7 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
419418
chanType |= channeldb.ScidAliasFeatureBit
420419
}
421420

422-
if req.AuxFundingDesc.IsSome() {
421+
if req.TapscriptRoot.IsSome() {
423422
chanType |= channeldb.TapscriptRootBit
424423
}
425424

@@ -444,39 +443,25 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
444443
RemoteBalance: theirBalance,
445444
FeePerKw: btcutil.Amount(req.CommitFeePerKw),
446445
CommitFee: commitFee,
447-
CustomBlob: fn.MapOption(func(desc AuxFundingDesc) tlv.Blob {
448-
return desc.CustomLocalCommitBlob
449-
})(req.AuxFundingDesc),
450446
},
451447
RemoteCommitment: channeldb.ChannelCommitment{
452448
LocalBalance: ourBalance,
453449
RemoteBalance: theirBalance,
454450
FeePerKw: btcutil.Amount(req.CommitFeePerKw),
455451
CommitFee: commitFee,
456-
CustomBlob: fn.MapOption(func(desc AuxFundingDesc) tlv.Blob {
457-
return desc.CustomRemoteCommitBlob
458-
})(req.AuxFundingDesc),
459452
},
460453
ThawHeight: thawHeight,
461454
Db: wallet.Cfg.Database,
462455
InitialLocalBalance: ourBalance,
463456
InitialRemoteBalance: theirBalance,
464457
Memo: req.Memo,
465-
CustomBlob: fn.MapOption(func(desc AuxFundingDesc) tlv.Blob {
466-
return desc.CustomFundingBlob
467-
})(req.AuxFundingDesc),
468-
TapscriptRoot: fn.MapOption(func(desc AuxFundingDesc) chainhash.Hash {
469-
return desc.TapscriptRoot
470-
})(req.AuxFundingDesc),
458+
TapscriptRoot: req.TapscriptRoot,
471459
},
472460
pushMSat: req.PushMSat,
473461
pendingChanID: req.PendingChanID,
474462
reservationID: id,
475463
wallet: wallet,
476464
chanFunder: req.ChanFunder,
477-
initAuxLeaves: fn.MapOption(func(desc AuxFundingDesc) CommitAuxLeaves {
478-
return desc.InitAuxLeaves
479-
})(req.AuxFundingDesc),
480465
}, nil
481466
}
482467

lnwallet/wallet.go

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -91,25 +91,21 @@ func (p *PsbtFundingRequired) Error() string {
9191
}
9292

9393
// AuxFundingDesc stores a series of attributes that may be used to modify the
94-
// way the channel funding occurs
94+
// way the channel funding occurs. This struct contains information that can
95+
// only be derived once both sides have received and sent their contributions
96+
// to the channel (keys, etc).
9597
type AuxFundingDesc struct {
9698
// CustomFundingBlob is a custom blob that'll be stored in the database
9799
// within the OpenChannel struct. This should represent information
98100
// static to the channel lifetime.
99101
CustomFundingBlob tlv.Blob
100102

101-
// TapscriptRoot is the root of the tapscript tree that will be used to
102-
// create the funding output.
103-
TapscriptRoot chainhash.Hash
104-
105103
// CustomLocalCommitBlob is a custom blob that'll be stored in the
106104
// first commitment entry for the local party.
107105
CustomLocalCommitBlob tlv.Blob
108106

109107
// CustomRemoteCommitBlob is a custom blob that'll be stored in the
110108
// first commitment entry for the remote party.
111-
//
112-
// TODO(roasbeef): have this just use the leaf fetcher?
113109
CustomRemoteCommitBlob tlv.Blob
114110

115111
// InitAuxLeaves is the set of aux leaves that'll be used for the very
@@ -229,9 +225,9 @@ type InitFundingReserveMsg struct {
229225
// channel that will be useful to our future selves.
230226
Memo []byte
231227

232-
// AuxFundingDesc is an optional descriptor that can be used to modify
233-
// the way channel funding occurs.
234-
AuxFundingDesc fn.Option[AuxFundingDesc]
228+
// TapscriptRoot is an optional tapscript root that if provided, will
229+
// be used to create the combined key for musig2 based channels.
230+
TapscriptRoot fn.Option[chainhash.Hash]
235231

236232
// err is a channel in which all errors will be sent across. Will be
237233
// nil if this initial set is successful.
@@ -268,7 +264,6 @@ type fundingReserveCancelMsg struct {
268264
type addContributionMsg struct {
269265
pendingFundingID uint64
270266

271-
// TODO(roasbeef): Should also carry SPV proofs in we're in SPV mode
272267
contribution *ChannelContribution
273268

274269
// NOTE: In order to avoid deadlocks, this channel MUST be buffered.
@@ -439,8 +434,6 @@ type LightningWallet struct {
439434
quit chan struct{}
440435

441436
wg sync.WaitGroup
442-
443-
// TODO(roasbeef): handle wallet lock/unlock
444437
}
445438

446439
// NewLightningWallet creates/opens and initializes a LightningWallet instance.
@@ -485,7 +478,6 @@ func (l *LightningWallet) Startup() error {
485478
}
486479

487480
l.wg.Add(1)
488-
// TODO(roasbeef): multiple request handlers?
489481
go l.requestHandler()
490482

491483
return nil
@@ -1439,7 +1431,6 @@ func (l *LightningWallet) initOurContribution(reservation *ChannelReservation,
14391431
// transaction via coin selection are freed allowing future reservations to
14401432
// include them.
14411433
func (l *LightningWallet) handleFundingCancelRequest(req *fundingReserveCancelMsg) {
1442-
// TODO(roasbeef): holding lock too long
14431434
l.limboMtx.Lock()
14441435
defer l.limboMtx.Unlock()
14451436

@@ -1464,11 +1455,6 @@ func (l *LightningWallet) handleFundingCancelRequest(req *fundingReserveCancelMs
14641455
)
14651456
}
14661457

1467-
// TODO(roasbeef): is it even worth it to keep track of unused keys?
1468-
1469-
// TODO(roasbeef): Is it possible to mark the unused change also as
1470-
// available?
1471-
14721458
delete(l.fundingLimbo, req.pendingFundingID)
14731459

14741460
pid := pendingReservation.pendingChanID
@@ -1642,16 +1628,24 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
16421628
// and remote key which will be needed to calculate the multisig
16431629
// funding output in a next step.
16441630
pendingChanID := pendingReservation.pendingChanID
1631+
16451632
walletLog.Debugf("Advancing PSBT funding flow for "+
16461633
"pending_id(%x), binding keys local_key=%v, "+
16471634
"remote_key=%x", pendingChanID,
16481635
&ourContribution.MultiSigKey,
16491636
theirContribution.MultiSigKey.PubKey.SerializeCompressed())
1637+
16501638
fundingIntent.BindKeys(
16511639
&ourContribution.MultiSigKey,
16521640
theirContribution.MultiSigKey.PubKey,
16531641
)
16541642

1643+
// We might have a tapscript root, so we'll bind that now to
1644+
// ensure we make the proper funding output.
1645+
fundingIntent.BindTapscriptRoot(
1646+
pendingReservation.partialState.TapscriptRoot,
1647+
)
1648+
16551649
// Exit early because we can't continue the funding flow yet.
16561650
req.err <- &PsbtFundingRequired{
16571651
Intent: fundingIntent,
@@ -1724,16 +1718,17 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
17241718
// the commitment transaction for the remote party, and verify their incoming
17251719
// partial signature.
17261720
func genMusigSession(ourContribution, theirContribution *ChannelContribution,
1727-
signer input.MuSig2Signer,
1728-
fundingOutput *wire.TxOut) *MusigPairSession {
1721+
signer input.MuSig2Signer, fundingOutput *wire.TxOut,
1722+
tapscriptRoot fn.Option[chainhash.Hash]) *MusigPairSession {
17291723

17301724
return NewMusigPairSession(&MusigSessionCfg{
1731-
LocalKey: ourContribution.MultiSigKey,
1732-
RemoteKey: theirContribution.MultiSigKey,
1733-
LocalNonce: *ourContribution.LocalNonce,
1734-
RemoteNonce: *theirContribution.LocalNonce,
1735-
Signer: signer,
1736-
InputTxOut: fundingOutput,
1725+
LocalKey: ourContribution.MultiSigKey,
1726+
RemoteKey: theirContribution.MultiSigKey,
1727+
LocalNonce: *ourContribution.LocalNonce,
1728+
RemoteNonce: *theirContribution.LocalNonce,
1729+
Signer: signer,
1730+
InputTxOut: fundingOutput,
1731+
TapscriptTweak: tapscriptRoot,
17371732
})
17381733
}
17391734

@@ -1783,6 +1778,7 @@ func (l *LightningWallet) signCommitTx(pendingReservation *ChannelReservation,
17831778
musigSessions := genMusigSession(
17841779
ourContribution, theirContribution,
17851780
l.Cfg.Signer, fundingOutput,
1781+
pendingReservation.partialState.TapscriptRoot,
17861782
)
17871783
pendingReservation.musigSessions = musigSessions
17881784
}
@@ -2166,6 +2162,7 @@ func (l *LightningWallet) verifyCommitSig(res *ChannelReservation,
21662162
res.musigSessions = genMusigSession(
21672163
res.ourContribution, res.theirContribution,
21682164
l.Cfg.Signer, fundingOutput,
2165+
res.partialState.TapscriptRoot,
21692166
)
21702167
}
21712168

@@ -2256,9 +2253,6 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
22562253

22572254
// As we're about to broadcast the funding transaction, we'll take note
22582255
// of the current height for record keeping purposes.
2259-
//
2260-
// TODO(roasbeef): this info can also be piped into light client's
2261-
// basic fee estimation?
22622256
_, bestHeight, err := l.Cfg.ChainIO.GetBestBlock()
22632257
if err != nil {
22642258
msg.err <- err

0 commit comments

Comments
 (0)