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