Skip to content

Commit 783fb1e

Browse files
authored
Merge pull request #1154 from lightninglabs/htlc-resolution
tapchannel: add awareness of 1st and 2nd level HTLC sweeps to the AuxSweeper
2 parents 39d1889 + f12575c commit 783fb1e

12 files changed

+1534
-259
lines changed

server.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ func (s *Server) FetchLeavesFromCommit(chanState lnwl.AuxChanState,
770770
// The aux leaf creator is fully stateless, and we don't need to wait
771771
// for the server to be started before being able to use it.
772772
return tapchannel.FetchLeavesFromCommit(
773-
s.chainParams, chanState, com, keys,
773+
s.chainParams, chanState, com, keys, whoseCommit,
774774
)
775775
}
776776

@@ -1162,12 +1162,13 @@ func (s *Server) NotifyBroadcast(req *sweep.BumpRequest,
11621162
tx *wire.MsgTx, fee btcutil.Amount,
11631163
outpointToTxIndex map[wire.OutPoint]int) error {
11641164

1165-
srvrLog.Tracef("NotifyBroadcast called, req=%v, tx=%v, fee=%v",
1166-
spew.Sdump(req), spew.Sdump(tx), fee)
1165+
srvrLog.Tracef("NotifyBroadcast called, req=%v, tx=%v, fee=%v, "+
1166+
"out_index=%v", spew.Sdump(req), spew.Sdump(tx), fee,
1167+
spew.Sdump(outpointToTxIndex))
11671168

11681169
if err := s.waitForReady(); err != nil {
11691170
return err
11701171
}
11711172

1172-
return s.cfg.AuxSweeper.NotifyBroadcast(req, tx, fee)
1173+
return s.cfg.AuxSweeper.NotifyBroadcast(req, tx, fee, outpointToTxIndex)
11731174
}

tapchannel/allocation.go

+3
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,9 @@ func DistributeCoins(inputs []*proof.Proof, allocations []*Allocation,
454454
AnchorOutputTapscriptSibling: sibling,
455455
ScriptKey: a.ScriptKey,
456456
ProofDeliveryAddress: deliveryAddr,
457+
RelativeLockTime: uint64(
458+
a.Sequence,
459+
),
457460
}
458461
p.packet.Outputs = append(p.packet.Outputs, vOut)
459462

tapchannel/aux_closer.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"github.com/btcsuite/btcd/btcutil"
1111
"github.com/btcsuite/btcd/txscript"
1212
"github.com/btcsuite/btcd/wire"
13-
"github.com/davecgh/go-spew/spew"
1413
"github.com/lightninglabs/taproot-assets/address"
1514
"github.com/lightninglabs/taproot-assets/asset"
1615
"github.com/lightninglabs/taproot-assets/fn"
@@ -250,7 +249,8 @@ func (a *AuxChanCloser) AuxCloseOutputs(
250249
}
251250

252251
log.Tracef("Decoded local_shutdown=%v, remote_shutdown=%v",
253-
spew.Sdump(localShutdown), spew.Sdump(remoteShutdown))
252+
limitSpewer.Sdump(localShutdown),
253+
limitSpewer.Sdump(remoteShutdown))
254254

255255
// To start with, we'll now create the allocations for the asset
256256
// outputs. We track the amount that'll go to the anchor assets, so we
@@ -570,7 +570,7 @@ func (a *AuxChanCloser) ShutdownBlob(
570570
return none, err
571571
}
572572

573-
log.Infof("Constructed shutdown record: %v", spew.Sdump(records))
573+
log.Infof("Constructed shutdown record: %v", limitSpewer.Sdump(records))
574574

575575
return lfn.Some[lnwire.CustomRecords](records), nil
576576
}

tapchannel/aux_funding_controller.go

+11-9
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"github.com/btcsuite/btcd/btcutil/psbt"
2020
"github.com/btcsuite/btcd/chaincfg/chainhash"
2121
"github.com/btcsuite/btcd/wire"
22-
"github.com/davecgh/go-spew/spew"
2322
"github.com/lightninglabs/lndclient"
2423
"github.com/lightninglabs/taproot-assets/address"
2524
"github.com/lightninglabs/taproot-assets/asset"
@@ -588,7 +587,7 @@ func (p *pendingAssetFunding) unlockAssetInputs(ctx context.Context,
588587
coinSelect tapfreighter.CoinSelector) error {
589588

590589
log.Debugf("unlocking asset inputs: %v",
591-
spew.Sdump(p.lockedAssetInputs))
590+
limitSpewer.Sdump(p.lockedAssetInputs))
592591

593592
err := coinSelect.ReleaseCoins(ctx, p.lockedAssetInputs...)
594593
if err != nil {
@@ -1002,7 +1001,8 @@ func (f *FundingController) anchorVPackets(fundedPkt *tapsend.FundedPsbt,
10021001
func (f *FundingController) signAndFinalizePsbt(ctx context.Context,
10031002
pkt *psbt.Packet) (*wire.MsgTx, error) {
10041003

1005-
log.Debugf("Signing and finalizing PSBT w/ lnd: %v", spew.Sdump(pkt))
1004+
log.Debugf("Signing and finalizing PSBT w/ lnd: %v",
1005+
limitSpewer.Sdump(pkt))
10061006

10071007
// By default, the wallet won't try to finalize output it sees are watch
10081008
// only (like the asset input), so we'll have it sign ourselves first.
@@ -1011,7 +1011,7 @@ func (f *FundingController) signAndFinalizePsbt(ctx context.Context,
10111011
return nil, fmt.Errorf("unable to sign PSBT: %w", err)
10121012
}
10131013

1014-
log.Debugf("Signed PSBT: %v", spew.Sdump(signedPkt))
1014+
log.Debugf("Signed PSBT: %v", limitSpewer.Sdump(signedPkt))
10151015

10161016
finalizedPkt, err := f.cfg.ChainWallet.SignAndFinalizePsbt(
10171017
ctx, signedPkt,
@@ -1020,7 +1020,7 @@ func (f *FundingController) signAndFinalizePsbt(ctx context.Context,
10201020
return nil, fmt.Errorf("unable to finalize PSBT: %w", err)
10211021
}
10221022

1023-
log.Debugf("Finalized PSBT: %v", spew.Sdump(signedPkt))
1023+
log.Debugf("Finalized PSBT: %v", limitSpewer.Sdump(signedPkt))
10241024

10251025
// Extra the tx manually, then perform some manual sanity checks to
10261026
// make sure things are ready for broadcast.
@@ -1123,7 +1123,8 @@ func (f *FundingController) completeChannelFunding(ctx context.Context,
11231123
// with lnd that we arrived at the proper TxOut.
11241124
fundingPsbt.UnsignedTx.TxOut[0].Value = int64(fundingReq.ChanAmt)
11251125

1126-
log.Debugf("Funding PSBT pre funding: %s", spew.Sdump(fundingPsbt))
1126+
log.Debugf("Funding PSBT pre funding: %s",
1127+
limitSpewer.Sdump(fundingPsbt))
11271128

11281129
// With the PSBT template created, we'll now ask lnd to fund the PSBT.
11291130
// This'll add yet another output (lnd's change output) to the
@@ -1135,7 +1136,8 @@ func (f *FundingController) completeChannelFunding(ctx context.Context,
11351136
return nil, fmt.Errorf("unable to fund PSBT: %w", err)
11361137
}
11371138

1138-
log.Infof("Funding PSBT post funding: %s", spew.Sdump(finalFundedPsbt))
1139+
log.Infof("Funding PSBT post funding: %s",
1140+
limitSpewer.Sdump(finalFundedPsbt))
11391141

11401142
// If we fail at any step in the process, we want to make sure we
11411143
// unlock the inputs, so we'll add them to funding state now.
@@ -1178,7 +1180,7 @@ func (f *FundingController) completeChannelFunding(ctx context.Context,
11781180
}
11791181

11801182
log.Debugf("Submitting finalized PSBT to lnd for verification: %s",
1181-
spew.Sdump(finalFundedPsbt.Pkt))
1183+
limitSpewer.Sdump(finalFundedPsbt.Pkt))
11821184

11831185
// At this point, we're nearly done, we'll now present the final PSBT
11841186
// to lnd to verification. If this passes, then we're clear to
@@ -1737,7 +1739,7 @@ func (f *FundingController) chanFunder() {
17371739
}
17381740

17391741
log.Infof("Returning funding desc: %v",
1740-
spew.Sdump(fundingDesc))
1742+
limitSpewer.Sdump(fundingDesc))
17411743

17421744
req.resp <- lfn.Some(*fundingDesc)
17431745

tapchannel/aux_invoice_manager.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"fmt"
66
"sync"
77

8-
"github.com/davecgh/go-spew/spew"
98
"github.com/lightninglabs/lndclient"
109
"github.com/lightninglabs/taproot-assets/address"
1110
"github.com/lightninglabs/taproot-assets/fn"
@@ -254,7 +253,8 @@ func (s *AuxInvoiceManager) priceFromQuote(rfqID rfqmsg.ID) (
254253
acceptedSellQuotes := s.cfg.RfqManager.LocalAcceptedSellQuotes()
255254

256255
log.Tracef("Currently available quotes: buy %v, sell %v",
257-
spew.Sdump(acceptedBuyQuotes), spew.Sdump(acceptedSellQuotes))
256+
limitSpewer.Sdump(acceptedBuyQuotes),
257+
limitSpewer.Sdump(acceptedSellQuotes))
258258

259259
buyQuote, isBuy := acceptedBuyQuotes[rfqID.Scid()]
260260
sellQuote, isSell := acceptedSellQuotes[rfqID.Scid()]

tapchannel/aux_leaf_creator.go

+22-3
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ import (
88
"github.com/btcsuite/btcd/txscript"
99
"github.com/btcsuite/btcd/wire"
1010
"github.com/lightninglabs/taproot-assets/address"
11+
"github.com/lightninglabs/taproot-assets/fn"
1112
cmsg "github.com/lightninglabs/taproot-assets/tapchannelmsg"
1213
"github.com/lightningnetwork/lnd/channeldb"
1314
lfn "github.com/lightningnetwork/lnd/fn"
1415
"github.com/lightningnetwork/lnd/input"
16+
"github.com/lightningnetwork/lnd/lntypes"
1517
lnwl "github.com/lightningnetwork/lnd/lnwallet"
1618
"github.com/lightningnetwork/lnd/tlv"
1719
)
@@ -78,7 +80,8 @@ func FetchLeavesFromView(chainParams *address.ChainParams,
7880
// to the passed aux blob, and an existing channel commitment.
7981
func FetchLeavesFromCommit(chainParams *address.ChainParams,
8082
chanState lnwl.AuxChanState, com channeldb.ChannelCommitment,
81-
keys lnwl.CommitmentKeyRing) lfn.Result[lnwl.CommitDiffAuxResult] {
83+
keys lnwl.CommitmentKeyRing,
84+
whoseCommit lntypes.ChannelParty) lfn.Result[lnwl.CommitDiffAuxResult] {
8285

8386
type returnType = lnwl.CommitDiffAuxResult
8487

@@ -115,9 +118,17 @@ func FetchLeavesFromCommit(chainParams *address.ChainParams,
115118
continue
116119
}
117120

121+
// If this is an incoming HTLC (to us), but on the
122+
// remote party's commitment transaction, then they'll
123+
// need to go to the second level to time it out.
124+
var cltvTimeout fn.Option[uint32]
125+
if whoseCommit == lntypes.Remote {
126+
cltvTimeout = fn.Some(htlc.RefundTimeout)
127+
}
128+
118129
leaf, err := CreateSecondLevelHtlcTx(
119130
chanState, com.CommitTx, htlc.Amt.ToSatoshis(),
120-
keys, chainParams, htlcOutputs,
131+
keys, chainParams, htlcOutputs, cltvTimeout,
121132
)
122133
if err != nil {
123134
return lfn.Err[returnType](fmt.Errorf("unable "+
@@ -147,9 +158,17 @@ func FetchLeavesFromCommit(chainParams *address.ChainParams,
147158
continue
148159
}
149160

161+
// If this is an outgoing commit on our local
162+
// commitment, then we'll need to go to the second level
163+
// to time out it out.
164+
var cltvTimeout fn.Option[uint32]
165+
if whoseCommit == lntypes.Local {
166+
cltvTimeout = fn.Some(htlc.RefundTimeout)
167+
}
168+
150169
leaf, err := CreateSecondLevelHtlcTx(
151170
chanState, com.CommitTx, htlc.Amt.ToSatoshis(),
152-
keys, chainParams, htlcOutputs,
171+
keys, chainParams, htlcOutputs, cltvTimeout,
153172
)
154173
if err != nil {
155174
return lfn.Err[returnType](fmt.Errorf("unable "+

tapchannel/aux_leaf_signer.go

+22-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"github.com/btcsuite/btcd/btcutil/psbt"
1010
"github.com/btcsuite/btcd/txscript"
1111
"github.com/btcsuite/btcd/wire"
12-
"github.com/davecgh/go-spew/spew"
1312
"github.com/lightninglabs/taproot-assets/address"
1413
"github.com/lightninglabs/taproot-assets/asset"
1514
"github.com/lightninglabs/taproot-assets/commitment"
@@ -358,9 +357,17 @@ func verifyHtlcSignature(chainParams *address.ChainParams,
358357
keyRing lnwallet.CommitmentKeyRing, sigs []*cmsg.AssetSig,
359358
htlcOutputs []*cmsg.AssetOutput, baseJob lnwallet.BaseAuxJob) error {
360359

360+
// If we're validating a signature for an outgoing HTLC, then it's an
361+
// outgoing HTLC for the remote party, so we'll need to sign it with the
362+
// proper lock time.
363+
var htlcTimeout fn.Option[uint32]
364+
if !baseJob.Incoming {
365+
htlcTimeout = fn.Some(baseJob.HTLC.Timeout)
366+
}
367+
361368
vPackets, err := htlcSecondLevelPacketsFromCommit(
362369
chainParams, chanState, commitTx, baseJob.KeyRing, htlcOutputs,
363-
baseJob,
370+
baseJob, htlcTimeout,
364371
)
365372
if err != nil {
366373
return fmt.Errorf("error generating second level packets: %w",
@@ -494,9 +501,17 @@ func (s *AuxLeafSigner) generateHtlcSignature(chanState lnwallet.AuxChanState,
494501
signDesc input.SignDescriptor,
495502
baseJob lnwallet.BaseAuxJob) (lnwallet.AuxSigJobResp, error) {
496503

504+
// If we're generating a signature for an incoming HTLC, then it's an
505+
// outgoing HTLC for the remote party, so we'll need to sign it with the
506+
// proper lock time.
507+
var htlcTimeout fn.Option[uint32]
508+
if baseJob.Incoming {
509+
htlcTimeout = fn.Some(baseJob.HTLC.Timeout)
510+
}
511+
497512
vPackets, err := htlcSecondLevelPacketsFromCommit(
498513
s.cfg.ChainParams, chanState, commitTx, baseJob.KeyRing,
499-
htlcOutputs, baseJob,
514+
htlcOutputs, baseJob, htlcTimeout,
500515
)
501516
if err != nil {
502517
return lnwallet.AuxSigJobResp{}, fmt.Errorf("error generating "+
@@ -584,11 +599,12 @@ func (s *AuxLeafSigner) generateHtlcSignature(chanState lnwallet.AuxChanState,
584599
func htlcSecondLevelPacketsFromCommit(chainParams *address.ChainParams,
585600
chanState lnwallet.AuxChanState, commitTx *wire.MsgTx,
586601
keyRing lnwallet.CommitmentKeyRing, htlcOutputs []*cmsg.AssetOutput,
587-
baseJob lnwallet.BaseAuxJob) ([]*tappsbt.VPacket, error) {
602+
baseJob lnwallet.BaseAuxJob,
603+
htlcTimeout fn.Option[uint32]) ([]*tappsbt.VPacket, error) {
588604

589605
packets, _, err := CreateSecondLevelHtlcPackets(
590606
chanState, commitTx, baseJob.HTLC.Amount.ToSatoshis(),
591-
keyRing, chainParams, htlcOutputs,
607+
keyRing, chainParams, htlcOutputs, htlcTimeout,
592608
)
593609
if err != nil {
594610
return nil, fmt.Errorf("error creating second level HTLC "+
@@ -632,7 +648,7 @@ func (v *schnorrSigValidator) ValidateWitnesses(newAsset *asset.Asset,
632648
if !ok {
633649
return fmt.Errorf("%w: no prev asset for "+
634650
"input_prev_id=%v", vm.ErrNoInputs,
635-
spew.Sdump(witness.PrevID))
651+
limitSpewer.Sdump(witness.PrevID))
636652
}
637653

638654
var (

0 commit comments

Comments
 (0)