From fa07a2d2486ad10f456ec195b1105fa002fb87b1 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 1 Mar 2023 21:50:55 -0800 Subject: [PATCH] input: HtlcSucceedInput to support sweeping for taproot chans --- input/input.go | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/input/input.go b/input/input.go index f1595e553..ad5bce163 100644 --- a/input/input.go +++ b/input/input.go @@ -153,8 +153,8 @@ func (i *inputKit) UnconfParent() *TxInfo { return i.unconfParent } -// BaseInput contains all the information needed to sweep a basic output -// (CSV/CLTV/no time lock) +// BaseInput contains all the information needed to sweep a basic +// output (CSV/CLTV/no time lock). type BaseInput struct { inputKit } @@ -267,6 +267,24 @@ func MakeHtlcSucceedInput(outpoint *wire.OutPoint, } } +// MakeTaprootHtlcSucceedInput creates a new HtlcSucceedInput that can be used +// to spend an HTLC output for a taproot channel on the remote party's +// commitment transaction. +func MakeTaprootHtlcSucceedInput(op *wire.OutPoint, signDesc *SignDescriptor, + preimage []byte, heightHint, blocksToMaturity uint32) HtlcSucceedInput { + + return HtlcSucceedInput{ + inputKit: inputKit{ + outpoint: *op, + witnessType: TaprootHtlcAcceptedRemoteSuccess, + signDesc: *signDesc, + heightHint: heightHint, + blockToMaturity: blocksToMaturity, + }, + preimage: preimage, + } +} + // CraftInputScript returns a valid set of input scripts allowing this output // to be spent. The returns input scripts should target the input at location // txIndex within the passed transaction. The input scripts generated by this @@ -281,9 +299,27 @@ func (h *HtlcSucceedInput) CraftInputScript(signer Signer, txn *wire.MsgTx, desc.InputIndex = txinIdx desc.PrevOutputFetcher = prevOutputFetcher - witness, err := SenderHtlcSpendRedeem( - signer, &desc, txn, h.preimage, + isTaproot := txscript.IsPayToTaproot(desc.Output.PkScript) + + var ( + witness wire.TxWitness + err error ) + if isTaproot { + if desc.ControlBlock == nil { + return nil, fmt.Errorf("ctrl block must be set") + } + + desc.SignMethod = TaprootScriptSpendSignMethod + + witness, err = SenderHTLCScriptTaprootRedeem( + signer, &desc, txn, h.preimage, nil, nil, + ) + } else { + witness, err = SenderHtlcSpendRedeem( + signer, &desc, txn, h.preimage, + ) + } if err != nil { return nil, err }