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