diff --git a/src/bench/wallet_ismine.cpp b/src/bench/wallet_ismine.cpp index 30c73eaaadf..6eef1efd992 100644 --- a/src/bench/wallet_ismine.cpp +++ b/src/bench/wallet_ismine.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -58,8 +57,8 @@ static void WalletIsMine(benchmark::Bench& bench, int num_combo = 0) bench.run([&] { LOCK(wallet->cs_wallet); - isminetype mine = wallet->IsMine(script); - assert(mine == ISMINE_NO); + bool mine = wallet->IsMine(script); + assert(!mine); }); TestUnloadWallet(std::move(wallet)); diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index 0b74c219763..2ccd514dbf0 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -43,10 +43,8 @@ namespace wallet { class CCoinControl; class CWallet; enum class AddressPurpose; -enum isminetype : unsigned int; struct CRecipient; struct WalletContext; -using isminefilter = std::underlying_type_t; } // namespace wallet namespace interfaces { @@ -224,16 +222,16 @@ public: virtual CAmount getAvailableBalance(const wallet::CCoinControl& coin_control) = 0; //! Return whether transaction input belongs to wallet. - virtual wallet::isminetype txinIsMine(const CTxIn& txin) = 0; + virtual bool txinIsMine(const CTxIn& txin) = 0; //! Return whether transaction output belongs to wallet. - virtual wallet::isminetype txoutIsMine(const CTxOut& txout) = 0; + virtual bool txoutIsMine(const CTxOut& txout) = 0; //! Return debit amount if transaction input belongs to wallet. - virtual CAmount getDebit(const CTxIn& txin, wallet::isminefilter filter) = 0; + virtual CAmount getDebit(const CTxIn& txin) = 0; //! Return credit amount if transaction input belongs to wallet. - virtual CAmount getCredit(const CTxOut& txout, wallet::isminefilter filter) = 0; + virtual CAmount getCredit(const CTxOut& txout) = 0; //! Return AvailableCoins + LockedCoins grouped by wallet address. //! (put change in one group with wallet address) @@ -355,11 +353,11 @@ public: struct WalletAddress { CTxDestination dest; - wallet::isminetype is_mine; + bool is_mine; wallet::AddressPurpose purpose; std::string name; - WalletAddress(CTxDestination dest, wallet::isminetype is_mine, wallet::AddressPurpose purpose, std::string name) + WalletAddress(CTxDestination dest, bool is_mine, wallet::AddressPurpose purpose, std::string name) : dest(std::move(dest)), is_mine(is_mine), purpose(std::move(purpose)), name(std::move(name)) { } @@ -383,11 +381,11 @@ struct WalletBalances struct WalletTx { CTransactionRef tx; - std::vector txin_is_mine; - std::vector txout_is_mine; + std::vector txin_is_mine; + std::vector txout_is_mine; std::vector txout_is_change; std::vector txout_address; - std::vector txout_address_is_mine; + std::vector txout_address_is_mine; CAmount credit; CAmount debit; CAmount change; diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index af301a498f7..93d31ee6054 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -17,17 +17,12 @@ #include #include #include -#include #include #include #include -using wallet::ISMINE_ALL; -using wallet::ISMINE_SPENDABLE; -using wallet::isminetype; - QString TransactionDesc::FormatTxStatus(const interfaces::WalletTxStatus& status, bool inMempool) { int depth = status.depth_in_main_chain; @@ -185,7 +180,7 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall // CAmount nUnmatured = 0; for (const CTxOut& txout : wtx.tx->vout) - nUnmatured += wallet.getCredit(txout, ISMINE_ALL); + nUnmatured += wallet.getCredit(txout); 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) + ")"; @@ -202,19 +197,10 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall } else { - isminetype fAllFromMe = ISMINE_SPENDABLE; - for (const isminetype mine : wtx.txin_is_mine) - { - if(fAllFromMe > mine) fAllFromMe = mine; - } + bool all_from_me = std::all_of(wtx.txin_is_mine.begin(), wtx.txin_is_mine.end(), [](bool mine) { return mine; }); + bool all_to_me = std::all_of(wtx.txout_is_mine.begin(), wtx.txout_is_mine.end(), [](bool mine) { return mine; }); - isminetype fAllToMe = ISMINE_SPENDABLE; - for (const isminetype mine : wtx.txout_is_mine) - { - if(fAllToMe > mine) fAllToMe = mine; - } - - if (fAllFromMe) + if (all_from_me) { // Debit // @@ -222,8 +208,8 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall for (const CTxOut& txout : wtx.tx->vout) { // Ignore change - isminetype toSelf = *(mine++); - if ((toSelf == ISMINE_SPENDABLE) && (fAllFromMe == ISMINE_SPENDABLE)) + bool toSelf = *(mine++); + if (toSelf && all_from_me) continue; if (!wtx.value_map.count("to") || wtx.value_map["to"].empty()) @@ -238,7 +224,7 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall address, &name, /*purpose=*/nullptr) && !name.empty()) strHTML += GUIUtil::HtmlEscape(name) + " "; strHTML += GUIUtil::HtmlEscape(EncodeDestination(address)); - if(toSelf == ISMINE_SPENDABLE) + if(toSelf) strHTML += " (" + tr("own address") + ")"; strHTML += "
"; } @@ -249,7 +235,7 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, txout.nValue) + "
"; } - if (fAllToMe) + if (all_to_me) { // Payment to self CAmount nChange = wtx.change; @@ -270,13 +256,13 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall auto mine = wtx.txin_is_mine.begin(); for (const CTxIn& txin : wtx.tx->vin) { if (*(mine++)) { - strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, -wallet.getDebit(txin, ISMINE_ALL)) + "
"; + strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, -wallet.getDebit(txin)) + "
"; } } mine = wtx.txout_is_mine.begin(); for (const CTxOut& txout : wtx.tx->vout) { if (*(mine++)) { - strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, wallet.getCredit(txout, ISMINE_ALL)) + "
"; + strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, wallet.getCredit(txout)) + "
"; } } } @@ -333,10 +319,10 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall strHTML += "

" + tr("Debug information") + "

"; for (const CTxIn& txin : wtx.tx->vin) if(wallet.txinIsMine(txin)) - strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, -wallet.getDebit(txin, ISMINE_ALL)) + "
"; + strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, -wallet.getDebit(txin)) + "
"; for (const CTxOut& txout : wtx.tx->vout) if(wallet.txoutIsMine(txout)) - strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, wallet.getCredit(txout, ISMINE_ALL)) + "
"; + strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, wallet.getCredit(txout)) + "
"; strHTML += "
" + tr("Transaction") + ":
"; strHTML += GUIUtil::HtmlEscape(wtx.tx->ToString(), true); @@ -361,7 +347,7 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall strHTML += QString::fromStdString(EncodeDestination(address)); } strHTML = strHTML + " " + tr("Amount") + "=" + BitcoinUnits::formatHtmlWithUnit(unit, vout.nValue); - strHTML = strHTML + " IsMine=" + (wallet.txoutIsMine(vout) & ISMINE_SPENDABLE ? tr("true") : tr("false")) + ""; + strHTML = strHTML + " IsMine=" + (wallet.txoutIsMine(vout) ? tr("true") : tr("false")) + ""; } } } diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 4325c7f1582..1143bc35610 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -7,16 +7,11 @@ #include #include #include -#include #include #include -using wallet::ISMINE_NO; -using wallet::ISMINE_SPENDABLE; -using wallet::isminetype; - /* Return positive answer if transaction should be shown in list. */ bool TransactionRecord::showTransaction() @@ -39,26 +34,26 @@ QList TransactionRecord::decomposeTransaction(const interface Txid hash = wtx.tx->GetHash(); std::map mapValue = wtx.value_map; - isminetype fAllFromMe = ISMINE_SPENDABLE; + bool all_from_me = true; bool any_from_me = false; if (wtx.is_coinbase) { - fAllFromMe = ISMINE_NO; + all_from_me = false; } else { - for (const isminetype mine : wtx.txin_is_mine) + for (const bool mine : wtx.txin_is_mine) { - if(fAllFromMe > mine) fAllFromMe = mine; + all_from_me = all_from_me && mine; if (mine) any_from_me = true; } } - if (fAllFromMe || !any_from_me) { + if (all_from_me || !any_from_me) { CAmount nTxFee = nDebit - wtx.tx->GetValueOut(); for(unsigned int i = 0; i < wtx.tx->vout.size(); i++) { const CTxOut& txout = wtx.tx->vout[i]; - if (fAllFromMe) { + if (all_from_me) { // Change is only really possible if we're the sender // Otherwise, someone just sent bitcoins to a change address, which should be shown if (wtx.txout_is_change[i]) { @@ -97,7 +92,7 @@ QList TransactionRecord::decomposeTransaction(const interface parts.append(sub); } - isminetype mine = wtx.txout_is_mine[i]; + bool mine = wtx.txout_is_mine[i]; if(mine) { // diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp index 0b56a232515..d55c4cfe3bb 100644 --- a/src/wallet/feebumper.cpp +++ b/src/wallet/feebumper.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -48,8 +47,7 @@ static feebumper::Result PreconditionChecks(const CWallet& wallet, const CWallet if (require_mine) { // check that original tx consists entirely of our inputs // if not, we can't bump the fee, because the wallet has no way of knowing the value of the other inputs (thus the fee) - isminefilter filter = ISMINE_SPENDABLE; - if (!AllInputsMine(wallet, *wtx.tx, filter)) { + if (!AllInputsMine(wallet, *wtx.tx)) { errors.emplace_back(Untranslated("Transaction contains inputs that don't belong to this wallet")); return feebumper::Result::WALLET_ERROR; } diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp index 07500cc088e..4dc873347ff 100644 --- a/src/wallet/interfaces.cpp +++ b/src/wallet/interfaces.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -74,10 +73,10 @@ WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx) result.txout_address.emplace_back(); result.txout_address_is_mine.emplace_back(ExtractDestination(txout.scriptPubKey, result.txout_address.back()) ? wallet.IsMine(result.txout_address.back()) : - ISMINE_NO); + false); } - result.credit = CachedTxGetCredit(wallet, wtx, ISMINE_ALL, /*avoid_reuse=*/true); - result.debit = CachedTxGetDebit(wallet, wtx, ISMINE_ALL, /*avoid_reuse=*/true); + result.credit = CachedTxGetCredit(wallet, wtx, /*avoid_reuse=*/true); + result.debit = CachedTxGetDebit(wallet, wtx, /*avoid_reuse=*/true); result.change = CachedTxGetChange(wallet, wtx); result.time = wtx.GetTxTime(); result.value_map = wtx.mapValue; @@ -173,7 +172,7 @@ public: bool isSpendable(const CTxDestination& dest) override { LOCK(m_wallet->cs_wallet); - return m_wallet->IsMine(dest) & ISMINE_SPENDABLE; + return m_wallet->IsMine(dest); } bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::optional& purpose) override { @@ -205,7 +204,7 @@ public: std::vector result; m_wallet->ForEachAddrBookEntry([&](const CTxDestination& dest, const std::string& label, bool is_change, const std::optional& purpose) EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet) { if (is_change) return; - isminetype is_mine = m_wallet->IsMine(dest); + bool is_mine = m_wallet->IsMine(dest); // In very old wallets, address purpose may not be recorded so we derive it from IsMine result.emplace_back(dest, is_mine, purpose.value_or(is_mine ? AddressPurpose::RECEIVE : AddressPurpose::SEND), label); }); @@ -423,25 +422,25 @@ public: return total_amount; } - isminetype txinIsMine(const CTxIn& txin) override + bool txinIsMine(const CTxIn& txin) override { LOCK(m_wallet->cs_wallet); return InputIsMine(*m_wallet, txin); } - isminetype txoutIsMine(const CTxOut& txout) override + bool txoutIsMine(const CTxOut& txout) override { LOCK(m_wallet->cs_wallet); return m_wallet->IsMine(txout); } - CAmount getDebit(const CTxIn& txin, isminefilter filter) override + CAmount getDebit(const CTxIn& txin) override { LOCK(m_wallet->cs_wallet); - return m_wallet->GetDebit(txin, filter); + return m_wallet->GetDebit(txin); } - CAmount getCredit(const CTxOut& txout, isminefilter filter) override + CAmount getCredit(const CTxOut& txout) override { LOCK(m_wallet->cs_wallet); - return OutputGetCredit(*m_wallet, txout, filter); + return OutputGetCredit(*m_wallet, txout); } CoinsList listCoins() override { diff --git a/src/wallet/receive.cpp b/src/wallet/receive.cpp index 46e52b3f505..df3fbc0877d 100644 --- a/src/wallet/receive.cpp +++ b/src/wallet/receive.cpp @@ -10,39 +10,39 @@ #include namespace wallet { -isminetype InputIsMine(const CWallet& wallet, const CTxIn& txin) +bool InputIsMine(const CWallet& wallet, const CTxIn& txin) { AssertLockHeld(wallet.cs_wallet); const CWalletTx* prev = wallet.GetWalletTx(txin.prevout.hash); if (prev && txin.prevout.n < prev->tx->vout.size()) { return wallet.IsMine(prev->tx->vout[txin.prevout.n]); } - return ISMINE_NO; + return false; } -bool AllInputsMine(const CWallet& wallet, const CTransaction& tx, const isminefilter& filter) +bool AllInputsMine(const CWallet& wallet, const CTransaction& tx) { LOCK(wallet.cs_wallet); for (const CTxIn& txin : tx.vin) { - if (!(InputIsMine(wallet, txin) & filter)) return false; + if (!InputIsMine(wallet, txin)) return false; } return true; } -CAmount OutputGetCredit(const CWallet& wallet, const CTxOut& txout, const isminefilter& filter) +CAmount OutputGetCredit(const CWallet& wallet, const CTxOut& txout) { if (!MoneyRange(txout.nValue)) throw std::runtime_error(std::string(__func__) + ": value out of range"); LOCK(wallet.cs_wallet); - return ((wallet.IsMine(txout) & filter) ? txout.nValue : 0); + return (wallet.IsMine(txout) ? txout.nValue : 0); } -CAmount TxGetCredit(const CWallet& wallet, const CTransaction& tx, const isminefilter& filter) +CAmount TxGetCredit(const CWallet& wallet, const CTransaction& tx) { CAmount nCredit = 0; for (const CTxOut& txout : tx.vout) { - nCredit += OutputGetCredit(wallet, txout, filter); + nCredit += OutputGetCredit(wallet, txout); if (!MoneyRange(nCredit)) throw std::runtime_error(std::string(__func__) + ": value out of range"); } @@ -97,17 +97,17 @@ CAmount TxGetChange(const CWallet& wallet, const CTransaction& tx) return nChange; } -static CAmount GetCachableAmount(const CWallet& wallet, const CWalletTx& wtx, CWalletTx::AmountType type, const isminefilter& filter, bool avoid_reuse) +static CAmount GetCachableAmount(const CWallet& wallet, const CWalletTx& wtx, CWalletTx::AmountType type, bool avoid_reuse) { auto& amount = wtx.m_amounts[type]; if (!amount.IsCached(avoid_reuse)) { - amount.Set(avoid_reuse, type == CWalletTx::DEBIT ? wallet.GetDebit(*wtx.tx, filter) : TxGetCredit(wallet, *wtx.tx, filter)); + amount.Set(avoid_reuse, type == CWalletTx::DEBIT ? wallet.GetDebit(*wtx.tx) : TxGetCredit(wallet, *wtx.tx)); wtx.m_is_cache_empty = false; } return amount.Get(avoid_reuse); } -CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter, bool avoid_reuse) +CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, bool avoid_reuse) { AssertLockHeld(wallet.cs_wallet); @@ -115,26 +115,16 @@ CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, const ism if (wallet.IsTxImmatureCoinBase(wtx)) return 0; - CAmount credit = 0; - const isminefilter get_amount_filter{filter & ISMINE_ALL}; - if (get_amount_filter) { - // GetBalance can assume transactions in mapWallet won't change - credit += GetCachableAmount(wallet, wtx, CWalletTx::CREDIT, get_amount_filter, avoid_reuse); - } - return credit; + // GetBalance can assume transactions in mapWallet won't change + return GetCachableAmount(wallet, wtx, CWalletTx::CREDIT, avoid_reuse); } -CAmount CachedTxGetDebit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter, bool avoid_reuse) +CAmount CachedTxGetDebit(const CWallet& wallet, const CWalletTx& wtx, bool avoid_reuse) { if (wtx.tx->vin.empty()) return 0; - CAmount debit = 0; - const isminefilter get_amount_filter{filter & ISMINE_ALL}; - if (get_amount_filter) { - debit += GetCachableAmount(wallet, wtx, CWalletTx::DEBIT, get_amount_filter, avoid_reuse); - } - return debit; + return GetCachableAmount(wallet, wtx, CWalletTx::DEBIT, avoid_reuse); } CAmount CachedTxGetChange(const CWallet& wallet, const CWalletTx& wtx) @@ -148,7 +138,7 @@ CAmount CachedTxGetChange(const CWallet& wallet, const CWalletTx& wtx) void CachedTxGetAmounts(const CWallet& wallet, const CWalletTx& wtx, std::list& listReceived, - std::list& listSent, CAmount& nFee, const isminefilter& filter, + std::list& listSent, CAmount& nFee, bool include_change) { nFee = 0; @@ -156,7 +146,7 @@ void CachedTxGetAmounts(const CWallet& wallet, const CWalletTx& wtx, listSent.clear(); // Compute fee: - CAmount nDebit = CachedTxGetDebit(wallet, wtx, filter, /*avoid_reuse=*/false); + CAmount nDebit = CachedTxGetDebit(wallet, wtx, /*avoid_reuse=*/false); if (nDebit > 0) // debit>0 means we signed/sent this transaction { CAmount nValueOut = wtx.tx->GetValueOut(); @@ -168,7 +158,7 @@ void CachedTxGetAmounts(const CWallet& wallet, const CWalletTx& wtx, for (unsigned int i = 0; i < wtx.tx->vout.size(); ++i) { const CTxOut& txout = wtx.tx->vout[i]; - isminetype fIsMine = wallet.IsMine(txout); + bool ismine = wallet.IsMine(txout); // Only need to handle txouts if AT LEAST one of these is true: // 1) they debit from us (sent) // 2) the output is to us (received) @@ -177,7 +167,7 @@ void CachedTxGetAmounts(const CWallet& wallet, const CWalletTx& wtx, if (!include_change && OutputIsChange(wallet, txout)) continue; } - else if (!(fIsMine & filter)) + else if (!ismine) continue; // In either case, we need to get the destination address @@ -197,15 +187,15 @@ void CachedTxGetAmounts(const CWallet& wallet, const CWalletTx& wtx, listSent.push_back(output); // If we are receiving the output, add it as a "received" entry - if (fIsMine & filter) + if (ismine) listReceived.push_back(output); } } -bool CachedTxIsFromMe(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter) +bool CachedTxIsFromMe(const CWallet& wallet, const CWalletTx& wtx) { - return (CachedTxGetDebit(wallet, wtx, filter, /*avoid_reuse=*/false) > 0); + return (CachedTxGetDebit(wallet, wtx, /*avoid_reuse=*/false) > 0); } // NOLINTNEXTLINE(misc-no-recursion) @@ -219,7 +209,7 @@ bool CachedTxIsTrusted(const CWallet& wallet, const CWalletTx& wtx, std::settx->vout[txin.prevout.n]; // Check that this specific input being spent is trusted - if (wallet.IsMine(parentOut) != ISMINE_SPENDABLE) return false; + if (!wallet.IsMine(parentOut)) return false; // If we've already trusted this parent, continue if (trusted_parents.count(parent->GetHash())) continue; // Recurse to check that the parent is also trusted @@ -264,13 +254,7 @@ Balance GetBalance(const CWallet& wallet, const int min_depth, bool avoid_reuse) if (!wallet.IsSpent(outpoint) && (allow_used_addresses || !wallet.IsSpentKey(txo.GetTxOut().scriptPubKey))) { // Get the amounts for mine - CAmount credit_mine = 0; - if (txo.GetIsMine() == ISMINE_SPENDABLE) { - credit_mine = txo.GetTxOut().nValue; - } else { - // We shouldn't see any other isminetypes - Assume(false); - } + CAmount credit_mine = txo.GetTxOut().nValue; // Set the amounts in the return object if (wallet.IsTxImmatureCoinBase(wtx) && wtx.isConfirmed()) { @@ -300,7 +284,7 @@ std::map GetAddressBalances(const CWallet& wallet) if (wallet.IsTxImmatureCoinBase(wtx)) continue; int nDepth = wallet.GetTxDepthInMainChain(wtx); - if (nDepth < (CachedTxIsFromMe(wallet, wtx, ISMINE_ALL) ? 0 : 1)) continue; + if (nDepth < (CachedTxIsFromMe(wallet, wtx) ? 0 : 1)) continue; CTxDestination addr; Assume(wallet.IsMine(txo.GetTxOut())); diff --git a/src/wallet/receive.h b/src/wallet/receive.h index 271c1a96226..f6c55a45360 100644 --- a/src/wallet/receive.h +++ b/src/wallet/receive.h @@ -8,27 +8,25 @@ #include #include #include -#include #include namespace wallet { -isminetype InputIsMine(const CWallet& wallet, const CTxIn& txin) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet); +bool InputIsMine(const CWallet& wallet, const CTxIn& txin) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet); -/** Returns whether all of the inputs match the filter */ -bool AllInputsMine(const CWallet& wallet, const CTransaction& tx, const isminefilter& filter); +/** Returns whether all of the inputs belong to the wallet*/ +bool AllInputsMine(const CWallet& wallet, const CTransaction& tx); -CAmount OutputGetCredit(const CWallet& wallet, const CTxOut& txout, const isminefilter& filter); -CAmount TxGetCredit(const CWallet& wallet, const CTransaction& tx, const isminefilter& filter); +CAmount OutputGetCredit(const CWallet& wallet, const CTxOut& txout); +CAmount TxGetCredit(const CWallet& wallet, const CTransaction& tx); bool ScriptIsChange(const CWallet& wallet, const CScript& script) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet); bool OutputIsChange(const CWallet& wallet, const CTxOut& txout) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet); CAmount OutputGetChange(const CWallet& wallet, const CTxOut& txout) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet); CAmount TxGetChange(const CWallet& wallet, const CTransaction& tx); -CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter, bool avoid_reuse) +CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, bool avoid_reuse) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet); -//! filter decides which addresses will count towards the debit -CAmount CachedTxGetDebit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter, bool avoid_reuse); +CAmount CachedTxGetDebit(const CWallet& wallet, const CWalletTx& wtx, bool avoid_reuse); CAmount CachedTxGetChange(const CWallet& wallet, const CWalletTx& wtx); struct COutputEntry { @@ -39,9 +37,9 @@ struct COutputEntry void CachedTxGetAmounts(const CWallet& wallet, const CWalletTx& wtx, std::list& listReceived, std::list& listSent, - CAmount& nFee, const isminefilter& filter, + CAmount& nFee, bool include_change); -bool CachedTxIsFromMe(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter); +bool CachedTxIsFromMe(const CWallet& wallet, const CWalletTx& wtx); bool CachedTxIsTrusted(const CWallet& wallet, const CWalletTx& wtx, std::set& trusted_parents) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet); bool CachedTxIsTrusted(const CWallet& wallet, const CWalletTx& wtx); diff --git a/src/wallet/rpc/addresses.cpp b/src/wallet/rpc/addresses.cpp index 756a59f5df2..a04e0903b9c 100644 --- a/src/wallet/rpc/addresses.cpp +++ b/src/wallet/rpc/addresses.cpp @@ -448,8 +448,8 @@ RPCHelpMan getaddressinfo() std::unique_ptr provider = pwallet->GetSolvingProvider(scriptPubKey); - isminetype mine = pwallet->IsMine(dest); - ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE)); + bool mine = pwallet->IsMine(dest); + ret.pushKV("ismine", mine); if (provider) { auto inferred = InferDescriptor(scriptPubKey, *provider); diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp index dd7c9172d98..c333cb54c99 100644 --- a/src/wallet/rpc/spend.cpp +++ b/src/wallet/rpc/spend.cpp @@ -1505,7 +1505,7 @@ RPCHelpMan sendall() throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input not available. UTXO (%s:%d) was already spent.", input.prevout.hash.ToString(), input.prevout.n)); } const CWalletTx* tx{pwallet->GetWalletTx(input.prevout.hash)}; - if (!tx || input.prevout.n >= tx->tx->vout.size() || !(pwallet->IsMine(tx->tx->vout[input.prevout.n]) & ISMINE_SPENDABLE)) { + if (!tx || input.prevout.n >= tx->tx->vout.size() || !pwallet->IsMine(tx->tx->vout[input.prevout.n])) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input not found. UTXO (%s:%d) is not part of wallet.", input.prevout.hash.ToString(), input.prevout.n)); } if (pwallet->GetTxDepthInMainChain(*tx) == 0) { diff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp index 8d2c7fb2135..073ba819989 100644 --- a/src/wallet/rpc/transactions.cpp +++ b/src/wallet/rpc/transactions.cpp @@ -83,8 +83,6 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, cons if (!params[1].isNull()) fIncludeEmpty = params[1].get_bool(); - isminefilter filter = ISMINE_SPENDABLE; - std::optional filtered_address{std::nullopt}; if (!by_label && !params[3].isNull() && !params[3].get_str().empty()) { if (!IsValidDestinationString(params[3].get_str())) { @@ -116,8 +114,7 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, cons continue; } - isminefilter mine = wallet.IsMine(address); - if (!(mine & filter)) + if (!wallet.IsMine(address)) continue; tallyitem& item = mapTally[address]; @@ -302,12 +299,11 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) * @param nMinDepth The minimum confirmation depth. * @param fLong Whether to include the JSON version of the transaction. * @param ret The vector into which the result is stored. - * @param filter_ismine The "is mine" filter flags. * @param filter_label Optional label string to filter incoming transactions. */ template static void ListTransactions(const CWallet& wallet, const CWalletTx& wtx, int nMinDepth, bool fLong, - Vec& ret, const isminefilter& filter_ismine, const std::optional& filter_label, + Vec& ret, const std::optional& filter_label, bool include_change = false) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) { @@ -315,7 +311,7 @@ static void ListTransactions(const CWallet& wallet, const CWalletTx& wtx, int nM std::list listReceived; std::list listSent; - CachedTxGetAmounts(wallet, wtx, listReceived, listSent, nFee, filter_ismine, include_change); + CachedTxGetAmounts(wallet, wtx, listReceived, listSent, nFee, include_change); // Sent if (!filter_label.has_value()) @@ -484,7 +480,6 @@ RPCHelpMan listtransactions() int nFrom = 0; if (!request.params[2].isNull()) nFrom = request.params[2].getInt(); - isminefilter filter = ISMINE_SPENDABLE; if (nCount < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count"); @@ -501,7 +496,7 @@ RPCHelpMan listtransactions() for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { CWalletTx *const pwtx = (*it).second; - ListTransactions(*pwallet, *pwtx, 0, true, ret, filter, filter_label); + ListTransactions(*pwallet, *pwtx, 0, true, ret, filter_label); if ((int)ret.size() >= (nCount+nFrom)) break; } } @@ -589,7 +584,6 @@ RPCHelpMan listsinceblock() std::optional height; // Height of the specified block or the common ancestor, if the block provided was in a deactivated chain. std::optional altheight; // Height of the specified block, even if it's in a deactivated chain. int target_confirms = 1; - isminefilter filter = ISMINE_SPENDABLE; uint256 blockId; if (!request.params[0].isNull() && !request.params[0].get_str().empty()) { @@ -623,7 +617,7 @@ RPCHelpMan listsinceblock() for (const auto& [_, tx] : wallet.mapWallet) { if (depth == -1 || abs(wallet.GetTxDepthInMainChain(tx)) < depth) { - ListTransactions(wallet, tx, 0, true, transactions, filter, filter_label, include_change); + ListTransactions(wallet, tx, 0, true, transactions, filter_label, include_change); } } @@ -640,7 +634,7 @@ RPCHelpMan listsinceblock() if (it != wallet.mapWallet.end()) { // We want all transactions regardless of confirmation count to appear here, // even negative confirmation ones, hence the big negative. - ListTransactions(wallet, it->second, -100000000, true, removed, filter, filter_label, include_change); + ListTransactions(wallet, it->second, -100000000, true, removed, filter_label, include_change); } } blockId = block.hashPrevBlock; @@ -730,8 +724,6 @@ RPCHelpMan gettransaction() Txid hash{Txid::FromUint256(ParseHashV(request.params[0], "txid"))}; - isminefilter filter = ISMINE_SPENDABLE; - bool verbose = request.params[2].isNull() ? false : request.params[2].get_bool(); UniValue entry(UniValue::VOBJ); @@ -741,19 +733,19 @@ RPCHelpMan gettransaction() } const CWalletTx& wtx = it->second; - CAmount nCredit = CachedTxGetCredit(*pwallet, wtx, filter, /*avoid_reuse=*/false); - CAmount nDebit = CachedTxGetDebit(*pwallet, wtx, filter, /*avoid_reuse=*/false); + CAmount nCredit = CachedTxGetCredit(*pwallet, wtx, /*avoid_reuse=*/false); + CAmount nDebit = CachedTxGetDebit(*pwallet, wtx, /*avoid_reuse=*/false); CAmount nNet = nCredit - nDebit; - CAmount nFee = (CachedTxIsFromMe(*pwallet, wtx, filter) ? wtx.tx->GetValueOut() - nDebit : 0); + CAmount nFee = (CachedTxIsFromMe(*pwallet, wtx) ? wtx.tx->GetValueOut() - nDebit : 0); entry.pushKV("amount", ValueFromAmount(nNet - nFee)); - if (CachedTxIsFromMe(*pwallet, wtx, filter)) + if (CachedTxIsFromMe(*pwallet, wtx)) entry.pushKV("fee", ValueFromAmount(nFee)); WalletTxToJSON(*pwallet, wtx, entry); UniValue details(UniValue::VARR); - ListTransactions(*pwallet, wtx, 0, false, details, filter, /*filter_label=*/std::nullopt); + ListTransactions(*pwallet, wtx, 0, false, details, /*filter_label=*/std::nullopt); entry.pushKV("details", std::move(details)); entry.pushKV("hex", EncodeHexTx(*wtx.tx)); diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp index 555a24c98ae..8e1cec55654 100644 --- a/src/wallet/rpc/wallet.cpp +++ b/src/wallet/rpc/wallet.cpp @@ -525,8 +525,6 @@ RPCHelpMan simulaterawtransaction() LOCK(wallet.cs_wallet); - isminefilter filter = ISMINE_SPENDABLE; - const auto& txs = request.params[0].get_array(); CAmount changes{0}; std::map new_utxos; // UTXO:s that were made available in transaction array @@ -559,7 +557,7 @@ RPCHelpMan simulaterawtransaction() if (coins.at(outpoint).IsSpent()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "One or more transaction inputs are missing or have been spent already"); } - changes -= wallet.GetDebit(txin, filter); + changes -= wallet.GetDebit(txin); } spent.insert(outpoint); } @@ -572,7 +570,7 @@ RPCHelpMan simulaterawtransaction() const auto& hash = mtx.GetHash(); for (size_t i = 0; i < mtx.vout.size(); ++i) { const auto& txout = mtx.vout[i]; - bool is_mine = 0 < (wallet.IsMine(txout) & filter); + bool is_mine = wallet.IsMine(txout); changes += new_utxos[COutPoint(hash, i)] = is_mine ? txout.nValue : 0; } } diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index e90573a3392..a78f32f8909 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -197,15 +197,15 @@ IsMineResult LegacyWalletIsMineInnerDONOTUSE(const LegacyDataSPKM& keystore, con } // namespace -isminetype LegacyDataSPKM::IsMine(const CScript& script) const +bool LegacyDataSPKM::IsMine(const CScript& script) const { switch (LegacyWalletIsMineInnerDONOTUSE(*this, script, IsMineSigVersion::TOP)) { case IsMineResult::INVALID: case IsMineResult::NO: - return ISMINE_NO; + return false; case IsMineResult::WATCH_ONLY: case IsMineResult::SPENDABLE: - return ISMINE_SPENDABLE; + return true; } assert(false); } @@ -506,12 +506,12 @@ std::unordered_set LegacyDataSPKM::GetCandidateScriptP std::unordered_set LegacyDataSPKM::GetScriptPubKeys() const { - // Run IsMine() on each candidate output script. Any script that is not ISMINE_NO is an output + // Run IsMine() on each candidate output script. Any script that IsMine is an output // script to return. // This both filters out things that are not watched by the wallet, and things that are invalid. std::unordered_set spks; for (const CScript& script : GetCandidateScriptPubKeys()) { - if (IsMine(script) != ISMINE_NO) { + if (IsMine(script)) { spks.insert(script); } } @@ -524,7 +524,7 @@ std::unordered_set LegacyDataSPKM::GetNotMineScriptPub LOCK(cs_KeyStore); std::unordered_set spks; for (const CScript& script : setWatchOnly) { - if (IsMine(script) == ISMINE_NO) spks.insert(script); + if (!IsMine(script)) spks.insert(script); } return spks; } @@ -612,7 +612,7 @@ std::optional LegacyDataSPKM::MigrateToDescriptor() for (const CScript& spk : desc_spks) { size_t erased = spks.erase(spk); assert(erased == 1); - assert(IsMine(spk) == ISMINE_SPENDABLE); + assert(IsMine(spk)); } out.desc_spkms.push_back(std::move(desc_spk_man)); @@ -661,7 +661,7 @@ std::optional LegacyDataSPKM::MigrateToDescriptor() for (const CScript& spk : desc_spks) { size_t erased = spks.erase(spk); assert(erased == 1); - assert(IsMine(spk) == ISMINE_SPENDABLE); + assert(IsMine(spk)); } out.desc_spkms.push_back(std::move(desc_spk_man)); @@ -748,7 +748,7 @@ std::optional LegacyDataSPKM::MigrateToDescriptor() for (const CScript& desc_spk : desc_spks) { auto del_it = spks.find(desc_spk); assert(del_it != spks.end()); - assert(IsMine(desc_spk) != ISMINE_NO); + assert(IsMine(desc_spk)); it = spks.erase(del_it); } } @@ -762,14 +762,14 @@ std::optional LegacyDataSPKM::MigrateToDescriptor() // Legacy wallets can also contain scripts whose P2SH, P2WSH, or P2SH-P2WSH it is not watching for // but can provide script data to a PSBT spending them. These "solvable" output scripts will need to // be put into the separate "solvables" wallet. - // These can be detected by going through the entire candidate output scripts, finding the ISMINE_NO scripts, + // These can be detected by going through the entire candidate output scripts, finding the not IsMine scripts, // and checking CanProvide() which will dummy sign. for (const CScript& script : GetCandidateScriptPubKeys()) { // Since we only care about P2SH, P2WSH, and P2SH-P2WSH, filter out any scripts that are not those if (!script.IsPayToScriptHash() && !script.IsPayToWitnessScriptHash()) { continue; } - if (IsMine(script) != ISMINE_NO) { + if (IsMine(script)) { continue; } SignatureData dummy_sigdata; @@ -861,13 +861,10 @@ util::Result DescriptorScriptPubKeyMan::GetNewDestination(const } } -isminetype DescriptorScriptPubKeyMan::IsMine(const CScript& script) const +bool DescriptorScriptPubKeyMan::IsMine(const CScript& script) const { LOCK(cs_desc_man); - if (m_map_script_pub_keys.count(script) > 0) { - return ISMINE_SPENDABLE; - } - return ISMINE_NO; + return m_map_script_pub_keys.contains(script); } bool DescriptorScriptPubKeyMan::CheckDecryptionKey(const CKeyingMaterial& master_key) diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h index f7d7a0d0674..d50bbe726af 100644 --- a/src/wallet/scriptpubkeyman.h +++ b/src/wallet/scriptpubkeyman.h @@ -85,7 +85,7 @@ public: explicit ScriptPubKeyMan(WalletStorage& storage) : m_storage(storage) {} virtual ~ScriptPubKeyMan() = default; virtual util::Result GetNewDestination(const OutputType type) { return util::Error{Untranslated("Not supported")}; } - virtual isminetype IsMine(const CScript& script) const { return ISMINE_NO; } + virtual bool IsMine(const CScript& script) const { return false; } //! Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the keys handled by it. virtual bool CheckDecryptionKey(const CKeyingMaterial& master_key) { return false; } @@ -197,7 +197,7 @@ private: // Used only in migration. std::unordered_set GetCandidateScriptPubKeys() const; - isminetype IsMine(const CScript& script) const override; + bool IsMine(const CScript& script) const override; bool CanProvide(const CScript& script, SignatureData& sigdata) override; public: using ScriptPubKeyMan::ScriptPubKeyMan; @@ -324,7 +324,7 @@ public: mutable RecursiveMutex cs_desc_man; util::Result GetNewDestination(const OutputType type) override; - isminetype IsMine(const CScript& script) const override; + bool IsMine(const CScript& script) const override; bool CheckDecryptionKey(const CKeyingMaterial& master_key) override; bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override; diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index a5bd816b56a..146fb49ea78 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -437,14 +437,11 @@ CoinsResult AvailableCoins(const CWallet& wallet, if (wallet.IsSpent(outpoint)) continue; - isminetype mine = wallet.IsMine(output); - assert(mine != ISMINE_NO); - if (!allow_used_addresses && wallet.IsSpentKey(output.scriptPubKey)) { continue; } - bool tx_from_me = CachedTxIsFromMe(wallet, wtx, ISMINE_ALL); + bool tx_from_me = CachedTxIsFromMe(wallet, wtx); std::unique_ptr provider = wallet.GetSolvingProvider(output.scriptPubKey); diff --git a/src/wallet/test/fuzz/scriptpubkeyman.cpp b/src/wallet/test/fuzz/scriptpubkeyman.cpp index 247c0f2de4a..3edf2265c6e 100644 --- a/src/wallet/test/fuzz/scriptpubkeyman.cpp +++ b/src/wallet/test/fuzz/scriptpubkeyman.cpp @@ -124,15 +124,14 @@ FUZZ_TARGET(scriptpubkeyman, .init = initialize_spkm) fuzzed_data_provider, [&] { const CScript script{ConsumeScript(fuzzed_data_provider)}; - auto is_mine{spk_manager->IsMine(script)}; - if (is_mine == isminetype::ISMINE_SPENDABLE) { + if (spk_manager->IsMine(script)) { assert(spk_manager->GetScriptPubKeys().count(script)); } }, [&] { auto spks{spk_manager->GetScriptPubKeys()}; for (const CScript& spk : spks) { - assert(spk_manager->IsMine(spk) == ISMINE_SPENDABLE); + assert(spk_manager->IsMine(spk)); CTxDestination dest; bool extract_dest{ExtractDestination(spk, dest)}; if (extract_dest) { diff --git a/src/wallet/test/ismine_tests.cpp b/src/wallet/test/ismine_tests.cpp index 9901590af33..b4cace21535 100644 --- a/src/wallet/test/ismine_tests.cpp +++ b/src/wallet/test/ismine_tests.cpp @@ -34,7 +34,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) std::unique_ptr& chain = m_node.chain; CScript scriptPubKey; - isminetype result; + bool result; // P2PK compressed - Descriptor { @@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) scriptPubKey = GetScriptForRawPubKey(pubkeys[0]); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); } // P2PK uncompressed - Descriptor @@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) scriptPubKey = GetScriptForRawPubKey(uncompressedPubkey); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); } // P2PKH compressed - Descriptor @@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) scriptPubKey = GetScriptForDestination(PKHash(pubkeys[0])); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); } // P2PKH uncompressed - Descriptor @@ -81,7 +81,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) scriptPubKey = GetScriptForDestination(PKHash(uncompressedPubkey)); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); } // P2SH - Descriptor @@ -94,7 +94,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) CScript redeemScript = GetScriptForDestination(PKHash(pubkeys[0])); scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript)); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); } // (P2PKH inside) P2SH inside P2SH (invalid) - Descriptor @@ -142,7 +142,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(pubkeys[0])); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); } // P2WPKH uncompressed (invalid) - Descriptor @@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) scriptPubKey = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]}); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); } // P2SH multisig - Descriptor @@ -177,7 +177,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) CScript redeemScript = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]}); scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript)); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); } // P2WSH multisig with compressed keys - Descriptor @@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) CScript redeemScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]}); scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(redeemScript)); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); } // P2WSH multisig with uncompressed key (invalid) - Descriptor @@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) CScript redeemScript = GetScriptForDestination(WitnessV0ScriptHash(witnessScript)); scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript)); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); } // Combo - Descriptor @@ -229,28 +229,28 @@ BOOST_AUTO_TEST_CASE(ismine_standard) // Test P2PK result = spk_manager->IsMine(GetScriptForRawPubKey(pubkeys[0])); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); // Test P2PKH result = spk_manager->IsMine(GetScriptForDestination(PKHash(pubkeys[0]))); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); // Test P2SH (combo descriptor does not describe P2SH) CScript redeemScript = GetScriptForDestination(PKHash(pubkeys[0])); scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript)); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(!result); // Test P2WPKH scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(pubkeys[0])); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); // P2SH-P2WPKH output redeemScript = GetScriptForDestination(WitnessV0KeyHash(pubkeys[0])); scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript)); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); // Test P2TR (combo descriptor does not describe P2TR) XOnlyPubKey xpk(pubkeys[0]); @@ -260,7 +260,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) WitnessV1Taproot output = builder.GetOutput(); scriptPubKey = GetScriptForDestination(output); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(!result); } // Taproot - Descriptor @@ -278,7 +278,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) WitnessV1Taproot output = builder.GetOutput(); scriptPubKey = GetScriptForDestination(output); result = spk_manager->IsMine(scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(result); } } diff --git a/src/wallet/transaction.h b/src/wallet/transaction.h index ec4fb99ed5f..bc6f0ef8450 100644 --- a/src/wallet/transaction.h +++ b/src/wallet/transaction.h @@ -388,13 +388,11 @@ class WalletTXO private: const CWalletTx& m_wtx; const CTxOut& m_output; - isminetype m_ismine; public: - WalletTXO(const CWalletTx& wtx, const CTxOut& output, const isminetype ismine) + WalletTXO(const CWalletTx& wtx, const CTxOut& output) : m_wtx(wtx), - m_output(output), - m_ismine(ismine) + m_output(output) { Assume(std::ranges::find(wtx.tx->vout, output) != wtx.tx->vout.end()); } @@ -402,9 +400,6 @@ public: const CWalletTx& GetWalletTx() const { return m_wtx; } const CTxOut& GetTxOut() const { return m_output; } - - isminetype GetIsMine() const { return m_ismine; } - void SetIsMine(isminetype ismine) { m_ismine = ismine; } }; } // namespace wallet diff --git a/src/wallet/types.h b/src/wallet/types.h index 066a286a6e2..10a463c4c35 100644 --- a/src/wallet/types.h +++ b/src/wallet/types.h @@ -17,32 +17,6 @@ #include namespace wallet { -/** - * IsMine() return codes, which depend on ScriptPubKeyMan implementation. - * Not every ScriptPubKeyMan covers all types, please refer to - * https://github.com/bitcoin/bitcoin/blob/master/doc/release-notes/release-notes-0.21.0.md#ismine-semantics - * for better understanding. - * - * For LegacyScriptPubKeyMan, - * ISMINE_NO: the scriptPubKey is not in the wallet; - * ISMINE_SPENDABLE: the scriptPubKey corresponds to an address owned by the wallet user (can spend with the private key); - * ISMINE_ALL: all ISMINE flags except for USED; - * ISMINE_ENUM_ELEMENTS: the number of isminetype enum elements. - * - * For DescriptorScriptPubKeyMan and future ScriptPubKeyMan, - * ISMINE_NO: the scriptPubKey is not in the wallet; - * ISMINE_SPENDABLE: the scriptPubKey matches a scriptPubKey in the wallet. - * - */ -enum isminetype : unsigned int { - ISMINE_NO = 0, - ISMINE_SPENDABLE = 1 << 1, - ISMINE_ALL = ISMINE_SPENDABLE, - ISMINE_ENUM_ELEMENTS, -}; -/** used for bitflags of isminetype */ -using isminefilter = std::underlying_type_t; - /** * Address purpose field that has been been stored with wallet sending and * receiving addresses since BIP70 payment protocol support was added in diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1eae6a971a0..6df74e848b8 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1569,45 +1569,45 @@ void CWallet::BlockUntilSyncedToCurrentChain() const { } // Note that this function doesn't distinguish between a 0-valued input, -// and a not-"is mine" (according to the filter) input. -CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const +// and a not-"is mine" input. +CAmount CWallet::GetDebit(const CTxIn &txin) const { LOCK(cs_wallet); auto txo = GetTXO(txin.prevout); - if (txo && (txo->GetIsMine() & filter)) { + if (txo) { return txo->GetTxOut().nValue; } return 0; } -isminetype CWallet::IsMine(const CTxOut& txout) const +bool CWallet::IsMine(const CTxOut& txout) const { AssertLockHeld(cs_wallet); return IsMine(txout.scriptPubKey); } -isminetype CWallet::IsMine(const CTxDestination& dest) const +bool CWallet::IsMine(const CTxDestination& dest) const { AssertLockHeld(cs_wallet); return IsMine(GetScriptForDestination(dest)); } -isminetype CWallet::IsMine(const CScript& script) const +bool CWallet::IsMine(const CScript& script) const { AssertLockHeld(cs_wallet); // Search the cache so that IsMine is called only on the relevant SPKMs instead of on everything in m_spk_managers const auto& it = m_cached_spks.find(script); if (it != m_cached_spks.end()) { - isminetype res = ISMINE_NO; + bool res = false; for (const auto& spkm : it->second) { - res = std::max(res, spkm->IsMine(script)); + res = res || spkm->IsMine(script); } - Assume(res == ISMINE_SPENDABLE); + Assume(res); return res; } - return ISMINE_NO; + return false; } bool CWallet::IsMine(const CTransaction& tx) const @@ -1619,30 +1619,30 @@ bool CWallet::IsMine(const CTransaction& tx) const return false; } -isminetype CWallet::IsMine(const COutPoint& outpoint) const +bool CWallet::IsMine(const COutPoint& outpoint) const { AssertLockHeld(cs_wallet); auto wtx = GetWalletTx(outpoint.hash); if (!wtx) { - return ISMINE_NO; + return false; } if (outpoint.n >= wtx->tx->vout.size()) { - return ISMINE_NO; + return false; } return IsMine(wtx->tx->vout[outpoint.n]); } bool CWallet::IsFromMe(const CTransaction& tx) const { - return (GetDebit(tx, ISMINE_ALL) > 0); + return (GetDebit(tx) > 0); } -CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const +CAmount CWallet::GetDebit(const CTransaction& tx) const { CAmount nDebit = 0; for (const CTxIn& txin : tx.vin) { - nDebit += GetDebit(txin, filter); + nDebit += GetDebit(txin); if (!MoneyRange(nDebit)) throw std::runtime_error(std::string(__func__) + ": value out of range"); } @@ -2377,7 +2377,7 @@ bool CWallet::SetAddressBookWithDB(WalletBatch& batch, const CTxDestination& add CAddressBookData& record = mi != m_address_book.end() ? mi->second : m_address_book[address]; record.SetLabel(strName); - is_mine = IsMine(address) != ISMINE_NO; + is_mine = IsMine(address); if (new_purpose) { /* update purpose only if requested */ record.purpose = new_purpose; } @@ -4444,15 +4444,11 @@ void CWallet::RefreshTXOsFromTx(const CWalletTx& wtx) AssertLockHeld(cs_wallet); for (uint32_t i = 0; i < wtx.tx->vout.size(); ++i) { const CTxOut& txout = wtx.tx->vout.at(i); - isminetype ismine = IsMine(txout); - if (ismine == ISMINE_NO) { - continue; - } + if (!IsMine(txout)) continue; COutPoint outpoint(wtx.GetHash(), i); if (m_txos.contains(outpoint)) { - m_txos.at(outpoint).SetIsMine(ismine); } else { - m_txos.emplace(outpoint, WalletTXO{wtx, txout, ismine}); + m_txos.emplace(outpoint, WalletTXO{wtx, txout}); } } } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 8a97abc3f5e..b341ac6da2d 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -786,19 +786,16 @@ public: util::Result GetNewDestination(const OutputType type, const std::string label); util::Result GetNewChangeDestination(const OutputType type); - isminetype IsMine(const CTxDestination& dest) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); - isminetype IsMine(const CScript& script) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); - /** - * Returns amount of debit if the input matches the - * filter, otherwise returns 0 - */ - CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const; - isminetype IsMine(const CTxOut& txout) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + bool IsMine(const CTxDestination& dest) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + bool IsMine(const CScript& script) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + /** Returns amount of debit, i.e. the amount leaving this wallet due to this input */ + CAmount GetDebit(const CTxIn& txin) const; + bool IsMine(const CTxOut& txout) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); bool IsMine(const CTransaction& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); - isminetype IsMine(const COutPoint& outpoint) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + bool IsMine(const COutPoint& outpoint) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); /** should probably be renamed to IsRelevantToMe */ bool IsFromMe(const CTransaction& tx) const; - CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const; + CAmount GetDebit(const CTransaction& tx) const; DBErrors LoadWallet();