Skip to content

Commit

Permalink
Merge pull request #1154 from lightninglabs/htlc-resolution
Browse files Browse the repository at this point in the history
tapchannel: add awareness of 1st and 2nd level HTLC sweeps to the AuxSweeper
  • Loading branch information
Roasbeef authored Nov 25, 2024
2 parents 39d1889 + f12575c commit 783fb1e
Show file tree
Hide file tree
Showing 12 changed files with 1,534 additions and 259 deletions.
9 changes: 5 additions & 4 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ func (s *Server) FetchLeavesFromCommit(chanState lnwl.AuxChanState,
// The aux leaf creator is fully stateless, and we don't need to wait
// for the server to be started before being able to use it.
return tapchannel.FetchLeavesFromCommit(
s.chainParams, chanState, com, keys,
s.chainParams, chanState, com, keys, whoseCommit,
)
}

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

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

if err := s.waitForReady(); err != nil {
return err
}

return s.cfg.AuxSweeper.NotifyBroadcast(req, tx, fee)
return s.cfg.AuxSweeper.NotifyBroadcast(req, tx, fee, outpointToTxIndex)
}
3 changes: 3 additions & 0 deletions tapchannel/allocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,9 @@ func DistributeCoins(inputs []*proof.Proof, allocations []*Allocation,
AnchorOutputTapscriptSibling: sibling,
ScriptKey: a.ScriptKey,
ProofDeliveryAddress: deliveryAddr,
RelativeLockTime: uint64(
a.Sequence,
),
}
p.packet.Outputs = append(p.packet.Outputs, vOut)

Expand Down
6 changes: 3 additions & 3 deletions tapchannel/aux_closer.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/davecgh/go-spew/spew"
"github.com/lightninglabs/taproot-assets/address"
"github.com/lightninglabs/taproot-assets/asset"
"github.com/lightninglabs/taproot-assets/fn"
Expand Down Expand Up @@ -250,7 +249,8 @@ func (a *AuxChanCloser) AuxCloseOutputs(
}

log.Tracef("Decoded local_shutdown=%v, remote_shutdown=%v",
spew.Sdump(localShutdown), spew.Sdump(remoteShutdown))
limitSpewer.Sdump(localShutdown),
limitSpewer.Sdump(remoteShutdown))

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

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

return lfn.Some[lnwire.CustomRecords](records), nil
}
Expand Down
20 changes: 11 additions & 9 deletions tapchannel/aux_funding_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"github.com/btcsuite/btcd/btcutil/psbt"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/davecgh/go-spew/spew"
"github.com/lightninglabs/lndclient"
"github.com/lightninglabs/taproot-assets/address"
"github.com/lightninglabs/taproot-assets/asset"
Expand Down Expand Up @@ -588,7 +587,7 @@ func (p *pendingAssetFunding) unlockAssetInputs(ctx context.Context,
coinSelect tapfreighter.CoinSelector) error {

log.Debugf("unlocking asset inputs: %v",
spew.Sdump(p.lockedAssetInputs))
limitSpewer.Sdump(p.lockedAssetInputs))

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

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

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

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

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

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

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

log.Debugf("Funding PSBT pre funding: %s", spew.Sdump(fundingPsbt))
log.Debugf("Funding PSBT pre funding: %s",
limitSpewer.Sdump(fundingPsbt))

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

log.Infof("Funding PSBT post funding: %s", spew.Sdump(finalFundedPsbt))
log.Infof("Funding PSBT post funding: %s",
limitSpewer.Sdump(finalFundedPsbt))

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

log.Debugf("Submitting finalized PSBT to lnd for verification: %s",
spew.Sdump(finalFundedPsbt.Pkt))
limitSpewer.Sdump(finalFundedPsbt.Pkt))

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

log.Infof("Returning funding desc: %v",
spew.Sdump(fundingDesc))
limitSpewer.Sdump(fundingDesc))

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

Expand Down
4 changes: 2 additions & 2 deletions tapchannel/aux_invoice_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"sync"

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

log.Tracef("Currently available quotes: buy %v, sell %v",
spew.Sdump(acceptedBuyQuotes), spew.Sdump(acceptedSellQuotes))
limitSpewer.Sdump(acceptedBuyQuotes),
limitSpewer.Sdump(acceptedSellQuotes))

buyQuote, isBuy := acceptedBuyQuotes[rfqID.Scid()]
sellQuote, isSell := acceptedSellQuotes[rfqID.Scid()]
Expand Down
25 changes: 22 additions & 3 deletions tapchannel/aux_leaf_creator.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import (
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/lightninglabs/taproot-assets/address"
"github.com/lightninglabs/taproot-assets/fn"
cmsg "github.com/lightninglabs/taproot-assets/tapchannelmsg"
"github.com/lightningnetwork/lnd/channeldb"
lfn "github.com/lightningnetwork/lnd/fn"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lntypes"
lnwl "github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/tlv"
)
Expand Down Expand Up @@ -78,7 +80,8 @@ func FetchLeavesFromView(chainParams *address.ChainParams,
// to the passed aux blob, and an existing channel commitment.
func FetchLeavesFromCommit(chainParams *address.ChainParams,
chanState lnwl.AuxChanState, com channeldb.ChannelCommitment,
keys lnwl.CommitmentKeyRing) lfn.Result[lnwl.CommitDiffAuxResult] {
keys lnwl.CommitmentKeyRing,
whoseCommit lntypes.ChannelParty) lfn.Result[lnwl.CommitDiffAuxResult] {

type returnType = lnwl.CommitDiffAuxResult

Expand Down Expand Up @@ -115,9 +118,17 @@ func FetchLeavesFromCommit(chainParams *address.ChainParams,
continue
}

// If this is an incoming HTLC (to us), but on the
// remote party's commitment transaction, then they'll
// need to go to the second level to time it out.
var cltvTimeout fn.Option[uint32]
if whoseCommit == lntypes.Remote {
cltvTimeout = fn.Some(htlc.RefundTimeout)
}

leaf, err := CreateSecondLevelHtlcTx(
chanState, com.CommitTx, htlc.Amt.ToSatoshis(),
keys, chainParams, htlcOutputs,
keys, chainParams, htlcOutputs, cltvTimeout,
)
if err != nil {
return lfn.Err[returnType](fmt.Errorf("unable "+
Expand Down Expand Up @@ -147,9 +158,17 @@ func FetchLeavesFromCommit(chainParams *address.ChainParams,
continue
}

// If this is an outgoing commit on our local
// commitment, then we'll need to go to the second level
// to time out it out.
var cltvTimeout fn.Option[uint32]
if whoseCommit == lntypes.Local {
cltvTimeout = fn.Some(htlc.RefundTimeout)
}

leaf, err := CreateSecondLevelHtlcTx(
chanState, com.CommitTx, htlc.Amt.ToSatoshis(),
keys, chainParams, htlcOutputs,
keys, chainParams, htlcOutputs, cltvTimeout,
)
if err != nil {
return lfn.Err[returnType](fmt.Errorf("unable "+
Expand Down
28 changes: 22 additions & 6 deletions tapchannel/aux_leaf_signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/btcsuite/btcd/btcutil/psbt"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/davecgh/go-spew/spew"
"github.com/lightninglabs/taproot-assets/address"
"github.com/lightninglabs/taproot-assets/asset"
"github.com/lightninglabs/taproot-assets/commitment"
Expand Down Expand Up @@ -358,9 +357,17 @@ func verifyHtlcSignature(chainParams *address.ChainParams,
keyRing lnwallet.CommitmentKeyRing, sigs []*cmsg.AssetSig,
htlcOutputs []*cmsg.AssetOutput, baseJob lnwallet.BaseAuxJob) error {

// If we're validating a signature for an outgoing HTLC, then it's an
// outgoing HTLC for the remote party, so we'll need to sign it with the
// proper lock time.
var htlcTimeout fn.Option[uint32]
if !baseJob.Incoming {
htlcTimeout = fn.Some(baseJob.HTLC.Timeout)
}

vPackets, err := htlcSecondLevelPacketsFromCommit(
chainParams, chanState, commitTx, baseJob.KeyRing, htlcOutputs,
baseJob,
baseJob, htlcTimeout,
)
if err != nil {
return fmt.Errorf("error generating second level packets: %w",
Expand Down Expand Up @@ -494,9 +501,17 @@ func (s *AuxLeafSigner) generateHtlcSignature(chanState lnwallet.AuxChanState,
signDesc input.SignDescriptor,
baseJob lnwallet.BaseAuxJob) (lnwallet.AuxSigJobResp, error) {

// If we're generating a signature for an incoming HTLC, then it's an
// outgoing HTLC for the remote party, so we'll need to sign it with the
// proper lock time.
var htlcTimeout fn.Option[uint32]
if baseJob.Incoming {
htlcTimeout = fn.Some(baseJob.HTLC.Timeout)
}

vPackets, err := htlcSecondLevelPacketsFromCommit(
s.cfg.ChainParams, chanState, commitTx, baseJob.KeyRing,
htlcOutputs, baseJob,
htlcOutputs, baseJob, htlcTimeout,
)
if err != nil {
return lnwallet.AuxSigJobResp{}, fmt.Errorf("error generating "+
Expand Down Expand Up @@ -584,11 +599,12 @@ func (s *AuxLeafSigner) generateHtlcSignature(chanState lnwallet.AuxChanState,
func htlcSecondLevelPacketsFromCommit(chainParams *address.ChainParams,
chanState lnwallet.AuxChanState, commitTx *wire.MsgTx,
keyRing lnwallet.CommitmentKeyRing, htlcOutputs []*cmsg.AssetOutput,
baseJob lnwallet.BaseAuxJob) ([]*tappsbt.VPacket, error) {
baseJob lnwallet.BaseAuxJob,
htlcTimeout fn.Option[uint32]) ([]*tappsbt.VPacket, error) {

packets, _, err := CreateSecondLevelHtlcPackets(
chanState, commitTx, baseJob.HTLC.Amount.ToSatoshis(),
keyRing, chainParams, htlcOutputs,
keyRing, chainParams, htlcOutputs, htlcTimeout,
)
if err != nil {
return nil, fmt.Errorf("error creating second level HTLC "+
Expand Down Expand Up @@ -632,7 +648,7 @@ func (v *schnorrSigValidator) ValidateWitnesses(newAsset *asset.Asset,
if !ok {
return fmt.Errorf("%w: no prev asset for "+
"input_prev_id=%v", vm.ErrNoInputs,
spew.Sdump(witness.PrevID))
limitSpewer.Sdump(witness.PrevID))
}

var (
Expand Down
Loading

0 comments on commit 783fb1e

Please sign in to comment.