diff options
author | Andrew Chow <achow101-github@achow101.com> | 2020-02-10 19:50:59 -0500 |
---|---|---|
committer | Andrew Chow <achow101-github@achow101.com> | 2020-03-09 11:16:20 -0400 |
commit | 82a30fade70a2a95c2bbeac4aa06dafda600479d (patch) | |
tree | cc02aef6e3e2821fde11a53a82469db51f5eb3cd /src/wallet/wallet.cpp | |
parent | 3d70dd99f9f74eef70b19ff6f6f850adc0d5ef8f (diff) |
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.cpp | 51 |
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; } |