mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-22 14:33:06 +01:00
Fix bug in taproot SIGHASH_ANYONECANPAY_SINGLE impl (#4440)
This commit is contained in:
parent
38d8f8cdf0
commit
3122e1d0f8
2 changed files with 49 additions and 6 deletions
|
@ -499,11 +499,6 @@ class TransactionSignatureSerializerTest extends BitcoinSUnitTest {
|
|||
signInfo.hashType,
|
||||
taprootOptions = TaprootSerializationOptions.empty)
|
||||
|
||||
if (oldHash != newHash) {
|
||||
println(oldHash.hex)
|
||||
println(newHash.hex)
|
||||
}
|
||||
|
||||
oldHash == newHash
|
||||
}
|
||||
}
|
||||
|
@ -939,4 +934,50 @@ class TransactionSignatureSerializerTest extends BitcoinSUnitTest {
|
|||
|
||||
assert(serialize.toHex == expected)
|
||||
}
|
||||
|
||||
it must "serialize a taprooot keypsend SIGHASH_SINGLE_ANYONECANPAY with annex correctly" in {
|
||||
val expected =
|
||||
"0083a3c824f5613e694f01ec975c5d145e8cccde50ab0ca8c5b41bfaedd041ea97b05285fff9df00dca26749010000bd2897010000000022512088ffcb569bf1dc1a9e0b22b8cb164c31bcf65e6e95fa113ddbdbbead6e85fedf4aa79981b0d1ad766994166c07455739e8a49adf25972a25046ede7f1573ec61b75beb3f7e93c573a659c28b99050bd63f8e7bd619af0175b784eadf33b52d95d3863c51"
|
||||
|
||||
val spendingTxHex =
|
||||
"a3c824f501ec975c5d145e8cccde50ab0ca8c5b41bfaedd041ea97b05285fff9df00dca26749010000004aa799810120931801000000001976a914a9afd3de61b334f2bf5db90a343f96ab28c4e8ed88ac613e694f"
|
||||
val spendingTx = Transaction.fromHex(spendingTxHex)
|
||||
val inputIndex = UInt32.zero
|
||||
val prevout = TransactionOutput.fromHex(
|
||||
"bd2897010000000022512088ffcb569bf1dc1a9e0b22b8cb164c31bcf65e6e95fa113ddbdbbead6e85fedf")
|
||||
val prevOutputs = Vector(prevout)
|
||||
val outputMap: Map[TransactionOutPoint, TransactionOutput] =
|
||||
spendingTx.inputs.map(_.previousOutput).zip(prevOutputs).toMap
|
||||
val witnessStackHex = Vector(
|
||||
"f14afc2bf9b4a9f8e4b5e8503e396de9ad12aacf7726fd53dc147978f52bf9435d658cb326f533b39c57af2c8406f5177120eda69e51f52e0fd076040c7d831d83",
|
||||
"50d8"
|
||||
)
|
||||
val witnessStack = witnessStackHex.map(w => ByteVector.fromValidHex(w))
|
||||
|
||||
val witness = TaprootKeyPath.fromStack(witnessStack.reverse)
|
||||
|
||||
val witnessTx =
|
||||
WitnessTransaction
|
||||
.toWitnessTx(spendingTx)
|
||||
.updateWitness(inputIndex.toInt, witness)
|
||||
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx, //spendingTx,
|
||||
inputIndex,
|
||||
outputMap,
|
||||
Policy.standardFlags)
|
||||
|
||||
val annexHashHex =
|
||||
"b0d1ad766994166c07455739e8a49adf25972a25046ede7f1573ec61b75beb3f"
|
||||
val annexHash = Sha256Digest.fromHex(annexHashHex)
|
||||
val taprootOptions =
|
||||
TaprootSerializationOptions(tapLeafHashOpt = None,
|
||||
annexHashOpt = Some(annexHash),
|
||||
codeSeparatorPosOpt = None)
|
||||
val serialize = TransactionSignatureSerializer.serializeForSignature(
|
||||
taprootTxSigComponent,
|
||||
HashType.sigHashSingleAnyoneCanPay,
|
||||
taprootOptions)
|
||||
|
||||
assert(serialize.toHex == expected)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -316,6 +316,7 @@ sealed abstract class TransactionSignatureSerializer {
|
|||
} else ByteVector.empty
|
||||
|
||||
val haveAnnex: Boolean = taprootOptions.haveAnnex
|
||||
|
||||
val annexByte = if (haveAnnex) 1.toByte else 0.toByte
|
||||
|
||||
val spendType: Byte = ((extFlag << 1) + annexByte).toByte
|
||||
|
@ -341,6 +342,7 @@ sealed abstract class TransactionSignatureSerializer {
|
|||
} else {
|
||||
ByteVector.empty
|
||||
}
|
||||
|
||||
val result = {
|
||||
if (isNotAnyoneCanPay) {
|
||||
if (!isNotSigHashSingle) {
|
||||
|
@ -365,7 +367,7 @@ sealed abstract class TransactionSignatureSerializer {
|
|||
hashType.byte) ++ version ++ locktimeBytes ++ ByteVector.fromByte(
|
||||
spendType) ++
|
||||
outPointHash ++ amounts ++ spentSPKs ++
|
||||
sequenceHash ++ outputHash ++ annexBytes ++ tapScriptBytes
|
||||
sequenceHash ++ annexBytes ++ outputHash ++ tapScriptBytes
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue