Skip to content

Commit 0a159f0

Browse files
committed
test, refactor: Remove remaining unbounded flags from coins_tests
1 parent c0b4b2c commit 0a159f0

File tree

1 file changed

+42
-33
lines changed

1 file changed

+42
-33
lines changed

src/test/coins_tests.cpp

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -567,38 +567,47 @@ constexpr CAmount VALUE1{100};
567567
constexpr CAmount VALUE2{200};
568568
constexpr CAmount VALUE3{300};
569569

570-
constexpr char DIRTY{CCoinsCacheEntry::DIRTY};
571-
constexpr char FRESH{CCoinsCacheEntry::FRESH};
572-
constexpr char CLEAN{0};
573-
574570
struct CoinEntry {
571+
enum class State { CLEAN, DIRTY, FRESH, DIRTY_FRESH };
572+
575573
const CAmount value;
576-
const char flags;
574+
const State state;
577575

578-
constexpr CoinEntry(const CAmount v, const char s) : value{v}, flags{s} {}
576+
constexpr CoinEntry(const CAmount v, const State s) : value{v}, state{s} {}
579577

580578
bool operator==(const CoinEntry& o) const = default;
581-
friend std::ostream& operator<<(std::ostream& os, const CoinEntry& e) { return os << e.value << ", " << e.flags; }
579+
friend std::ostream& operator<<(std::ostream& os, const CoinEntry& e) { return os << e.value << ", " << e.state; }
580+
581+
constexpr bool IsDirtyFresh() const { return state == State::DIRTY_FRESH; }
582+
constexpr bool IsDirty() const { return state == State::DIRTY || IsDirtyFresh(); }
583+
constexpr bool IsFresh() const { return state == State::FRESH || IsDirtyFresh(); }
584+
585+
static constexpr State ToState(const bool is_dirty, const bool is_fresh) {
586+
if (is_dirty && is_fresh) return State::DIRTY_FRESH;
587+
if (is_dirty) return State::DIRTY;
588+
if (is_fresh) return State::FRESH;
589+
return State::CLEAN;
590+
}
582591
};
583592

584593
using MaybeCoin = std::optional<CoinEntry>;
585594
using CoinOrError = std::variant<MaybeCoin, std::string>;
586595

587596
constexpr MaybeCoin MISSING {std::nullopt};
588-
constexpr MaybeCoin SPENT_DIRTY {{SPENT, DIRTY}};
589-
constexpr MaybeCoin SPENT_DIRTY_FRESH {{SPENT, DIRTY | FRESH}};
590-
constexpr MaybeCoin SPENT_FRESH {{SPENT, FRESH}};
591-
constexpr MaybeCoin SPENT_CLEAN {{SPENT, CLEAN}};
592-
constexpr MaybeCoin VALUE1_DIRTY {{VALUE1, DIRTY}};
593-
constexpr MaybeCoin VALUE1_DIRTY_FRESH{{VALUE1, DIRTY | FRESH}};
594-
constexpr MaybeCoin VALUE1_FRESH {{VALUE1, FRESH}};
595-
constexpr MaybeCoin VALUE1_CLEAN {{VALUE1, CLEAN}};
596-
constexpr MaybeCoin VALUE2_DIRTY {{VALUE2, DIRTY}};
597-
constexpr MaybeCoin VALUE2_DIRTY_FRESH{{VALUE2, DIRTY | FRESH}};
598-
constexpr MaybeCoin VALUE2_FRESH {{VALUE2, FRESH}};
599-
constexpr MaybeCoin VALUE2_CLEAN {{VALUE2, CLEAN}};
600-
constexpr MaybeCoin VALUE3_DIRTY {{VALUE3, DIRTY}};
601-
constexpr MaybeCoin VALUE3_DIRTY_FRESH{{VALUE3, DIRTY | FRESH}};
597+
constexpr MaybeCoin SPENT_DIRTY {{SPENT, CoinEntry::State::DIRTY}};
598+
constexpr MaybeCoin SPENT_DIRTY_FRESH {{SPENT, CoinEntry::State::DIRTY_FRESH}};
599+
constexpr MaybeCoin SPENT_FRESH {{SPENT, CoinEntry::State::FRESH}};
600+
constexpr MaybeCoin SPENT_CLEAN {{SPENT, CoinEntry::State::CLEAN}};
601+
constexpr MaybeCoin VALUE1_DIRTY {{VALUE1, CoinEntry::State::DIRTY}};
602+
constexpr MaybeCoin VALUE1_DIRTY_FRESH{{VALUE1, CoinEntry::State::DIRTY_FRESH}};
603+
constexpr MaybeCoin VALUE1_FRESH {{VALUE1, CoinEntry::State::FRESH}};
604+
constexpr MaybeCoin VALUE1_CLEAN {{VALUE1, CoinEntry::State::CLEAN}};
605+
constexpr MaybeCoin VALUE2_DIRTY {{VALUE2, CoinEntry::State::DIRTY}};
606+
constexpr MaybeCoin VALUE2_DIRTY_FRESH{{VALUE2, CoinEntry::State::DIRTY_FRESH}};
607+
constexpr MaybeCoin VALUE2_FRESH {{VALUE2, CoinEntry::State::FRESH}};
608+
constexpr MaybeCoin VALUE2_CLEAN {{VALUE2, CoinEntry::State::CLEAN}};
609+
constexpr MaybeCoin VALUE3_DIRTY {{VALUE3, CoinEntry::State::DIRTY}};
610+
constexpr MaybeCoin VALUE3_DIRTY_FRESH{{VALUE3, CoinEntry::State::DIRTY_FRESH}};
602611

603612
constexpr auto EX_OVERWRITE_UNSPENT{"Attempted to overwrite an unspent coin (when possible_overwrite is false)"};
604613
constexpr auto EX_FRESH_MISAPPLIED {"FRESH flag misapplied to coin that exists in parent cache"};
@@ -621,22 +630,22 @@ static size_t InsertCoinsMapEntry(CCoinsMap& map, CoinsCachePair& sentinel, cons
621630
SetCoinsValue(cache_coin.value, entry.coin);
622631
auto [iter, inserted] = map.emplace(OUTPOINT, std::move(entry));
623632
assert(inserted);
624-
if (cache_coin.flags & DIRTY) CCoinsCacheEntry::SetDirty(*iter, sentinel);
625-
if (cache_coin.flags & FRESH) CCoinsCacheEntry::SetFresh(*iter, sentinel);
633+
if (cache_coin.IsDirty()) CCoinsCacheEntry::SetDirty(*iter, sentinel);
634+
if (cache_coin.IsFresh()) CCoinsCacheEntry::SetFresh(*iter, sentinel);
626635
return iter->second.coin.DynamicMemoryUsage();
627636
}
628637

629-
MaybeCoin GetCoinsMapEntry(const CCoinsMap& map, const COutPoint& outp = OUTPOINT)
638+
static MaybeCoin GetCoinsMapEntry(const CCoinsMap& map, const COutPoint& outp = OUTPOINT)
630639
{
631640
if (auto it{map.find(outp)}; it != map.end()) {
632641
return CoinEntry{
633642
it->second.coin.IsSpent() ? SPENT : it->second.coin.out.nValue,
634-
static_cast<char>((it->second.IsDirty() ? DIRTY : 0) | (it->second.IsFresh() ? FRESH : 0))};
643+
CoinEntry::ToState(it->second.IsDirty(), it->second.IsFresh())};
635644
}
636645
return MISSING;
637646
}
638647

639-
void WriteCoinsViewEntry(CCoinsView& view, const MaybeCoin& cache_coin)
648+
static void WriteCoinsViewEntry(CCoinsView& view, const MaybeCoin& cache_coin)
640649
{
641650
CoinsCachePair sentinel{};
642651
sentinel.second.SelfRef(sentinel);
@@ -652,7 +661,7 @@ class SingleEntryCacheTest
652661
public:
653662
SingleEntryCacheTest(const CAmount base_value, const MaybeCoin& cache_coin)
654663
{
655-
auto base_cache_coin{base_value == ABSENT ? MISSING : CoinEntry{base_value, DIRTY}};
664+
auto base_cache_coin{base_value == ABSENT ? MISSING : CoinEntry{base_value, CoinEntry::State::DIRTY}};
656665
WriteCoinsViewEntry(base, base_cache_coin);
657666
if (cache_coin) cache.usage() += InsertCoinsMapEntry(cache.map(), cache.sentinel(), *cache_coin);
658667
}
@@ -800,7 +809,7 @@ BOOST_AUTO_TEST_CASE(ccoins_add)
800809
}
801810
}
802811

803-
void CheckWriteCoins(const MaybeCoin& parent, const MaybeCoin& child, const CoinOrError& expected)
812+
static void CheckWriteCoins(const MaybeCoin& parent, const MaybeCoin& child, const CoinOrError& expected)
804813
{
805814
SingleEntryCacheTest test{ABSENT, parent};
806815
auto write_coins{[&] { WriteCoinsViewEntry(test.cache, child); }};
@@ -870,7 +879,7 @@ BOOST_AUTO_TEST_CASE(ccoins_write)
870879
CheckWriteCoins(VALUE1_DIRTY_FRESH, VALUE2_DIRTY, VALUE2_DIRTY_FRESH );
871880
CheckWriteCoins(VALUE1_DIRTY_FRESH, VALUE2_DIRTY_FRESH, EX_FRESH_MISAPPLIED);
872881

873-
// The checks above omit cases where the child flags are not DIRTY, since
882+
// The checks above omit cases where the child state is not DIRTY, since
874883
// they would be too repetitive (the parent cache is never updated in these
875884
// cases). The loop below covers these cases and makes sure the parent cache
876885
// is always left unchanged.
@@ -946,7 +955,7 @@ void TestFlushBehavior(
946955
BOOST_CHECK(!base.HaveCoin(outp));
947956
BOOST_CHECK(view->HaveCoin(outp));
948957

949-
BOOST_CHECK_EQUAL(GetCoinsMapEntry(view->map(), outp), CoinEntry(coin.out.nValue, DIRTY|FRESH));
958+
BOOST_CHECK_EQUAL(GetCoinsMapEntry(view->map(), outp), CoinEntry(coin.out.nValue, CoinEntry::State::DIRTY_FRESH));
950959

951960
// --- 2. Flushing all caches (without erasing)
952961
//
@@ -958,7 +967,7 @@ void TestFlushBehavior(
958967

959968
// --- 3. Ensuring the entry still exists in the cache and has been written to parent
960969
//
961-
BOOST_CHECK_EQUAL(GetCoinsMapEntry(view->map(), outp), CoinEntry(coin.out.nValue, CLEAN)); // Flags should have been wiped.
970+
BOOST_CHECK_EQUAL(GetCoinsMapEntry(view->map(), outp), CoinEntry(coin.out.nValue, CoinEntry::State::CLEAN)); // State should have been wiped.
962971

963972
// Both views should now have the coin.
964973
BOOST_CHECK(base.HaveCoin(outp));
@@ -978,7 +987,7 @@ void TestFlushBehavior(
978987
//
979988
BOOST_CHECK(!GetCoinsMapEntry(view->map(), outp));
980989
view->AccessCoin(outp);
981-
BOOST_CHECK_EQUAL(GetCoinsMapEntry(view->map(), outp), CoinEntry(coin.out.nValue, CLEAN));
990+
BOOST_CHECK_EQUAL(GetCoinsMapEntry(view->map(), outp), CoinEntry(coin.out.nValue, CoinEntry::State::CLEAN));
982991
}
983992

984993
// Can't overwrite an entry without specifying that an overwrite is
@@ -1043,7 +1052,7 @@ void TestFlushBehavior(
10431052
all_caches[0]->AddCoin(outp, std::move(coin), false);
10441053

10451054
// Coin should be FRESH in the cache.
1046-
BOOST_CHECK_EQUAL(GetCoinsMapEntry(all_caches[0]->map(), outp), CoinEntry(coin_val, DIRTY|FRESH));
1055+
BOOST_CHECK_EQUAL(GetCoinsMapEntry(all_caches[0]->map(), outp), CoinEntry(coin_val, CoinEntry::State::DIRTY_FRESH));
10471056
// Base shouldn't have seen coin.
10481057
BOOST_CHECK(!base.HaveCoin(outp));
10491058

0 commit comments

Comments
 (0)