Branch data Line data Source code
1 : : // Copyright (c) 2009-2022 The Bitcoin Core developers 2 : : // Distributed under the MIT software license, see the accompanying 3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : : 5 : : #include <coins.h> 6 : : #include <consensus/amount.h> 7 : : #include <consensus/tx_verify.h> 8 : : #include <node/psbt.h> 9 : : #include <policy/policy.h> 10 : : #include <policy/settings.h> 11 : : #include <tinyformat.h> 12 : : 13 : : #include <numeric> 14 : : 15 : : namespace node { 16 : 1782 : PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx) 17 [ + - ]: 173 : { 18 [ + - ]: 173 : // Go through each input and build status 19 : 1782 : PSBTAnalysis result; 20 : : 21 : 1782 : bool calc_fee = true; 22 : : 23 : 1782 : CAmount in_amt = 0; 24 : : 25 [ + - + - ]: 1782 : result.inputs.resize(psbtx.tx->vin.size()); 26 : : 27 [ + - ]: 1955 : const PrecomputedTransactionData txdata = PrecomputePSBTData(psbtx); 28 : : 29 [ + - + + ]: 4656 : for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) { 30 : 3249 : PSBTInput& input = psbtx.inputs[i]; 31 : 3249 : PSBTInputAnalysis& input_analysis = result.inputs[i]; 32 : : 33 : : // We set next role here and ratchet backwards as required 34 : 3249 : input_analysis.next = PSBTRole::EXTRACTOR; 35 : : 36 : : // Check for a UTXO 37 [ + - ]: 3249 : CTxOut utxo; 38 [ + - + + ]: 3249 : if (psbtx.GetInputUTXO(utxo, i)) { 39 [ + - + + : 1643 : if (!MoneyRange(utxo.nValue) || !MoneyRange(in_amt + utxo.nValue)) { + - + + ] 40 [ + - + - ]: 344 : result.SetInvalid(strprintf("PSBT is not valid. Input %u has invalid value", i)); 41 : 344 : return result; 42 : : } 43 : 1299 : in_amt += utxo.nValue; 44 : 1299 : input_analysis.has_utxo = true; 45 : 1299 : } else { 46 [ + - + + : 1606 : if (input.non_witness_utxo && psbtx.tx->vin[i].prevout.n >= input.non_witness_utxo->vout.size()) { + - + - ] 47 [ + - + - ]: 12 : result.SetInvalid(strprintf("PSBT is not valid. Input %u specifies invalid prevout", i)); 48 : 12 : return result; 49 : : } 50 : 1594 : input_analysis.has_utxo = false; 51 : 1594 : input_analysis.is_final = false; 52 : 1594 : input_analysis.next = PSBTRole::UPDATER; 53 : 1594 : calc_fee = false; 54 : : } 55 : : 56 [ + - + + : 2893 : if (!utxo.IsNull() && utxo.scriptPubKey.IsUnspendable()) { + - + + ] 57 [ + - + - ]: 19 : result.SetInvalid(strprintf("PSBT is not valid. Input %u spends unspendable output", i)); 58 : 19 : return result; 59 : : } 60 : : 61 : : // Check if it is final 62 [ + - + - : 2874 : if (!PSBTInputSignedAndVerified(psbtx, i, &txdata)) { + + ] 63 : 2798 : input_analysis.is_final = false; 64 : : 65 : : // Figure out what is missing 66 [ + - ]: 2798 : SignatureData outdata; 67 [ + - ]: 2798 : bool complete = SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, &txdata, 1, &outdata); 68 : : 69 : : // Things are missing 70 [ + + ]: 2798 : if (!complete) { 71 [ + - ]: 2760 : input_analysis.missing_pubkeys = outdata.missing_pubkeys; 72 : 2760 : input_analysis.missing_redeem_script = outdata.missing_redeem_script; 73 : 2760 : input_analysis.missing_witness_script = outdata.missing_witness_script; 74 [ + - ]: 2933 : input_analysis.missing_sigs = outdata.missing_sigs; 75 : : 76 : : // If we are only missing signatures and nothing else, then next is signer 77 [ + + + - : 2760 : if (outdata.missing_pubkeys.empty() && outdata.missing_redeem_script.IsNull() && outdata.missing_witness_script.IsNull() && !outdata.missing_sigs.empty()) { + + + - + - + + ] 78 : 305 : input_analysis.next = PSBTRole::SIGNER; 79 : 305 : } else { 80 : 2455 : input_analysis.next = PSBTRole::UPDATER; 81 : : } 82 : 2760 : } else { 83 : 38 : input_analysis.next = PSBTRole::FINALIZER; 84 : : } 85 [ + - - + ]: 2874 : } else if (!utxo.IsNull()){ 86 : 76 : input_analysis.is_final = true; 87 : 76 : } 88 [ + + ]: 3249 : } 89 : : 90 : : // Calculate next role for PSBT by grabbing "minimum" PSBTInput next role 91 : 1407 : result.next = PSBTRole::EXTRACTOR; 92 [ + - + + ]: 4062 : for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) { 93 : 2655 : PSBTInputAnalysis& input_analysis = result.inputs[i]; 94 [ + - ]: 2655 : result.next = std::min(result.next, input_analysis.next); 95 : 2655 : } 96 [ + - ]: 1407 : assert(result.next > PSBTRole::CREATOR); 97 : : 98 [ + + ]: 1407 : if (calc_fee) { 99 : : // Get the output amount 100 [ + - + - : 817 : CAmount out_amt = std::accumulate(psbtx.tx->vout.begin(), psbtx.tx->vout.end(), CAmount(0), + - ] 101 : 4704 : [](CAmount a, const CTxOut& b) { 102 [ + + + + : 4704 : if (!MoneyRange(a) || !MoneyRange(b.nValue) || !MoneyRange(a + b.nValue)) { + + ] 103 : 3981 : return CAmount(-1); 104 : : } 105 : 723 : return a += b.nValue; 106 : 4704 : } 107 : : ); 108 [ + - + + ]: 817 : if (!MoneyRange(out_amt)) { 109 [ + - + - ]: 379 : result.SetInvalid("PSBT is not valid. Output amount invalid"); 110 : 379 : return result; 111 : : } 112 : : 113 : : // Get the fee 114 : 438 : CAmount fee = in_amt - out_amt; 115 [ + - ]: 438 : result.fee = fee; 116 : : 117 : : // Estimate the size 118 [ + - + - ]: 438 : CMutableTransaction mtx(*psbtx.tx); 119 : 438 : CCoinsView view_dummy; 120 [ + - ]: 438 : CCoinsViewCache view(&view_dummy); 121 : 438 : bool success = true; 122 : : 123 [ + - + + ]: 666 : for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) { 124 : 468 : PSBTInput& input = psbtx.inputs[i]; 125 [ + - ]: 468 : Coin newcoin; 126 : : 127 [ + - + + : 468 : if (!SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, nullptr, 1) || !psbtx.GetInputUTXO(newcoin.out, i)) { + - + - ] 128 : 240 : success = false; 129 : 240 : break; 130 : : } else { 131 [ + - ]: 228 : mtx.vin[i].scriptSig = input.final_script_sig; 132 [ + - ]: 228 : mtx.vin[i].scriptWitness = input.final_script_witness; 133 : 228 : newcoin.nHeight = 1; 134 [ + - + - ]: 228 : view.AddCoin(psbtx.tx->vin[i].prevout, std::move(newcoin), true); 135 : : } 136 [ - + + ]: 468 : } 137 : : 138 [ + + ]: 438 : if (success) { 139 [ + - ]: 198 : CTransaction ctx = CTransaction(mtx); 140 [ + - + - ]: 198 : size_t size(GetVirtualTransactionSize(ctx, GetTransactionSigOpCost(ctx, view, STANDARD_SCRIPT_VERIFY_FLAGS), ::nBytesPerSigOp)); 141 [ + - ]: 198 : result.estimated_vsize = size; 142 : : // Estimate fee rate 143 [ + - ]: 198 : CFeeRate feerate(fee, size); 144 [ + - ]: 198 : result.estimated_feerate = feerate; 145 : 198 : } 146 : : 147 : 438 : } 148 : : 149 : 1028 : return result; 150 [ + - ]: 1782 : } 151 : : } // namespace node