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