Skip to content

Commit cb40b3a

Browse files
committed
Figure out what is missing during signing
When signing an input, figure out what was requested for but was unable to be found and store it in a SignatureData. Return this information in SignPSBTInput.
1 parent 08f749c commit cb40b3a

File tree

4 files changed

+34
-7
lines changed

4 files changed

+34
-7
lines changed

src/psbt.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,12 @@ void PSBTOutput::Merge(const PSBTOutput& output)
191191
if (redeem_script.empty() && !output.redeem_script.empty()) redeem_script = output.redeem_script;
192192
if (witness_script.empty() && !output.witness_script.empty()) witness_script = output.witness_script;
193193
}
194-
195194
bool PSBTInputSigned(PSBTInput& input)
196195
{
197196
return !input.final_script_sig.empty() || !input.final_script_witness.IsNull();
198197
}
199198

200-
bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, int sighash)
199+
bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, int sighash, SignatureData* out_sigdata, bool use_dummy)
201200
{
202201
PSBTInput& input = psbt.inputs.at(index);
203202
const CMutableTransaction& tx = *psbt.tx;
@@ -237,9 +236,14 @@ bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction&
237236
return false;
238237
}
239238

240-
MutableTransactionSignatureCreator creator(&tx, index, utxo.nValue, sighash);
241239
sigdata.witness = false;
242-
bool sig_complete = ProduceSignature(provider, creator, utxo.scriptPubKey, sigdata);
240+
bool sig_complete;
241+
if (use_dummy) {
242+
sig_complete = ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, utxo.scriptPubKey, sigdata);
243+
} else {
244+
MutableTransactionSignatureCreator creator(&tx, index, utxo.nValue, sighash);
245+
sig_complete = ProduceSignature(provider, creator, utxo.scriptPubKey, sigdata);
246+
}
243247
// Verify that a witness signature was produced in case one was required.
244248
if (require_witness_sig && !sigdata.witness) return false;
245249
input.FromSignatureData(sigdata);
@@ -250,6 +254,14 @@ bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction&
250254
input.non_witness_utxo = nullptr;
251255
}
252256

257+
// Fill in the missing info
258+
if (out_sigdata) {
259+
out_sigdata->missing_pubkeys = sigdata.missing_pubkeys;
260+
out_sigdata->missing_sigs = sigdata.missing_sigs;
261+
out_sigdata->missing_redeem_script = sigdata.missing_redeem_script;
262+
out_sigdata->missing_witness_script = sigdata.missing_witness_script;
263+
}
264+
253265
return sig_complete;
254266
}
255267

src/psbt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ struct PartiallySignedTransaction
544544
bool PSBTInputSigned(PSBTInput& input);
545545

546546
/** Signs a PSBTInput, verifying that all provided data matches what is being signed. */
547-
bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, int sighash = SIGHASH_ALL);
547+
bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, int sighash = SIGHASH_ALL, SignatureData* out_sigdata = nullptr, bool use_dummy = false);
548548

549549
/**
550550
* Finalizes a PSBT if possible, combining partial signatures.

src/script/sign.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ static bool CreateSig(const BaseSignatureCreator& creator, SignatureData& sigdat
8383
assert(i.second);
8484
return true;
8585
}
86+
// Could not make signature or signature not found, add keyid to missing
87+
sigdata.missing_sigs.push_back(keyid);
8688
return false;
8789
}
8890

@@ -116,17 +118,24 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
116118
case TX_PUBKEYHASH: {
117119
CKeyID keyID = CKeyID(uint160(vSolutions[0]));
118120
CPubKey pubkey;
119-
if (!GetPubKey(provider, sigdata, keyID, pubkey)) return false;
121+
if (!GetPubKey(provider, sigdata, keyID, pubkey)) {
122+
// Pubkey could not be found, add to missing
123+
sigdata.missing_pubkeys.push_back(keyID);
124+
return false;
125+
}
120126
if (!CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) return false;
121127
ret.push_back(std::move(sig));
122128
ret.push_back(ToByteVector(pubkey));
123129
return true;
124130
}
125131
case TX_SCRIPTHASH:
126-
if (GetCScript(provider, sigdata, uint160(vSolutions[0]), scriptRet)) {
132+
h160 = uint160(vSolutions[0]);
133+
if (GetCScript(provider, sigdata, h160, scriptRet)) {
127134
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
128135
return true;
129136
}
137+
// Could not find redeemScript, add to missing
138+
sigdata.missing_redeem_script = h160;
130139
return false;
131140

132141
case TX_MULTISIG: {
@@ -154,6 +163,8 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
154163
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
155164
return true;
156165
}
166+
// Could not find witnessScript, add to missing
167+
sigdata.missing_witness_script = uint256(vSolutions[0]);
157168
return false;
158169

159170
default:

src/script/sign.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ struct SignatureData {
117117
CScriptWitness scriptWitness; ///< The scriptWitness of an input. Contains complete signatures or the traditional partial signatures format. scriptWitness is part of a transaction input per BIP 144.
118118
std::map<CKeyID, SigPair> signatures; ///< BIP 174 style partial signatures for the input. May contain all signatures necessary for producing a final scriptSig or scriptWitness.
119119
std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>> misc_pubkeys;
120+
std::vector<CKeyID> missing_pubkeys; ///< KeyIDs of pubkeys which could not be found
121+
std::vector<CKeyID> missing_sigs; ///< KeyIDs of pubkeys for signatures which could not be found
122+
uint160 missing_redeem_script; ///< ScriptID of the missing redeemScript (if any)
123+
uint256 missing_witness_script; ///< SHA256 of the missing witnessScript (if any)
120124

121125
SignatureData() {}
122126
explicit SignatureData(const CScript& script) : scriptSig(script) {}

0 commit comments

Comments
 (0)