Skip to content

Commit bedd3be

Browse files
kwvggades
authored andcommitted
partial bitcoin#13932: Additional utility RPCs for PSBT
1 parent 9349817 commit bedd3be

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

src/script/sign.cpp

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

@@ -120,17 +122,24 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
120122
case TX_PUBKEYHASH: {
121123
CKeyID keyID = CKeyID(uint160(vSolutions[0]));
122124
CPubKey pubkey;
123-
if (!GetPubKey(provider, sigdata, keyID, pubkey)) return false;
125+
if (!GetPubKey(provider, sigdata, keyID, pubkey)) {
126+
// Pubkey could not be found, add to missing
127+
sigdata.missing_pubkeys.push_back(keyID);
128+
return false;
129+
}
124130
if (!CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) return false;
125131
ret.push_back(std::move(sig));
126132
ret.push_back(ToByteVector(pubkey));
127133
return true;
128134
}
129135
case TX_SCRIPTHASH:
130-
if (GetCScript(provider, sigdata, uint160(vSolutions[0]), scriptRet)) {
136+
h160 = uint160(vSolutions[0]);
137+
if (GetCScript(provider, sigdata, h160, scriptRet)) {
131138
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
132139
return true;
133140
}
141+
// Could not find redeemScript, add to missing
142+
sigdata.missing_redeem_script = h160;
134143
return false;
135144

136145
case TX_MULTISIG: {
@@ -453,6 +462,37 @@ bool PartiallySignedTransaction::IsSane() const
453462
return true;
454463
}
455464

465+
bool PartiallySignedTransaction::AddInput(const CTxIn& txin, PSBTInput& psbtin)
466+
{
467+
if (std::find(tx->vin.begin(), tx->vin.end(), txin) != tx->vin.end()) {
468+
return false;
469+
}
470+
tx->vin.push_back(txin);
471+
psbtin.partial_sigs.clear();
472+
psbtin.final_script_sig.clear();
473+
inputs.push_back(psbtin);
474+
return true;
475+
}
476+
477+
bool PartiallySignedTransaction::AddOutput(const CTxOut& txout, const PSBTOutput& psbtout)
478+
{
479+
tx->vout.push_back(txout);
480+
outputs.push_back(psbtout);
481+
return true;
482+
}
483+
484+
bool PartiallySignedTransaction::GetInputUTXO(CTxOut& utxo, int input_index) const
485+
{
486+
PSBTInput input = inputs[input_index];
487+
int prevout_index = tx->vin[input_index].prevout.n;
488+
if (input.non_witness_utxo) {
489+
utxo = input.non_witness_utxo->vout[prevout_index];
490+
} else {
491+
return false;
492+
}
493+
return true;
494+
}
495+
456496
bool PSBTInput::IsNull() const
457497
{
458498
return !non_witness_utxo && partial_sigs.empty() && unknown.empty() && hd_keypaths.empty() && redeem_script.empty();

src/script/sign.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ struct SignatureData {
108108
CScript redeem_script; ///< The redeemScript (if any) for the input
109109
std::map<CKeyID, SigPair> signatures; ///< BIP 174 style partial signatures for the input. May contain all signatures necessary for producing a final scriptSig.
110110
std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>> misc_pubkeys;
111+
std::vector<CKeyID> missing_pubkeys; ///< KeyIDs of pubkeys which could not be found
112+
std::vector<CKeyID> missing_sigs; ///< KeyIDs of pubkeys for signatures which could not be found
113+
uint160 missing_redeem_script; ///< ScriptID of the missing redeemScript (if any)
111114

112115
SignatureData() {}
113116
explicit SignatureData(const CScript& script) : scriptSig(script) {}
@@ -474,6 +477,8 @@ struct PartiallySignedTransaction
474477
bool IsNull() const;
475478
void Merge(const PartiallySignedTransaction& psbt);
476479
bool IsSane() const;
480+
bool AddInput(const CTxIn& txin, PSBTInput& psbtin);
481+
bool AddOutput(const CTxOut& txout, const PSBTOutput& psbtout);
477482
PartiallySignedTransaction() {}
478483
PartiallySignedTransaction(const PartiallySignedTransaction& psbt_in) : tx(psbt_in.tx), inputs(psbt_in.inputs), outputs(psbt_in.outputs), unknown(psbt_in.unknown) {}
479484

@@ -487,6 +492,15 @@ struct PartiallySignedTransaction
487492
return !(a == b);
488493
}
489494

495+
/**
496+
* Finds the UTXO for a given input index
497+
*
498+
* @param[out] utxo The UTXO of the input if found
499+
* @param[in] input_index Index of the input to retrieve the UTXO of
500+
* @return Whether the UTXO for the specified input was found
501+
*/
502+
bool GetInputUTXO(CTxOut& utxo, int input_index) const;
503+
490504
template <typename Stream>
491505
inline void Serialize(Stream& s) const {
492506

0 commit comments

Comments
 (0)