aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfanquake <fanquake@gmail.com>2020-01-04 17:43:11 +0800
committerfanquake <fanquake@gmail.com>2020-01-04 18:31:39 +0800
commitfebf04841fd94429ad13c9c1548bd052cdf82833 (patch)
treed76fab00be071d671a69447ec73453ed4d70af1f /src
parent310b29f9c326a14060c3c0b0561cd59af7d3c1e5 (diff)
parentca5f8deefd778195cb10a3419d3b5c0693abb958 (diff)
downloadbitcoin-febf04841fd94429ad13c9c1548bd052cdf82833.tar.xz
Merge #17853: [0.19] psbt: handle unspendable psbts
ca5f8deefd778195cb10a3419d3b5c0693abb958 Mark PSBTs spending unspendable outputs as invalid in analysis (Andrew Chow) 551583398ba4fdae973c047bc60556ffa17c6431 Have a PSBTAnalysis state that indicates invalid PSBT (Andrew Chow) Pull request description: Backport of #17524 ACKs for top commit: achow101: ACK ca5f8deefd778195cb10a3419d3b5c0693abb958 Tree-SHA512: b5f2b951beb9477ac3176a0aade845654d2108ca3a9fbc72097ba4b4797df5419053d6b489bbaa03be08cb8cfdc37a83db8b7642ffa52d42b7aa8ea14aff39cc
Diffstat (limited to 'src')
-rw-r--r--src/node/psbt.cpp6
-rw-r--r--src/node/psbt.h11
-rw-r--r--src/psbt.cpp1
-rw-r--r--src/psbt.h1
-rw-r--r--src/rpc/rawtransaction.cpp6
5 files changed, 24 insertions, 1 deletions
diff --git a/src/node/psbt.cpp b/src/node/psbt.cpp
index 12559c5a5f..9a30c3f083 100644
--- a/src/node/psbt.cpp
+++ b/src/node/psbt.cpp
@@ -7,6 +7,7 @@
#include <node/psbt.h>
#include <policy/policy.h>
#include <policy/settings.h>
+#include <tinyformat.h>
#include <numeric>
@@ -39,6 +40,11 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
calc_fee = false;
}
+ if (!utxo.IsNull() && utxo.scriptPubKey.IsUnspendable()) {
+ result.SetInvalid(strprintf("PSBT is not valid. Input %u spends unspendable output", i));
+ return result;
+ }
+
// Check if it is final
if (!utxo.IsNull() && !PSBTInputSigned(input)) {
input_analysis.is_final = false;
diff --git a/src/node/psbt.h b/src/node/psbt.h
index e04366a20f..7384dc415c 100644
--- a/src/node/psbt.h
+++ b/src/node/psbt.h
@@ -30,6 +30,17 @@ struct PSBTAnalysis {
Optional<CAmount> fee; //!< Amount of fee being paid by the transaction
std::vector<PSBTInputAnalysis> inputs; //!< More information about the individual inputs of the transaction
PSBTRole next; //!< Which of the BIP 174 roles needs to handle the transaction next
+ std::string error; //!< Error message
+
+ void SetInvalid(std::string err_msg)
+ {
+ estimated_vsize = nullopt;
+ estimated_feerate = nullopt;
+ fee = nullopt;
+ inputs.clear();
+ next = PSBTRole::CREATOR;
+ error = err_msg;
+ }
};
/**
diff --git a/src/psbt.cpp b/src/psbt.cpp
index fe74002e82..20473429a4 100644
--- a/src/psbt.cpp
+++ b/src/psbt.cpp
@@ -349,6 +349,7 @@ TransactionError CombinePSBTs(PartiallySignedTransaction& out, const std::vector
std::string PSBTRoleName(PSBTRole role) {
switch (role) {
+ case PSBTRole::CREATOR: return "creator";
case PSBTRole::UPDATER: return "updater";
case PSBTRole::SIGNER: return "signer";
case PSBTRole::FINALIZER: return "finalizer";
diff --git a/src/psbt.h b/src/psbt.h
index 6d77db0c6f..437b75d7cf 100644
--- a/src/psbt.h
+++ b/src/psbt.h
@@ -552,6 +552,7 @@ struct PartiallySignedTransaction
};
enum class PSBTRole {
+ CREATOR,
UPDATER,
SIGNER,
FINALIZER,
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index f548d356cf..2fd6b9709f 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -1671,6 +1671,7 @@ UniValue analyzepsbt(const JSONRPCRequest& request)
" \"estimated_feerate\" : feerate (numeric, optional) Estimated feerate of the final signed transaction in " + CURRENCY_UNIT + "/kB. Shown only if all UTXO slots in the PSBT have been filled.\n"
" \"fee\" : fee (numeric, optional) The transaction fee paid. Shown only if all UTXO slots in the PSBT have been filled.\n"
" \"next\" : \"role\" (string) Role of the next person that this psbt needs to go to\n"
+ " \"error\" : \"error\" (string) Error message if there is one"
"}\n"
},
RPCExamples {
@@ -1723,7 +1724,7 @@ UniValue analyzepsbt(const JSONRPCRequest& request)
}
inputs_result.push_back(input_univ);
}
- result.pushKV("inputs", inputs_result);
+ if (!inputs_result.empty()) result.pushKV("inputs", inputs_result);
if (psbta.estimated_vsize != nullopt) {
result.pushKV("estimated_vsize", (int)*psbta.estimated_vsize);
@@ -1735,6 +1736,9 @@ UniValue analyzepsbt(const JSONRPCRequest& request)
result.pushKV("fee", ValueFromAmount(*psbta.fee));
}
result.pushKV("next", PSBTRoleName(psbta.next));
+ if (!psbta.error.empty()) {
+ result.pushKV("error", psbta.error);
+ }
return result;
}