mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-19 23:03:45 +01:00
coins, refactor: Split up AddFlags to remove invalid states
CCoinsCacheEntry provided general access to its internal flags state, even though in reality it could only be clean, fresh, dirty or fresh|dirty. After it got dirtied we couldn't set the state back to clean by AddFlags(0) - tests were explicitly checking against that. This commit cleans up the public interface to make this distinction cleaner and invalid behavior impossible instead of just checked by tests. This includes the removal of redundant `inline` qualifiers (we're inside a struct). Also renamed `self` to `pair` to simplify the upcoming commits. Also modernized `EmplaceCoinInternalDANGER` since it was already modified. Co-authored-by: Andrew Toth <andrewstoth@gmail.com>
This commit is contained in:
@@ -49,7 +49,7 @@ CCoinsMap::iterator CCoinsViewCache::FetchCoin(const COutPoint &outpoint) const
|
||||
cachedCoinsUsage += ret->second.coin.DynamicMemoryUsage();
|
||||
if (ret->second.coin.IsSpent()) { // TODO GetCoin cannot return spent coins
|
||||
// The parent only has an empty entry for this outpoint; we can consider our version as fresh.
|
||||
ret->second.AddFlags(CCoinsCacheEntry::FRESH, *ret, m_sentinel);
|
||||
CCoinsCacheEntry::SetFresh(*ret, m_sentinel);
|
||||
}
|
||||
} else {
|
||||
cacheCoins.erase(ret);
|
||||
@@ -95,7 +95,8 @@ 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, m_sentinel);
|
||||
CCoinsCacheEntry::SetDirty(*it, m_sentinel);
|
||||
if (fresh) CCoinsCacheEntry::SetFresh(*it, m_sentinel);
|
||||
cachedCoinsUsage += it->second.coin.DynamicMemoryUsage();
|
||||
TRACE5(utxocache, add,
|
||||
outpoint.hash.data(),
|
||||
@@ -107,13 +108,8 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi
|
||||
|
||||
void CCoinsViewCache::EmplaceCoinInternalDANGER(COutPoint&& outpoint, Coin&& coin) {
|
||||
cachedCoinsUsage += coin.DynamicMemoryUsage();
|
||||
auto [it, inserted] = cacheCoins.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(std::move(outpoint)),
|
||||
std::forward_as_tuple(std::move(coin)));
|
||||
if (inserted) {
|
||||
it->second.AddFlags(CCoinsCacheEntry::DIRTY, *it, m_sentinel);
|
||||
}
|
||||
auto [it, inserted] = cacheCoins.try_emplace(std::move(outpoint), std::move(coin));
|
||||
if (inserted) CCoinsCacheEntry::SetDirty(*it, m_sentinel);
|
||||
}
|
||||
|
||||
void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight, bool check_for_overwrite) {
|
||||
@@ -143,7 +139,7 @@ bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
|
||||
if (it->second.IsFresh()) {
|
||||
cacheCoins.erase(it);
|
||||
} else {
|
||||
it->second.AddFlags(CCoinsCacheEntry::DIRTY, *it, m_sentinel);
|
||||
CCoinsCacheEntry::SetDirty(*it, m_sentinel);
|
||||
it->second.coin.Clear();
|
||||
}
|
||||
return true;
|
||||
@@ -203,13 +199,11 @@ bool CCoinsViewCache::BatchWrite(CoinsViewCacheCursor& cursor, const uint256 &ha
|
||||
entry.coin = it->second.coin;
|
||||
}
|
||||
cachedCoinsUsage += entry.coin.DynamicMemoryUsage();
|
||||
entry.AddFlags(CCoinsCacheEntry::DIRTY, *itUs, m_sentinel);
|
||||
CCoinsCacheEntry::SetDirty(*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, *itUs, m_sentinel);
|
||||
}
|
||||
if (it->second.IsFresh()) CCoinsCacheEntry::SetFresh(*itUs, m_sentinel);
|
||||
}
|
||||
} else {
|
||||
// Found the entry in the parent cache
|
||||
@@ -237,7 +231,7 @@ bool CCoinsViewCache::BatchWrite(CoinsViewCacheCursor& cursor, const uint256 &ha
|
||||
itUs->second.coin = it->second.coin;
|
||||
}
|
||||
cachedCoinsUsage += itUs->second.coin.DynamicMemoryUsage();
|
||||
itUs->second.AddFlags(CCoinsCacheEntry::DIRTY, *itUs, m_sentinel);
|
||||
CCoinsCacheEntry::SetDirty(*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
|
||||
|
||||
Reference in New Issue
Block a user