aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet.cpp
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2020-02-10 19:50:59 -0500
committerAndrew Chow <achow101-github@achow101.com>2020-03-09 11:16:20 -0400
commit82a30fade70a2a95c2bbeac4aa06dafda600479d (patch)
treecc02aef6e3e2821fde11a53a82469db51f5eb3cd /src/wallet/wallet.cpp
parent3d70dd99f9f74eef70b19ff6f6f850adc0d5ef8f (diff)
downloadbitcoin-82a30fade70a2a95c2bbeac4aa06dafda600479d.tar.xz
Move key and script filling and signing from CWallet::FillPSBT to ScriptPubKeyMan::FillPSBT
Instead of fetching a SigningProvider from ScriptPubKeyMan in order to fill and sign the keys and scripts for a PSBT, just pass that PSBT to a new FillPSBT function that does all that for us.
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r--src/wallet/wallet.cpp51
1 files changed, 34 insertions, 17 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 099a79ed64..de09e60014 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2481,7 +2481,6 @@ TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& comp
{
LOCK(cs_wallet);
// Get all of the previous transactions
- complete = true;
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
const CTxIn& txin = psbtx.tx->vin[i];
PSBTInput& input = psbtx.inputs.at(i);
@@ -2506,13 +2505,22 @@ TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& comp
input.non_witness_utxo = wtx.tx;
}
}
+ }
+
+ // Fill in information from ScriptPubKeyMans
+ // Because each ScriptPubKeyMan may be able to fill more than one input, we need to keep track of each ScriptPubKeyMan that has filled this psbt.
+ // Each iteration, we may fill more inputs than the input that is specified in that iteration.
+ // We assume that each input is filled by only one ScriptPubKeyMan
+ std::set<uint256> visited_spk_mans;
+ for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
+ const CTxIn& txin = psbtx.tx->vin[i];
+ PSBTInput& input = psbtx.inputs.at(i);
- // Get the Sighash type
- if (sign && input.sighash_type > 0 && input.sighash_type != sighash_type) {
- return TransactionError::SIGHASH_MISMATCH;
+ if (PSBTInputSigned(input)) {
+ continue;
}
- // Get the scriptPubKey to know which SigningProvider to use
+ // Get the scriptPubKey to know which ScriptPubKeyMan to use
CScript script;
if (!input.witness_utxo.IsNull()) {
script = input.witness_utxo.scriptPubKey;
@@ -2523,29 +2531,38 @@ TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& comp
script = input.non_witness_utxo->vout[txin.prevout.n].scriptPubKey;
} else {
// There's no UTXO so we can just skip this now
- complete = false;
continue;
}
SignatureData sigdata;
input.FillSignatureData(sigdata);
- std::unique_ptr<SigningProvider> provider = GetSigningProvider(script, sigdata);
- if (!provider) {
- complete = false;
+ std::set<ScriptPubKeyMan*> spk_mans = GetScriptPubKeyMans(script, sigdata);
+ if (spk_mans.size() == 0) {
continue;
}
- complete &= SignPSBTInput(HidingSigningProvider(provider.get(), !sign, !bip32derivs), psbtx, i, sighash_type);
- }
+ for (auto& spk_man : spk_mans) {
+ // If we've already been signed by this spk_man, skip it
+ if (visited_spk_mans.count(spk_man->GetID()) > 0) {
+ continue;
+ }
+
+ // Fill in the information from the spk_man
+ TransactionError res = spk_man->FillPSBT(psbtx, sighash_type, sign, bip32derivs);
+ if (res != TransactionError::OK) {
+ return res;
+ }
- // Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change
- for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
- const CTxOut& out = psbtx.tx->vout.at(i);
- std::unique_ptr<SigningProvider> provider = GetSigningProvider(out.scriptPubKey);
- if (provider) {
- UpdatePSBTOutput(HidingSigningProvider(provider.get(), true, !bip32derivs), psbtx, i);
+ // Add this spk_man to visited_spk_mans so we can skip it later
+ visited_spk_mans.insert(spk_man->GetID());
}
}
+ // Complete if every input is now signed
+ complete = true;
+ for (const auto& input : psbtx.inputs) {
+ complete &= PSBTInputSigned(input);
+ }
+
return TransactionError::OK;
}