aboutsummaryrefslogtreecommitdiff
path: root/src/node/psbt.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <[email protected]>2019-04-10 15:44:41 +0200
committerWladimir J. van der Laan <[email protected]>2019-04-10 15:51:37 +0200
commit6a135fbe5b30c3603616589b4779b1ce602c9392 (patch)
tree389c652246ff9834aa6c92487cb1657794f9b56d /src/node/psbt.cpp
parentMerge #15659: [docs] fix findFork comment (diff)
parent[build] Move AnalyzePSBT from psbt.cpp to node/psbt.cpp (diff)
downloaddiscoin-6a135fbe5b30c3603616589b4779b1ce602c9392.tar.xz
discoin-6a135fbe5b30c3603616589b4779b1ce602c9392.zip
Merge #15638: Move-only: Pull wallet code out of libbitcoin_server
4d074e84a2cf419510e2920417799f62747f4b07 [build] Move AnalyzePSBT from psbt.cpp to node/psbt.cpp (Russell Yanofsky) fd509bd1f71df628b933ea7a135a9a957a5e0136 [docs] Document src subdirectories and different libraries (John Newbery) 9eaeb7fb8d4ab0d4493849e6c17e314fd75fea9c [build] Move wallet load functions to wallet/load unit (John Newbery) 91a25d1e711bfc0617027eee18b9777ff368d6b9 [build] Add several util units (John Newbery) 99517866b62c261f990e1f897502855afc12f2a7 [build] Move several units into common libraries (John Newbery) 0509465542d63a5bbe7296f283f44dd491e74f78 [build] Move rpc rawtransaction util functions to rpc/rawtransaction_util.cpp (John Newbery) 1acc61f8746bc6efb905e121a9f607c4f5982b35 [build] Move rpc utility methods to rpc/util (John Newbery) 4a75c9d6512a5580e60104103ea11d2cd9586354 [build] Move policy settings to new src/policy/settings unit (John Newbery) fdf8888b6f0c63e8a4cb1459752625e642d6a4dd [build] Move CheckTransaction from lib_server to lib_consensus (John Newbery) Pull request description: This is a move-only commit. No code is changing and the moves can be easily verified with: ```sh git log -p -n1 --color-moved=dimmed_zebra ``` This commit moves functions and variables that wallet code depends on out of libbitcoin_server.a, so the bitcoin-wallet tool can be built without libbitcoin_server.a in #15639, and attempting to access server state from wallet code will result in link errors instead of silently broken code. List of moves: - `CheckTransaction` moves from `consensus/tx_verify.cpp` to `consensus/tx_check.cpp` - `urlDecode` moves from `httpserver.cpp` to `util/url.cpp` - `TransactionErrorString` moves from `node/transaction.cpp` to `util/error.cpp` - `StringForFeeReason` and `FeeModeFromString` move from `policy/fees.cpp` to `util/fees.cpp` - `incrementalRelayFee` `dustRelayFee` and `nBytesPerSigOp` move from `policy/policy.cpp` to `policy/settings.cpp` - `SignalsOptInRBF` moves from `policy/rbf.cpp` to `util/rbf.cpp` - `fIsBareMultisigStd` moves from `validation.cpp` to `policy/settings.cpp` - `ConstructTransaction` `TxInErrorToJSON` and `SignTransaction` move from `rpc/rawtransaction.cpp` to `rpc/rawtransaction_util.cpp` - `RPCTypeCheck` `RPCTypeCheckArgument` `RPCTypeCheckObj` `AmountFromValue` `ParseHashV``ParseHashO` `ParseHexV` `ParseHexO` `HelpExampleCli` and `HelpExampleRpc` move from `rpc/server.cpp` to `rpc/util.cpp` - `AmountHighWarn` and `AmountErrMsg` move from `ui_interface.cpp` to `util/error.cpp` - `FormatStateMessage` and `strMessageMagic` move from `validation.cpp` to `util/validation.cpp` - `VerifyWallets` `LoadWallets` `StartWallets` `FlushWallets` `StopWallets` and `UnloadWallets` move from `wallet/init.cpp` to `wallet/node.cpp` ACKs for commit 4d074e: jnewbery: utACK 4d074e84a2cf419510e2920417799f62747f4b07 (checked by doing the rebase myself and verifying no difference between my branch and 4d074e84a2cf419510e2920417799f62747f4b07) Tree-SHA512: 5e1604a9fb06475f2b96da0de0baa8330f4dda834dc20a0183ef11e1e4c27631d1d1bbb9abf0054efc03d56945fdf9920f63366b6a4f200f665b742a479ff75c
Diffstat (limited to 'src/node/psbt.cpp')
-rw-r--r--src/node/psbt.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/node/psbt.cpp b/src/node/psbt.cpp
new file mode 100644
index 000000000..12559c5a5
--- /dev/null
+++ b/src/node/psbt.cpp
@@ -0,0 +1,134 @@
+// Copyright (c) 2009-2018 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <coins.h>
+#include <consensus/tx_verify.h>
+#include <node/psbt.h>
+#include <policy/policy.h>
+#include <policy/settings.h>
+
+#include <numeric>
+
+PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
+{
+ // Go through each input and build status
+ PSBTAnalysis result;
+
+ bool calc_fee = true;
+ bool all_final = true;
+ bool only_missing_sigs = true;
+ bool only_missing_final = false;
+ CAmount in_amt = 0;
+
+ result.inputs.resize(psbtx.tx->vin.size());
+
+ for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
+ PSBTInput& input = psbtx.inputs[i];
+ PSBTInputAnalysis& input_analysis = result.inputs[i];
+
+ // Check for a UTXO
+ CTxOut utxo;
+ if (psbtx.GetInputUTXO(utxo, i)) {
+ in_amt += utxo.nValue;
+ input_analysis.has_utxo = true;
+ } else {
+ input_analysis.has_utxo = false;
+ input_analysis.is_final = false;
+ input_analysis.next = PSBTRole::UPDATER;
+ calc_fee = false;
+ }
+
+ // Check if it is final
+ if (!utxo.IsNull() && !PSBTInputSigned(input)) {
+ input_analysis.is_final = false;
+ all_final = false;
+
+ // Figure out what is missing
+ SignatureData outdata;
+ bool complete = SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, 1, &outdata);
+
+ // Things are missing
+ if (!complete) {
+ input_analysis.missing_pubkeys = outdata.missing_pubkeys;
+ input_analysis.missing_redeem_script = outdata.missing_redeem_script;
+ input_analysis.missing_witness_script = outdata.missing_witness_script;
+ input_analysis.missing_sigs = outdata.missing_sigs;
+
+ // If we are only missing signatures and nothing else, then next is signer
+ if (outdata.missing_pubkeys.empty() && outdata.missing_redeem_script.IsNull() && outdata.missing_witness_script.IsNull() && !outdata.missing_sigs.empty()) {
+ input_analysis.next = PSBTRole::SIGNER;
+ } else {
+ only_missing_sigs = false;
+ input_analysis.next = PSBTRole::UPDATER;
+ }
+ } else {
+ only_missing_final = true;
+ input_analysis.next = PSBTRole::FINALIZER;
+ }
+ } else if (!utxo.IsNull()){
+ input_analysis.is_final = true;
+ }
+ }
+
+ if (all_final) {
+ only_missing_sigs = false;
+ result.next = PSBTRole::EXTRACTOR;
+ }
+ if (calc_fee) {
+ // Get the output amount
+ CAmount out_amt = std::accumulate(psbtx.tx->vout.begin(), psbtx.tx->vout.end(), CAmount(0),
+ [](CAmount a, const CTxOut& b) {
+ return a += b.nValue;
+ }
+ );
+
+ // Get the fee
+ CAmount fee = in_amt - out_amt;
+ result.fee = fee;
+
+ // Estimate the size
+ CMutableTransaction mtx(*psbtx.tx);
+ CCoinsView view_dummy;
+ CCoinsViewCache view(&view_dummy);
+ bool success = true;
+
+ for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
+ PSBTInput& input = psbtx.inputs[i];
+ Coin newcoin;
+
+ if (!SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, 1, nullptr, true) || !psbtx.GetInputUTXO(newcoin.out, i)) {
+ success = false;
+ break;
+ } else {
+ mtx.vin[i].scriptSig = input.final_script_sig;
+ mtx.vin[i].scriptWitness = input.final_script_witness;
+ newcoin.nHeight = 1;
+ view.AddCoin(psbtx.tx->vin[i].prevout, std::move(newcoin), true);
+ }
+ }
+
+ if (success) {
+ CTransaction ctx = CTransaction(mtx);
+ size_t size = GetVirtualTransactionSize(ctx, GetTransactionSigOpCost(ctx, view, STANDARD_SCRIPT_VERIFY_FLAGS));
+ result.estimated_vsize = size;
+ // Estimate fee rate
+ CFeeRate feerate(fee, size);
+ result.estimated_feerate = feerate;
+ }
+
+ if (only_missing_sigs) {
+ result.next = PSBTRole::SIGNER;
+ } else if (only_missing_final) {
+ result.next = PSBTRole::FINALIZER;
+ } else if (all_final) {
+ result.next = PSBTRole::EXTRACTOR;
+ } else {
+ result.next = PSBTRole::UPDATER;
+ }
+ } else {
+ result.next = PSBTRole::UPDATER;
+ }
+
+ return result;
+}