contractcourt: update htlcSuccessResolver for taproot chans

This commit is contained in:
Olaoluwa Osuntokun
2023-03-01 22:16:42 -08:00
parent 23f7ee39c7
commit df2a2d83ea
2 changed files with 91 additions and 29 deletions

View File

@@ -7,6 +7,7 @@ import (
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/chainntnfs"
@@ -14,6 +15,7 @@ import (
"github.com/lightningnetwork/lnd/channeldb/models"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/labels"
"github.com/lightningnetwork/lnd/lnutils"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/sweep"
)
@@ -171,9 +173,9 @@ func (h *htlcSuccessResolver) broadcastSuccessTx() (*wire.OutPoint, error) {
// If we have non-nil SignDetails, this means that have a 2nd level
// HTLC transaction that is signed using sighash SINGLE|ANYONECANPAY
// (the case for anchor type channels). In this case we can re-sign it
// and attach fees at will. We let the sweeper handle this job.
// We use the checkpointed outputIncubating field to determine if we
// already swept the HTLC output into the second level transaction.
// and attach fees at will. We let the sweeper handle this job. We use
// the checkpointed outputIncubating field to determine if we already
// swept the HTLC output into the second level transaction.
if h.htlcResolution.SignDetails != nil {
return h.broadcastReSignedSuccessTx()
}
@@ -233,16 +235,29 @@ func (h *htlcSuccessResolver) broadcastReSignedSuccessTx() (
// We will have to let the sweeper re-sign the success tx and wait for
// it to confirm, if we haven't already.
isTaproot := txscript.IsPayToTaproot(
h.htlcResolution.SweepSignDesc.Output.PkScript,
)
if !h.outputIncubating {
log.Infof("%T(%x): offering second-layer transition tx to "+
"sweeper: %v", h, h.htlc.RHash[:],
spew.Sdump(h.htlcResolution.SignedSuccessTx))
secondLevelInput := input.MakeHtlcSecondLevelSuccessAnchorInput(
h.htlcResolution.SignedSuccessTx,
h.htlcResolution.SignDetails, h.htlcResolution.Preimage,
h.broadcastHeight,
)
var secondLevelInput input.HtlcSecondLevelAnchorInput
if isTaproot {
secondLevelInput = input.MakeHtlcSecondLevelSuccessTaprootInput(
h.htlcResolution.SignedSuccessTx,
h.htlcResolution.SignDetails, h.htlcResolution.Preimage,
h.broadcastHeight,
)
} else {
secondLevelInput = input.MakeHtlcSecondLevelSuccessAnchorInput(
h.htlcResolution.SignedSuccessTx,
h.htlcResolution.SignDetails, h.htlcResolution.Preimage,
h.broadcastHeight,
)
}
_, err := h.Sweeper.SweepInput(
&secondLevelInput,
sweep.Params{
@@ -341,13 +356,20 @@ func (h *htlcSuccessResolver) broadcastReSignedSuccessTx() (
// Let the sweeper sweep the second-level output now that the
// CSV/CLTV locks have expired.
var witType input.StandardWitnessType
if isTaproot {
witType = input.TaprootHtlcAcceptedSuccessSecondLevel
} else {
witType = input.HtlcAcceptedSuccessSecondLevel
}
inp := h.makeSweepInput(
op, input.HtlcAcceptedSuccessSecondLevel,
op, witType,
input.LeaseHtlcAcceptedSuccessSecondLevel,
&h.htlcResolution.SweepSignDesc,
h.htlcResolution.CsvDelay, h.broadcastHeight,
h.htlc.RHash,
)
// TODO(roasbeef): need to update above for leased types
_, err = h.Sweeper.SweepInput(
inp,
sweep.Params{
@@ -377,17 +399,32 @@ func (h *htlcSuccessResolver) resolveRemoteCommitOutput() (
log.Infof("%T(%x): crafting sweep tx for incoming+remote "+
"htlc confirmed", h, h.htlc.RHash[:])
isTaproot := txscript.IsPayToTaproot(
h.htlcResolution.SweepSignDesc.Output.PkScript,
)
// Before we can craft out sweeping transaction, we need to
// create an input which contains all the items required to add
// this input to a sweeping transaction, and generate a
// witness.
inp := input.MakeHtlcSucceedInput(
&h.htlcResolution.ClaimOutpoint,
&h.htlcResolution.SweepSignDesc,
h.htlcResolution.Preimage[:],
h.broadcastHeight,
h.htlcResolution.CsvDelay,
)
var inp input.Input
if isTaproot {
inp = lnutils.Ptr(input.MakeTaprootHtlcSucceedInput(
&h.htlcResolution.ClaimOutpoint,
&h.htlcResolution.SweepSignDesc,
h.htlcResolution.Preimage[:],
h.broadcastHeight,
h.htlcResolution.CsvDelay,
))
} else {
inp = lnutils.Ptr(input.MakeHtlcSucceedInput(
&h.htlcResolution.ClaimOutpoint,
&h.htlcResolution.SweepSignDesc,
h.htlcResolution.Preimage[:],
h.broadcastHeight,
h.htlcResolution.CsvDelay,
))
}
// With the input created, we can now generate the full sweep
// transaction, that we'll use to move these coins back into
@@ -400,7 +437,7 @@ func (h *htlcSuccessResolver) resolveRemoteCommitOutput() (
// TODO: Use time-based sweeper and result chan.
var err error
h.sweepTx, err = h.Sweeper.CreateSweepTx(
[]input.Input{&inp},
[]input.Input{inp},
sweep.FeePreference{
ConfTarget: sweepConfTarget,
}, 0,