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