Bitcoin Core 31.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
psbt.cpp
Go to the documentation of this file.
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>
8#include <node/psbt.h>
9#include <policy/policy.h>
10#include <policy/settings.h>
11#include <tinyformat.h>
12
13#include <numeric>
14
15namespace node {
17{
18 // Go through each input and build status
19 PSBTAnalysis result;
20
21 bool calc_fee = true;
22
23 CAmount in_amt = 0;
24
25 result.inputs.resize(psbtx.tx->vin.size());
26
28
29 for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
30 PSBTInput& input = psbtx.inputs[i];
32
33 // We set next role here and ratchet backwards as required
35
36 // Check for a UTXO
38 if (psbtx.GetInputUTXO(utxo, i)) {
39 if (!MoneyRange(utxo.nValue) || !MoneyRange(in_amt + utxo.nValue)) {
40 result.SetInvalid(strprintf("PSBT is not valid. Input %u has invalid value", i));
41 return result;
42 }
43 in_amt += utxo.nValue;
44 input_analysis.has_utxo = true;
45 } else {
46 if (input.non_witness_utxo && psbtx.tx->vin[i].prevout.n >= input.non_witness_utxo->vout.size()) {
47 result.SetInvalid(strprintf("PSBT is not valid. Input %u specifies invalid prevout", i));
48 return result;
49 }
50 input_analysis.has_utxo = false;
51 input_analysis.is_final = false;
53 calc_fee = false;
54 }
55
56 if (!utxo.IsNull() && utxo.scriptPubKey.IsUnspendable()) {
57 result.SetInvalid(strprintf("PSBT is not valid. Input %u spends unspendable output", i));
58 return result;
59 }
60
61 // Check if it is final
62 if (!PSBTInputSignedAndVerified(psbtx, i, &txdata)) {
63 input_analysis.is_final = false;
64
65 // Figure out what is missing
67 bool complete = SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, &txdata, std::nullopt, &outdata) == PSBTError::OK;
68
69 // Things are missing
70 if (!complete) {
71 input_analysis.missing_pubkeys = outdata.missing_pubkeys;
72 input_analysis.missing_redeem_script = outdata.missing_redeem_script;
73 input_analysis.missing_witness_script = outdata.missing_witness_script;
74 input_analysis.missing_sigs = outdata.missing_sigs;
75
76 // If we are only missing signatures and nothing else, then next is signer
77 if (outdata.missing_pubkeys.empty() && outdata.missing_redeem_script.IsNull() && outdata.missing_witness_script.IsNull() && !outdata.missing_sigs.empty()) {
79 } else {
81 }
82 } else {
84 }
85 } else if (!utxo.IsNull()){
86 input_analysis.is_final = true;
87 }
88 }
89
90 // Calculate next role for PSBT by grabbing "minimum" PSBTInput next role
92 for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
94 result.next = std::min(result.next, input_analysis.next);
95 }
97
98 if (calc_fee) {
99 // Get the output amount
100 CAmount out_amt = std::accumulate(psbtx.tx->vout.begin(), psbtx.tx->vout.end(), CAmount(0),
101 [](CAmount a, const CTxOut& b) {
102 if (!MoneyRange(a) || !MoneyRange(b.nValue) || !MoneyRange(a + b.nValue)) {
103 return CAmount(-1);
104 }
105 return a += b.nValue;
106 }
107 );
108 if (!MoneyRange(out_amt)) {
109 result.SetInvalid("PSBT is not valid. Output amount invalid");
110 return result;
111 }
112
113 // Get the fee
115 result.fee = fee;
116
117 // Estimate the size
121 bool success = true;
122
123 for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
124 PSBTInput& input = psbtx.inputs[i];
126
127 if (SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, nullptr, std::nullopt) != PSBTError::OK || !psbtx.GetInputUTXO(newcoin.out, i)) {
128 success = false;
129 break;
130 } else {
131 mtx.vin[i].scriptSig = input.final_script_sig;
132 mtx.vin[i].scriptWitness = input.final_script_witness;
133 newcoin.nHeight = 1;
134 view.AddCoin(psbtx.tx->vin[i].prevout, std::move(newcoin), true);
135 }
136 }
137
138 if (success) {
141 result.estimated_vsize = size;
142 // Estimate fee rate
143 CFeeRate feerate(fee, size);
144 result.estimated_feerate = feerate;
145 }
146
147 }
148
149 return result;
150}
151} // namespace node
bool MoneyRange(const CAmount &nValue)
Definition amount.h:27
int64_t CAmount
Amount in satoshis (Can be negative)
Definition amount.h:12
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition coins.h:368
Abstract view on the open txout dataset.
Definition coins.h:308
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac.
Definition feerate.h:32
The basic transaction that is broadcasted on the network and contained in blocks.
An output of a transaction.
CAmount nValue
A UTXO entry.
Definition coins.h:35
uint64_t fee
PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
Provides helpful miscellaneous information about where a PSBT is in the signing workflow.
Definition psbt.cpp:16
unsigned int nBytesPerSigOp
Definition settings.cpp:10
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)
Compute the virtual transaction size (weight reinterpreted as bytes).
Definition policy.cpp:381
static constexpr script_verify_flags STANDARD_SCRIPT_VERIFY_FLAGS
Standard script verification flags that standard transactions will comply with.
Definition policy.h:118
bool PSBTInputSignedAndVerified(const PartiallySignedTransaction &psbt, unsigned int input_index, const PrecomputedTransactionData *txdata)
Checks whether a PSBTInput is already signed by doing script verification using final fields.
Definition psbt.cpp:325
PrecomputedTransactionData PrecomputePSBTData(const PartiallySignedTransaction &psbt)
Compute a PrecomputedTransactionData object from a psbt.
Definition psbt.cpp:385
PSBTError SignPSBTInput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index, const PrecomputedTransactionData *txdata, std::optional< int > sighash, SignatureData *out_sigdata, bool finalize)
Signs a PSBTInput, verifying that all provided data matches what is being signed.
Definition psbt.cpp:402
const SigningProvider & DUMMY_SIGNING_PROVIDER
A mutable version of CTransaction.
A structure for PSBTs which contain per-input information.
Definition psbt.h:262
CScriptWitness final_script_witness
Definition psbt.h:268
CTransactionRef non_witness_utxo
Definition psbt.h:263
CScript final_script_sig
Definition psbt.h:267
A version of CTransaction with the PSBT format.
Definition psbt.h:1139
Holds the results of AnalyzePSBT (miscellaneous information about a PSBT)
Definition psbt.h:30
std::vector< PSBTInputAnalysis > inputs
More information about the individual inputs of the transaction.
Definition psbt.h:34
void SetInvalid(std::string err_msg)
Definition psbt.h:38
std::optional< CAmount > fee
Amount of fee being paid by the transaction.
Definition psbt.h:33
std::optional< size_t > estimated_vsize
Estimated weight of the transaction.
Definition psbt.h:31
std::optional< CFeeRate > estimated_feerate
Estimated feerate (fee / weight) of the transaction.
Definition psbt.h:32
PSBTRole next
Which of the BIP 174 roles needs to handle the transaction next.
Definition psbt.h:35
Holds an analysis of one input from a PSBT.
Definition psbt.h:16
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
int64_t GetTransactionSigOpCost(const CTransaction &tx, const CCoinsViewCache &inputs, script_verify_flags flags)
Compute total signature operation cost of a transaction.
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:73
assert(!tx.IsCoinBase())