mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-03 18:47:38 +01:00
Add test case for SIGHASH_ALL_ANYONECANPAY
in taproot (#4442)
* Add test case for SIGHASH_ALL_ANYONECANPAY in taproot * Remove spendingTx comment
This commit is contained in:
parent
3122e1d0f8
commit
0c14fc961b
2 changed files with 67 additions and 16 deletions
|
@ -561,7 +561,7 @@ class TransactionSignatureSerializerTest extends BitcoinSUnitTest {
|
|||
|
||||
val outputMap: Map[TransactionOutPoint, TransactionOutput] =
|
||||
spendingTx.inputs.map(_.previousOutput).zip(Vector(prevOutput)).toMap
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx, //spendingTx,
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx,
|
||||
inputIndex,
|
||||
outputMap,
|
||||
Policy.standardFlags)
|
||||
|
@ -616,7 +616,7 @@ class TransactionSignatureSerializerTest extends BitcoinSUnitTest {
|
|||
val outputMap: Map[TransactionOutPoint, TransactionOutput] =
|
||||
spendingTx.inputs.map(_.previousOutput).zip(prevOutputs).toMap
|
||||
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx, //spendingTx,
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx,
|
||||
inputIndex,
|
||||
outputMap,
|
||||
Policy.standardFlags)
|
||||
|
@ -688,7 +688,7 @@ class TransactionSignatureSerializerTest extends BitcoinSUnitTest {
|
|||
.toWitnessTx(spendingTx)
|
||||
.updateWitness(inputIndex.toInt, witness)
|
||||
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx, //spendingTx,
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx,
|
||||
inputIndex,
|
||||
outputMap,
|
||||
Policy.standardFlags)
|
||||
|
@ -731,7 +731,7 @@ class TransactionSignatureSerializerTest extends BitcoinSUnitTest {
|
|||
.toWitnessTx(spendingTx)
|
||||
.updateWitness(inputIndex.toInt, witness)
|
||||
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx, //spendingTx,
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx,
|
||||
inputIndex,
|
||||
outputMap,
|
||||
Policy.standardFlags)
|
||||
|
@ -782,7 +782,7 @@ class TransactionSignatureSerializerTest extends BitcoinSUnitTest {
|
|||
.toWitnessTx(spendingTx)
|
||||
.updateWitness(inputIndex.toInt, witness)
|
||||
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx, //spendingTx,
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx,
|
||||
inputIndex,
|
||||
outputMap,
|
||||
Policy.standardFlags)
|
||||
|
@ -829,7 +829,7 @@ class TransactionSignatureSerializerTest extends BitcoinSUnitTest {
|
|||
.toWitnessTx(spendingTx)
|
||||
.updateWitness(inputIndex.toInt, witness)
|
||||
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx, //spendingTx,
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx,
|
||||
inputIndex,
|
||||
outputMap,
|
||||
Policy.standardFlags)
|
||||
|
@ -920,7 +920,7 @@ class TransactionSignatureSerializerTest extends BitcoinSUnitTest {
|
|||
.toWitnessTx(spendingTx)
|
||||
.updateWitness(inputIndex.toInt, witness)
|
||||
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx, //spendingTx,
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx,
|
||||
inputIndex,
|
||||
outputMap,
|
||||
Policy.standardFlags)
|
||||
|
@ -961,7 +961,7 @@ class TransactionSignatureSerializerTest extends BitcoinSUnitTest {
|
|||
.toWitnessTx(spendingTx)
|
||||
.updateWitness(inputIndex.toInt, witness)
|
||||
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx, //spendingTx,
|
||||
val taprootTxSigComponent = TaprootTxSigComponent(witnessTx,
|
||||
inputIndex,
|
||||
outputMap,
|
||||
Policy.standardFlags)
|
||||
|
@ -980,4 +980,43 @@ class TransactionSignatureSerializerTest extends BitcoinSUnitTest {
|
|||
|
||||
assert(serialize.toHex == expected)
|
||||
}
|
||||
|
||||
it must "serialize a taproot keyspend SIGHASH_ALL_ANYONECANSPEND" in {
|
||||
val expected =
|
||||
"00816c780499da010000a0e6c05b4d684eeb145d9225f15319226c5fd78617f5db646630c0584662a6a3008c033b67f78dfe0867489e0e5a032f24d14ee3c57637c22e71701fd79b64012ad200000094037f010000000022512057c1162a56ec9db80a8eb342634f613c8d990bf305925df7ddb85b356ce8f0bb7138b5c8"
|
||||
|
||||
val spendingTxHex =
|
||||
"6c780499018c033b67f78dfe0867489e0e5a032f24d14ee3c57637c22e71701fd79b64012ad2000000007138b5c80168666e0000000000160014e7f8b1de86947bf379378ebd4368d37361fac307da010000"
|
||||
val spendingTx = Transaction.fromHex(spendingTxHex)
|
||||
val inputIndex = UInt32.zero
|
||||
val prevout = TransactionOutput.fromHex(
|
||||
"94037f010000000022512057c1162a56ec9db80a8eb342634f613c8d990bf305925df7ddb85b356ce8f0bb")
|
||||
val prevOutputs = Vector(prevout)
|
||||
val outputMap: Map[TransactionOutPoint, TransactionOutput] =
|
||||
spendingTx.inputs.map(_.previousOutput).zip(prevOutputs).toMap
|
||||
val witnessStackHex = Vector(
|
||||
"228187c314a903fe94c1c8260c243e0949a3233d404a58f90cd991a44f5dad4d89bd5763525b437a10a973abd8eb99adcfec9e2865fa235fa4d6af82c427f17a81")
|
||||
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,
|
||||
inputIndex,
|
||||
outputMap,
|
||||
Policy.standardFlags)
|
||||
|
||||
val taprootOptions = TaprootSerializationOptions.empty
|
||||
|
||||
val serialize = TransactionSignatureSerializer.serializeForSignature(
|
||||
taprootTxSigComponent,
|
||||
HashType.sigHashAllAnyoneCanPay,
|
||||
taprootOptions)
|
||||
|
||||
assert(serialize.toHex == expected)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -248,6 +248,8 @@ sealed abstract class TransactionSignatureSerializer {
|
|||
val isNotAnyoneCanPay = !HashType.isAnyoneCanPay(hashType)
|
||||
val isNotSigHashSingle = !HashType.isSigHashSingle(hashType.num)
|
||||
val isNotSigHashNone = !HashType.isSigHashNone(hashType.num)
|
||||
val isSigHashAllAnyoneCanPay =
|
||||
HashType.isSigHashAllAnyoneCanPay(hashType.num)
|
||||
|
||||
val extFlag = taprootSigVersion match {
|
||||
case SigVersionTaprootKeySpend => 0.toByte
|
||||
|
@ -265,6 +267,7 @@ sealed abstract class TransactionSignatureSerializer {
|
|||
val b = spendingTransaction.inputs(inputIndex.toInt).previousOutput
|
||||
b.bytes
|
||||
}
|
||||
|
||||
val amounts = {
|
||||
if (isNotAnyoneCanPay) {
|
||||
val b = BytesUtil.toByteVector(outputs.map(_.value))
|
||||
|
@ -282,6 +285,7 @@ sealed abstract class TransactionSignatureSerializer {
|
|||
b.bytes
|
||||
}
|
||||
}
|
||||
|
||||
val sequenceHash: ByteVector =
|
||||
if (isNotAnyoneCanPay) {
|
||||
val sequences = spendingTransaction.inputs.map(_.sequence)
|
||||
|
@ -314,7 +318,6 @@ sealed abstract class TransactionSignatureSerializer {
|
|||
.bytes
|
||||
hash
|
||||
} else ByteVector.empty
|
||||
|
||||
val haveAnnex: Boolean = taprootOptions.haveAnnex
|
||||
|
||||
val annexByte = if (haveAnnex) 1.toByte else 0.toByte
|
||||
|
@ -361,15 +364,24 @@ sealed abstract class TransactionSignatureSerializer {
|
|||
inputIndexBytes ++ annexBytes ++ tapScriptBytes
|
||||
}
|
||||
|
||||
} else {
|
||||
if (isSigHashAllAnyoneCanPay) {
|
||||
//different ordering if we use SIGHASH_ANYONECANPAY
|
||||
epoch ++ ByteVector
|
||||
.fromByte(
|
||||
hashType.byte) ++ version ++ locktimeBytes ++ outputHash ++
|
||||
ByteVector.fromByte(
|
||||
spendType) ++ outPointHash ++ amounts ++ spentSPKs ++
|
||||
sequenceHash ++ annexBytes ++ tapScriptBytes
|
||||
} else {
|
||||
//different ordering if we use SIGHASH_ANYONECANPAY
|
||||
epoch ++ ByteVector.fromByte(
|
||||
hashType.byte) ++ version ++ locktimeBytes ++ ByteVector.fromByte(
|
||||
spendType) ++
|
||||
hashType.byte) ++ version ++ locktimeBytes ++ ByteVector
|
||||
.fromByte(spendType) ++
|
||||
outPointHash ++ amounts ++ spentSPKs ++
|
||||
sequenceHash ++ annexBytes ++ outputHash ++ tapScriptBytes
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue