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