diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp index 16d206bb85..6f3d7d2952 100644 --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -438,11 +438,11 @@ class WalletImpl : public Wallet LOCK(m_wallet->cs_wallet); return m_wallet->GetDebit(txin, filter); } - CAmountMap getCredit(const CTxOut& txout, isminefilter filter) override + CAmountMap getCredit(const CTransaction& tx, const size_t out_index, isminefilter filter) override { auto locked_chain = m_wallet->chain().lock(); LOCK(m_wallet->cs_wallet); - return m_wallet->GetCredit(txout, filter); + return m_wallet->GetCredit(tx, out_index, filter); } CoinsList listCoins() override { diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index 6e192dfeb6..edcad2b479 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -215,7 +215,7 @@ class Wallet virtual CAmountMap getDebit(const CTxIn& txin, isminefilter filter) = 0; //! Return credit amount if transaction input belongs to wallet. - virtual CAmountMap getCredit(const CTxOut& txout, isminefilter filter) = 0; + virtual CAmountMap getCredit(const CTransaction& tx, const size_t out_index, isminefilter filter) = 0; //! Return AvailableCoins + LockedCoins grouped by wallet address. //! (put change in one group with wallet address) diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 6457f00658..d59f042de5 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -136,8 +136,8 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall // Coinbase // CAmount nUnmatured = 0; - for (const CTxOut& txout : wtx.tx->vout) - nUnmatured += valueFor(wallet.getCredit(txout, ISMINE_ALL), ::policyAsset); + for (size_t nOut = 0; nOut < wtx.tx->vout.size(); nOut++) + nUnmatured += valueFor(wallet.getCredit(*(wtx.tx), nOut, ISMINE_ALL), ::policyAsset); strHTML += "" + tr("Credit") + ": "; if (status.is_in_main_chain) strHTML += BitcoinUnits::formatHtmlWithUnit(unit, nUnmatured)+ " (" + tr("matures in %n more block(s)", "", status.blocks_to_maturity) + ")"; @@ -233,9 +233,9 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall } } mine = wtx.txout_is_mine.begin(); - for (const CTxOut& txout : wtx.tx->vout) { + for (size_t nOut = 0; nOut < wtx.tx->vout.size(); nOut++) { if (*(mine++)) { - strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, valueFor(wallet.getCredit(txout, ISMINE_ALL), ::policyAsset)) + "
"; + strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, valueFor(wallet.getCredit(*(wtx.tx), nOut, ISMINE_ALL), ::policyAsset)) + "
"; } } } @@ -293,9 +293,12 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall for (const CTxIn& txin : wtx.tx->vin) if(wallet.txinIsMine(txin)) strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, -valueFor(wallet.getDebit(txin, ISMINE_ALL), ::policyAsset)) + "
"; - for (const CTxOut& txout : wtx.tx->vout) - if(wallet.txoutIsMine(txout)) - strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, valueFor(wallet.getCredit(txout, ISMINE_ALL), ::policyAsset)) + "
"; + for (size_t nOut = 0; nOut < wtx.tx->vout.size(); nOut++) { + const CTxOut& txout = wtx.tx->vout[nOut]; + if(wallet.txoutIsMine(txout)) { + strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, valueFor(wallet.getCredit(*(wtx.tx), nOut, ISMINE_ALL), ::policyAsset)) + "
"; + } + } strHTML += "
" + tr("Transaction") + ":
"; strHTML += GUIUtil::HtmlEscape(wtx.tx->ToString(), true); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e494e080c6..f988d3034e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1346,19 +1346,22 @@ isminetype CWallet::IsMine(const CTxOut& txout) const return ::IsMine(*this, txout.scriptPubKey); } -CAmountMap CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const +CAmountMap CWallet::GetCredit(const CTransaction& tx, const size_t out_index, const isminefilter& filter) const { - assert(false && "CWallet::GetCredit(const CTxOut&, const isminefilter&): this method should not be used anymore"); - - CAmountMap credit; - if (txout.nAsset.IsExplicit() && txout.nValue.IsExplicit()) { - credit[txout.nAsset.GetAsset()] = txout.nValue.GetAmount(); - } else { - WalletLogPrintf("WARNING: Calculating credit of blinded transaction.\n"); + { + LOCK(cs_wallet); + std::map::const_iterator mi = mapWallet.find(tx.GetHash()); + if (mi != mapWallet.end()) + { + const CWalletTx& wtx = (*mi).second; + if (out_index < wtx.tx->vout.size() && IsMine(wtx.tx->vout[out_index]) & filter) { + CAmountMap amounts; + amounts[wtx.GetOutputAsset(out_index)] = std::max(0, wtx.GetOutputValueOut(out_index)); + return amounts; + } + } } - if (!MoneyRange(credit)) - throw std::runtime_error(std::string(__func__) + ": value out of range"); - return ((IsMine(txout) & filter) ? credit : CAmountMap()); + return CAmountMap(); } bool CWallet::IsChange(const CTxOut& txout) const @@ -1459,20 +1462,6 @@ CAmountMap CWallet::GetCredit(const CWalletTx& wtx, const isminefilter& filter) return nCredit; } -CAmountMap CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const -{ - assert(false && "CWallet::GetCredit(const CTransaction&, const isminefilter&): this method should not be used anymore"); - - CAmountMap nCredit; - for (const CTxOut& txout : tx.vout) - { - nCredit += GetCredit(txout, filter); - if (!MoneyRange(nCredit)) - throw std::runtime_error(std::string(__func__) + ": value out of range"); - } - return nCredit; -} - CAmountMap CWallet::GetChange(const CWalletTx& wtx) const { CAmountMap nChange; for (unsigned int i = 0; i < wtx.tx->vout.size(); ++i) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 2c8e65bd4d..7fa912b20d 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1149,7 +1149,7 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface */ CAmountMap GetDebit(const CTxIn& txin, const isminefilter& filter) const; isminetype IsMine(const CTxOut& txout) const; - CAmountMap GetCredit(const CTxOut& txout, const isminefilter& filter) const; + CAmountMap GetCredit(const CTransaction& tx, const size_t out_index, const isminefilter& filter) const; bool IsChange(const CTxOut& txout) const; bool IsChange(const CScript& script) const; CAmountMap GetChange(const CTxOut& txout) const; @@ -1159,7 +1159,6 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface CAmountMap GetDebit(const CTransaction& tx, const isminefilter& filter) const; /** Returns whether all of the inputs match the filter */ bool IsAllFromMe(const CTransaction& tx, const isminefilter& filter) const; - CAmountMap GetCredit(const CTransaction& tx, const isminefilter& filter) const; CAmountMap GetChange(const CTransaction& tx) const; // ELEMENTS: