| 555 | } |
| 556 | |
| 557 | bool PSBTInputSignedAndVerified(const PartiallySignedTransaction& psbt, unsigned int input_index, const PrecomputedTransactionData* txdata) |
| 558 | { |
| 559 | CTxOut utxo; |
| 560 | assert(input_index < psbt.inputs.size()); |
| 561 | const PSBTInput& input = psbt.inputs[input_index]; |
| 562 | |
| 563 | if (input.non_witness_utxo) { |
| 564 | // If we're taking our information from a non-witness UTXO, verify that it matches the prevout. |
| 565 | COutPoint prevout = input.GetOutPoint(); |
| 566 | if (prevout.n >= input.non_witness_utxo->vout.size()) { |
| 567 | return false; |
| 568 | } |
| 569 | if (input.non_witness_utxo->GetHash() != prevout.hash) { |
| 570 | return false; |
| 571 | } |
| 572 | utxo = input.non_witness_utxo->vout[prevout.n]; |
| 573 | } else if (!input.witness_utxo.IsNull()) { |
| 574 | utxo = input.witness_utxo; |
| 575 | } else { |
| 576 | return false; |
| 577 | } |
| 578 | |
| 579 | std::optional<CMutableTransaction> unsigned_tx = psbt.GetUnsignedTx(); |
| 580 | if (!unsigned_tx) { |
| 581 | return false; |
| 582 | } |
| 583 | const CMutableTransaction& tx = *unsigned_tx; |
| 584 | if (txdata) { |
| 585 | return VerifyScript(input.final_script_sig, utxo.scriptPubKey, &input.final_script_witness, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker{&tx, input_index, utxo.nValue, *txdata, MissingDataBehavior::FAIL}); |
| 586 | } else { |
| 587 | return VerifyScript(input.final_script_sig, utxo.scriptPubKey, &input.final_script_witness, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker{&tx, input_index, utxo.nValue, MissingDataBehavior::FAIL}); |
| 588 | } |
| 589 | } |
| 590 | |
| 591 | size_t CountPSBTUnsignedInputs(const PartiallySignedTransaction& psbt) { |
| 592 | size_t count = 0; |
no test coverage detected