Skip to content

Commit f35aead

Browse files
Roasbeefguggero
authored andcommitted
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 ad3094d commit f35aead

File tree

3 files changed

+145
-34
lines changed

3 files changed

+145
-34
lines changed

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
@@ -2253,10 +2252,29 @@ func (f *Manager) waitForPsbt(intent *chanfunding.PsbtIntent,
22532252
return
22542253
}
22552254

2255+
// At this point, we'll see if there's an AuxFundingDesc we
2256+
// need to deliver so the funding process can continue
2257+
// properly.
2258+
chanState := resCtx.reservation.ChanState()
2259+
localKeys, remoteKeys := resCtx.reservation.CommitmentKeyRings()
2260+
auxFundingDesc := fn.MapOption(
2261+
func(a AuxFundingController) fn.Option[lnwallet.AuxFundingDesc] {
2262+
return a.DescFromPendingChanID(
2263+
cid.tempChanID, chanState, *localKeys,
2264+
*remoteKeys, true,
2265+
)
2266+
},
2267+
)(f.cfg.AuxFundingController)
2268+
22562269
// A non-nil error means we can continue the funding flow.
22572270
// Notify the wallet so it can prepare everything we need to
22582271
// continue.
2259-
err = resCtx.reservation.ProcessPsbt()
2272+
//
2273+
// We'll also pass along the aux funding controller as well,
2274+
// which may be used to help process the finalized PSBT.
2275+
err = resCtx.reservation.ProcessPsbt(
2276+
fn.FlattenOption(auxFundingDesc),
2277+
)
22602278
if err != nil {
22612279
failFlow("error continuing PSBT flow", err)
22622280
return
@@ -2320,6 +2338,10 @@ func (f *Manager) continueFundingAccept(resCtx *reservationWithCtx,
23202338
// funding flow fails.
23212339
cid.setChanID(channelID)
23222340

2341+
// Now that we're ready to resume the funding flow, we'll call into the
2342+
// aux controller with the final funding details so we can obtain the
2343+
// funding descs we need.
2344+
23232345
// Send the FundingCreated msg.
23242346
fundingCreated := &lnwire.FundingCreated{
23252347
PendingChannelID: cid.tempChanID,
@@ -2382,7 +2404,6 @@ func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
23822404
// final funding transaction, as well as a signature for our version of
23832405
// the commitment transaction. So at this point, we can validate the
23842406
// initiator's commitment transaction, then send our own if it's valid.
2385-
// TODO(roasbeef): make case (p vs P) consistent throughout
23862407
fundingOut := msg.FundingPoint
23872408
log.Infof("completing pending_id(%x) with ChannelPoint(%v)",
23882409
pendingChanID[:], fundingOut)
@@ -2414,16 +2435,32 @@ func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
24142435
}
24152436
}
24162437

2438+
// At this point, we'll see if there's an AuxFundingDesc we need to
2439+
// deliver so the funding process can continue properly.
2440+
chanState := resCtx.reservation.ChanState()
2441+
localKeys, remoteKeys := resCtx.reservation.CommitmentKeyRings()
2442+
auxFundingDesc := fn.MapOption(
2443+
func(a AuxFundingController) fn.Option[lnwallet.AuxFundingDesc] {
2444+
return a.DescFromPendingChanID(
2445+
cid.tempChanID, chanState, *localKeys,
2446+
*remoteKeys, true,
2447+
)
2448+
},
2449+
)(f.cfg.AuxFundingController)
2450+
24172451
// With all the necessary data available, attempt to advance the
24182452
// funding workflow to the next stage. If this succeeds then the
24192453
// funding transaction will broadcast after our next message.
24202454
// CompleteReservationSingle will also mark the channel as 'IsPending'
24212455
// in the database.
2456+
//
2457+
// We'll also directly pass in the AuxFundiner controller as well,
2458+
// which may be used by the reservation system to finalize funding our
2459+
// our side.
24222460
completeChan, err := resCtx.reservation.CompleteReservationSingle(
2423-
&fundingOut, commitSig,
2461+
&fundingOut, commitSig, fn.FlattenOption(auxFundingDesc),
24242462
)
24252463
if err != nil {
2426-
// TODO(roasbeef): better error logging: peerID, channelID, etc.
24272464
log.Errorf("unable to complete single reservation: %v", err)
24282465
f.failFundingFlow(peer, cid, err)
24292466
return
@@ -2734,9 +2771,6 @@ func (f *Manager) funderProcessFundingSigned(peer lnpeer.Peer,
27342771

27352772
// Send an update to the upstream client that the negotiation process
27362773
// is over.
2737-
//
2738-
// TODO(roasbeef): add abstraction over updates to accommodate
2739-
// long-polling, or SSE, etc.
27402774
upd := &lnrpc.OpenStatusUpdate{
27412775
Update: &lnrpc.OpenStatusUpdate_ChanPending{
27422776
ChanPending: &lnrpc.PendingUpdate{
@@ -4441,7 +4475,6 @@ func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey,
44414475

44424476
// InitFundingWorkflow sends a message to the funding manager instructing it
44434477
// to initiate a single funder workflow with the source peer.
4444-
// TODO(roasbeef): re-visit blocking nature..
44454478
func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) {
44464479
f.fundingRequests <- msg
44474480
}

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: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ type addContributionMsg struct {
282282
type continueContributionMsg struct {
283283
pendingFundingID uint64
284284

285+
auxFundingDesc fn.Option[AuxFundingDesc]
286+
285287
// NOTE: In order to avoid deadlocks, this channel MUST be buffered.
286288
err chan error
287289
}
@@ -337,6 +339,8 @@ type addCounterPartySigsMsg struct {
337339
type addSingleFunderSigsMsg struct {
338340
pendingFundingID uint64
339341

342+
auxFundingDesc fn.Option[AuxFundingDesc]
343+
340344
// fundingOutpoint is the outpoint of the completed funding
341345
// transaction as assembled by the workflow initiator.
342346
fundingOutpoint *wire.OutPoint
@@ -1489,19 +1493,14 @@ func defaultCommitOpts() createCommitOpts {
14891493
return createCommitOpts{}
14901494
}
14911495

1492-
// WithLocalAuxLeaves is a functional option that can be used to set the local
1493-
// aux leaves for a new commitment transaction.
1494-
func WithLocalAuxLeaves(leaves fn.Option[CommitAuxLeaves]) CreateCommitOpt {
1495-
return func(o *createCommitOpts) {
1496-
o.localAuxLeaves = leaves
1497-
}
1498-
}
1496+
// WithAuxLeaves is a functional option that can be used to set the aux leaves
1497+
// for a new commitment transaction.
1498+
func WithAuxLeaves(localLeaves,
1499+
remoteLeaves fn.Option[CommitAuxLeaves]) CreateCommitOpt {
14991500

1500-
// WithRemoteAuxLeaves is a functional option that can be used to set the remote
1501-
// aux leaves for a new commitment transaction.
1502-
func WithRemoteAuxLeaves(leaves fn.Option[CommitAuxLeaves]) CreateCommitOpt {
15031501
return func(o *createCommitOpts) {
1504-
o.remoteAuxLeaves = leaves
1502+
o.localAuxLeaves = localLeaves
1503+
o.remoteAuxLeaves = remoteLeaves
15051504
}
15061505
}
15071506

@@ -1828,6 +1827,24 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) {
18281827
return
18291828
}
18301829

1830+
chanState := pendingReservation.partialState
1831+
1832+
// If we have an aux funding desc, then we can use it to populate some
1833+
// of the optional, but opaque TLV blobs we'll carry for the channel.
1834+
chanState.CustomBlob = fn.MapOption(func(desc AuxFundingDesc) tlv.Blob {
1835+
return desc.CustomFundingBlob
1836+
})(req.auxFundingDesc)
1837+
chanState.LocalCommitment.CustomBlob = fn.MapOption(
1838+
func(desc AuxFundingDesc) tlv.Blob {
1839+
return desc.CustomLocalCommitBlob
1840+
},
1841+
)(req.auxFundingDesc)
1842+
chanState.RemoteCommitment.CustomBlob = fn.MapOption(
1843+
func(desc AuxFundingDesc) tlv.Blob {
1844+
return desc.CustomRemoteCommitBlob
1845+
},
1846+
)(req.auxFundingDesc)
1847+
18311848
ourContribution := pendingReservation.ourContribution
18321849
theirContribution := pendingReservation.theirContribution
18331850
chanPoint := pendingReservation.partialState.FundingOutpoint
@@ -1886,7 +1903,6 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) {
18861903
// Store their current commitment point. We'll need this after the
18871904
// first state transition in order to verify the authenticity of the
18881905
// revocation.
1889-
chanState := pendingReservation.partialState
18901906
chanState.RemoteCurrentRevocation = theirContribution.FirstCommitmentPoint
18911907

18921908
// Create the txin to our commitment transaction; required to construct
@@ -1903,15 +1919,21 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) {
19031919
leaseExpiry = pendingReservation.partialState.ThawHeight
19041920
}
19051921

1922+
localAuxLeaves := fn.MapOption(func(desc AuxFundingDesc) CommitAuxLeaves {
1923+
return desc.LocalInitAuxLeaves
1924+
})(req.auxFundingDesc)
1925+
remoteAuxLeaves := fn.MapOption(func(desc AuxFundingDesc) CommitAuxLeaves {
1926+
return desc.RemoteInitAuxLeaves
1927+
})(req.auxFundingDesc)
1928+
19061929
ourCommitTx, theirCommitTx, err := CreateCommitmentTxns(
19071930
localBalance, remoteBalance, ourContribution.ChannelConfig,
19081931
theirContribution.ChannelConfig,
19091932
ourContribution.FirstCommitmentPoint,
19101933
theirContribution.FirstCommitmentPoint, fundingTxIn,
19111934
pendingReservation.partialState.ChanType,
19121935
pendingReservation.partialState.IsInitiator, leaseExpiry,
1913-
WithLocalAuxLeaves(pendingReservation.localInitAuxLeaves),
1914-
WithRemoteAuxLeaves(pendingReservation.remoteInitAuxLeaves),
1936+
WithAuxLeaves(localAuxLeaves, remoteAuxLeaves),
19151937
)
19161938
if err != nil {
19171939
req.err <- err
@@ -2327,11 +2349,24 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
23272349
pendingReservation.Lock()
23282350
defer pendingReservation.Unlock()
23292351

2330-
// TODO(roasbeef): get funding desc
2331-
// * set all blobs
2332-
// * get the local+remote commitAux leaves for below commitment txns
2333-
23342352
chanState := pendingReservation.partialState
2353+
2354+
// If we have an aux funding desc, then we can use it to populate some
2355+
// of the optional, but opaque TLV blobs we'll carry for the channel.
2356+
chanState.CustomBlob = fn.MapOption(func(desc AuxFundingDesc) tlv.Blob {
2357+
return desc.CustomFundingBlob
2358+
})(req.auxFundingDesc)
2359+
chanState.LocalCommitment.CustomBlob = fn.MapOption(
2360+
func(desc AuxFundingDesc) tlv.Blob {
2361+
return desc.CustomLocalCommitBlob
2362+
},
2363+
)(req.auxFundingDesc)
2364+
chanState.RemoteCommitment.CustomBlob = fn.MapOption(
2365+
func(desc AuxFundingDesc) tlv.Blob {
2366+
return desc.CustomRemoteCommitBlob
2367+
},
2368+
)(req.auxFundingDesc)
2369+
23352370
chanType := pendingReservation.partialState.ChanType
23362371
chanState.FundingOutpoint = *req.fundingOutpoint
23372372
fundingTxIn := wire.NewTxIn(req.fundingOutpoint, nil, nil)
@@ -2345,6 +2380,14 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
23452380
if pendingReservation.partialState.ChanType.HasLeaseExpiration() {
23462381
leaseExpiry = pendingReservation.partialState.ThawHeight
23472382
}
2383+
2384+
localAuxLeaves := fn.MapOption(func(desc AuxFundingDesc) CommitAuxLeaves {
2385+
return desc.LocalInitAuxLeaves
2386+
})(req.auxFundingDesc)
2387+
remoteAuxLeaves := fn.MapOption(func(desc AuxFundingDesc) CommitAuxLeaves {
2388+
return desc.RemoteInitAuxLeaves
2389+
})(req.auxFundingDesc)
2390+
23482391
ourCommitTx, theirCommitTx, err := CreateCommitmentTxns(
23492392
localBalance, remoteBalance,
23502393
pendingReservation.ourContribution.ChannelConfig,
@@ -2353,8 +2396,7 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
23532396
pendingReservation.theirContribution.FirstCommitmentPoint,
23542397
*fundingTxIn, chanType,
23552398
pendingReservation.partialState.IsInitiator, leaseExpiry,
2356-
WithLocalAuxLeaves(pendingReservation.localInitAuxLeaves),
2357-
WithRemoteAuxLeaves(pendingReservation.remoteInitAuxLeaves),
2399+
WithAuxLeaves(localAuxLeaves, remoteAuxLeaves),
23582400
)
23592401
if err != nil {
23602402
req.err <- err

0 commit comments

Comments
 (0)