aboutsummaryrefslogtreecommitdiff
path: root/src/psbt.cpp
diff options
context:
space:
mode:
authorGlenn Willen <gwillen@nerdnet.org>2019-01-09 03:08:32 -0800
committerGlenn Willen <gwillen@nerdnet.org>2019-02-11 14:08:04 -0800
commit102faad81efa1cb12c29c466cfe81fc8c7351e1d (patch)
tree7353c37cc34161eb350e41cac2f1a7e1e8b8ee23 /src/psbt.cpp
parent78b9893d020e8b1351565f1adbf591cb32f6dc90 (diff)
downloadbitcoin-102faad81efa1cb12c29c466cfe81fc8c7351e1d.tar.xz
Factor out combine / finalize / extract PSBT helpers
Refactor the new CombinePSBT, FinalizePSBT, and FinalizeAndExtractPSBT general-purpose functions out of the combinepsbt and finalizepsbt RPCs, for use in the GUI code.
Diffstat (limited to 'src/psbt.cpp')
-rw-r--r--src/psbt.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/psbt.cpp b/src/psbt.cpp
index 06032d6953..81633c0cc7 100644
--- a/src/psbt.cpp
+++ b/src/psbt.cpp
@@ -232,3 +232,52 @@ bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction&
return sig_complete;
}
+
+bool FinalizePSBT(PartiallySignedTransaction& psbtx)
+{
+ // Finalize input signatures -- in case we have partial signatures that add up to a complete
+ // signature, but have not combined them yet (e.g. because the combiner that created this
+ // PartiallySignedTransaction did not understand them), this will combine them into a final
+ // script.
+ bool complete = true;
+ for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
+ complete &= SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, SIGHASH_ALL);
+ }
+
+ return complete;
+}
+
+bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransaction& result)
+{
+ // It's not safe to extract a PSBT that isn't finalized, and there's no easy way to check
+ // whether a PSBT is finalized without finalizing it, so we just do this.
+ if (!FinalizePSBT(psbtx)) {
+ return false;
+ }
+
+ result = *psbtx.tx;
+ for (unsigned int i = 0; i < result.vin.size(); ++i) {
+ result.vin[i].scriptSig = psbtx.inputs[i].final_script_sig;
+ result.vin[i].scriptWitness = psbtx.inputs[i].final_script_witness;
+ }
+ return true;
+}
+
+bool CombinePSBTs(PartiallySignedTransaction& out, TransactionError& error, const std::vector<PartiallySignedTransaction>& psbtxs)
+{
+ out = psbtxs[0]; // Copy the first one
+
+ // Merge
+ for (auto it = std::next(psbtxs.begin()); it != psbtxs.end(); ++it) {
+ if (!out.Merge(*it)) {
+ error = TransactionError::PSBT_MISMATCH;
+ return false;
+ }
+ }
+ if (!out.IsSane()) {
+ error = TransactionError::INVALID_PSBT;
+ return false;
+ }
+
+ return true;
+}