psbt.cpp
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 PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx) 17 { 18 // Go through each input and build status 19 PSBTAnalysis result; 20 21 bool calc_fee = true; 22 23 CAmount in_amt = 0; 24 25 result.inputs.resize(psbtx.tx->vin.size()); 26 27 const PrecomputedTransactionData txdata = PrecomputePSBTData(psbtx); 28 29 for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) { 30 PSBTInput& input = psbtx.inputs[i]; 31 PSBTInputAnalysis& input_analysis = result.inputs[i]; 32 33 // We set next role here and ratchet backwards as required 34 input_analysis.next = PSBTRole::EXTRACTOR; 35 36 // Check for a UTXO 37 CTxOut utxo; 38 if (psbtx.GetInputUTXO(utxo, i)) { 39 if (!MoneyRange(utxo.nValue) || !MoneyRange(in_amt + utxo.nValue)) { 40 result.SetInvalid(strprintf("PSBT is not valid. Input %u has invalid value", i)); 41 return result; 42 } 43 in_amt += utxo.nValue; 44 input_analysis.has_utxo = true; 45 } else { 46 if (input.non_witness_utxo && psbtx.tx->vin[i].prevout.n >= input.non_witness_utxo->vout.size()) { 47 result.SetInvalid(strprintf("PSBT is not valid. Input %u specifies invalid prevout", i)); 48 return result; 49 } 50 input_analysis.has_utxo = false; 51 input_analysis.is_final = false; 52 input_analysis.next = PSBTRole::UPDATER; 53 calc_fee = false; 54 } 55 56 if (!utxo.IsNull() && utxo.scriptPubKey.IsUnspendable()) { 57 result.SetInvalid(strprintf("PSBT is not valid. Input %u spends unspendable output", i)); 58 return result; 59 } 60 61 // Check if it is final 62 if (!PSBTInputSignedAndVerified(psbtx, i, &txdata)) { 63 input_analysis.is_final = false; 64 65 // Figure out what is missing 66 SignatureData outdata; 67 bool complete = SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, &txdata, std::nullopt, &outdata) == PSBTError::OK; 68 69 // Things are missing 70 if (!complete) { 71 input_analysis.missing_pubkeys = outdata.missing_pubkeys; 72 input_analysis.missing_redeem_script = outdata.missing_redeem_script; 73 input_analysis.missing_witness_script = outdata.missing_witness_script; 74 input_analysis.missing_sigs = outdata.missing_sigs; 75 76 // If we are only missing signatures and nothing else, then next is signer 77 if (outdata.missing_pubkeys.empty() && outdata.missing_redeem_script.IsNull() && outdata.missing_witness_script.IsNull() && !outdata.missing_sigs.empty()) { 78 input_analysis.next = PSBTRole::SIGNER; 79 } else { 80 input_analysis.next = PSBTRole::UPDATER; 81 } 82 } else { 83 input_analysis.next = PSBTRole::FINALIZER; 84 } 85 } else if (!utxo.IsNull()){ 86 input_analysis.is_final = true; 87 } 88 } 89 90 // Calculate next role for PSBT by grabbing "minimum" PSBTInput next role 91 result.next = PSBTRole::EXTRACTOR; 92 for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) { 93 PSBTInputAnalysis& input_analysis = result.inputs[i]; 94 result.next = std::min(result.next, input_analysis.next); 95 } 96 assert(result.next > PSBTRole::CREATOR); 97 98 if (calc_fee) { 99 // Get the output amount 100 CAmount out_amt = std::accumulate(psbtx.tx->vout.begin(), psbtx.tx->vout.end(), CAmount(0), 101 [](CAmount a, const CTxOut& b) { 102 if (!MoneyRange(a) || !MoneyRange(b.nValue) || !MoneyRange(a + b.nValue)) { 103 return CAmount(-1); 104 } 105 return a += b.nValue; 106 } 107 ); 108 if (!MoneyRange(out_amt)) { 109 result.SetInvalid("PSBT is not valid. Output amount invalid"); 110 return result; 111 } 112 113 // Get the fee 114 CAmount fee = in_amt - out_amt; 115 result.fee = fee; 116 117 // Estimate the size 118 CMutableTransaction mtx(*psbtx.tx); 119 CCoinsView view_dummy; 120 CCoinsViewCache view(&view_dummy); 121 bool success = true; 122 123 for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) { 124 PSBTInput& input = psbtx.inputs[i]; 125 Coin newcoin; 126 127 if (SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, nullptr, std::nullopt) != PSBTError::OK || !psbtx.GetInputUTXO(newcoin.out, i)) { 128 success = false; 129 break; 130 } else { 131 mtx.vin[i].scriptSig = input.final_script_sig; 132 mtx.vin[i].scriptWitness = input.final_script_witness; 133 newcoin.nHeight = 1; 134 view.AddCoin(psbtx.tx->vin[i].prevout, std::move(newcoin), true); 135 } 136 } 137 138 if (success) { 139 CTransaction ctx = CTransaction(mtx); 140 size_t size(GetVirtualTransactionSize(ctx, GetTransactionSigOpCost(ctx, view, STANDARD_SCRIPT_VERIFY_FLAGS), ::nBytesPerSigOp)); 141 result.estimated_vsize = size; 142 // Estimate fee rate 143 CFeeRate feerate(fee, size); 144 result.estimated_feerate = feerate; 145 } 146 147 } 148 149 return result; 150 } 151 } // namespace node