Skip to content

Commit 1cba88a

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 ed9ab51 commit 1cba88a

File tree

4 files changed

+121
-18
lines changed

4 files changed

+121
-18
lines changed

funding/manager.go

Lines changed: 40 additions & 12 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
@@ -1256,8 +1255,8 @@ func (f *Manager) stateStep(channel *channeldb.OpenChannel,
12561255

12571256
// advancePendingChannelState waits for a pending channel's funding tx to
12581257
// confirm, and marks it open in the database when that happens.
1259-
func (f *Manager) advancePendingChannelState(
1260-
channel *channeldb.OpenChannel, pendingChanID PendingChanID) error {
1258+
func (f *Manager) advancePendingChannelState(channel *channeldb.OpenChannel,
1259+
pendingChanID PendingChanID) error {
12611260

12621261
if channel.IsZeroConf() {
12631262
// Persist the alias to the alias database.
@@ -2244,10 +2243,27 @@ func (f *Manager) waitForPsbt(intent *chanfunding.PsbtIntent,
22442243
return
22452244
}
22462245

2246+
// At this point, we'll see if there's an AuxFundingDesc we
2247+
// need to deliver so the funding process can continue
2248+
// properly.
2249+
chanState := resCtx.reservation.ChanState()
2250+
localKeys, remoteKeys := resCtx.reservation.CommitmentKeyRings()
2251+
auxFundingDesc, err := descFromPendingChanID(
2252+
f.cfg.AuxFundingController, cid.tempChanID, chanState,
2253+
*localKeys, *remoteKeys, true,
2254+
)
2255+
if err != nil {
2256+
failFlow("error continuing PSBT flow", err)
2257+
return
2258+
}
2259+
22472260
// A non-nil error means we can continue the funding flow.
22482261
// Notify the wallet so it can prepare everything we need to
22492262
// continue.
2250-
err = resCtx.reservation.ProcessPsbt()
2263+
//
2264+
// We'll also pass along the aux funding controller as well,
2265+
// which may be used to help process the finalized PSBT.
2266+
err = resCtx.reservation.ProcessPsbt(auxFundingDesc)
22512267
if err != nil {
22522268
failFlow("error continuing PSBT flow", err)
22532269
return
@@ -2373,7 +2389,6 @@ func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
23732389
// final funding transaction, as well as a signature for our version of
23742390
// the commitment transaction. So at this point, we can validate the
23752391
// initiator's commitment transaction, then send our own if it's valid.
2376-
// TODO(roasbeef): make case (p vs P) consistent throughout
23772392
fundingOut := msg.FundingPoint
23782393
log.Infof("completing pending_id(%x) with ChannelPoint(%v)",
23792394
pendingChanID[:], fundingOut)
@@ -2405,16 +2420,33 @@ func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
24052420
}
24062421
}
24072422

2423+
// At this point, we'll see if there's an AuxFundingDesc we need to
2424+
// deliver so the funding process can continue properly.
2425+
chanState := resCtx.reservation.ChanState()
2426+
localKeys, remoteKeys := resCtx.reservation.CommitmentKeyRings()
2427+
auxFundingDesc, err := descFromPendingChanID(
2428+
f.cfg.AuxFundingController, cid.tempChanID, chanState,
2429+
*localKeys, *remoteKeys, true,
2430+
)
2431+
if err != nil {
2432+
log.Errorf("error continuing PSBT flow: %v", err)
2433+
f.failFundingFlow(peer, cid, err)
2434+
return
2435+
}
2436+
24082437
// With all the necessary data available, attempt to advance the
24092438
// funding workflow to the next stage. If this succeeds then the
24102439
// funding transaction will broadcast after our next message.
24112440
// CompleteReservationSingle will also mark the channel as 'IsPending'
24122441
// in the database.
2442+
//
2443+
// We'll also directly pass in the AuxFundiner controller as well,
2444+
// which may be used by the reservation system to finalize funding our
2445+
// side.
24132446
completeChan, err := resCtx.reservation.CompleteReservationSingle(
2414-
&fundingOut, commitSig,
2447+
&fundingOut, commitSig, auxFundingDesc,
24152448
)
24162449
if err != nil {
2417-
// TODO(roasbeef): better error logging: peerID, channelID, etc.
24182450
log.Errorf("unable to complete single reservation: %v", err)
24192451
f.failFundingFlow(peer, cid, err)
24202452
return
@@ -2725,9 +2757,6 @@ func (f *Manager) funderProcessFundingSigned(peer lnpeer.Peer,
27252757

27262758
// Send an update to the upstream client that the negotiation process
27272759
// is over.
2728-
//
2729-
// TODO(roasbeef): add abstraction over updates to accommodate
2730-
// long-polling, or SSE, etc.
27312760
upd := &lnrpc.OpenStatusUpdate{
27322761
Update: &lnrpc.OpenStatusUpdate_ChanPending{
27332762
ChanPending: &lnrpc.PendingUpdate{
@@ -3634,7 +3663,7 @@ func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
36343663
// a zero-conf channel. This will wait for the real confirmation, add the
36353664
// confirmed SCID to the router graph, and then announce after six confs.
36363665
func (f *Manager) waitForZeroConfChannel(c *channeldb.OpenChannel,
3637-
pendingID PendingChanID) error {
3666+
_ PendingChanID) error {
36383667

36393668
// First we'll check whether the channel is confirmed on-chain. If it
36403669
// is already confirmed, the chainntnfs subsystem will return with the
@@ -4432,7 +4461,6 @@ func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey,
44324461

44334462
// InitFundingWorkflow sends a message to the funding manager instructing it
44344463
// to initiate a single funder workflow with the source peer.
4435-
// TODO(roasbeef): re-visit blocking nature..
44364464
func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) {
44374465
f.fundingRequests <- msg
44384466
}

lnwallet/reservation.go

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/btcsuite/btcd/chaincfg/chainhash"
1212
"github.com/btcsuite/btcd/wire"
1313
"github.com/lightningnetwork/lnd/channeldb"
14+
"github.com/lightningnetwork/lnd/fn"
1415
"github.com/lightningnetwork/lnd/input"
1516
"github.com/lightningnetwork/lnd/keychain"
1617
"github.com/lightningnetwork/lnd/lnwallet/chanfunding"
@@ -602,12 +603,15 @@ func (r *ChannelReservation) IsCannedShim() bool {
602603
}
603604

604605
// ProcessPsbt continues a previously paused funding flow that involves PSBT to
605-
// construct the funding transaction. This method can be called once the PSBT is
606-
// finalized and the signed transaction is available.
607-
func (r *ChannelReservation) ProcessPsbt() error {
606+
// construct the funding transaction. This method can be called once the PSBT
607+
// is finalized and the signed transaction is available.
608+
func (r *ChannelReservation) ProcessPsbt(
609+
auxFundingDesc fn.Option[AuxFundingDesc]) error {
610+
608611
errChan := make(chan error, 1)
609612

610613
r.wallet.msgChan <- &continueContributionMsg{
614+
auxFundingDesc: auxFundingDesc,
611615
pendingFundingID: r.reservationID,
612616
err: errChan,
613617
}
@@ -709,8 +713,10 @@ func (r *ChannelReservation) CompleteReservation(fundingInputScripts []*input.Sc
709713
// available via the .OurSignatures() method. As this method should only be
710714
// called as a response to a single funder channel, only a commitment signature
711715
// will be populated.
712-
func (r *ChannelReservation) CompleteReservationSingle(fundingPoint *wire.OutPoint,
713-
commitSig input.Signature) (*channeldb.OpenChannel, error) {
716+
func (r *ChannelReservation) CompleteReservationSingle(
717+
fundingPoint *wire.OutPoint, commitSig input.Signature,
718+
auxFundingDesc fn.Option[AuxFundingDesc]) (*channeldb.OpenChannel,
719+
error) {
714720

715721
errChan := make(chan error, 1)
716722
completeChan := make(chan *channeldb.OpenChannel, 1)
@@ -720,6 +726,7 @@ func (r *ChannelReservation) CompleteReservationSingle(fundingPoint *wire.OutPoi
720726
fundingOutpoint: fundingPoint,
721727
theirCommitmentSig: commitSig,
722728
completeChan: completeChan,
729+
auxFundingDesc: auxFundingDesc,
723730
err: errChan,
724731
}
725732

@@ -805,6 +812,38 @@ func (r *ChannelReservation) Cancel() error {
805812
return <-errChan
806813
}
807814

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

lnwallet/test/test_interface.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"github.com/lightningnetwork/lnd/chainntnfs"
3535
"github.com/lightningnetwork/lnd/chainntnfs/btcdnotify"
3636
"github.com/lightningnetwork/lnd/channeldb"
37+
"github.com/lightningnetwork/lnd/fn"
3738
"github.com/lightningnetwork/lnd/input"
3839
"github.com/lightningnetwork/lnd/keychain"
3940
"github.com/lightningnetwork/lnd/kvdb"
@@ -936,6 +937,7 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness,
936937
fundingPoint := aliceChanReservation.FundingOutpoint()
937938
_, err = bobChanReservation.CompleteReservationSingle(
938939
fundingPoint, aliceCommitSig,
940+
fn.None[lnwallet.AuxFundingDesc](),
939941
)
940942
require.NoError(t, err, "bob unable to consume single reservation")
941943

lnwallet/wallet.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1830,6 +1830,24 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) {
18301830
return
18311831
}
18321832

1833+
chanState := pendingReservation.partialState
1834+
1835+
// If we have an aux funding desc, then we can use it to populate some
1836+
// of the optional, but opaque TLV blobs we'll carry for the channel.
1837+
chanState.CustomBlob = fn.MapOption(func(desc AuxFundingDesc) tlv.Blob {
1838+
return desc.CustomFundingBlob
1839+
})(req.auxFundingDesc)
1840+
chanState.LocalCommitment.CustomBlob = fn.MapOption(
1841+
func(desc AuxFundingDesc) tlv.Blob {
1842+
return desc.CustomLocalCommitBlob
1843+
},
1844+
)(req.auxFundingDesc)
1845+
chanState.RemoteCommitment.CustomBlob = fn.MapOption(
1846+
func(desc AuxFundingDesc) tlv.Blob {
1847+
return desc.CustomRemoteCommitBlob
1848+
},
1849+
)(req.auxFundingDesc)
1850+
18331851
ourContribution := pendingReservation.ourContribution
18341852
theirContribution := pendingReservation.theirContribution
18351853
chanPoint := pendingReservation.partialState.FundingOutpoint
@@ -1888,7 +1906,6 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) {
18881906
// Store their current commitment point. We'll need this after the
18891907
// first state transition in order to verify the authenticity of the
18901908
// revocation.
1891-
chanState := pendingReservation.partialState
18921909
chanState.RemoteCurrentRevocation = theirContribution.FirstCommitmentPoint
18931910

18941911
// Create the txin to our commitment transaction; required to construct
@@ -2340,6 +2357,23 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
23402357
defer pendingReservation.Unlock()
23412358

23422359
chanState := pendingReservation.partialState
2360+
2361+
// If we have an aux funding desc, then we can use it to populate some
2362+
// of the optional, but opaque TLV blobs we'll carry for the channel.
2363+
chanState.CustomBlob = fn.MapOption(func(desc AuxFundingDesc) tlv.Blob {
2364+
return desc.CustomFundingBlob
2365+
})(req.auxFundingDesc)
2366+
chanState.LocalCommitment.CustomBlob = fn.MapOption(
2367+
func(desc AuxFundingDesc) tlv.Blob {
2368+
return desc.CustomLocalCommitBlob
2369+
},
2370+
)(req.auxFundingDesc)
2371+
chanState.RemoteCommitment.CustomBlob = fn.MapOption(
2372+
func(desc AuxFundingDesc) tlv.Blob {
2373+
return desc.CustomRemoteCommitBlob
2374+
},
2375+
)(req.auxFundingDesc)
2376+
23432377
chanType := pendingReservation.partialState.ChanType
23442378
chanState.FundingOutpoint = *req.fundingOutpoint
23452379
fundingTxIn := wire.NewTxIn(req.fundingOutpoint, nil, nil)

0 commit comments

Comments
 (0)