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 
22  Amount in_amt{Amount::zero()};
23 
24  result.inputs.resize(psbtx.tx->vin.size());
25 
26  for (size_t i = 0; i < psbtx.tx->vin.size(); ++i) {
27  PSBTInput &input = psbtx.inputs[i];
28  PSBTInputAnalysis &input_analysis = result.inputs[i];
29 
30  // We set next role here and ratchet backwards as required
31  input_analysis.next = PSBTRole::EXTRACTOR;
32 
33  // Check for a UTXO
34  CTxOut utxo;
35  if (psbtx.GetInputUTXO(utxo, i)) {
36  if (!MoneyRange(utxo.nValue) || !MoneyRange(in_amt + utxo.nValue)) {
37  result.SetInvalid(strprintf(
38  "PSBT is not valid. Input %u has invalid value", i));
39  return result;
40  }
41  in_amt += utxo.nValue;
42  input_analysis.has_utxo = true;
43  } else {
44  input_analysis.has_utxo = false;
45  input_analysis.is_final = false;
46  input_analysis.next = PSBTRole::UPDATER;
47  calc_fee = false;
48  }
49 
50  if (!utxo.IsNull() && utxo.scriptPubKey.IsUnspendable()) {
51  result.SetInvalid(strprintf(
52  "PSBT is not valid. Input %u spends unspendable output", i));
53  return result;
54  }
55 
56  // Check if it is final
57  if (!utxo.IsNull() && !PSBTInputSigned(input)) {
58  input_analysis.is_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  input_analysis.next = PSBTRole::UPDATER;
80  }
81  } else {
82  input_analysis.next = PSBTRole::FINALIZER;
83  }
84  } else if (!utxo.IsNull()) {
85  input_analysis.is_final = true;
86  }
87  }
88 
89  // Calculate next role for PSBT by grabbing "minumum" PSBTInput next role
90  result.next = PSBTRole::EXTRACTOR;
91  for (size_t i = 0; i < psbtx.tx->vin.size(); ++i) {
92  PSBTInputAnalysis &input_analysis = result.inputs[i];
93  result.next = std::min(result.next, input_analysis.next);
94  }
95  assert(result.next > PSBTRole::CREATOR);
96 
97  if (calc_fee) {
98  // Get the output amount
99  Amount out_amt =
100  std::accumulate(psbtx.tx->vout.begin(), psbtx.tx->vout.end(),
101  Amount::zero(), [](Amount a, const CTxOut &b) {
102  if (!MoneyRange(a) || !MoneyRange(b.nValue) ||
103  !MoneyRange(a + b.nValue)) {
104  return -1 * SATOSHI;
105  }
106  return a += b.nValue;
107  });
108  if (!MoneyRange(out_amt)) {
109  result.SetInvalid(
110  strprintf("PSBT is not valid. Output amount invalid"));
111  return result;
112  }
113 
114  // Get the fee
115  Amount fee = in_amt - out_amt;
116  result.fee = fee;
117 
118  // Estimate the size
119  CMutableTransaction mtx(*psbtx.tx);
120  CCoinsView view_dummy;
121  CCoinsViewCache view(&view_dummy);
122  bool success = true;
123 
124  for (size_t i = 0; i < psbtx.tx->vin.size(); ++i) {
125  PSBTInput &input = psbtx.inputs[i];
126  CTxOut newUtxo;
127 
128  if (!SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i,
129  SigHashType().withForkId(), nullptr, true) ||
130  !psbtx.GetInputUTXO(newUtxo, i)) {
131  success = false;
132  break;
133  } else {
134  mtx.vin[i].scriptSig = input.final_script_sig;
135  view.AddCoin(psbtx.tx->vin[i].prevout, Coin(newUtxo, 1, false),
136  true);
137  }
138  }
139 
140  if (success) {
142  size_t size = ctx.GetTotalSize();
143  result.estimated_vsize = size;
144  // Estimate fee rate
145  CFeeRate feerate(fee, size);
146  result.estimated_feerate = feerate;
147  }
148  }
149 
150  return result;
151 }
152 } // namespace node
bool MoneyRange(const Amount nValue)
Definition: amount.h:166
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:274
std::vector< CTxIn > vin
Definition: transaction.h:276
bool IsUnspendable() const
Returns whether the script is guaranteed to fail at execution, regardless of the initial stack.
Definition: script.h:548
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:192
An output of a transaction.
Definition: transaction.h:128
CScript scriptPubKey
Definition: transaction.h:131
Amount nValue
Definition: transaction.h:130
bool IsNull() const
Definition: transaction.h:145
A UTXO entry.
Definition: coins.h:27
Signature hash type wrapper class.
Definition: sighashtype.h:37
bool IsNull() const
Definition: uint256.h:32
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:160
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:186
const SigningProvider & DUMMY_SIGNING_PROVIDER
Definition: amount.h:19
static constexpr Amount zero() noexcept
Definition: amount.h:32
A structure for PSBTs which contain per-input information.
Definition: psbt.h:44
CScript final_script_sig
Definition: psbt.h:47
A version of CTransaction with the PSBT format.
Definition: psbt.h:334
bool GetInputUTXO(CTxOut &utxo, int input_index) const
Finds the UTXO for a given input index.
Definition: psbt.cpp:57
std::vector< PSBTInput > inputs
Definition: psbt.h:336
std::optional< CMutableTransaction > tx
Definition: psbt.h:335
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:1202
assert(!tx.IsCoinBase())