aboutsummaryrefslogtreecommitdiff
path: root/src/script/sign.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/sign.cpp')
-rw-r--r--src/script/sign.cpp44
1 files changed, 34 insertions, 10 deletions
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index 1ab5051ff7..f97d6a2533 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -233,10 +233,17 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
return sigdata.complete;
}
-bool SignPSBTInput(const SigningProvider& provider, const CMutableTransaction& tx, PSBTInput& input, SignatureData& sigdata, int index, int sighash)
+bool PSBTInputSigned(PSBTInput& input)
{
- // if this input has a final scriptsig or scriptwitness, don't do anything with it
- if (!input.final_script_sig.empty() || !input.final_script_witness.IsNull()) {
+ return !input.final_script_sig.empty() || !input.final_script_witness.IsNull();
+}
+
+bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, SignatureData& sigdata, int index, int sighash)
+{
+ PSBTInput& input = psbt.inputs.at(index);
+ const CMutableTransaction& tx = *psbt.tx;
+
+ if (PSBTInputSigned(input)) {
return true;
}
@@ -246,15 +253,19 @@ bool SignPSBTInput(const SigningProvider& provider, const CMutableTransaction& t
// Get UTXO
bool require_witness_sig = false;
CTxOut utxo;
+
+ // Verify input sanity, which checks that at most one of witness or non-witness utxos is provided.
+ if (!input.IsSane()) {
+ return false;
+ }
+
if (input.non_witness_utxo) {
// If we're taking our information from a non-witness UTXO, verify that it matches the prevout.
- if (input.non_witness_utxo->GetHash() != tx.vin[index].prevout.hash) return false;
- // If both witness and non-witness UTXO are provided, verify that they match. This check shouldn't
- // matter, as the PSBT deserializer enforces only one of both is provided, and the only way both
- // can be present is when they're added simultaneously by FillPSBT (in which case they always match).
- // Still, check in order to not rely on callers to enforce this.
- if (!input.witness_utxo.IsNull() && input.non_witness_utxo->vout[tx.vin[index].prevout.n] != input.witness_utxo) return false;
- utxo = input.non_witness_utxo->vout[tx.vin[index].prevout.n];
+ COutPoint prevout = tx.vin[index].prevout;
+ if (input.non_witness_utxo->GetHash() != prevout.hash) {
+ return false;
+ }
+ utxo = input.non_witness_utxo->vout[prevout.n];
} else if (!input.witness_utxo.IsNull()) {
utxo = input.witness_utxo;
// When we're taking our information from a witness UTXO, we can't verify it is actually data from
@@ -272,6 +283,13 @@ bool SignPSBTInput(const SigningProvider& provider, const CMutableTransaction& t
// Verify that a witness signature was produced in case one was required.
if (require_witness_sig && !sigdata.witness) return false;
input.FromSignatureData(sigdata);
+
+ // If we have a witness signature, use the smaller witness UTXO.
+ if (sigdata.witness) {
+ input.witness_utxo = utxo;
+ input.non_witness_utxo = nullptr;
+ }
+
return sig_complete;
}
@@ -491,6 +509,12 @@ bool IsSolvable(const SigningProvider& provider, const CScript& script)
return false;
}
+PartiallySignedTransaction::PartiallySignedTransaction(const CTransaction& tx) : tx(tx)
+{
+ inputs.resize(tx.vin.size());
+ outputs.resize(tx.vout.size());
+}
+
bool PartiallySignedTransaction::IsNull() const
{
return !tx && inputs.empty() && outputs.empty() && unknown.empty();