Skip to content

Commit 7fb94c0

Browse files
committed
Merge #17889: wallet: Improve CWallet:MarkDestinationsDirty
2b16414 wallet: Improve CWallet:MarkDestinationsDirty (João Barbosa) Pull request description: Improve `CWallet:MarkDestinationsDirty` by skipping transactions that already have the cache invalidated. Skipping a transaction avoids at worst case extracting all output destinations. ACKs for top commit: meshcollider: re-utACK 2b16414 Tree-SHA512: 479dc2dde4b653b856e3d6a0c59a34fe33e963eb131a2d88552a8b30471b8725a087888fe5d7db6e4ee19b74072fe64441497f033be7d1931637f756e0d8fef5
2 parents 95ca6ae + 2b16414 commit 7fb94c0

File tree

3 files changed

+12
-2
lines changed

3 files changed

+12
-2
lines changed

src/wallet/test/coinselector_tests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ static void add_coin(CWallet& wallet, const CAmount& nValue, int nAge = 6*24, bo
7878
if (fIsFromMe)
7979
{
8080
wtx->m_amounts[CWalletTx::DEBIT].Set(ISMINE_SPENDABLE, 1);
81+
wtx->m_is_cache_empty = false;
8182
}
8283
COutput output(wtx.get(), nInput, nAge, true /* spendable */, true /* solvable */, true /* safe */);
8384
vCoins.push_back(output);

src/wallet/wallet.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,6 +1795,7 @@ CAmount CWalletTx::GetCachableAmount(AmountType type, const isminefilter& filter
17951795
auto& amount = m_amounts[type];
17961796
if (recalculate || !amount.m_cached[filter]) {
17971797
amount.Set(filter, type == DEBIT ? pwallet->GetDebit(*tx, filter) : pwallet->GetCredit(*tx, filter));
1798+
m_is_cache_empty = false;
17981799
}
17991800
return amount.m_value[filter];
18001801
}
@@ -1871,6 +1872,7 @@ CAmount CWalletTx::GetAvailableCredit(bool fUseCache, const isminefilter& filter
18711872

18721873
if (allow_cache) {
18731874
m_amounts[AVAILABLE_CREDIT].Set(filter, nCredit);
1875+
m_is_cache_empty = false;
18741876
}
18751877

18761878
return nCredit;
@@ -3171,10 +3173,9 @@ int64_t CWallet::GetOldestKeyPoolTime()
31713173
void CWallet::MarkDestinationsDirty(const std::set<CTxDestination>& destinations) {
31723174
for (auto& entry : mapWallet) {
31733175
CWalletTx& wtx = entry.second;
3174-
3176+
if (wtx.m_is_cache_empty) continue;
31753177
for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
31763178
CTxDestination dst;
3177-
31783179
if (ExtractDestination(wtx.tx->vout[i].scriptPubKey, dst) && destinations.count(dst)) {
31793180
wtx.MarkDirty();
31803181
break;

src/wallet/wallet.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,13 @@ class CWalletTx
313313
enum AmountType { DEBIT, CREDIT, IMMATURE_CREDIT, AVAILABLE_CREDIT, AMOUNTTYPE_ENUM_ELEMENTS };
314314
CAmount GetCachableAmount(AmountType type, const isminefilter& filter, bool recalculate = false) const;
315315
mutable CachableAmount m_amounts[AMOUNTTYPE_ENUM_ELEMENTS];
316+
/**
317+
* This flag is true if all m_amounts caches are empty. This is particularly
318+
* useful in places where MarkDirty is conditionally called and the
319+
* condition can be expensive and thus can be skipped if the flag is true.
320+
* See MarkDestinationsDirty.
321+
*/
322+
mutable bool m_is_cache_empty{true};
316323
mutable bool fChangeCached;
317324
mutable bool fInMempool;
318325
mutable CAmount nChangeCached;
@@ -439,6 +446,7 @@ class CWalletTx
439446
m_amounts[IMMATURE_CREDIT].Reset();
440447
m_amounts[AVAILABLE_CREDIT].Reset();
441448
fChangeCached = false;
449+
m_is_cache_empty = true;
442450
}
443451

444452
void BindWallet(CWallet *pwalletIn)

0 commit comments

Comments
 (0)