mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-02-22 06:21:40 +01:00
input: update all taproot script spends to optionally make the ctrl block
In this commit, we update all the taproot scripts spends to optionally make the control block. This is useful in cases where we've already created the control block, or may not have the items needed to construct it in the first place. We also add the control block to the sign descriptor itself.
This commit is contained in:
parent
405a435a84
commit
4c7da7df49
5 changed files with 354 additions and 92 deletions
|
@ -665,7 +665,7 @@ func senderHtlcTapScriptTree(senderHtlcKey, receiverHtlcKey,
|
|||
// SenderHTLCScriptTaproot constructs the taproot witness program (schnorr key)
|
||||
// for an outgoing HTLC on the sender's version of the commitment transaction.
|
||||
// This method returns the top level tweaked public key that commits to both
|
||||
// the script paths.
|
||||
// the script paths. This is also known as an offered HTLC.
|
||||
//
|
||||
// The returned key commits to a tapscript tree with two possible paths:
|
||||
//
|
||||
|
@ -727,12 +727,21 @@ func SenderHTLCScriptTaprootRedeem(signer Signer, signDesc *SignDescriptor,
|
|||
|
||||
// In addition to the signature and the witness/leaf script, we also
|
||||
// need to make a control block proof using the tapscript tree.
|
||||
successTapLeafHash := txscript.NewBaseTapLeaf(
|
||||
signDesc.WitnessScript,
|
||||
).TapHash()
|
||||
successIdx := tapscriptTree.LeafProofIndex[successTapLeafHash]
|
||||
successMerkleProof := tapscriptTree.LeafMerkleProofs[successIdx]
|
||||
successControlBlock := successMerkleProof.ToControlBlock(revokeKey)
|
||||
var ctrlBlock []byte
|
||||
if signDesc.ControlBlock == nil {
|
||||
successControlBlock := MakeTaprootCtrlBlock(
|
||||
signDesc.WitnessScript, revokeKey, tapscriptTree,
|
||||
)
|
||||
|
||||
ctrlBytes, err := successControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctrlBlock = ctrlBytes
|
||||
} else {
|
||||
ctrlBlock = signDesc.ControlBlock
|
||||
}
|
||||
|
||||
// The final witness stack is:
|
||||
// <receiver sig> <preimage> <success_script> <control_block>
|
||||
|
@ -740,10 +749,7 @@ func SenderHTLCScriptTaprootRedeem(signer Signer, signDesc *SignDescriptor,
|
|||
witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
|
||||
witnessStack[1] = preimage
|
||||
witnessStack[2] = signDesc.WitnessScript
|
||||
witnessStack[3], err = successControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
witnessStack[3] = ctrlBlock
|
||||
|
||||
return witnessStack, nil
|
||||
}
|
||||
|
@ -765,12 +771,20 @@ func SenderHTLCScriptTaprootTimeout(receiverSig Signature,
|
|||
|
||||
// With the sweep signature obtained, we'll obtain the control block
|
||||
// proof needed to perform a valid spend for the timeout path.
|
||||
timeoutTapLeafHash := txscript.NewBaseTapLeaf(
|
||||
signDesc.WitnessScript,
|
||||
).TapHash()
|
||||
timeoutIdx := tapscriptTree.LeafProofIndex[timeoutTapLeafHash]
|
||||
timeoutMerkleProof := tapscriptTree.LeafMerkleProofs[timeoutIdx]
|
||||
timeoutControlBlock := timeoutMerkleProof.ToControlBlock(revokeKey)
|
||||
var ctrlBlockBytes []byte
|
||||
if signDesc.ControlBlock == nil {
|
||||
timeoutControlBlock := MakeTaprootCtrlBlock(
|
||||
signDesc.WitnessScript, revokeKey, tapscriptTree,
|
||||
)
|
||||
ctrlBytes, err := timeoutControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctrlBlockBytes = ctrlBytes
|
||||
} else {
|
||||
ctrlBlockBytes = signDesc.ControlBlock
|
||||
}
|
||||
|
||||
// The final witness stack is:
|
||||
// <receiver sig> <local sig> <timeout_script> <control_block>
|
||||
|
@ -778,10 +792,7 @@ func SenderHTLCScriptTaprootTimeout(receiverSig Signature,
|
|||
witnessStack[0] = maybeAppendSighash(receiverSig, receiverSigHash)
|
||||
witnessStack[1] = maybeAppendSighash(sweepSig, signDesc.HashType)
|
||||
witnessStack[2] = signDesc.WitnessScript
|
||||
witnessStack[3], err = timeoutControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
witnessStack[3] = ctrlBlockBytes
|
||||
|
||||
return witnessStack, nil
|
||||
}
|
||||
|
@ -1200,7 +1211,7 @@ func receiverHtlcTapScriptTree(senderHtlcKey, receiverHtlcKey,
|
|||
// ReceiverHTLCScriptTaproot constructs the taproot witness program (schnor
|
||||
// key) for an incoming HTLC on the receiver's version of the commitment
|
||||
// transaction. This method returns the top level tweaked public key that
|
||||
// commits to both the script paths. From the PoV for the receiver, this is an
|
||||
// commits to both the script paths. From the PoV of the receiver, this is an
|
||||
// accepted HTLC.
|
||||
//
|
||||
// The returned key commits to a tapscript tree with two possible paths:
|
||||
|
@ -1257,12 +1268,20 @@ func ReceiverHTLCScriptTaprootRedeem(senderSig Signature,
|
|||
|
||||
// In addition to the signature and the witness/leaf script, we also
|
||||
// need to make a control block proof using the tapscript tree.
|
||||
successTapLeafHash := txscript.NewBaseTapLeaf(
|
||||
signDesc.WitnessScript,
|
||||
).TapHash()
|
||||
successIdx := tapscriptTree.LeafProofIndex[successTapLeafHash]
|
||||
successMerkleProof := tapscriptTree.LeafMerkleProofs[successIdx]
|
||||
successControlBlock := successMerkleProof.ToControlBlock(revokeKey)
|
||||
var ctrlBlock []byte
|
||||
if signDesc.ControlBlock == nil {
|
||||
redeemControlBlock := MakeTaprootCtrlBlock(
|
||||
signDesc.WitnessScript, revokeKey, tapscriptTree,
|
||||
)
|
||||
ctrlBytes, err := redeemControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctrlBlock = ctrlBytes
|
||||
} else {
|
||||
ctrlBlock = signDesc.ControlBlock
|
||||
}
|
||||
|
||||
// The final witness stack is:
|
||||
// * <sender sig> <receiver sig> <preimage> <success_script>
|
||||
|
@ -1272,10 +1291,7 @@ func ReceiverHTLCScriptTaprootRedeem(senderSig Signature,
|
|||
witnessStack[1] = maybeAppendSighash(sweepSig, signDesc.HashType)
|
||||
witnessStack[2] = paymentPreimage
|
||||
witnessStack[3] = signDesc.WitnessScript
|
||||
witnessStack[4], err = successControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
witnessStack[4] = ctrlBlock
|
||||
|
||||
return witnessStack, nil
|
||||
}
|
||||
|
@ -1311,22 +1327,25 @@ func ReceiverHTLCScriptTaprootTimeout(signer Signer, signDesc *SignDescriptor,
|
|||
|
||||
// In addition to the signature and the witness/leaf script, we also
|
||||
// need to make a control block proof using the tapscript tree.
|
||||
timeoutTapLeafHash := txscript.NewBaseTapLeaf(
|
||||
signDesc.WitnessScript,
|
||||
).TapHash()
|
||||
timeoutIdx := tapscriptTree.LeafProofIndex[timeoutTapLeafHash]
|
||||
timeoutMerkleProof := tapscriptTree.LeafMerkleProofs[timeoutIdx]
|
||||
timeoutControlBlock := timeoutMerkleProof.ToControlBlock(revokeKey)
|
||||
var ctrlBlock []byte
|
||||
if signDesc.ControlBlock == nil {
|
||||
timeoutControlBlock := MakeTaprootCtrlBlock(
|
||||
signDesc.WitnessScript, revokeKey, tapscriptTree,
|
||||
)
|
||||
ctrlBlock, err = timeoutControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
ctrlBlock = signDesc.ControlBlock
|
||||
}
|
||||
|
||||
// The final witness is pretty simple, we just need to present a valid
|
||||
// signature for the script, and then provide the control block.
|
||||
witnessStack := make(wire.TxWitness, 3)
|
||||
witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
|
||||
witnessStack[1] = signDesc.WitnessScript
|
||||
witnessStack[2], err = timeoutControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
witnessStack[2] = ctrlBlock
|
||||
|
||||
return witnessStack, nil
|
||||
}
|
||||
|
@ -1542,7 +1561,7 @@ func TaprootHtlcSpendRevoke(signer Signer, signDesc *SignDescriptor,
|
|||
// NOTE: The caller MUST set the txn version, sequence number, and sign
|
||||
// descriptor's sig hash cache before invocation.
|
||||
func TaprootHtlcSpendSuccess(signer Signer, signDesc *SignDescriptor,
|
||||
revokeKey *btcec.PublicKey, sweepTx *wire.MsgTx,
|
||||
sweepTx *wire.MsgTx, revokeKey *btcec.PublicKey,
|
||||
tapscriptTree *txscript.IndexedTapScriptTree) (wire.TxWitness, error) {
|
||||
|
||||
// First, we'll generate the sweep signature based on the populated
|
||||
|
@ -1553,14 +1572,21 @@ func TaprootHtlcSpendSuccess(signer Signer, signDesc *SignDescriptor,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Now that we have the sweep signature, we'll construct the control
|
||||
// block needed to spend the script path.
|
||||
redeemTapLeafHash := txscript.NewBaseTapLeaf(
|
||||
signDesc.WitnessScript,
|
||||
).TapHash()
|
||||
redeemIdx := tapscriptTree.LeafProofIndex[redeemTapLeafHash]
|
||||
redeemMerkleProof := tapscriptTree.LeafMerkleProofs[redeemIdx]
|
||||
redeemControlBlock := redeemMerkleProof.ToControlBlock(revokeKey)
|
||||
var ctrlBlock []byte
|
||||
if signDesc.ControlBlock == nil {
|
||||
// Now that we have the sweep signature, we'll construct the control
|
||||
// block needed to spend the script path.
|
||||
redeemControlBlock := MakeTaprootCtrlBlock(
|
||||
signDesc.WitnessScript, revokeKey, tapscriptTree,
|
||||
)
|
||||
|
||||
ctrlBlock, err = redeemControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
ctrlBlock = signDesc.ControlBlock
|
||||
}
|
||||
|
||||
// Now that we have the redeem control block, we can construct the
|
||||
// final witness needed to spend the script:
|
||||
|
@ -1569,10 +1595,7 @@ func TaprootHtlcSpendSuccess(signer Signer, signDesc *SignDescriptor,
|
|||
witnessStack := make(wire.TxWitness, 3)
|
||||
witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
|
||||
witnessStack[1] = signDesc.WitnessScript
|
||||
witnessStack[2], err = redeemControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
witnessStack[2] = ctrlBlock
|
||||
|
||||
return witnessStack, nil
|
||||
}
|
||||
|
@ -1946,6 +1969,19 @@ func TaprootCommitScriptToSelf(csvTimeout uint32,
|
|||
return commitScriptTree.TaprootKey, nil
|
||||
}
|
||||
|
||||
// MakeTaprootSCtrlBlock takes a leaf script, the internal key (usually the
|
||||
// revoke key), and a script tree and creates a valid control block for a spend
|
||||
// of the leaf.
|
||||
func MakeTaprootCtrlBlock(leafScript []byte, internalKey *btcec.PublicKey,
|
||||
scriptTree *txscript.IndexedTapScriptTree) txscript.ControlBlock {
|
||||
|
||||
tapLeafHash := txscript.NewBaseTapLeaf(leafScript).TapHash()
|
||||
scriptIdx := scriptTree.LeafProofIndex[tapLeafHash]
|
||||
settleMerkleProof := scriptTree.LeafMerkleProofs[scriptIdx]
|
||||
|
||||
return settleMerkleProof.ToControlBlock(internalKey)
|
||||
}
|
||||
|
||||
// TaprootCommitSpendSuccess constructs a valid witness allowing a node to
|
||||
// sweep the settled taproot output after the delay has passed for a force
|
||||
// close.
|
||||
|
@ -1955,14 +1991,24 @@ func TaprootCommitSpendSuccess(signer Signer, signDesc *SignDescriptor,
|
|||
|
||||
// First, we'll need to construct a valid control block to execute the
|
||||
// leaf script for sweep settlement.
|
||||
settleTapleafHash := txscript.NewBaseTapLeaf(
|
||||
signDesc.WitnessScript,
|
||||
).TapHash()
|
||||
settleIdx := scriptTree.LeafProofIndex[settleTapleafHash]
|
||||
settleMerkleProof := scriptTree.LeafMerkleProofs[settleIdx]
|
||||
settleControlBlock := settleMerkleProof.ToControlBlock(
|
||||
&TaprootNUMSKey,
|
||||
)
|
||||
//
|
||||
// TODO(roasbeef); make into closure instead? only need reovke key and
|
||||
// scriptTree to make the ctrl block -- then default version that would
|
||||
// take froms ign desc?
|
||||
var ctrlBlockBytes []byte
|
||||
if signDesc.ControlBlock == nil {
|
||||
settleControlBlock := MakeTaprootCtrlBlock(
|
||||
signDesc.WitnessScript, &TaprootNUMSKey, scriptTree,
|
||||
)
|
||||
ctrlBytes, err := settleControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctrlBlockBytes = ctrlBytes
|
||||
} else {
|
||||
ctrlBlockBytes = signDesc.ControlBlock
|
||||
}
|
||||
|
||||
// With the control block created, we'll now generate the signature we
|
||||
// need to authorize the spend.
|
||||
|
@ -1977,7 +2023,7 @@ func TaprootCommitSpendSuccess(signer Signer, signDesc *SignDescriptor,
|
|||
witnessStack := make(wire.TxWitness, 3)
|
||||
witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
|
||||
witnessStack[1] = signDesc.WitnessScript
|
||||
witnessStack[2], err = settleControlBlock.ToBytes()
|
||||
witnessStack[2] = ctrlBlockBytes
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1993,14 +2039,20 @@ func TaprootCommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
|
|||
|
||||
// First, we'll need to construct a valid control block to execute the
|
||||
// leaf script for revocation path.
|
||||
revokeTapleafHash := txscript.NewBaseTapLeaf(
|
||||
signDesc.WitnessScript,
|
||||
).TapHash()
|
||||
revokeIdx := scriptTree.LeafProofIndex[revokeTapleafHash]
|
||||
revokeMerkleProof := scriptTree.LeafMerkleProofs[revokeIdx]
|
||||
revokeControlBlock := revokeMerkleProof.ToControlBlock(
|
||||
&TaprootNUMSKey,
|
||||
)
|
||||
var ctrlBlockBytes []byte
|
||||
if signDesc.ControlBlock == nil {
|
||||
revokeCtrlBlock := MakeTaprootCtrlBlock(
|
||||
signDesc.WitnessScript, &TaprootNUMSKey, scriptTree,
|
||||
)
|
||||
revokeBytes, err := revokeCtrlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctrlBlockBytes = revokeBytes
|
||||
} else {
|
||||
ctrlBlockBytes = signDesc.ControlBlock
|
||||
}
|
||||
|
||||
// With the control block created, we'll now generate the signature we
|
||||
// need to authorize the spend.
|
||||
|
@ -2015,10 +2067,7 @@ func TaprootCommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
|
|||
witnessStack := make(wire.TxWitness, 3)
|
||||
witnessStack[0] = maybeAppendSighash(revokeSig, signDesc.HashType)
|
||||
witnessStack[1] = signDesc.WitnessScript
|
||||
witnessStack[2], err = revokeControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
witnessStack[2] = ctrlBlockBytes
|
||||
|
||||
return witnessStack, nil
|
||||
}
|
||||
|
@ -2307,12 +2356,20 @@ func TaprootCommitRemoteSpend(signer Signer, signDesc *SignDescriptor,
|
|||
|
||||
// First, we'll need to construct a valid control block to execute the
|
||||
// leaf script for sweep settlement.
|
||||
settleTapleafHash := txscript.NewBaseTapLeaf(
|
||||
signDesc.WitnessScript,
|
||||
).TapHash()
|
||||
settleIdx := scriptTree.LeafProofIndex[settleTapleafHash]
|
||||
settleMerkleProof := scriptTree.LeafMerkleProofs[settleIdx]
|
||||
settleControlBlock := settleMerkleProof.ToControlBlock(&TaprootNUMSKey)
|
||||
var ctrlBlockBytes []byte
|
||||
if signDesc.ControlBlock == nil {
|
||||
settleControlBlock := MakeTaprootCtrlBlock(
|
||||
signDesc.WitnessScript, &TaprootNUMSKey, scriptTree,
|
||||
)
|
||||
ctrlBytes, err := settleControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctrlBlockBytes = ctrlBytes
|
||||
} else {
|
||||
ctrlBlockBytes = signDesc.ControlBlock
|
||||
}
|
||||
|
||||
// With the control block created, we'll now generate the signature we
|
||||
// need to authorize the spend.
|
||||
|
@ -2327,10 +2384,7 @@ func TaprootCommitRemoteSpend(signer Signer, signDesc *SignDescriptor,
|
|||
witnessStack := make(wire.TxWitness, 3)
|
||||
witnessStack[0] = maybeAppendSighash(sweepSig, signDesc.HashType)
|
||||
witnessStack[1] = signDesc.WitnessScript
|
||||
witnessStack[2], err = settleControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
witnessStack[2] = ctrlBlockBytes
|
||||
|
||||
return witnessStack, nil
|
||||
}
|
||||
|
@ -2507,11 +2561,11 @@ func TaprootOutputKeyAnchor(key *btcec.PublicKey) (*btcec.PublicKey, error) {
|
|||
// TaprootAnchorSpend constructs a valid witness allowing a node to sweep their
|
||||
// anchor output.
|
||||
func TaprootAnchorSpend(signer Signer, signDesc *SignDescriptor,
|
||||
revokeTx *wire.MsgTx) (wire.TxWitness, error) {
|
||||
sweepTx *wire.MsgTx) (wire.TxWitness, error) {
|
||||
|
||||
// For this spend type, we only need a single signature which'll be a
|
||||
// keyspend using the revoke private key.
|
||||
sweepSig, err := signer.SignOutputRaw(revokeTx, signDesc)
|
||||
// keyspend using the anchor private key.
|
||||
sweepSig, err := signer.SignOutputRaw(sweepTx, signDesc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -98,6 +98,13 @@ type SignDescriptor struct {
|
|||
// This MUST be set when spending Taproot outputs.
|
||||
PrevOutputFetcher txscript.PrevOutputFetcher
|
||||
|
||||
// ControlBlock is a fully serialized control block that contains the
|
||||
// merkle proof necessary to spend a taproot output. This may
|
||||
// optionally be set if the SignMethod is
|
||||
// input.TaprootScriptSpendSignMethod. In which case, this should be an
|
||||
// inclusion proof for the WitnessScript.
|
||||
ControlBlock []byte
|
||||
|
||||
// InputIndex is the target input within the transaction that should be
|
||||
// signed.
|
||||
InputIndex int
|
||||
|
@ -218,6 +225,8 @@ func WriteSignDescriptor(w io.Writer, sd *SignDescriptor) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// TODO(roasbeef): also write ctrl block?
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -998,7 +998,7 @@ var witnessSizeTests = []witnessSizeTest{
|
|||
}
|
||||
|
||||
witness, err := input.TaprootHtlcSpendSuccess(
|
||||
signer, signDesc, revokeKey.PubKey(), testTx,
|
||||
signer, signDesc, testTx, revokeKey.PubKey(),
|
||||
scriptTree,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -1675,8 +1675,8 @@ func secondLevelHtlcSuccessWitGen(sigHash txscript.SigHashType,
|
|||
}
|
||||
|
||||
return TaprootHtlcSpendSuccess(
|
||||
signer, signDesc, scriptTree.revokeKey.PubKey(),
|
||||
spendTx, scriptTree.scriptTree,
|
||||
signer, signDesc, spendTx,
|
||||
scriptTree.revokeKey.PubKey(), scriptTree.scriptTree,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -515,6 +515,205 @@ func (wt StandardWitnessType) WitnessGenerator(signer Signer,
|
|||
case NestedWitnessKeyHash:
|
||||
return signer.ComputeInputScript(tx, desc)
|
||||
|
||||
case TaprootLocalCommitSpend:
|
||||
// Ensure that the sign desc has the proper sign method
|
||||
// set, and a valid prev output fetcher.
|
||||
desc.SignMethod = TaprootScriptSpendSignMethod
|
||||
|
||||
// The control block bytes must be set at this point.
|
||||
if desc.ControlBlock == nil {
|
||||
return nil, fmt.Errorf("control block must be " +
|
||||
"set for taproot spend")
|
||||
}
|
||||
|
||||
witness, err := TaprootCommitSpendSuccess(
|
||||
signer, desc, tx, nil,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{
|
||||
Witness: witness,
|
||||
}, nil
|
||||
|
||||
case TaprootRemoteCommitSpend:
|
||||
// Ensure that the sign desc has the proper sign method
|
||||
// set, and a valid prev output fetcher.
|
||||
desc.SignMethod = TaprootScriptSpendSignMethod
|
||||
|
||||
// The control block bytes must be set at this point.
|
||||
if desc.ControlBlock == nil {
|
||||
return nil, fmt.Errorf("control block must be " +
|
||||
"set for taproot spend")
|
||||
}
|
||||
|
||||
witness, err := TaprootCommitRemoteSpend(
|
||||
signer, desc, tx, nil,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{
|
||||
Witness: witness,
|
||||
}, nil
|
||||
|
||||
case TaprootAnchorSweepSpend:
|
||||
// Ensure that the sign desc has the proper sign method
|
||||
// set, and a valid prev output fetcher.
|
||||
desc.SignMethod = TaprootKeySpendSignMethod
|
||||
|
||||
// The tap tweak must be set at this point.
|
||||
if desc.TapTweak == nil {
|
||||
return nil, fmt.Errorf("tap tweak must be " +
|
||||
"set for keyspend")
|
||||
}
|
||||
|
||||
witness, err := TaprootAnchorSpend(
|
||||
signer, desc, tx,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{
|
||||
Witness: witness,
|
||||
}, nil
|
||||
|
||||
case TaprootHtlcOfferedTimeoutSecondLevel,
|
||||
TaprootHtlcAcceptedSuccessSecondLevel:
|
||||
// Ensure that the sign desc has the proper sign method
|
||||
// set, and a valid prev output fetcher.
|
||||
desc.SignMethod = TaprootScriptSpendSignMethod
|
||||
|
||||
// The control block bytes must be set at this point.
|
||||
if desc.ControlBlock == nil {
|
||||
return nil, fmt.Errorf("control block must be " +
|
||||
"set for taproot spend")
|
||||
}
|
||||
|
||||
witness, err := TaprootHtlcSpendSuccess(
|
||||
signer, desc, tx, nil, nil,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{
|
||||
Witness: witness,
|
||||
}, nil
|
||||
|
||||
case TaprootHtlcSecondLevelRevoke:
|
||||
// Ensure that the sign desc has the proper sign method
|
||||
// set, and a valid prev output fetcher.
|
||||
desc.SignMethod = TaprootKeySpendSignMethod
|
||||
|
||||
// The tap tweak must be set at this point.
|
||||
if desc.TapTweak == nil {
|
||||
return nil, fmt.Errorf("tap tweak must be " +
|
||||
"set for keyspend")
|
||||
}
|
||||
|
||||
witness, err := TaprootHtlcSpendRevoke(
|
||||
signer, desc, tx,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{
|
||||
Witness: witness,
|
||||
}, nil
|
||||
|
||||
case TaprootHtlcOfferedRevoke:
|
||||
// Ensure that the sign desc has the proper sign method
|
||||
// set, and a valid prev output fetcher.
|
||||
desc.SignMethod = TaprootKeySpendSignMethod
|
||||
|
||||
// The tap tweak must be set at this point.
|
||||
if desc.TapTweak == nil {
|
||||
return nil, fmt.Errorf("tap tweak must be " +
|
||||
"set for keyspend")
|
||||
}
|
||||
|
||||
witness, err := SenderHTLCScriptTaprootRevoke(
|
||||
signer, desc, tx,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{
|
||||
Witness: witness,
|
||||
}, nil
|
||||
|
||||
case TaprootHtlcAcceptedRevoke:
|
||||
// Ensure that the sign desc has the proper sign method
|
||||
// set, and a valid prev output fetcher.
|
||||
desc.SignMethod = TaprootKeySpendSignMethod
|
||||
|
||||
// The tap tweak must be set at this point.
|
||||
if desc.TapTweak == nil {
|
||||
return nil, fmt.Errorf("tap tweak must be " +
|
||||
"set for keyspend")
|
||||
}
|
||||
|
||||
witness, err := ReceiverHTLCScriptTaprootRevoke(
|
||||
signer, desc, tx,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{
|
||||
Witness: witness,
|
||||
}, nil
|
||||
|
||||
case TaprootHtlcOfferedRemoteTimeout:
|
||||
// Ensure that the sign desc has the proper sign method
|
||||
// set, and a valid prev output fetcher.
|
||||
desc.SignMethod = TaprootScriptSpendSignMethod
|
||||
|
||||
// The control block bytes must be set at this point.
|
||||
if desc.ControlBlock == nil {
|
||||
return nil, fmt.Errorf("control block must be " +
|
||||
"set for taproot spend")
|
||||
}
|
||||
|
||||
witness, err := ReceiverHTLCScriptTaprootTimeout(
|
||||
signer, desc, tx, -1, nil, nil,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{
|
||||
Witness: witness,
|
||||
}, nil
|
||||
|
||||
case TaprootCommitmentRevoke:
|
||||
// Ensure that the sign desc has the proper sign method
|
||||
// set, and a valid prev output fetcher.
|
||||
desc.SignMethod = TaprootScriptSpendSignMethod
|
||||
|
||||
// The control block bytes must be set at this point.
|
||||
if desc.ControlBlock == nil {
|
||||
return nil, fmt.Errorf("control block " +
|
||||
"must be set for taproot spend")
|
||||
}
|
||||
|
||||
witness, err := TaprootCommitSpendRevoke(
|
||||
signer, desc, tx, nil,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Script{
|
||||
Witness: witness,
|
||||
}, nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown witness type: %v", wt)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue