Skip to content

Commit da4b505

Browse files
committed
funding+lnwallet: finish hook up new aux funding flow
For the initiator, once we get the signal that the PSBT has been finalized, we'll call into the aux funder to get the funding desc. For the responder, once we receive the funding_created message, we'll do the same. We now also have local+remote aux leaves for the commitment transaction.
1 parent 48994fa commit da4b505

File tree

4 files changed

+153
-32
lines changed

4 files changed

+153
-32
lines changed

funding/aux_funding.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package funding
22

33
import (
44
"github.com/btcsuite/btcd/chaincfg/chainhash"
5+
"github.com/lightningnetwork/lnd/channeldb"
56
"github.com/lightningnetwork/lnd/fn"
67
"github.com/lightningnetwork/lnd/lnwallet"
78
"github.com/lightningnetwork/lnd/protofsm"
@@ -20,10 +21,10 @@ type AuxFundingController interface {
2021
// DescPendingChanID takes a pending channel ID, that may already be
2122
// known due to prior custom channel messages, and maybe returns an aux
2223
// funding desc which can be used to modify how a channel is funded.
23-
//
24-
// TODO(roasbeef): erorr on validation if fail due to invalid root
25-
// match?
26-
DescFromPendingChanID(PendingChanID) fn.Option[lnwallet.AuxFundingDesc]
24+
DescFromPendingChanID(pid PendingChanID,
25+
openChan *channeldb.OpenChannel,
26+
localKeyRing, remoteKeyRing lnwallet.CommitmentKeyRing,
27+
initiator bool) fn.Option[lnwallet.AuxFundingDesc]
2728

2829
// DeriveTapscriptRoot takes a pending channel ID and maybe returns a
2930
// tapscript root that should be used when creating any musig2 sessions

funding/manager.go

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ const (
9999
// you and limitless channel size (apart from 21 million cap).
100100
MaxBtcFundingAmountWumbo = btcutil.Amount(1000000000)
101101

102-
// TODO(roasbeef): tune.
103102
msgBufferSize = 50
104103

105104
// MaxWaitNumBlocksFundingConf is the maximum number of blocks to wait
@@ -2232,10 +2231,29 @@ func (f *Manager) waitForPsbt(intent *chanfunding.PsbtIntent,
22322231
return
22332232
}
22342233

2234+
// At this point, we'll see if there's an AuxFundingDesc we
2235+
// need to deliver so the funding process can continue
2236+
// properly.
2237+
chanState := resCtx.reservation.ChanState()
2238+
localKeys, remoteKeys := resCtx.reservation.CommitmentKeyRings()
2239+
auxFundingDesc := fn.MapOption(
2240+
func(a AuxFundingController) fn.Option[lnwallet.AuxFundingDesc] {
2241+
return a.DescFromPendingChanID(
2242+
cid.tempChanID, chanState, *localKeys,
2243+
*remoteKeys, true,
2244+
)
2245+
},
2246+
)(f.cfg.AuxFundingController)
2247+
22352248
// A non-nil error means we can continue the funding flow.
22362249
// Notify the wallet so it can prepare everything we need to
22372250
// continue.
2238-
err = resCtx.reservation.ProcessPsbt()
2251+
//
2252+
// We'll also pass along the aux funding controller as well,
2253+
// which may be used to help process the finalized PSBT.
2254+
err = resCtx.reservation.ProcessPsbt(
2255+
fn.FlattenOption(auxFundingDesc),
2256+
)
22392257
if err != nil {
22402258
failFlow("error continuing PSBT flow", err)
22412259
return
@@ -2299,6 +2317,10 @@ func (f *Manager) continueFundingAccept(resCtx *reservationWithCtx,
22992317
// funding flow fails.
23002318
cid.setChanID(channelID)
23012319

2320+
// Now that we're ready to resume the funding flow, we'll call into the
2321+
// aux controller with the final funding details so we can obtain the
2322+
// funding descs we need.
2323+
23022324
// Send the FundingCreated msg.
23032325
fundingCreated := &lnwire.FundingCreated{
23042326
PendingChannelID: cid.tempChanID,
@@ -2361,7 +2383,6 @@ func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
23612383
// final funding transaction, as well as a signature for our version of
23622384
// the commitment transaction. So at this point, we can validate the
23632385
// initiator's commitment transaction, then send our own if it's valid.
2364-
// TODO(roasbeef): make case (p vs P) consistent throughout
23652386
fundingOut := msg.FundingPoint
23662387
log.Infof("completing pending_id(%x) with ChannelPoint(%v)",
23672388
pendingChanID[:], fundingOut)
@@ -2393,16 +2414,32 @@ func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
23932414
}
23942415
}
23952416

2417+
// At this point, we'll see if there's an AuxFundingDesc we need to
2418+
// deliver so the funding process can continue properly.
2419+
chanState := resCtx.reservation.ChanState()
2420+
localKeys, remoteKeys := resCtx.reservation.CommitmentKeyRings()
2421+
auxFundingDesc := fn.MapOption(
2422+
func(a AuxFundingController) fn.Option[lnwallet.AuxFundingDesc] {
2423+
return a.DescFromPendingChanID(
2424+
cid.tempChanID, chanState, *localKeys,
2425+
*remoteKeys, true,
2426+
)
2427+
},
2428+
)(f.cfg.AuxFundingController)
2429+
23962430
// With all the necessary data available, attempt to advance the
23972431
// funding workflow to the next stage. If this succeeds then the
23982432
// funding transaction will broadcast after our next message.
23992433
// CompleteReservationSingle will also mark the channel as 'IsPending'
24002434
// in the database.
2435+
//
2436+
// We'll also directly pass in the AuxFundiner controller as well,
2437+
// which may be used by the reservation system to finalize funding our
2438+
// our side.
24012439
completeChan, err := resCtx.reservation.CompleteReservationSingle(
2402-
&fundingOut, commitSig,
2440+
&fundingOut, commitSig, fn.FlattenOption(auxFundingDesc),
24032441
)
24042442
if err != nil {
2405-
// TODO(roasbeef): better error logging: peerID, channelID, etc.
24062443
log.Errorf("unable to complete single reservation: %v", err)
24072444
f.failFundingFlow(peer, cid, err)
24082445
return
@@ -2713,9 +2750,6 @@ func (f *Manager) funderProcessFundingSigned(peer lnpeer.Peer,
27132750

27142751
// Send an update to the upstream client that the negotiation process
27152752
// is over.
2716-
//
2717-
// TODO(roasbeef): add abstraction over updates to accommodate
2718-
// long-polling, or SSE, etc.
27192753
upd := &lnrpc.OpenStatusUpdate{
27202754
Update: &lnrpc.OpenStatusUpdate_ChanPending{
27212755
ChanPending: &lnrpc.PendingUpdate{
@@ -4420,7 +4454,6 @@ func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey,
44204454

44214455
// InitFundingWorkflow sends a message to the funding manager instructing it
44224456
// to initiate a single funder workflow with the source peer.
4423-
// TODO(roasbeef): re-visit blocking nature..
44244457
func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) {
44254458
f.fundingRequests <- msg
44264459
}

lnwallet/reservation.go

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -612,12 +612,15 @@ func (r *ChannelReservation) IsCannedShim() bool {
612612
}
613613

614614
// ProcessPsbt continues a previously paused funding flow that involves PSBT to
615-
// construct the funding transaction. This method can be called once the PSBT is
616-
// finalized and the signed transaction is available.
617-
func (r *ChannelReservation) ProcessPsbt() error {
615+
// construct the funding transaction. This method can be called once the PSBT
616+
// is finalized and the signed transaction is available.
617+
func (r *ChannelReservation) ProcessPsbt(
618+
auxFundingDesc fn.Option[AuxFundingDesc]) error {
619+
618620
errChan := make(chan error, 1)
619621

620622
r.wallet.msgChan <- &continueContributionMsg{
623+
auxFundingDesc: auxFundingDesc,
621624
pendingFundingID: r.reservationID,
622625
err: errChan,
623626
}
@@ -719,8 +722,10 @@ func (r *ChannelReservation) CompleteReservation(fundingInputScripts []*input.Sc
719722
// available via the .OurSignatures() method. As this method should only be
720723
// called as a response to a single funder channel, only a commitment signature
721724
// will be populated.
722-
func (r *ChannelReservation) CompleteReservationSingle(fundingPoint *wire.OutPoint,
723-
commitSig input.Signature) (*channeldb.OpenChannel, error) {
725+
func (r *ChannelReservation) CompleteReservationSingle(
726+
fundingPoint *wire.OutPoint, commitSig input.Signature,
727+
auxFundingDesc fn.Option[AuxFundingDesc],
728+
) (*channeldb.OpenChannel, error) {
724729

725730
errChan := make(chan error, 1)
726731
completeChan := make(chan *channeldb.OpenChannel, 1)
@@ -730,6 +735,7 @@ func (r *ChannelReservation) CompleteReservationSingle(fundingPoint *wire.OutPoi
730735
fundingOutpoint: fundingPoint,
731736
theirCommitmentSig: commitSig,
732737
completeChan: completeChan,
738+
auxFundingDesc: auxFundingDesc,
733739
err: errChan,
734740
}
735741

@@ -815,6 +821,36 @@ func (r *ChannelReservation) Cancel() error {
815821
return <-errChan
816822
}
817823

824+
// ChanState the current open channel state.
825+
func (r *ChannelReservation) ChanState() *channeldb.OpenChannel {
826+
r.RLock()
827+
defer r.RUnlock()
828+
return r.partialState
829+
}
830+
831+
// CommitmentKeyRings returns the local+remote key ring used for the very first
832+
// commitment transaction both parties.
833+
func (r *ChannelReservation) CommitmentKeyRings() (*CommitmentKeyRing, *CommitmentKeyRing) {
834+
r.RLock()
835+
defer r.RUnlock()
836+
837+
chanType := r.partialState.ChanType
838+
ourChanCfg := r.ourContribution.ChannelConfig
839+
theirChanCfg := r.theirContribution.ChannelConfig
840+
841+
localKeys := DeriveCommitmentKeys(
842+
r.ourContribution.FirstCommitmentPoint, true, chanType,
843+
ourChanCfg, theirChanCfg,
844+
)
845+
846+
remoteKeys := DeriveCommitmentKeys(
847+
r.theirContribution.FirstCommitmentPoint, false, chanType,
848+
ourChanCfg, theirChanCfg,
849+
)
850+
851+
return localKeys, remoteKeys
852+
}
853+
818854
// VerifyConstraints is a helper function that can be used to check the sanity
819855
// of various channel constraints.
820856
func VerifyConstraints(c *channeldb.ChannelConstraints,

lnwallet/wallet.go

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ type addContributionMsg struct {
280280
type continueContributionMsg struct {
281281
pendingFundingID uint64
282282

283+
auxFundingDesc fn.Option[AuxFundingDesc]
284+
283285
// NOTE: In order to avoid deadlocks, this channel MUST be buffered.
284286
err chan error
285287
}
@@ -335,6 +337,8 @@ type addCounterPartySigsMsg struct {
335337
type addSingleFunderSigsMsg struct {
336338
pendingFundingID uint64
337339

340+
auxFundingDesc fn.Option[AuxFundingDesc]
341+
338342
// fundingOutpoint is the outpoint of the completed funding
339343
// transaction as assembled by the workflow initiator.
340344
fundingOutpoint *wire.OutPoint
@@ -1475,7 +1479,8 @@ func (l *LightningWallet) handleFundingCancelRequest(req *fundingReserveCancelMs
14751479
// createCommitOpts is a struct that holds the options for creating a a new
14761480
// commitment transaction.
14771481
type createCommitOpts struct {
1478-
auxLeaves fn.Option[CommitAuxLeaves]
1482+
localAuxLeaves fn.Option[CommitAuxLeaves]
1483+
remoteAuxLeaves fn.Option[CommitAuxLeaves]
14791484
}
14801485

14811486
// defaultCommitOpts returns a new createCommitOpts with default values.
@@ -1485,11 +1490,12 @@ func defaultCommitOpts() createCommitOpts {
14851490

14861491
// WithAuxLeaves is a functional option that can be used to set the aux leaves
14871492
// for a new commitment transaction.
1488-
//
1489-
// TODO(roasbeef): local+remote leaves
1490-
func WithAuxLeaves(leaves fn.Option[CommitAuxLeaves]) CreateCommitOpt {
1493+
func WithAuxLeaves(localLeaves, remoteLeaves fn.Option[CommitAuxLeaves],
1494+
) CreateCommitOpt {
1495+
14911496
return func(o *createCommitOpts) {
1492-
o.auxLeaves = leaves
1497+
o.localAuxLeaves = localLeaves
1498+
o.remoteAuxLeaves = remoteLeaves
14931499
}
14941500
}
14951501

@@ -1523,7 +1529,7 @@ func CreateCommitmentTxns(localBalance, remoteBalance btcutil.Amount,
15231529
ourCommitTx, err := CreateCommitTx(
15241530
chanType, fundingTxIn, localCommitmentKeys, ourChanCfg,
15251531
theirChanCfg, localBalance, remoteBalance, 0, initiator,
1526-
leaseExpiry, options.auxLeaves,
1532+
leaseExpiry, options.localAuxLeaves,
15271533
)
15281534
if err != nil {
15291535
return nil, nil, err
@@ -1537,7 +1543,7 @@ func CreateCommitmentTxns(localBalance, remoteBalance btcutil.Amount,
15371543
theirCommitTx, err := CreateCommitTx(
15381544
chanType, fundingTxIn, remoteCommitmentKeys, theirChanCfg,
15391545
ourChanCfg, remoteBalance, localBalance, 0, !initiator,
1540-
leaseExpiry, options.auxLeaves,
1546+
leaseExpiry, options.remoteAuxLeaves,
15411547
)
15421548
if err != nil {
15431549
return nil, nil, err
@@ -1816,6 +1822,24 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) {
18161822
return
18171823
}
18181824

1825+
chanState := pendingReservation.partialState
1826+
1827+
// If we have an aux funding desc, then we can use it to populate some
1828+
// of the optional, but opaque TLV blobs we'll carry for the channel.
1829+
chanState.CustomBlob = fn.MapOption(func(desc AuxFundingDesc) tlv.Blob {
1830+
return desc.CustomFundingBlob
1831+
})(req.auxFundingDesc)
1832+
chanState.LocalCommitment.CustomBlob = fn.MapOption(
1833+
func(desc AuxFundingDesc) tlv.Blob {
1834+
return desc.CustomLocalCommitBlob
1835+
},
1836+
)(req.auxFundingDesc)
1837+
chanState.RemoteCommitment.CustomBlob = fn.MapOption(
1838+
func(desc AuxFundingDesc) tlv.Blob {
1839+
return desc.CustomRemoteCommitBlob
1840+
},
1841+
)(req.auxFundingDesc)
1842+
18191843
ourContribution := pendingReservation.ourContribution
18201844
theirContribution := pendingReservation.theirContribution
18211845
chanPoint := pendingReservation.partialState.FundingOutpoint
@@ -1874,7 +1898,6 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) {
18741898
// Store their current commitment point. We'll need this after the
18751899
// first state transition in order to verify the authenticity of the
18761900
// revocation.
1877-
chanState := pendingReservation.partialState
18781901
chanState.RemoteCurrentRevocation = theirContribution.FirstCommitmentPoint
18791902

18801903
// Create the txin to our commitment transaction; required to construct
@@ -1891,14 +1914,21 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) {
18911914
leaseExpiry = pendingReservation.partialState.ThawHeight
18921915
}
18931916

1917+
localAuxLeaves := fn.MapOption(func(desc AuxFundingDesc) CommitAuxLeaves {
1918+
return desc.LocalInitAuxLeaves
1919+
})(req.auxFundingDesc)
1920+
remoteAuxLeaves := fn.MapOption(func(desc AuxFundingDesc) CommitAuxLeaves {
1921+
return desc.RemoteInitAuxLeaves
1922+
})(req.auxFundingDesc)
1923+
18941924
ourCommitTx, theirCommitTx, err := CreateCommitmentTxns(
18951925
localBalance, remoteBalance, ourContribution.ChannelConfig,
18961926
theirContribution.ChannelConfig,
18971927
ourContribution.FirstCommitmentPoint,
18981928
theirContribution.FirstCommitmentPoint, fundingTxIn,
18991929
pendingReservation.partialState.ChanType,
19001930
pendingReservation.partialState.IsInitiator, leaseExpiry,
1901-
WithAuxLeaves(pendingReservation.initAuxLeaves),
1931+
WithAuxLeaves(localAuxLeaves, remoteAuxLeaves),
19021932
)
19031933
if err != nil {
19041934
req.err <- err
@@ -2314,11 +2344,24 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
23142344
pendingReservation.Lock()
23152345
defer pendingReservation.Unlock()
23162346

2317-
// TODO(roasbeef): get funding desc
2318-
// * set all blobs
2319-
// * get the local+remote commitAux leaves for below commitment txns
2320-
23212347
chanState := pendingReservation.partialState
2348+
2349+
// If we have an aux funding desc, then we can use it to populate some
2350+
// of the optional, but opaque TLV blobs we'll carry for the channel.
2351+
chanState.CustomBlob = fn.MapOption(func(desc AuxFundingDesc) tlv.Blob {
2352+
return desc.CustomFundingBlob
2353+
})(req.auxFundingDesc)
2354+
chanState.LocalCommitment.CustomBlob = fn.MapOption(
2355+
func(desc AuxFundingDesc) tlv.Blob {
2356+
return desc.CustomLocalCommitBlob
2357+
},
2358+
)(req.auxFundingDesc)
2359+
chanState.RemoteCommitment.CustomBlob = fn.MapOption(
2360+
func(desc AuxFundingDesc) tlv.Blob {
2361+
return desc.CustomRemoteCommitBlob
2362+
},
2363+
)(req.auxFundingDesc)
2364+
23222365
chanType := pendingReservation.partialState.ChanType
23232366
chanState.FundingOutpoint = *req.fundingOutpoint
23242367
fundingTxIn := wire.NewTxIn(req.fundingOutpoint, nil, nil)
@@ -2332,6 +2375,14 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
23322375
if pendingReservation.partialState.ChanType.HasLeaseExpiration() {
23332376
leaseExpiry = pendingReservation.partialState.ThawHeight
23342377
}
2378+
2379+
localAuxLeaves := fn.MapOption(func(desc AuxFundingDesc) CommitAuxLeaves {
2380+
return desc.LocalInitAuxLeaves
2381+
})(req.auxFundingDesc)
2382+
remoteAuxLeaves := fn.MapOption(func(desc AuxFundingDesc) CommitAuxLeaves {
2383+
return desc.RemoteInitAuxLeaves
2384+
})(req.auxFundingDesc)
2385+
23352386
ourCommitTx, theirCommitTx, err := CreateCommitmentTxns(
23362387
localBalance, remoteBalance,
23372388
pendingReservation.ourContribution.ChannelConfig,
@@ -2340,7 +2391,7 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
23402391
pendingReservation.theirContribution.FirstCommitmentPoint,
23412392
*fundingTxIn, chanType,
23422393
pendingReservation.partialState.IsInitiator, leaseExpiry,
2343-
WithAuxLeaves(pendingReservation.initAuxLeaves),
2394+
WithAuxLeaves(localAuxLeaves, remoteAuxLeaves),
23442395
)
23452396
if err != nil {
23462397
req.err <- err

0 commit comments

Comments
 (0)