Bitcoin ABC  0.26.3
P2P Digital Currency
psbt.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2018 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 {
17  // Go through each input and build status
18  PSBTAnalysis result;
19 
20  bool calc_fee = true;
21  bool all_final = true;
22  bool only_missing_sigs = true;
23  bool only_missing_final = false;
24  Amount in_amt{Amount::zero()};
25 
26  result.inputs.resize(psbtx.tx->vin.size());
27 
28  for (size_t i = 0; i < psbtx.tx->vin.size(); ++i) {
29  PSBTInput &input = psbtx.inputs[i];
30  PSBTInputAnalysis &input_analysis = result.inputs[i];
31 
32  // Check for a UTXO
33  CTxOut utxo;
34  if (psbtx.GetInputUTXO(utxo, i)) {
35  if (!MoneyRange(utxo.nValue) || !MoneyRange(in_amt + utxo.nValue)) {
36  result.SetInvalid(strprintf(
37  "PSBT is not valid. Input %u has invalid value", i));
38  return result;
39  }
40  in_amt += utxo.nValue;
41  input_analysis.has_utxo = true;
42  } else {
43  input_analysis.has_utxo = false;
44  input_analysis.is_final = false;
45  input_analysis.next = PSBTRole::UPDATER;
46  calc_fee = false;
47  }
48 
49  if (!utxo.IsNull() && utxo.scriptPubKey.IsUnspendable()) {
50  result.SetInvalid(strprintf(
51  "PSBT is not valid. Input %u spends unspendable output", i));
52  return result;
53  }
54 
55  // Check if it is final
56  if (!utxo.IsNull() && !PSBTInputSigned(input)) {
57  input_analysis.is_final = false;
58  all_final = false;
59 
60  // Figure out what is missing
61  SignatureData outdata;
62  bool complete = SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i,
63  SigHashType().withForkId(), &outdata);
64 
65  // Things are missing
66  if (!complete) {
67  input_analysis.missing_pubkeys = outdata.missing_pubkeys;
68  input_analysis.missing_redeem_script =
69  outdata.missing_redeem_script;
70  input_analysis.missing_sigs = outdata.missing_sigs;
71 
72  // If we are only missing signatures and nothing else, then next
73  // is signer
74  if (outdata.missing_pubkeys.empty() &&
75  outdata.missing_redeem_script.IsNull() &&
76  !outdata.missing_sigs.empty()) {
77  input_analysis.next = PSBTRole::SIGNER;
78  } else {
79  only_missing_sigs = false;
80  input_analysis.next = PSBTRole::UPDATER;
81  }
82  } else {
83  only_missing_final = true;
84  input_analysis.next = PSBTRole::FINALIZER;
85  }
86  } else if (!utxo.IsNull()) {
87  input_analysis.is_final = true;
88  }
89  }
90 
91  if (all_final) {
92  only_missing_sigs = false;
93  result.next = PSBTRole::EXTRACTOR;
94  }
95  if (calc_fee) {
96  // Get the output amount
97  Amount out_amt =
98  std::accumulate(psbtx.tx->vout.begin(), psbtx.tx->vout.end(),
99  Amount::zero(), [](Amount a, const CTxOut &b) {
100  if (!MoneyRange(a) || !MoneyRange(b.nValue) ||
101  !MoneyRange(a + b.nValue)) {
102  return -1 * SATOSHI;
103  }
104  return a += b.nValue;
105  });
106  if (!MoneyRange(out_amt)) {
107  result.SetInvalid(
108  strprintf("PSBT is not valid. Output amount invalid"));
109  return result;
110  }
111 
112  // Get the fee
113  Amount fee = in_amt - out_amt;
114  result.fee = fee;
115 
116  // Estimate the size
117  CMutableTransaction mtx(*psbtx.tx);
118  CCoinsView view_dummy;
119  CCoinsViewCache view(&view_dummy);
120  bool success = true;
121 
122  for (size_t i = 0; i < psbtx.tx->vin.size(); ++i) {
123  PSBTInput &input = psbtx.inputs[i];
124  CTxOut newUtxo;
125 
126  if (!SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i,
127  SigHashType().withForkId(), nullptr, true) ||
128  !psbtx.GetInputUTXO(newUtxo, i)) {
129  success = false;
130  break;
131  } else {
132  mtx.vin[i].scriptSig = input.final_script_sig;
133  view.AddCoin(psbtx.tx->vin[i].prevout, Coin(newUtxo, 1, false),
134  true);
135  }
136  }
137 
138  if (success) {
140  size_t size = ctx.GetTotalSize();
141  result.estimated_vsize = size;
142  // Estimate fee rate
143  CFeeRate feerate(fee, size);
144  result.estimated_feerate = feerate;
145  }
146 
147  if (only_missing_sigs) {
148  result.next = PSBTRole::SIGNER;
149  } else if (only_missing_final) {
150  result.next = PSBTRole::FINALIZER;
151  } else if (all_final) {
152  result.next = PSBTRole::EXTRACTOR;
153  } else {
154  result.next = PSBTRole::UPDATER;
155  }
156  } else {
157  result.next = PSBTRole::UPDATER;
158  }
159 
160  return result;
161 }
162 } // namespace node
bool MoneyRange(const Amount nValue)
Definition: amount.h:176
secp256k1_context * ctx
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:203
void AddCoin(const COutPoint &outpoint, Coin coin, bool possible_overwrite)
Add a coin.
Definition: coins.cpp:100
Abstract view on the open txout dataset.
Definition: coins.h:147
Fee rate in satoshis per kilobyte: Amount / kB.
Definition: feerate.h:21
A mutable version of CTransaction.
Definition: transaction.h:278
std::vector< CTxIn > vin
Definition: transaction.h:280
bool IsUnspendable() const
Returns whether the script is guaranteed to fail at execution, regardless of the initial stack.
Definition: script.h:549
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:194
An output of a transaction.
Definition: transaction.h:130
CScript scriptPubKey
Definition: transaction.h:133
Amount nValue
Definition: transaction.h:132
bool IsNull() const
Definition: transaction.h:147
A UTXO entry.
Definition: coins.h:27
Signature hash type wrapper class.
Definition: sighashtype.h:37
bool IsNull() const
Definition: uint256.h:30
Definition: init.h:28
PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
Provides helpful miscellaneous information about where a PSBT is in the signing workflow.
Definition: psbt.cpp:16
bool PSBTInputSigned(const PSBTInput &input)
Checks whether a PSBTInput is already signed.
Definition: psbt.cpp:159
bool SignPSBTInput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index, SigHashType sighash, SignatureData *out_sigdata, bool use_dummy)
Signs a PSBTInput, verifying that all provided data matches what is being signed.
Definition: psbt.cpp:185
const SigningProvider & DUMMY_SIGNING_PROVIDER
Definition: amount.h:19
static constexpr Amount zero()
Definition: amount.h:42
A structure for PSBTs which contain per-input information.
Definition: psbt.h:45
CScript final_script_sig
Definition: psbt.h:48
A version of CTransaction with the PSBT format.
Definition: psbt.h:335
bool GetInputUTXO(CTxOut &utxo, int input_index) const
Finds the UTXO for a given input index.
Definition: psbt.cpp:56
std::vector< PSBTInput > inputs
Definition: psbt.h:337
std::optional< CMutableTransaction > tx
Definition: psbt.h:336
uint160 missing_redeem_script
ScriptID of the missing redeemScript (if any)
Definition: sign.h:83
std::vector< CKeyID > missing_sigs
KeyIDs of pubkeys for signatures which could not be found.
Definition: sign.h:81
std::vector< CKeyID > missing_pubkeys
KeyIDs of pubkeys which could not be found.
Definition: sign.h:79
Holds the results of AnalyzePSBT (miscellaneous information about a PSBT)
Definition: psbt.h:35
std::vector< PSBTInputAnalysis > inputs
More information about the individual inputs of the transaction.
Definition: psbt.h:43
void SetInvalid(std::string err_msg)
Definition: psbt.h:49
std::optional< Amount > fee
Amount of fee being paid by the transaction.
Definition: psbt.h:41
std::optional< size_t > estimated_vsize
Estimated weight of the transaction.
Definition: psbt.h:37
std::optional< CFeeRate > estimated_feerate
Estimated feerate (fee / weight) of the transaction.
Definition: psbt.h:39
PSBTRole next
Which of the BIP 174 roles needs to handle the transaction next.
Definition: psbt.h:45
Holds an analysis of one input from a PSBT.
Definition: psbt.h:16
std::vector< CKeyID > missing_sigs
Pubkeys whose signatures are missing.
Definition: psbt.h:27
bool has_utxo
Whether we have UTXO information for this input.
Definition: psbt.h:18
PSBTRole next
Which of the BIP 174 roles needs to handle this input next.
Definition: psbt.h:22
std::vector< CKeyID > missing_pubkeys
Pubkeys whose BIP32 derivation path is missing.
Definition: psbt.h:25
uint160 missing_redeem_script
Hash160 of redeem script, if missing.
Definition: psbt.h:29
bool is_final
Whether the input has all required information including signatures.
Definition: psbt.h:20
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1201