wallet: Remove ISMINE_USED

This isminetype is not a real isminetype as it is never returned by
IsMine. This is only used for isminefilters in one function, which can
be better represented with a bool parameter avoid_reuse.
This commit is contained in:
Ava Chow
2025-05-15 14:14:16 -07:00
parent 6a7aa01574
commit 009a69a616
6 changed files with 41 additions and 29 deletions

View File

@@ -76,8 +76,8 @@ WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx)
wallet.IsMine(result.txout_address.back()) : wallet.IsMine(result.txout_address.back()) :
ISMINE_NO); ISMINE_NO);
} }
result.credit = CachedTxGetCredit(wallet, wtx, ISMINE_ALL); result.credit = CachedTxGetCredit(wallet, wtx, ISMINE_ALL, /*avoid_reuse=*/true);
result.debit = CachedTxGetDebit(wallet, wtx, ISMINE_ALL); result.debit = CachedTxGetDebit(wallet, wtx, ISMINE_ALL, /*avoid_reuse=*/true);
result.change = CachedTxGetChange(wallet, wtx); result.change = CachedTxGetChange(wallet, wtx);
result.time = wtx.GetTxTime(); result.time = wtx.GetTxTime();
result.value_map = wtx.mapValue; result.value_map = wtx.mapValue;

View File

@@ -97,17 +97,17 @@ CAmount TxGetChange(const CWallet& wallet, const CTransaction& tx)
return nChange; return nChange;
} }
static CAmount GetCachableAmount(const CWallet& wallet, const CWalletTx& wtx, CWalletTx::AmountType type, const isminefilter& filter) static CAmount GetCachableAmount(const CWallet& wallet, const CWalletTx& wtx, CWalletTx::AmountType type, const isminefilter& filter, bool avoid_reuse)
{ {
auto& amount = wtx.m_amounts[type]; auto& amount = wtx.m_amounts[type];
if (!amount.m_cached[filter]) { if (!amount.IsCached(avoid_reuse)) {
amount.Set(filter, type == CWalletTx::DEBIT ? wallet.GetDebit(*wtx.tx, filter) : TxGetCredit(wallet, *wtx.tx, filter)); amount.Set(avoid_reuse, type == CWalletTx::DEBIT ? wallet.GetDebit(*wtx.tx, filter) : TxGetCredit(wallet, *wtx.tx, filter));
wtx.m_is_cache_empty = false; wtx.m_is_cache_empty = false;
} }
return amount.m_value[filter]; return amount.Get(avoid_reuse);
} }
CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter) CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter, bool avoid_reuse)
{ {
AssertLockHeld(wallet.cs_wallet); AssertLockHeld(wallet.cs_wallet);
@@ -119,12 +119,12 @@ CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, const ism
const isminefilter get_amount_filter{filter & ISMINE_ALL}; const isminefilter get_amount_filter{filter & ISMINE_ALL};
if (get_amount_filter) { if (get_amount_filter) {
// GetBalance can assume transactions in mapWallet won't change // GetBalance can assume transactions in mapWallet won't change
credit += GetCachableAmount(wallet, wtx, CWalletTx::CREDIT, get_amount_filter); credit += GetCachableAmount(wallet, wtx, CWalletTx::CREDIT, get_amount_filter, avoid_reuse);
} }
return credit; return credit;
} }
CAmount CachedTxGetDebit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter) CAmount CachedTxGetDebit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter, bool avoid_reuse)
{ {
if (wtx.tx->vin.empty()) if (wtx.tx->vin.empty())
return 0; return 0;
@@ -132,7 +132,7 @@ CAmount CachedTxGetDebit(const CWallet& wallet, const CWalletTx& wtx, const ismi
CAmount debit = 0; CAmount debit = 0;
const isminefilter get_amount_filter{filter & ISMINE_ALL}; const isminefilter get_amount_filter{filter & ISMINE_ALL};
if (get_amount_filter) { if (get_amount_filter) {
debit += GetCachableAmount(wallet, wtx, CWalletTx::DEBIT, get_amount_filter); debit += GetCachableAmount(wallet, wtx, CWalletTx::DEBIT, get_amount_filter, avoid_reuse);
} }
return debit; return debit;
} }
@@ -156,7 +156,7 @@ void CachedTxGetAmounts(const CWallet& wallet, const CWalletTx& wtx,
listSent.clear(); listSent.clear();
// Compute fee: // Compute fee:
CAmount nDebit = CachedTxGetDebit(wallet, wtx, filter); CAmount nDebit = CachedTxGetDebit(wallet, wtx, filter, /*avoid_reuse=*/false);
if (nDebit > 0) // debit>0 means we signed/sent this transaction if (nDebit > 0) // debit>0 means we signed/sent this transaction
{ {
CAmount nValueOut = wtx.tx->GetValueOut(); CAmount nValueOut = wtx.tx->GetValueOut();
@@ -205,7 +205,7 @@ void CachedTxGetAmounts(const CWallet& wallet, const CWalletTx& wtx,
bool CachedTxIsFromMe(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter) bool CachedTxIsFromMe(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter)
{ {
return (CachedTxGetDebit(wallet, wtx, filter) > 0); return (CachedTxGetDebit(wallet, wtx, filter, /*avoid_reuse=*/false) > 0);
} }
// NOLINTNEXTLINE(misc-no-recursion) // NOLINTNEXTLINE(misc-no-recursion)

View File

@@ -25,10 +25,10 @@ bool OutputIsChange(const CWallet& wallet, const CTxOut& txout) EXCLUSIVE_LOCKS_
CAmount OutputGetChange(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 TxGetChange(const CWallet& wallet, const CTransaction& tx);
CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter) CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter, bool avoid_reuse)
EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet); EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
//! filter decides which addresses will count towards the debit //! filter decides which addresses will count towards the debit
CAmount CachedTxGetDebit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter); CAmount CachedTxGetDebit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter, bool avoid_reuse);
CAmount CachedTxGetChange(const CWallet& wallet, const CWalletTx& wtx); CAmount CachedTxGetChange(const CWallet& wallet, const CWalletTx& wtx);
struct COutputEntry struct COutputEntry
{ {

View File

@@ -741,8 +741,8 @@ RPCHelpMan gettransaction()
} }
const CWalletTx& wtx = it->second; const CWalletTx& wtx = it->second;
CAmount nCredit = CachedTxGetCredit(*pwallet, wtx, filter); CAmount nCredit = CachedTxGetCredit(*pwallet, wtx, filter, /*avoid_reuse=*/false);
CAmount nDebit = CachedTxGetDebit(*pwallet, wtx, filter); CAmount nDebit = CachedTxGetDebit(*pwallet, wtx, filter, /*avoid_reuse=*/false);
CAmount nNet = nCredit - nDebit; CAmount nNet = nCredit - nDebit;
CAmount nFee = (CachedTxIsFromMe(*pwallet, wtx, filter) ? wtx.tx->GetValueOut() - nDebit : 0); CAmount nFee = (CachedTxIsFromMe(*pwallet, wtx, filter) ? wtx.tx->GetValueOut() - nDebit : 0);

View File

@@ -128,21 +128,38 @@ std::string TxStateString(const T& state)
} }
/** /**
* Cachable amount subdivided into watchonly and spendable parts. * Cachable amount subdivided into avoid reuse and all balances
*/ */
struct CachableAmount struct CachableAmount
{ {
// NO and ALL are never (supposed to be) cached std::optional<CAmount> m_avoid_reuse_value;
std::bitset<ISMINE_ENUM_ELEMENTS> m_cached; std::optional<CAmount> m_all_value;
CAmount m_value[ISMINE_ENUM_ELEMENTS];
inline void Reset() inline void Reset()
{ {
m_cached.reset(); m_avoid_reuse_value.reset();
m_all_value.reset();
} }
void Set(isminefilter filter, CAmount value) void Set(bool avoid_reuse, CAmount value)
{ {
m_cached.set(filter); if (avoid_reuse) {
m_value[filter] = value; m_avoid_reuse_value = value;
} else {
m_all_value = value;
}
}
CAmount Get(bool avoid_reuse)
{
if (avoid_reuse) {
Assert(m_avoid_reuse_value.has_value());
return m_avoid_reuse_value.value();
}
Assert(m_all_value.has_value());
return m_all_value.value();
}
bool IsCached(bool avoid_reuse)
{
if (avoid_reuse) return m_avoid_reuse_value.has_value();
return m_all_value.has_value();
} }
}; };

View File

@@ -26,23 +26,18 @@ namespace wallet {
* For LegacyScriptPubKeyMan, * For LegacyScriptPubKeyMan,
* ISMINE_NO: the scriptPubKey is not in the wallet; * 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_SPENDABLE: the scriptPubKey corresponds to an address owned by the wallet user (can spend with the private key);
* ISMINE_USED: the scriptPubKey corresponds to a used address owned by the wallet user;
* ISMINE_ALL: all ISMINE flags except for USED; * ISMINE_ALL: all ISMINE flags except for USED;
* ISMINE_ALL_USED: all ISMINE flags including USED;
* ISMINE_ENUM_ELEMENTS: the number of isminetype enum elements. * ISMINE_ENUM_ELEMENTS: the number of isminetype enum elements.
* *
* For DescriptorScriptPubKeyMan and future ScriptPubKeyMan, * For DescriptorScriptPubKeyMan and future ScriptPubKeyMan,
* ISMINE_NO: the scriptPubKey is not in the wallet; * ISMINE_NO: the scriptPubKey is not in the wallet;
* ISMINE_SPENDABLE: the scriptPubKey matches a scriptPubKey in the wallet. * ISMINE_SPENDABLE: the scriptPubKey matches a scriptPubKey in the wallet.
* ISMINE_USED: the scriptPubKey corresponds to a used address owned by the wallet user.
* *
*/ */
enum isminetype : unsigned int { enum isminetype : unsigned int {
ISMINE_NO = 0, ISMINE_NO = 0,
ISMINE_SPENDABLE = 1 << 1, ISMINE_SPENDABLE = 1 << 1,
ISMINE_USED = 1 << 2,
ISMINE_ALL = ISMINE_SPENDABLE, ISMINE_ALL = ISMINE_SPENDABLE,
ISMINE_ALL_USED = ISMINE_ALL | ISMINE_USED,
ISMINE_ENUM_ELEMENTS, ISMINE_ENUM_ELEMENTS,
}; };
/** used for bitflags of isminetype */ /** used for bitflags of isminetype */