mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-08 05:08:13 +02:00
watchtower/lookout: make justice desciptor taproot ready
This commit is contained in:
@@ -176,6 +176,8 @@ func (p *JusticeDescriptor) assembleJusticeTxn(txWeight int64,
|
|||||||
return nil, fmt.Errorf("error creating previous output "+
|
return nil, fmt.Errorf("error creating previous output "+
|
||||||
"fetcher: %v", err)
|
"fetcher: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hashes := txscript.NewTxSigHashes(justiceTxn, prevOutFetcher)
|
||||||
for _, inp := range inputs {
|
for _, inp := range inputs {
|
||||||
// Lookup the input's new post-sort position.
|
// Lookup the input's new post-sort position.
|
||||||
i := inputIndex[inp.outPoint]
|
i := inputIndex[inp.outPoint]
|
||||||
@@ -186,7 +188,7 @@ func (p *JusticeDescriptor) assembleJusticeTxn(txWeight int64,
|
|||||||
vm, err := txscript.NewEngine(
|
vm, err := txscript.NewEngine(
|
||||||
inp.txOut.PkScript, justiceTxn, i,
|
inp.txOut.PkScript, justiceTxn, i,
|
||||||
txscript.StandardVerifyFlags,
|
txscript.StandardVerifyFlags,
|
||||||
nil, nil, inp.txOut.Value, prevOutFetcher,
|
nil, hashes, inp.txOut.Value, prevOutFetcher,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/btcsuite/btcd/btcutil/txsort"
|
"github.com/btcsuite/btcd/btcutil/txsort"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"github.com/lightningnetwork/lnd/keychain"
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
@@ -53,6 +54,8 @@ var (
|
|||||||
altruistCommitType = blob.FlagCommitOutputs.Type()
|
altruistCommitType = blob.FlagCommitOutputs.Type()
|
||||||
|
|
||||||
altruistAnchorCommitType = blob.TypeAltruistAnchorCommit
|
altruistAnchorCommitType = blob.TypeAltruistAnchorCommit
|
||||||
|
|
||||||
|
altruisticTaprootCommitType = blob.TypeAltruistTaprootCommit
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestJusticeDescriptor asserts that a JusticeDescriptor is able to produce the
|
// TestJusticeDescriptor asserts that a JusticeDescriptor is able to produce the
|
||||||
@@ -74,6 +77,10 @@ func TestJusticeDescriptor(t *testing.T) {
|
|||||||
name: "altruist anchor commit type",
|
name: "altruist anchor commit type",
|
||||||
blobType: altruistAnchorCommitType,
|
blobType: altruistAnchorCommitType,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "altruist taproot commit type",
|
||||||
|
blobType: altruisticTaprootCommitType,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
@@ -85,6 +92,7 @@ func TestJusticeDescriptor(t *testing.T) {
|
|||||||
|
|
||||||
func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
|
func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
|
||||||
isAnchorChannel := blobType.IsAnchorChannel()
|
isAnchorChannel := blobType.IsAnchorChannel()
|
||||||
|
isTaprootChannel := blobType.IsTaprootChannel()
|
||||||
|
|
||||||
const (
|
const (
|
||||||
localAmount = btcutil.Amount(100000)
|
localAmount = btcutil.Amount(100000)
|
||||||
@@ -108,15 +116,34 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
|
|||||||
toRemoteKeyLoc = signer.AddPrivKey(toRemoteSK)
|
toRemoteKeyLoc = signer.AddPrivKey(toRemoteSK)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Construct the to-local witness script.
|
var (
|
||||||
toLocalScript, err := input.CommitScriptToSelf(
|
toLocalScript, toLocalScriptHash []byte
|
||||||
csvDelay, toLocalPK, revPK,
|
toLocalCommitTree *input.CommitScriptTree
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Compute the to-local witness script hash.
|
if isTaprootChannel {
|
||||||
toLocalScriptHash, err := input.WitnessScriptHash(toLocalScript)
|
toLocalCommitTree, err = input.NewLocalCommitScriptTree(
|
||||||
require.NoError(t, err)
|
csvDelay, toLocalPK, revPK,
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
toLocalScript = toLocalCommitTree.RevocationLeaf.Script
|
||||||
|
|
||||||
|
toLocalScriptHash, err = input.PayToTaprootScript(
|
||||||
|
toLocalCommitTree.TaprootKey,
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
} else {
|
||||||
|
// Construct the to-local witness script.
|
||||||
|
toLocalScript, err = input.CommitScriptToSelf(
|
||||||
|
csvDelay, toLocalPK, revPK,
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Compute the to-local witness script hash.
|
||||||
|
toLocalScriptHash, err = input.WitnessScriptHash(toLocalScript)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
// Compute the to-remote redeem script, witness script hash, and
|
// Compute the to-remote redeem script, witness script hash, and
|
||||||
// sequence numbers.
|
// sequence numbers.
|
||||||
@@ -140,8 +167,37 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
|
|||||||
toRemoteRedeemScript []byte
|
toRemoteRedeemScript []byte
|
||||||
toRemoteScriptHash []byte
|
toRemoteScriptHash []byte
|
||||||
toRemoteSigningScript []byte
|
toRemoteSigningScript []byte
|
||||||
|
toRemoteCtrlBlock []byte
|
||||||
)
|
)
|
||||||
if isAnchorChannel {
|
switch {
|
||||||
|
case isTaprootChannel:
|
||||||
|
toRemoteSequence = 1
|
||||||
|
|
||||||
|
commitScriptTree, err := input.NewRemoteCommitScriptTree(
|
||||||
|
toRemotePK,
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
toRemoteSigningScript = commitScriptTree.SettleLeaf.Script
|
||||||
|
|
||||||
|
toRemoteScriptHash, err = input.PayToTaprootScript(
|
||||||
|
commitScriptTree.TaprootKey,
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
tree := commitScriptTree.TapscriptTree
|
||||||
|
settleTapleafHash := commitScriptTree.SettleLeaf.TapHash()
|
||||||
|
settleIdx := tree.LeafProofIndex[settleTapleafHash]
|
||||||
|
settleMerkleProof := tree.LeafMerkleProofs[settleIdx]
|
||||||
|
settleControlBlock := settleMerkleProof.ToControlBlock(
|
||||||
|
&input.TaprootNUMSKey,
|
||||||
|
)
|
||||||
|
|
||||||
|
ctrlBytes, err := settleControlBlock.ToBytes()
|
||||||
|
require.NoError(t, err)
|
||||||
|
toRemoteCtrlBlock = ctrlBytes
|
||||||
|
|
||||||
|
case isAnchorChannel:
|
||||||
toRemoteSequence = 1
|
toRemoteSequence = 1
|
||||||
toRemoteRedeemScript, err = input.CommitScriptToRemoteConfirmed(
|
toRemoteRedeemScript, err = input.CommitScriptToRemoteConfirmed(
|
||||||
toRemotePK,
|
toRemotePK,
|
||||||
@@ -155,7 +211,8 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
|
|||||||
|
|
||||||
// As it should be.
|
// As it should be.
|
||||||
toRemoteSigningScript = toRemoteRedeemScript
|
toRemoteSigningScript = toRemoteRedeemScript
|
||||||
} else {
|
|
||||||
|
default:
|
||||||
toRemoteRedeemScript = toRemotePK.SerializeCompressed()
|
toRemoteRedeemScript = toRemotePK.SerializeCompressed()
|
||||||
toRemoteScriptHash, err = input.CommitScriptUnencumbered(
|
toRemoteScriptHash, err = input.CommitScriptUnencumbered(
|
||||||
toRemotePK,
|
toRemotePK,
|
||||||
@@ -269,31 +326,82 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
|
|||||||
justiceTxn.TxOut = outputs
|
justiceTxn.TxOut = outputs
|
||||||
txsort.InPlaceSort(justiceTxn)
|
txsort.InPlaceSort(justiceTxn)
|
||||||
|
|
||||||
hashCache := input.NewTxSigHashesV0Only(justiceTxn)
|
var (
|
||||||
|
toLocalSignDesc *input.SignDescriptor
|
||||||
|
toRemoteSignDesc *input.SignDescriptor
|
||||||
|
)
|
||||||
|
|
||||||
// Create the sign descriptor used to sign for the to-local input.
|
if isTaprootChannel {
|
||||||
toLocalSignDesc := &input.SignDescriptor{
|
prevOuts := map[wire.OutPoint]*wire.TxOut{
|
||||||
KeyDesc: keychain.KeyDescriptor{
|
{
|
||||||
KeyLocator: revKeyLoc,
|
Hash: breachTxID,
|
||||||
},
|
Index: 0,
|
||||||
WitnessScript: toLocalScript,
|
}: breachTxn.TxOut[0],
|
||||||
Output: breachTxn.TxOut[0],
|
{
|
||||||
SigHashes: hashCache,
|
Hash: breachTxID,
|
||||||
InputIndex: 0,
|
Index: 1,
|
||||||
HashType: txscript.SigHashAll,
|
}: breachTxn.TxOut[1],
|
||||||
}
|
}
|
||||||
|
prevOutputFetcher := txscript.NewMultiPrevOutFetcher(prevOuts)
|
||||||
|
hashCache := txscript.NewTxSigHashes(
|
||||||
|
justiceTxn, prevOutputFetcher,
|
||||||
|
)
|
||||||
|
|
||||||
// Create the sign descriptor used to sign for the to-remote input.
|
toLocalSignDesc = &input.SignDescriptor{
|
||||||
toRemoteSignDesc := &input.SignDescriptor{
|
KeyDesc: keychain.KeyDescriptor{
|
||||||
KeyDesc: keychain.KeyDescriptor{
|
KeyLocator: revKeyLoc,
|
||||||
KeyLocator: toRemoteKeyLoc,
|
},
|
||||||
PubKey: toRemotePK,
|
WitnessScript: toLocalScript,
|
||||||
},
|
Output: breachTxn.TxOut[0],
|
||||||
WitnessScript: toRemoteSigningScript,
|
SigHashes: hashCache,
|
||||||
Output: breachTxn.TxOut[1],
|
PrevOutputFetcher: prevOutputFetcher,
|
||||||
SigHashes: hashCache,
|
InputIndex: 0,
|
||||||
InputIndex: 1,
|
HashType: txscript.SigHashDefault,
|
||||||
HashType: txscript.SigHashAll,
|
SignMethod: input.TaprootScriptSpendSignMethod,
|
||||||
|
}
|
||||||
|
|
||||||
|
toRemoteSignDesc = &input.SignDescriptor{
|
||||||
|
KeyDesc: keychain.KeyDescriptor{
|
||||||
|
KeyLocator: toRemoteKeyLoc,
|
||||||
|
PubKey: toRemotePK,
|
||||||
|
},
|
||||||
|
WitnessScript: toRemoteSigningScript,
|
||||||
|
Output: breachTxn.TxOut[1],
|
||||||
|
PrevOutputFetcher: prevOutputFetcher,
|
||||||
|
SigHashes: hashCache,
|
||||||
|
InputIndex: 1,
|
||||||
|
HashType: txscript.SigHashDefault,
|
||||||
|
SignMethod: input.TaprootScriptSpendSignMethod,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hashCache := input.NewTxSigHashesV0Only(justiceTxn)
|
||||||
|
|
||||||
|
// Create the sign descriptor used to sign for the to-local
|
||||||
|
// input.
|
||||||
|
toLocalSignDesc = &input.SignDescriptor{
|
||||||
|
KeyDesc: keychain.KeyDescriptor{
|
||||||
|
KeyLocator: revKeyLoc,
|
||||||
|
},
|
||||||
|
WitnessScript: toLocalScript,
|
||||||
|
Output: breachTxn.TxOut[0],
|
||||||
|
SigHashes: hashCache,
|
||||||
|
InputIndex: 0,
|
||||||
|
HashType: txscript.SigHashAll,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the sign descriptor used to sign for the to-remote
|
||||||
|
// input.
|
||||||
|
toRemoteSignDesc = &input.SignDescriptor{
|
||||||
|
KeyDesc: keychain.KeyDescriptor{
|
||||||
|
KeyLocator: toRemoteKeyLoc,
|
||||||
|
PubKey: toRemotePK,
|
||||||
|
},
|
||||||
|
WitnessScript: toRemoteSigningScript,
|
||||||
|
Output: breachTxn.TxOut[1],
|
||||||
|
SigHashes: hashCache,
|
||||||
|
InputIndex: 1,
|
||||||
|
HashType: txscript.SigHashAll,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that our test justice transaction is sane.
|
// Verify that our test justice transaction is sane.
|
||||||
@@ -301,21 +409,19 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
|
|||||||
err = blockchain.CheckTransactionSanity(btx)
|
err = blockchain.CheckTransactionSanity(btx)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
// Compute a DER-encoded signature for the to-local input.
|
// Compute a signature for the to-local input.
|
||||||
toLocalSigRaw, err := signer.SignOutputRaw(justiceTxn, toLocalSignDesc)
|
toLocalSigRaw, err := signer.SignOutputRaw(justiceTxn, toLocalSignDesc)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
// Compute the witness for the to-remote input. The first element is a
|
// Compute the witness for the to-remote input.
|
||||||
// DER-encoded signature under the to-remote pubkey. The sighash flag is
|
|
||||||
// also present, so we trim it.
|
|
||||||
toRemoteSigRaw, err := signer.SignOutputRaw(justiceTxn, toRemoteSignDesc)
|
toRemoteSigRaw, err := signer.SignOutputRaw(justiceTxn, toRemoteSignDesc)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
// Convert the DER to-local sig into a fixed-size signature.
|
// Convert the to-local sig into a fixed-size signature.
|
||||||
toLocalSig, err := lnwire.NewSigFromSignature(toLocalSigRaw)
|
toLocalSig, err := lnwire.NewSigFromSignature(toLocalSigRaw)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
// Convert the DER to-remote sig into a fixed-size signature.
|
// Convert the to-remote sig into a fixed-size signature.
|
||||||
toRemoteSig, err := lnwire.NewSigFromSignature(toRemoteSigRaw)
|
toRemoteSig, err := lnwire.NewSigFromSignature(toRemoteSigRaw)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
@@ -342,7 +448,7 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
|
|||||||
// Exact retribution on the offender. If no error is returned, we expect
|
// Exact retribution on the offender. If no error is returned, we expect
|
||||||
// the justice transaction to be published via the channel.
|
// the justice transaction to be published via the channel.
|
||||||
err = punisher.Punish(justiceDesc, nil)
|
err = punisher.Punish(justiceDesc, nil)
|
||||||
require.Nil(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Retrieve the published justice transaction.
|
// Retrieve the published justice transaction.
|
||||||
var wtJusticeTxn *wire.MsgTx
|
var wtJusticeTxn *wire.MsgTx
|
||||||
@@ -352,18 +458,59 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
|
|||||||
t.Fatalf("punisher did not publish justice txn")
|
t.Fatalf("punisher did not publish justice txn")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct the test's to-local witness.
|
if isTaprootChannel {
|
||||||
justiceTxn.TxIn[0].Witness = make([][]byte, 3)
|
revokeLeaf := txscript.NewBaseTapLeaf(toLocalScript)
|
||||||
justiceTxn.TxIn[0].Witness[0] = append(toLocalSigRaw.Serialize(),
|
outputKey := txscript.ComputeTaprootOutputKey(
|
||||||
byte(txscript.SigHashAll))
|
&input.TaprootNUMSKey, toLocalCommitTree.TapscriptRoot,
|
||||||
justiceTxn.TxIn[0].Witness[1] = []byte{1}
|
)
|
||||||
justiceTxn.TxIn[0].Witness[2] = toLocalScript
|
|
||||||
|
|
||||||
// Construct the test's to-remote witness.
|
var outputKeyYIsOdd bool
|
||||||
justiceTxn.TxIn[1].Witness = make([][]byte, 2)
|
if outputKey.SerializeCompressed()[0] ==
|
||||||
justiceTxn.TxIn[1].Witness[0] = append(toRemoteSigRaw.Serialize(),
|
secp.PubKeyFormatCompressedOdd {
|
||||||
byte(txscript.SigHashAll))
|
|
||||||
justiceTxn.TxIn[1].Witness[1] = toRemoteRedeemScript
|
outputKeyYIsOdd = true
|
||||||
|
}
|
||||||
|
|
||||||
|
delayScriptHash := toLocalCommitTree.SettleLeaf.TapHash()
|
||||||
|
|
||||||
|
ctrlBlock := txscript.ControlBlock{
|
||||||
|
InternalKey: &input.TaprootNUMSKey,
|
||||||
|
OutputKeyYIsOdd: outputKeyYIsOdd,
|
||||||
|
LeafVersion: revokeLeaf.LeafVersion,
|
||||||
|
InclusionProof: delayScriptHash[:],
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrlBytes, err := ctrlBlock.ToBytes()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
justiceTxn.TxIn[0].Witness = make([][]byte, 3)
|
||||||
|
justiceTxn.TxIn[0].Witness[0] = toLocalSigRaw.Serialize()
|
||||||
|
justiceTxn.TxIn[0].Witness[1] = toLocalScript
|
||||||
|
justiceTxn.TxIn[0].Witness[2] = ctrlBytes
|
||||||
|
|
||||||
|
// Construct the test's to-remote witness.
|
||||||
|
justiceTxn.TxIn[1].Witness = make([][]byte, 3)
|
||||||
|
justiceTxn.TxIn[1].Witness[0] = toRemoteSigRaw.Serialize()
|
||||||
|
justiceTxn.TxIn[1].Witness[1] = toRemoteSigningScript
|
||||||
|
justiceTxn.TxIn[1].Witness[2] = toRemoteCtrlBlock
|
||||||
|
} else {
|
||||||
|
// Construct the test's to-local witness.
|
||||||
|
justiceTxn.TxIn[0].Witness = make([][]byte, 3)
|
||||||
|
justiceTxn.TxIn[0].Witness[0] = append(
|
||||||
|
toLocalSigRaw.Serialize(),
|
||||||
|
byte(txscript.SigHashAll),
|
||||||
|
)
|
||||||
|
justiceTxn.TxIn[0].Witness[1] = []byte{1}
|
||||||
|
justiceTxn.TxIn[0].Witness[2] = toLocalScript
|
||||||
|
|
||||||
|
// Construct the test's to-remote witness.
|
||||||
|
justiceTxn.TxIn[1].Witness = make([][]byte, 2)
|
||||||
|
justiceTxn.TxIn[1].Witness[0] = append(
|
||||||
|
toRemoteSigRaw.Serialize(),
|
||||||
|
byte(txscript.SigHashAll),
|
||||||
|
)
|
||||||
|
justiceTxn.TxIn[1].Witness[1] = toRemoteRedeemScript
|
||||||
|
}
|
||||||
|
|
||||||
// Assert that the watchtower derives the same justice txn.
|
// Assert that the watchtower derives the same justice txn.
|
||||||
require.Equal(t, justiceTxn, wtJusticeTxn)
|
require.Equal(t, justiceTxn, wtJusticeTxn)
|
||||||
|
@@ -2,6 +2,7 @@ package wtmock
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec/v2"
|
"github.com/btcsuite/btcd/btcec/v2"
|
||||||
@@ -47,6 +48,69 @@ func (s *MockSigner) SignOutputRaw(tx *wire.MsgTx,
|
|||||||
panic("cannot sign w/ unknown key")
|
panic("cannot sign w/ unknown key")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In case of a taproot output any signature is always a Schnorr
|
||||||
|
// signature, based on the new tapscript sighash algorithm.
|
||||||
|
if txscript.IsPayToTaproot(signDesc.Output.PkScript) {
|
||||||
|
sigHashes := txscript.NewTxSigHashes(
|
||||||
|
tx, signDesc.PrevOutputFetcher,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Are we spending a script path or the key path? The API is
|
||||||
|
// slightly different, so we need to account for that to get the
|
||||||
|
// raw signature.
|
||||||
|
var (
|
||||||
|
rawSig []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
switch signDesc.SignMethod {
|
||||||
|
case input.TaprootKeySpendBIP0086SignMethod,
|
||||||
|
input.TaprootKeySpendSignMethod:
|
||||||
|
|
||||||
|
// This function tweaks the private key using the tap
|
||||||
|
// root key supplied as the tweak.
|
||||||
|
rawSig, err = txscript.RawTxInTaprootSignature(
|
||||||
|
tx, sigHashes, signDesc.InputIndex,
|
||||||
|
signDesc.Output.Value, signDesc.Output.PkScript,
|
||||||
|
signDesc.TapTweak, signDesc.HashType,
|
||||||
|
privKey,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
case input.TaprootScriptSpendSignMethod:
|
||||||
|
leaf := txscript.TapLeaf{
|
||||||
|
LeafVersion: txscript.BaseLeafVersion,
|
||||||
|
Script: witnessScript,
|
||||||
|
}
|
||||||
|
rawSig, err = txscript.RawTxInTapscriptSignature(
|
||||||
|
tx, sigHashes, signDesc.InputIndex,
|
||||||
|
signDesc.Output.Value, signDesc.Output.PkScript,
|
||||||
|
leaf, signDesc.HashType, privKey,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown sign method: %v",
|
||||||
|
signDesc.SignMethod)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The signature returned above might have a sighash flag
|
||||||
|
// attached if a non-default type was used. We'll slice this
|
||||||
|
// off if it exists to ensure we can properly parse the raw
|
||||||
|
// signature.
|
||||||
|
sig, err := schnorr.ParseSignature(
|
||||||
|
rawSig[:schnorr.SignatureSize],
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sig, nil
|
||||||
|
}
|
||||||
|
|
||||||
sig, err := txscript.RawTxInWitnessSignature(
|
sig, err := txscript.RawTxInWitnessSignature(
|
||||||
tx, signDesc.SigHashes, signDesc.InputIndex, amt,
|
tx, signDesc.SigHashes, signDesc.InputIndex, amt,
|
||||||
witnessScript, signDesc.HashType, privKey,
|
witnessScript, signDesc.HashType, privKey,
|
||||||
|
Reference in New Issue
Block a user