aboutsummaryrefslogtreecommitdiff
path: root/src/coins.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/coins.cpp')
-rw-r--r--src/coins.cpp21
1 files changed, 12 insertions, 9 deletions
diff --git a/src/coins.cpp b/src/coins.cpp
index 8e8edcca63..739cc7bc3b 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -34,7 +34,9 @@ size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }
CCoinsViewCache::CCoinsViewCache(CCoinsView* baseIn, bool deterministic) :
CCoinsViewBacked(baseIn), m_deterministic(deterministic),
cacheCoins(0, SaltedOutpointHasher(/*deterministic=*/deterministic), CCoinsMap::key_equal{}, &m_cache_coins_memory_resource)
-{}
+{
+ m_sentinel.second.SelfRef(m_sentinel);
+}
size_t CCoinsViewCache::DynamicMemoryUsage() const {
return memusage::DynamicUsage(cacheCoins) + cachedCoinsUsage;
@@ -51,7 +53,7 @@ CCoinsMap::iterator CCoinsViewCache::FetchCoin(const COutPoint &outpoint) const
if (ret->second.coin.IsSpent()) {
// The parent only has an empty entry for this outpoint; we can consider our
// version as fresh.
- ret->second.AddFlags(CCoinsCacheEntry::FRESH);
+ ret->second.AddFlags(CCoinsCacheEntry::FRESH, *ret, m_sentinel);
}
cachedCoinsUsage += ret->second.coin.DynamicMemoryUsage();
return ret;
@@ -96,7 +98,7 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi
fresh = !it->second.IsDirty();
}
it->second.coin = std::move(coin);
- it->second.AddFlags(CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0));
+ it->second.AddFlags(CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0), *it, m_sentinel);
cachedCoinsUsage += it->second.coin.DynamicMemoryUsage();
TRACE5(utxocache, add,
outpoint.hash.data(),
@@ -113,7 +115,7 @@ void CCoinsViewCache::EmplaceCoinInternalDANGER(COutPoint&& outpoint, Coin&& coi
std::forward_as_tuple(std::move(outpoint)),
std::forward_as_tuple(std::move(coin)));
if (inserted) {
- it->second.AddFlags(CCoinsCacheEntry::DIRTY);
+ it->second.AddFlags(CCoinsCacheEntry::DIRTY, *it, m_sentinel);
}
}
@@ -144,7 +146,7 @@ bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
if (it->second.IsFresh()) {
cacheCoins.erase(it);
} else {
- it->second.AddFlags(CCoinsCacheEntry::DIRTY);
+ it->second.AddFlags(CCoinsCacheEntry::DIRTY, *it, m_sentinel);
it->second.coin.Clear();
}
return true;
@@ -196,7 +198,8 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
if (!(it->second.IsFresh() && it->second.coin.IsSpent())) {
// Create the coin in the parent cache, move the data up
// and mark it as dirty.
- CCoinsCacheEntry& entry = cacheCoins[it->first];
+ itUs = cacheCoins.try_emplace(it->first).first;
+ CCoinsCacheEntry& entry{itUs->second};
if (erase) {
// The `move` call here is purely an optimization; we rely on the
// `mapCoins.erase` call in the `for` expression to actually remove
@@ -206,12 +209,12 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
entry.coin = it->second.coin;
}
cachedCoinsUsage += entry.coin.DynamicMemoryUsage();
- entry.AddFlags(CCoinsCacheEntry::DIRTY);
+ entry.AddFlags(CCoinsCacheEntry::DIRTY, *itUs, m_sentinel);
// We can mark it FRESH in the parent if it was FRESH in the child
// Otherwise it might have just been flushed from the parent's cache
// and already exist in the grandparent
if (it->second.IsFresh()) {
- entry.AddFlags(CCoinsCacheEntry::FRESH);
+ entry.AddFlags(CCoinsCacheEntry::FRESH, *itUs, m_sentinel);
}
}
} else {
@@ -241,7 +244,7 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
itUs->second.coin = it->second.coin;
}
cachedCoinsUsage += itUs->second.coin.DynamicMemoryUsage();
- itUs->second.AddFlags(CCoinsCacheEntry::DIRTY);
+ itUs->second.AddFlags(CCoinsCacheEntry::DIRTY, *itUs, m_sentinel);
// NOTE: It isn't safe to mark the coin as FRESH in the parent
// cache. If it already existed and was spent in the parent
// cache then marking it FRESH would prevent that spentness