aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Willen <gwillen@nerdnet.org>2019-01-29 22:51:56 -0800
committerGlenn Willen <gwillen@nerdnet.org>2019-02-11 14:08:04 -0800
commit78b9893d020e8b1351565f1adbf591cb32f6dc90 (patch)
tree599c5a1b8627fb1681b038d3b89aef07f3ea8663
parentbd0dbe8763fc3029cf96531c9ccaba280b939445 (diff)
Remove op== on PSBTs; check compatibility in Merge
Remove the op== on PartiallySignedTransaction, which only checks that the CTransactions are equal. Instead, check this directly in Merge, and return false if the CTransactions are not equal (so the PSBTs cannot be merged.)
-rw-r--r--src/psbt.cpp9
-rw-r--r--src/psbt.h15
-rw-r--r--src/rpc/rawtransaction.cpp3
3 files changed, 13 insertions, 14 deletions
diff --git a/src/psbt.cpp b/src/psbt.cpp
index 97fb39f1c8..06032d6953 100644
--- a/src/psbt.cpp
+++ b/src/psbt.cpp
@@ -16,8 +16,13 @@ bool PartiallySignedTransaction::IsNull() const
return !tx && inputs.empty() && outputs.empty() && unknown.empty();
}
-void PartiallySignedTransaction::Merge(const PartiallySignedTransaction& psbt)
+bool PartiallySignedTransaction::Merge(const PartiallySignedTransaction& psbt)
{
+ // Prohibited to merge two PSBTs over different transactions
+ if (tx->GetHash() != psbt.tx->GetHash()) {
+ return false;
+ }
+
for (unsigned int i = 0; i < inputs.size(); ++i) {
inputs[i].Merge(psbt.inputs[i]);
}
@@ -25,6 +30,8 @@ void PartiallySignedTransaction::Merge(const PartiallySignedTransaction& psbt)
outputs[i].Merge(psbt.outputs[i]);
}
unknown.insert(psbt.unknown.begin(), psbt.unknown.end());
+
+ return true;
}
bool PartiallySignedTransaction::IsSane() const
diff --git a/src/psbt.h b/src/psbt.h
index ad6f003015..4b7ea4383a 100644
--- a/src/psbt.h
+++ b/src/psbt.h
@@ -384,22 +384,15 @@ struct PartiallySignedTransaction
std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
bool IsNull() const;
- void Merge(const PartiallySignedTransaction& psbt);
+
+ /** Merge psbt into this. The two psbts must have the same underlying CTransaction (i.e. the
+ * same actual Bitcoin transaction.) Returns true if the merge succeeded, false otherwise. */
+ NODISCARD bool Merge(const PartiallySignedTransaction& psbt);
bool IsSane() const;
PartiallySignedTransaction() {}
PartiallySignedTransaction(const PartiallySignedTransaction& psbt_in) : tx(psbt_in.tx), inputs(psbt_in.inputs), outputs(psbt_in.outputs), unknown(psbt_in.unknown) {}
explicit PartiallySignedTransaction(const CMutableTransaction& tx);
- // Only checks if they refer to the same transaction
- friend bool operator==(const PartiallySignedTransaction& a, const PartiallySignedTransaction &b)
- {
- return a.tx->GetHash() == b.tx->GetHash();
- }
- friend bool operator!=(const PartiallySignedTransaction& a, const PartiallySignedTransaction &b)
- {
- return !(a == b);
- }
-
template <typename Stream>
inline void Serialize(Stream& s) const {
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index bc836614ae..4205a3d10f 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -1481,10 +1481,9 @@ UniValue combinepsbt(const JSONRPCRequest& request)
// Merge
for (auto it = std::next(psbtxs.begin()); it != psbtxs.end(); ++it) {
- if (*it != merged_psbt) {
+ if (!merged_psbt.Merge(*it)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "PSBTs do not refer to the same transactions.");
}
- merged_psbt.Merge(*it);
}
if (!merged_psbt.IsSane()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Merged PSBT is inconsistent");