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()) :
ISMINE_NO);
}
result.credit = CachedTxGetCredit(wallet, wtx, ISMINE_ALL);
result.debit = CachedTxGetDebit(wallet, wtx, ISMINE_ALL);
result.credit = CachedTxGetCredit(wallet, wtx, ISMINE_ALL, /*avoid_reuse=*/true);
result.debit = CachedTxGetDebit(wallet, wtx, ISMINE_ALL, /*avoid_reuse=*/true);
result.change = CachedTxGetChange(wallet, wtx);
result.time = wtx.GetTxTime();
result.value_map = wtx.mapValue;

View File

@@ -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)
static CAmount GetCachableAmount(const CWallet& wallet, const CWalletTx& wtx, CWalletTx::AmountType type, const isminefilter& filter, bool avoid_reuse)
{
auto& amount = wtx.m_amounts[type];
if (!amount.m_cached[filter]) {
amount.Set(filter, type == CWalletTx::DEBIT ? wallet.GetDebit(*wtx.tx, filter) : TxGetCredit(wallet, *wtx.tx, filter));
if (!amount.IsCached(avoid_reuse)) {
amount.Set(avoid_reuse, type == CWalletTx::DEBIT ? wallet.GetDebit(*wtx.tx, filter) : TxGetCredit(wallet, *wtx.tx, filter));
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);
@@ -119,12 +119,12 @@ CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, const ism
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);
credit += GetCachableAmount(wallet, wtx, CWalletTx::CREDIT, get_amount_filter, avoid_reuse);
}
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())
return 0;
@@ -132,7 +132,7 @@ CAmount CachedTxGetDebit(const CWallet& wallet, const CWalletTx& wtx, const ismi
CAmount debit = 0;
const isminefilter get_amount_filter{filter & ISMINE_ALL};
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;
}
@@ -156,7 +156,7 @@ void CachedTxGetAmounts(const CWallet& wallet, const CWalletTx& wtx,
listSent.clear();
// 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
{
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)
{
return (CachedTxGetDebit(wallet, wtx, filter) > 0);
return (CachedTxGetDebit(wallet, wtx, filter, /*avoid_reuse=*/false) > 0);
}
// 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 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);
//! 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);
struct COutputEntry
{

View File

@@ -741,8 +741,8 @@ RPCHelpMan gettransaction()
}
const CWalletTx& wtx = it->second;
CAmount nCredit = CachedTxGetCredit(*pwallet, wtx, filter);
CAmount nDebit = CachedTxGetDebit(*pwallet, wtx, filter);
CAmount nCredit = CachedTxGetCredit(*pwallet, wtx, filter, /*avoid_reuse=*/false);
CAmount nDebit = CachedTxGetDebit(*pwallet, wtx, filter, /*avoid_reuse=*/false);
CAmount nNet = nCredit - nDebit;
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
{
// NO and ALL are never (supposed to be) cached
std::bitset<ISMINE_ENUM_ELEMENTS> m_cached;
CAmount m_value[ISMINE_ENUM_ELEMENTS];
std::optional<CAmount> m_avoid_reuse_value;
std::optional<CAmount> m_all_value;
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);
m_value[filter] = value;
if (avoid_reuse) {
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,
* 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_USED: the scriptPubKey corresponds to a used address owned by the wallet user;
* 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.
*
* For DescriptorScriptPubKeyMan and future ScriptPubKeyMan,
* ISMINE_NO: the scriptPubKey is not 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 {
ISMINE_NO = 0,
ISMINE_SPENDABLE = 1 << 1,
ISMINE_USED = 1 << 2,
ISMINE_ALL = ISMINE_SPENDABLE,
ISMINE_ALL_USED = ISMINE_ALL | ISMINE_USED,
ISMINE_ENUM_ELEMENTS,
};
/** used for bitflags of isminetype */