diff --git a/src/coins.cpp b/src/coins.cpp index ecc435e6e7d..8c32752a3aa 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -51,7 +51,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.flags = CCoinsCacheEntry::FRESH; + ret->second.AddFlags(CCoinsCacheEntry::FRESH); } cachedCoinsUsage += ret->second.coin.DynamicMemoryUsage(); return ret; @@ -96,7 +96,7 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi fresh = !it->second.IsDirty(); } it->second.coin = std::move(coin); - it->second.flags |= CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0); + it->second.AddFlags(CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0)); cachedCoinsUsage += it->second.coin.DynamicMemoryUsage(); TRACE5(utxocache, add, outpoint.hash.data(), @@ -141,7 +141,7 @@ bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) { if (it->second.IsFresh()) { cacheCoins.erase(it); } else { - it->second.flags |= CCoinsCacheEntry::DIRTY; + it->second.AddFlags(CCoinsCacheEntry::DIRTY); it->second.coin.Clear(); } return true; @@ -203,12 +203,12 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn entry.coin = it->second.coin; } cachedCoinsUsage += entry.coin.DynamicMemoryUsage(); - entry.flags = CCoinsCacheEntry::DIRTY; + entry.AddFlags(CCoinsCacheEntry::DIRTY); // 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.flags |= CCoinsCacheEntry::FRESH; + entry.AddFlags(CCoinsCacheEntry::FRESH); } } } else { @@ -238,7 +238,7 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn itUs->second.coin = it->second.coin; } cachedCoinsUsage += itUs->second.coin.DynamicMemoryUsage(); - itUs->second.flags |= CCoinsCacheEntry::DIRTY; + itUs->second.AddFlags(CCoinsCacheEntry::DIRTY); // 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 @@ -273,7 +273,7 @@ bool CCoinsViewCache::Sync() cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage(); it = cacheCoins.erase(it); } else { - it->second.flags = 0; + it->second.ClearFlags(); ++it; } } diff --git a/src/coins.h b/src/coins.h index df4d7a78831..b85c316ee51 100644 --- a/src/coins.h +++ b/src/coins.h @@ -131,6 +131,11 @@ struct CCoinsCacheEntry explicit CCoinsCacheEntry(Coin&& coin_) : coin(std::move(coin_)), flags(0) {} CCoinsCacheEntry(Coin&& coin_, unsigned char flag) : coin(std::move(coin_)), flags(flag) {} + inline void AddFlags(unsigned char flags) noexcept { this->flags |= flags; } + inline void ClearFlags() noexcept + { + flags = 0; + } inline unsigned char GetFlags() const noexcept { return flags; } inline bool IsDirty() const noexcept { return flags & DIRTY; } inline bool IsFresh() const noexcept { return flags & FRESH; } diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 1502595cbb5..8ac972c4e0d 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -584,7 +584,7 @@ static size_t InsertCoinsMapEntry(CCoinsMap& map, CAmount value, char flags) } assert(flags != NO_ENTRY); CCoinsCacheEntry entry; - entry.flags = flags; + entry.AddFlags(flags); SetCoinsValue(value, entry.coin); auto inserted = map.emplace(OUTPOINT, std::move(entry)); assert(inserted.second); diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp index 41c971c237b..5f942eba671 100644 --- a/src/test/fuzz/coins_view.cpp +++ b/src/test/fuzz/coins_view.cpp @@ -125,7 +125,7 @@ FUZZ_TARGET(coins_view, .init = initialize_coins_view) LIMITED_WHILE(good_data && fuzzed_data_provider.ConsumeBool(), 10'000) { CCoinsCacheEntry coins_cache_entry; - coins_cache_entry.flags = fuzzed_data_provider.ConsumeIntegral(); + coins_cache_entry.AddFlags(fuzzed_data_provider.ConsumeIntegral()); if (fuzzed_data_provider.ConsumeBool()) { coins_cache_entry.coin = random_coin; } else {