diff options
author | Andrew Chow <achow101-github@achow101.com> | 2020-08-16 21:35:23 -0400 |
---|---|---|
committer | Andrew Chow <achow101-github@achow101.com> | 2020-08-16 21:37:27 -0400 |
commit | 2d48d7dcfb93eeec36dd6f5cbad289b89ec69324 (patch) | |
tree | b684167b052b8da1dbd90d6d15b057d72ce65ddd /src | |
parent | bf0dc356ac4a2bdeda1908af021dea2de0dfb35a (diff) |
Simplify and fix CWallet::SignTransaction
Backport CWallet::SignTransaction from master which is simpler and not
broken.
Diffstat (limited to 'src')
-rw-r--r-- | src/wallet/wallet.cpp | 50 |
1 files changed, 8 insertions, 42 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index af3f958349..bd2b0145b8 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2474,50 +2474,16 @@ bool CWallet::SignTransaction(CMutableTransaction& tx) const bool CWallet::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const { - // Sign the tx with ScriptPubKeyMans - // Because each ScriptPubKeyMan can sign more than one input, we need to keep track of each ScriptPubKeyMan that has signed this transaction. - // Each iteration, we may sign more txins than the txin that is specified in that iteration. - // We assume that each input is signed by only one ScriptPubKeyMan. - std::set<uint256> visited_spk_mans; - for (unsigned int i = 0; i < tx.vin.size(); i++) { - // Get the prevout - CTxIn& txin = tx.vin[i]; - auto coin = coins.find(txin.prevout); - if (coin == coins.end() || coin->second.IsSpent()) { - input_errors[i] = "Input not found or already spent"; - continue; - } - - // Check if this input is complete - SignatureData sigdata = DataFromTransaction(tx, i, coin->second.out); - if (sigdata.complete) { - continue; - } - - // Input needs to be signed, find the right ScriptPubKeyMan - std::set<ScriptPubKeyMan*> spk_mans = GetScriptPubKeyMans(coin->second.out.scriptPubKey, sigdata); - if (spk_mans.size() == 0) { - input_errors[i] = "Unable to sign input, missing keys"; - continue; - } - - 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; - } - - // Sign the tx. - // spk_man->SignTransaction will return true if the transaction is complete, - // so we can exit early and return true if that happens. - if (spk_man->SignTransaction(tx, coins, sighash, input_errors)) { - return true; - } - - // Add this spk_man to visited_spk_mans so we can skip it later - visited_spk_mans.insert(spk_man->GetID()); + // Try to sign with all ScriptPubKeyMans + for (ScriptPubKeyMan* spk_man : GetAllScriptPubKeyMans()) { + // spk_man->SignTransaction will return true if the transaction is complete, + // so we can exit early and return true if that happens + if (spk_man->SignTransaction(tx, coins, sighash, input_errors)) { + return true; } } + + // At this point, one input was not fully signed otherwise we would have exited already return false; } |