| 632 | } |
| 633 | |
| 634 | bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, const PrecomputedTransactionData* txdata, int sighash, SignatureData* out_sigdata, bool finalize) |
| 635 | { |
| 636 | PSBTInput& input = psbt.inputs.at(index); |
| 637 | |
| 638 | // If this input is a peg-in, also make the peg-in witness |
| 639 | if (input.m_peg_in_tx.index() != 0 |
| 640 | && input.m_peg_in_txout_proof.index() != 0 |
| 641 | && !input.m_peg_in_claim_script.empty() |
| 642 | && !input.m_peg_in_genesis_hash.IsNull() |
| 643 | && input.m_peg_in_value != std::nullopt) { |
| 644 | if (Params().GetConsensus().ParentChainHasPow()) { |
| 645 | input.m_peg_in_witness = CreatePeginWitness(*input.m_peg_in_value, Params().GetConsensus().pegged_asset, input.m_peg_in_genesis_hash, input.m_peg_in_claim_script, *std::get_if<Sidechain::Bitcoin::CTransactionRef>(&input.m_peg_in_tx), *std::get_if<Sidechain::Bitcoin::CMerkleBlock>(&input.m_peg_in_txout_proof)); |
| 646 | } else { |
| 647 | input.m_peg_in_witness = CreatePeginWitness(*input.m_peg_in_value, Params().GetConsensus().pegged_asset, input.m_peg_in_genesis_hash, input.m_peg_in_claim_script, *std::get_if<CTransactionRef>(&input.m_peg_in_tx), *std::get_if<CMerkleBlock>(&input.m_peg_in_txout_proof)); |
| 648 | } |
| 649 | } |
| 650 | |
| 651 | const CMutableTransaction& tx = psbt.GetUnsignedTx(); |
| 652 | |
| 653 | if (PSBTInputSigned(input)) { |
| 654 | return true; |
| 655 | } |
| 656 | |
| 657 | // Fill SignatureData with input info |
| 658 | SignatureData sigdata; |
| 659 | input.FillSignatureData(sigdata); |
| 660 | |
| 661 | // Get UTXO |
| 662 | bool require_witness_sig = false; |
| 663 | CTxOut utxo; |
| 664 | |
| 665 | if (input.non_witness_utxo) { |
| 666 | // If we're taking our information from a non-witness UTXO, verify that it matches the prevout. |
| 667 | COutPoint prevout = input.GetOutPoint(); |
| 668 | if (prevout.n >= input.non_witness_utxo->vout.size()) { |
| 669 | return false; |
| 670 | } |
| 671 | if (input.non_witness_utxo->GetHash() != prevout.hash) { |
| 672 | return false; |
| 673 | } |
| 674 | utxo = input.non_witness_utxo->vout[prevout.n]; |
| 675 | } else if (!input.witness_utxo.IsNull()) { |
| 676 | utxo = input.witness_utxo; |
| 677 | // When we're taking our information from a witness UTXO, we can't verify it is actually data from |
| 678 | // the output being spent. This is safe in case a witness signature is produced (which includes this |
| 679 | // information directly in the hash), but not for non-witness signatures. Remember that we require |
| 680 | // a witness signature in this situation. |
| 681 | require_witness_sig = true; |
| 682 | } else if (input.m_peg_in_value && !input.m_peg_in_claim_script.empty()) { |
| 683 | utxo = CTxOut(Params().GetConsensus().pegged_asset, CConfidentialValue(*input.m_peg_in_value), input.m_peg_in_claim_script); |
| 684 | } else { |
| 685 | return false; |
| 686 | } |
| 687 | |
| 688 | sigdata.witness = false; |
| 689 | bool sig_complete; |
| 690 | if (txdata == nullptr) { |
| 691 | sig_complete = ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, utxo.scriptPubKey, sigdata); |
no test coverage detected