@@ -34,7 +34,9 @@ size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }
3434CCoinsViewCache::CCoinsViewCache (CCoinsView* baseIn, bool deterministic) :
3535 CCoinsViewBacked(baseIn), m_deterministic(deterministic),
3636 cacheCoins(0 , SaltedOutpointHasher(/* deterministic=*/ deterministic), CCoinsMap::key_equal{}, &m_cache_coins_memory_resource)
37- {}
37+ {
38+ m_sentinel.second .SelfRef (m_sentinel);
39+ }
3840
3941size_t CCoinsViewCache::DynamicMemoryUsage () const {
4042 return memusage::DynamicUsage (cacheCoins) + cachedCoinsUsage;
@@ -51,7 +53,7 @@ CCoinsMap::iterator CCoinsViewCache::FetchCoin(const COutPoint &outpoint) const
5153 if (ret->second .coin .IsSpent ()) {
5254 // The parent only has an empty entry for this outpoint; we can consider our
5355 // version as fresh.
54- ret->second .AddFlags (CCoinsCacheEntry::FRESH);
56+ ret->second .AddFlags (CCoinsCacheEntry::FRESH, *ret, m_sentinel );
5557 }
5658 cachedCoinsUsage += ret->second .coin .DynamicMemoryUsage ();
5759 return ret;
@@ -96,7 +98,7 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi
9698 fresh = !it->second .IsDirty ();
9799 }
98100 it->second .coin = std::move (coin);
99- it->second .AddFlags (CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0 ));
101+ it->second .AddFlags (CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0 ), *it, m_sentinel );
100102 cachedCoinsUsage += it->second .coin .DynamicMemoryUsage ();
101103 TRACE5 (utxocache, add,
102104 outpoint.hash .data (),
@@ -113,7 +115,7 @@ void CCoinsViewCache::EmplaceCoinInternalDANGER(COutPoint&& outpoint, Coin&& coi
113115 std::forward_as_tuple (std::move (outpoint)),
114116 std::forward_as_tuple (std::move (coin)));
115117 if (inserted) {
116- it->second .AddFlags (CCoinsCacheEntry::DIRTY);
118+ it->second .AddFlags (CCoinsCacheEntry::DIRTY, *it, m_sentinel );
117119 }
118120}
119121
@@ -144,7 +146,7 @@ bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
144146 if (it->second .IsFresh ()) {
145147 cacheCoins.erase (it);
146148 } else {
147- it->second .AddFlags (CCoinsCacheEntry::DIRTY);
149+ it->second .AddFlags (CCoinsCacheEntry::DIRTY, *it, m_sentinel );
148150 it->second .coin .Clear ();
149151 }
150152 return true ;
@@ -196,7 +198,8 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
196198 if (!(it->second .IsFresh () && it->second .coin .IsSpent ())) {
197199 // Create the coin in the parent cache, move the data up
198200 // and mark it as dirty.
199- CCoinsCacheEntry& entry = cacheCoins[it->first ];
201+ itUs = cacheCoins.try_emplace (it->first ).first ;
202+ CCoinsCacheEntry& entry{itUs->second };
200203 if (erase) {
201204 // The `move` call here is purely an optimization; we rely on the
202205 // `mapCoins.erase` call in the `for` expression to actually remove
@@ -206,12 +209,12 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
206209 entry.coin = it->second .coin ;
207210 }
208211 cachedCoinsUsage += entry.coin .DynamicMemoryUsage ();
209- entry.AddFlags (CCoinsCacheEntry::DIRTY);
212+ entry.AddFlags (CCoinsCacheEntry::DIRTY, *itUs, m_sentinel );
210213 // We can mark it FRESH in the parent if it was FRESH in the child
211214 // Otherwise it might have just been flushed from the parent's cache
212215 // and already exist in the grandparent
213216 if (it->second .IsFresh ()) {
214- entry.AddFlags (CCoinsCacheEntry::FRESH);
217+ entry.AddFlags (CCoinsCacheEntry::FRESH, *itUs, m_sentinel );
215218 }
216219 }
217220 } else {
@@ -241,7 +244,7 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
241244 itUs->second .coin = it->second .coin ;
242245 }
243246 cachedCoinsUsage += itUs->second .coin .DynamicMemoryUsage ();
244- itUs->second .AddFlags (CCoinsCacheEntry::DIRTY);
247+ itUs->second .AddFlags (CCoinsCacheEntry::DIRTY, *itUs, m_sentinel );
245248 // NOTE: It isn't safe to mark the coin as FRESH in the parent
246249 // cache. If it already existed and was spent in the parent
247250 // cache then marking it FRESH would prevent that spentness
0 commit comments