Fixed PSBT.verifyFinalizedInput (#2040)

* Fixed PSBT.verifyFinalizedInput to allow NonWitnessUTXO to be set with a WitnessUTXO

* Added unit test

* Fixed bug where verifyFinalizedInput was also broken for P2SH(Segwit)
This commit is contained in:
Nadav Kohen 2020-09-21 17:01:27 -05:00 committed by GitHub
parent 27b467a50d
commit be7bd70805
2 changed files with 37 additions and 2 deletions

View file

@ -505,4 +505,16 @@ class PSBTUnitTest extends BitcoinSAsyncTest {
assertThrows[IllegalArgumentException]( assertThrows[IllegalArgumentException](
finalizedPsbt.addScriptWitnessToOutput(p2wshWitness, index = 0)) finalizedPsbt.addScriptWitnessToOutput(p2wshWitness, index = 0))
} }
it must "verify PSBT segwit inputs correctly without WitnessUTXO" in {
val psbt = PSBT(
"70736274ff0100c50200000002a24b1b49ea1254b012a9c3df19b2d6402c308551fbc1c18bad0fef1a124f2dde0000000000ffffffff1a0219a04c444997abc3c7be01959456a1f81d200536a5f891666759bd2a627d0000000000ffffffff03a9c2eb0b00000000220020678c17924488e698d2b68bb423eb8e9af4887b572013704729ed41a4ec6592d52ee0f50500000000160014aca7c242226afe7ab436cf2bd060f516031cfb3f2ee0f50500000000160014d1bce3d788eb843a277fb693dd1822d8dfadc15900000000000001002902000000000100c2eb0b000000001600147e94acc71e93c253f9644394a9d3cfc83f6723b10000000001070001086b0247304402207364ea96d6ef6415e7a742f0c957cf6a3ddce787d5707abdcf1d7f806c80d06a02201dbbab252279de1b19ec85d652fdcfc162551980f19847dceae7fd8a59bc87570121035c32b574250d7e084fa920f8891c7016f2788dd7518ccb85b3f0ba6474a22c9600000000")
assert(psbt.verifyFinalizedInput(1))
}
it must "verify PSBT p2sh(segwit) inputs correctly without WitnessUTXO" in {
val psbt = PSBT(
"70736274ff01005502000000010e43b32dc23232b9c74bb0d4b940e6242c8acc875f41a6e4f6063e99dcbe4eda0000000000000000000180f0fa02000000001976a9149d936768e7338f716548af87b61ad83b80ea422188ac000000000001002a02000000000100e1f5050000000017a914e9b5fdcca093fde8d0424238a517034664c4715a8700000000010717160014cbcdc27013a54990a8e468dbdabf95166ca614e701086b024730440220489caebd034c1c1caf869d1463543248d78b9c8fde4cdd6044220c123ba9489c022007214b4ac24f5b4e278172b8af2fed27990fb10fa1961b3288dd0fc9226ef05d012102b38f6ec85730be3e8fa5a0da221209781de35c2e572e82f2d707e7b67be1b9c20000")
assert(psbt.verifyFinalizedInput(0))
}
} }

View file

@ -565,8 +565,31 @@ case class PSBT(
val inputMap = inputMaps(index) val inputMap = inputMaps(index)
require(inputMap.isFinalized, "Input must be finalized to verify") require(inputMap.isFinalized, "Input must be finalized to verify")
val wUtxoOpt = inputMap.witnessUTXOOpt
val utxoOpt = inputMap.nonWitnessOrUnknownUTXOOpt val utxoOpt = inputMap.nonWitnessOrUnknownUTXOOpt
val wUtxoOpt = inputMap.witnessUTXOOpt match {
case Some(wutxo) => Some(wutxo)
case None =>
utxoOpt match {
case Some(utxo) =>
val output = utxo.transactionSpent.outputs(
transaction.inputs(index).previousOutput.vout.toInt)
output.scriptPubKey match {
case _: RawScriptPubKey => None
case _: P2SHScriptPubKey =>
inputMap.finalizedScriptSigOpt match {
case Some(
FinalizedScriptSig(scriptSig: P2SHScriptSignature)) =>
scriptSig.redeemScript match {
case _: NonWitnessScriptPubKey => None
case _: WitnessScriptPubKey => Some(WitnessUTXO(output))
}
case None | Some(_) => None
}
case _: WitnessScriptPubKey => Some(WitnessUTXO(output))
}
case None => None
}
}
val newInput = { val newInput = {
val input = transaction.inputs(index) val input = transaction.inputs(index)
@ -583,7 +606,7 @@ case class PSBT(
inputMap.finalizedScriptWitnessOpt match { inputMap.finalizedScriptWitnessOpt match {
case Some(scriptWit) => case Some(scriptWit) =>
val wtx = { val wtx = {
val wtx = WitnessTransaction.toWitnessTx(transaction) val wtx = WitnessTransaction.toWitnessTx(tx)
wtx.updateWitness(index, scriptWit.scriptWitness) wtx.updateWitness(index, scriptWit.scriptWitness)
} }
val output = wUtxo.witnessUTXO val output = wUtxo.witnessUTXO