From 9aacb38cf0819e875d661e8bf16b5d443e181937 Mon Sep 17 00:00:00 2001 From: furszy Date: Sun, 28 Jun 2020 21:38:19 -0300 Subject: [PATCH] Prevent multiple calls to CWallet::AvailableCoins Coming from btc@bb16c8894becfba8764b13d448ba6e7e7f1608c2 Github-Pull: #1717 Rebased-From: 49f4124f9657a66946bee166332c8d5d3fd8db9e --- src/wallet/wallet.cpp | 24 +++++++++++++----------- src/wallet/wallet.h | 2 +- src/wallet/wallet_zerocoin.cpp | 6 +++++- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b90ea3d5c3a34..2356cc240d404 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2311,18 +2311,10 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int return true; } -bool CWallet::SelectCoinsToSpend(const CAmount& nTargetValue, std::set >& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl, AvailableCoinsType coin_type, bool useIX, bool fIncludeColdStaking, bool fIncludeDelegated) const +bool CWallet::SelectCoinsToSpend(const std::vector& vAvailableCoins, const CAmount& nTargetValue, std::set >& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl) const { // Note: this function should never be used for "always free" tx types like dstx - std::vector vCoins; - AvailableCoins(&vCoins, - coinControl, - fIncludeDelegated, - fIncludeColdStaking, - coin_type, - true, // fOnlyConfirmed - false, // fIncludeZeroValue - useIX); + std::vector vCoins(vAvailableCoins); // coin control -> return all selected outputs (we want all selected to go into the transaction for sure) if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs) { @@ -2507,6 +2499,16 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, { LOCK2(cs_main, cs_wallet); { + std::vector vAvailableCoins; + AvailableCoins(&vAvailableCoins, + coinControl, + fIncludeDelegated, + false, // fIncludeColdStaking + coin_type, + true, // fOnlyConfirmed + false, // fIncludeZeroValue + useIX); + nFeeRet = 0; if (nFeePay > 0) nFeeRet = nFeePay; while (true) { @@ -2552,7 +2554,7 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, std::set > setCoins; CAmount nValueIn = 0; - if (!SelectCoinsToSpend(nTotalValue, setCoins, nValueIn, coinControl, coin_type, useIX, false, fIncludeDelegated)) { + if (!SelectCoinsToSpend(vAvailableCoins, nTotalValue, setCoins, nValueIn, coinControl)) { if (coin_type == ALL_COINS) { strFailReason = _("Insufficient funds."); } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index c43b6189174ef..6b13877ca761b 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -355,7 +355,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface int nWatchonlyConfig = 1 ) const; //! >> Available coins (spending) - bool SelectCoinsToSpend(const CAmount& nTargetValue, std::set >& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl = nullptr, AvailableCoinsType coin_type = ALL_COINS, bool useIX = true, bool fIncludeColdStaking = false, bool fIncludeDelegated = true) const; + bool SelectCoinsToSpend(const std::vector& vAvailableCoins, const CAmount& nTargetValue, std::set >& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl = nullptr) const; bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, CAmount& nValueRet) const; //! >> Available coins (staking) bool StakeableCoins(std::vector* pCoins = nullptr); diff --git a/src/wallet/wallet_zerocoin.cpp b/src/wallet/wallet_zerocoin.cpp index fa006d154500a..0b968f32d5099 100644 --- a/src/wallet/wallet_zerocoin.cpp +++ b/src/wallet/wallet_zerocoin.cpp @@ -302,10 +302,14 @@ bool CWallet::CreateZerocoinMintTransaction(const CAmount nValue, // calculate fee CAmount nTotalValue = nValue + Params().GetConsensus().ZC_MinMintFee * txNew.vout.size(); + // Get the available coins + std::vector vAvailableCoins; + AvailableCoins(&vAvailableCoins, coinControl); + CAmount nValueIn = 0; std::set > setCoins; // select UTXO's to use - if (!SelectCoinsToSpend(nTotalValue, setCoins, nValueIn, coinControl)) { + if (!SelectCoinsToSpend(vAvailableCoins, nTotalValue, setCoins, nValueIn, coinControl)) { strFailReason = _("Insufficient or insufficient confirmed funds, you might need to wait a few minutes and try again."); return false; }