It does make the callsites less elegant. Here’s the diff:
0diff --git a/src/coins.cpp b/src/coins.cpp
1index 5caf0e2789..81be5967b7 100644
2--- a/src/coins.cpp
3+++ b/src/coins.cpp
4@@ -96,7 +96,11 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi
5 cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
6 }
7 it->second.coin = std::move(coin);
8- CCoinsCacheEntry::SetDirty(*it, m_sentinel, fresh);
9+ if (fresh) {
10+ CCoinsCacheEntry::SetFreshAndDirty(*it, m_sentinel);
11+ } else {
12+ CCoinsCacheEntry::SetDirty(*it, m_sentinel);
13+ }
14 cachedCoinsUsage += it->second.coin.DynamicMemoryUsage();
15 TRACEPOINT(utxocache, add,
16 outpoint.hash.data(),
17@@ -206,7 +210,11 @@ bool CCoinsViewCache::BatchWrite(CoinsViewCacheCursor& cursor, const uint256 &ha
18 // We can mark it FRESH in the parent if it was FRESH in the child
19 // Otherwise it might have just been flushed from the parent's cache
20 // and already exist in the grandparent
21- CCoinsCacheEntry::SetDirty(*itUs, m_sentinel, it->second.IsFresh());
22+ if (it->second.IsFresh()) {
23+ CCoinsCacheEntry::SetFreshAndDirty(*itUs, m_sentinel);
24+ } else {
25+ CCoinsCacheEntry::SetDirty(*itUs, m_sentinel);
26+ }
27 }
28 } else {
29 // Found the entry in the parent cache
30diff --git a/src/coins.h b/src/coins.h
31index e1463d1236..ceb075bd6f 100644
32--- a/src/coins.h
33+++ b/src/coins.h
34@@ -109,7 +109,7 @@ struct CCoinsCacheEntry
35 private:
36 /**
37 * These are used to create a doubly linked list of flagged entries.
38- * They are set in SetDirty and unset in SetClean.
39+ * They are set in SetDirty/SetFreshAndDirty and unset in SetClean.
40 * A flagged entry is any entry that is DIRTY or DIRTY-and-FRESH.
41 *
42 * DIRTY entries are tracked so that only modified entries can be passed to
43@@ -167,9 +167,14 @@ public:
44 SetClean();
45 }
46
47- static void SetDirty(CoinsCachePair& pair, CoinsCachePair& sentinel, bool fresh = false) noexcept
48+ static void SetDirty(CoinsCachePair& pair, CoinsCachePair& sentinel) noexcept
49 {
50- AddFlags(fresh ? DIRTY | FRESH : DIRTY, pair, sentinel);
51+ AddFlags(DIRTY, pair, sentinel);
52+ }
53+
54+ static void SetFreshAndDirty(CoinsCachePair& pair, CoinsCachePair& sentinel) noexcept
55+ {
56+ AddFlags(DIRTY | FRESH, pair, sentinel);
57 }
58
59 void SetClean() noexcept
60diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp
61index cc5146a915..c499fde360 100644
62--- a/src/test/coins_tests.cpp
63+++ b/src/test/coins_tests.cpp
64@@ -633,8 +633,10 @@ static size_t InsertCoinsMapEntry(CCoinsMap& map, CoinsCachePair& sentinel, cons
65 SetCoinsValue(cache_coin.value, entry.coin);
66 auto [iter, inserted] = map.emplace(OUTPOINT, std::move(entry));
67 assert(inserted);
68- if (cache_coin.IsDirty()) {
69- CCoinsCacheEntry::SetDirty(*iter, sentinel, cache_coin.IsDirtyFresh());
70+ if (cache_coin.IsDirtyFresh()) {
71+ CCoinsCacheEntry::SetFreshAndDirty(*iter, sentinel);
72+ } else if (cache_coin.IsDirty()) {
73+ CCoinsCacheEntry::SetDirty(*iter, sentinel);
74 }
75 return iter->second.coin.DynamicMemoryUsage();
76 }
77diff --git a/src/test/coinscachepair_tests.cpp b/src/test/coinscachepair_tests.cpp
78index 1110f1cdd1..73fbf784c5 100644
79--- a/src/test/coinscachepair_tests.cpp
80+++ b/src/test/coinscachepair_tests.cpp
81@@ -155,7 +155,7 @@ BOOST_AUTO_TEST_CASE(linked_list_set_state)
82 BOOST_CHECK_EQUAL(sentinel.second.Prev(), &n1);
83
84 // Check that setting DIRTY and FRESH on new node inserts it after n1
85- CCoinsCacheEntry::SetDirty(n2, sentinel, /*fresh=*/true);
86+ CCoinsCacheEntry::SetFreshAndDirty(n2, sentinel);
87 BOOST_CHECK(n2.second.IsFresh() && n2.second.IsDirty());
88 BOOST_CHECK_EQUAL(n2.second.Next(), &sentinel);
89 BOOST_CHECK_EQUAL(n2.second.Prev(), &n1);
90@@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE(linked_list_set_state)
91 BOOST_CHECK_EQUAL(sentinel.second.Prev(), &n2);
92
93 // Check that we can set extra state, but they don't change our position
94- CCoinsCacheEntry::SetDirty(n1, sentinel, /*fresh=*/true);
95+ CCoinsCacheEntry::SetFreshAndDirty(n1, sentinel);
96 BOOST_CHECK(n1.second.IsDirty() && n1.second.IsFresh());
97 BOOST_CHECK_EQUAL(n1.second.Next(), &n2);
98 BOOST_CHECK_EQUAL(n1.second.Prev(), &sentinel);
99diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp
100index d538a62825..0a2df0fdb6 100644
101--- a/src/test/fuzz/coins_view.cpp
102+++ b/src/test/fuzz/coins_view.cpp
103@@ -143,7 +143,13 @@ void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsView& backend
104 coins_cache_entry.coin = *opt_coin;
105 }
106 auto it{coins_map.emplace(random_out_point, std::move(coins_cache_entry)).first};
107- if (dirty) CCoinsCacheEntry::SetDirty(*it, sentinel, fresh);
108+ if (dirty) {
109+ if (fresh) {
110+ CCoinsCacheEntry::SetFreshAndDirty(*it, sentinel);
111+ } else {
112+ CCoinsCacheEntry::SetDirty(*it, sentinel);
113+ }
114+ }
115 }
116 bool expected_code_path = false;
117 try {