aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSamuel Dobson <dobsonsa68@gmail.com>2020-01-17 14:15:10 +1300
committerSamuel Dobson <dobsonsa68@gmail.com>2020-01-17 14:15:33 +1300
commit7fb94c0ed418202ba0b49f5886bcf0c9cac22552 (patch)
tree6cfc5eb5d604be934db936c09ef6d495973a821b /src
parent95ca6aeec7b8d9dbf39e3a036a5c238634ce3793 (diff)
parent2b1641492fbf81e2c5a95f3e580811ca8700adc5 (diff)
Merge #17889: wallet: Improve CWallet:MarkDestinationsDirty
2b1641492fbf81e2c5a95f3e580811ca8700adc5 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 2b1641492fbf81e2c5a95f3e580811ca8700adc5 Tree-SHA512: 479dc2dde4b653b856e3d6a0c59a34fe33e963eb131a2d88552a8b30471b8725a087888fe5d7db6e4ee19b74072fe64441497f033be7d1931637f756e0d8fef5
Diffstat (limited to 'src')
-rw-r--r--src/wallet/test/coinselector_tests.cpp1
-rw-r--r--src/wallet/wallet.cpp5
-rw-r--r--src/wallet/wallet.h8
3 files changed, 12 insertions, 2 deletions
diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp
index 7e9f88f6b7..0e0f06c64c 100644
--- a/src/wallet/test/coinselector_tests.cpp
+++ b/src/wallet/test/coinselector_tests.cpp
@@ -78,6 +78,7 @@ static void add_coin(CWallet& wallet, const CAmount& nValue, int nAge = 6*24, bo
if (fIsFromMe)
{
wtx->m_amounts[CWalletTx::DEBIT].Set(ISMINE_SPENDABLE, 1);
+ wtx->m_is_cache_empty = false;
}
COutput output(wtx.get(), nInput, nAge, true /* spendable */, true /* solvable */, true /* safe */);
vCoins.push_back(output);
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index c30125e827..724997a36d 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1795,6 +1795,7 @@ CAmount CWalletTx::GetCachableAmount(AmountType type, const isminefilter& filter
auto& amount = m_amounts[type];
if (recalculate || !amount.m_cached[filter]) {
amount.Set(filter, type == DEBIT ? pwallet->GetDebit(*tx, filter) : pwallet->GetCredit(*tx, filter));
+ m_is_cache_empty = false;
}
return amount.m_value[filter];
}
@@ -1871,6 +1872,7 @@ CAmount CWalletTx::GetAvailableCredit(bool fUseCache, const isminefilter& filter
if (allow_cache) {
m_amounts[AVAILABLE_CREDIT].Set(filter, nCredit);
+ m_is_cache_empty = false;
}
return nCredit;
@@ -3171,10 +3173,9 @@ int64_t CWallet::GetOldestKeyPoolTime()
void CWallet::MarkDestinationsDirty(const std::set<CTxDestination>& destinations) {
for (auto& entry : mapWallet) {
CWalletTx& wtx = entry.second;
-
+ if (wtx.m_is_cache_empty) continue;
for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
CTxDestination dst;
-
if (ExtractDestination(wtx.tx->vout[i].scriptPubKey, dst) && destinations.count(dst)) {
wtx.MarkDirty();
break;
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 846a502614..6835f33b52 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -313,6 +313,13 @@ public:
enum AmountType { DEBIT, CREDIT, IMMATURE_CREDIT, AVAILABLE_CREDIT, AMOUNTTYPE_ENUM_ELEMENTS };
CAmount GetCachableAmount(AmountType type, const isminefilter& filter, bool recalculate = false) const;
mutable CachableAmount m_amounts[AMOUNTTYPE_ENUM_ELEMENTS];
+ /**
+ * This flag is true if all m_amounts caches are empty. This is particularly
+ * useful in places where MarkDirty is conditionally called and the
+ * condition can be expensive and thus can be skipped if the flag is true.
+ * See MarkDestinationsDirty.
+ */
+ mutable bool m_is_cache_empty{true};
mutable bool fChangeCached;
mutable bool fInMempool;
mutable CAmount nChangeCached;
@@ -439,6 +446,7 @@ public:
m_amounts[IMMATURE_CREDIT].Reset();
m_amounts[AVAILABLE_CREDIT].Reset();
fChangeCached = false;
+ m_is_cache_empty = true;
}
void BindWallet(CWallet *pwalletIn)