Skip to content

Commit 593d5fe

Browse files
committed
Merge bitcoin/bitcoin#33354: txgraph: use enum Level instead of bool main_only
d45f371 txgraph: use enum Level instead of bool main_only (Pieter Wuille) Pull request description: Part of #30289. Inspired by bitcoin/bitcoin#28676 (comment). Since there has been more than one case in the development of #28676 of calling a `TxGraph` function without correctly setting the `bool main_only` argument that many of its interface functions have, make these mandatory and explicit, using an `enum class Level`: ```c++ enum class Level { TOP, //!< Refers to staging if it exists, main otherwise. MAIN //!< Always refers to the main graph, whether staging is present or not. }; ``` ACKs for top commit: instagibbs: ACK d45f371 vasild: ACK d45f371 glozow: code review ACK d45f371 Tree-SHA512: d1c4b37e8ab3ec91b414df8970cb47aa080803f68da5881c8e1cbdc6939dea7851e0f715192cf3edd44b7f328cd6b678474d41f9cd9da8cb68f6c5fd78cb71b1
2 parents ee42d59 + d45f371 commit 593d5fe

File tree

5 files changed

+103
-105
lines changed

5 files changed

+103
-105
lines changed

src/bench/txgraph.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ void BenchTxGraphTrim(benchmark::Bench& bench)
114114
graph->GetBlockBuilder();
115115
});
116116

117-
assert(!graph->IsOversized());
117+
assert(!graph->IsOversized(TxGraph::Level::TOP));
118118
// At least 99% of chains must survive.
119-
assert(graph->GetTransactionCount() >= (NUM_TOP_CHAINS * NUM_TX_PER_TOP_CHAIN * 99) / 100);
119+
assert(graph->GetTransactionCount(TxGraph::Level::TOP) >= (NUM_TOP_CHAINS * NUM_TX_PER_TOP_CHAIN * 99) / 100);
120120
}
121121

122122
} // namespace

src/test/fuzz/txgraph.cpp

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -383,14 +383,14 @@ FUZZ_TARGET(txgraph)
383383

384384
/** Function to construct the correct fee-size diagram a real graph has based on its graph
385385
* order (as reported by GetCluster(), so it works for both main and staging). */
386-
auto get_diagram_fn = [&](bool main_only) -> std::vector<FeeFrac> {
387-
int level = main_only ? 0 : sims.size() - 1;
386+
auto get_diagram_fn = [&](TxGraph::Level level_select) -> std::vector<FeeFrac> {
387+
int level = level_select == TxGraph::Level::MAIN ? 0 : sims.size() - 1;
388388
auto& sim = sims[level];
389389
// For every transaction in the graph, request its cluster, and throw them into a set.
390390
std::set<std::vector<TxGraph::Ref*>> clusters;
391391
for (auto i : sim.graph.Positions()) {
392392
auto ref = sim.GetRef(i);
393-
clusters.insert(real->GetCluster(*ref, main_only));
393+
clusters.insert(real->GetCluster(*ref, level_select));
394394
}
395395
// Compute the chunkings of each (deduplicated) cluster.
396396
size_t num_tx{0};
@@ -423,19 +423,19 @@ FUZZ_TARGET(txgraph)
423423
// operations), and the second-lowest bit as a way of selecting main vs. staging, and leave
424424
// the rest of the bits in command.
425425
bool alt = command & 1;
426-
bool use_main = command & 2;
426+
TxGraph::Level level_select = (command & 2) ? TxGraph::Level::MAIN : TxGraph::Level::TOP;
427427
command >>= 2;
428428

429429
/** Use the bottom 2 bits of command to select an entry in the block_builders vector (if
430-
* any). These use the same bits as alt/use_main, so don't use those in actions below
430+
* any). These use the same bits as alt/level_select, so don't use those in actions below
431431
* where builder_idx is used as well. */
432432
int builder_idx = block_builders.empty() ? -1 : int((orig_command & 3) % block_builders.size());
433433

434434
// Provide convenient aliases for the top simulated graph (main, or staging if it exists),
435-
// one for the simulated graph selected based on use_main (for operations that can operate
435+
// one for the simulated graph selected based on level_select (for operations that can operate
436436
// on both graphs), and one that always refers to the main graph.
437437
auto& top_sim = sims.back();
438-
auto& sel_sim = use_main ? sims[0] : top_sim;
438+
auto& sel_sim = level_select == TxGraph::Level::MAIN ? sims[0] : top_sim;
439439
auto& main_sim = sims[0];
440440

441441
// Keep decrementing command for each applicable operation, until one is hit. Multiple
@@ -546,18 +546,18 @@ FUZZ_TARGET(txgraph)
546546
break;
547547
} else if (command-- == 0) {
548548
// GetTransactionCount.
549-
assert(real->GetTransactionCount(use_main) == sel_sim.GetTransactionCount());
549+
assert(real->GetTransactionCount(level_select) == sel_sim.GetTransactionCount());
550550
break;
551551
} else if (command-- == 0) {
552552
// Exists.
553553
auto ref = pick_fn();
554-
bool exists = real->Exists(*ref, use_main);
554+
bool exists = real->Exists(*ref, level_select);
555555
bool should_exist = sel_sim.Find(ref) != SimTxGraph::MISSING;
556556
assert(exists == should_exist);
557557
break;
558558
} else if (command-- == 0) {
559559
// IsOversized.
560-
assert(sel_sim.IsOversized() == real->IsOversized(use_main));
560+
assert(sel_sim.IsOversized() == real->IsOversized(level_select));
561561
break;
562562
} else if (command-- == 0) {
563563
// GetIndividualFeerate.
@@ -590,8 +590,8 @@ FUZZ_TARGET(txgraph)
590590
} else if (!sel_sim.IsOversized() && command-- == 0) {
591591
// GetAncestors/GetDescendants.
592592
auto ref = pick_fn();
593-
auto result = alt ? real->GetDescendants(*ref, use_main)
594-
: real->GetAncestors(*ref, use_main);
593+
auto result = alt ? real->GetDescendants(*ref, level_select)
594+
: real->GetAncestors(*ref, level_select);
595595
assert(result.size() <= max_cluster_count);
596596
auto result_set = sel_sim.MakeSet(result);
597597
assert(result.size() == result_set.Count());
@@ -610,8 +610,8 @@ FUZZ_TARGET(txgraph)
610610
// Their order should not matter, shuffle them.
611611
std::shuffle(refs.begin(), refs.end(), rng);
612612
// Invoke the real function, and convert to SimPos set.
613-
auto result = alt ? real->GetDescendantsUnion(refs, use_main)
614-
: real->GetAncestorsUnion(refs, use_main);
613+
auto result = alt ? real->GetDescendantsUnion(refs, level_select)
614+
: real->GetAncestorsUnion(refs, level_select);
615615
auto result_set = sel_sim.MakeSet(result);
616616
assert(result.size() == result_set.Count());
617617
// Compute the expected result.
@@ -623,7 +623,7 @@ FUZZ_TARGET(txgraph)
623623
} else if (!sel_sim.IsOversized() && command-- == 0) {
624624
// GetCluster.
625625
auto ref = pick_fn();
626-
auto result = real->GetCluster(*ref, use_main);
626+
auto result = real->GetCluster(*ref, level_select);
627627
// Check cluster count limit.
628628
assert(result.size() <= max_cluster_count);
629629
// Require the result to be topologically valid and not contain duplicates.
@@ -712,7 +712,7 @@ FUZZ_TARGET(txgraph)
712712
// Their order should not matter, shuffle them.
713713
std::shuffle(refs.begin(), refs.end(), rng);
714714
// Invoke the real function.
715-
auto result = real->CountDistinctClusters(refs, use_main);
715+
auto result = real->CountDistinctClusters(refs, level_select);
716716
// Build a set with representatives of the clusters the Refs occur in in the
717717
// simulated graph. For each, remember the lowest-index transaction SimPos in the
718718
// cluster.
@@ -905,7 +905,7 @@ FUZZ_TARGET(txgraph)
905905

906906
// First, we need to have dependencies applied and linearizations fixed to avoid
907907
// circular dependencies in implied graph; trigger it via whatever means.
908-
real->CountDistinctClusters({}, false);
908+
real->CountDistinctClusters({}, TxGraph::Level::TOP);
909909

910910
// Gather the current clusters.
911911
auto clusters = top_sim.GetComponents();
@@ -1110,7 +1110,7 @@ FUZZ_TARGET(txgraph)
11101110

11111111
// Check that the implied ordering gives rise to a combined diagram that matches the
11121112
// diagram constructed from the individual cluster linearization chunkings.
1113-
auto main_real_diagram = get_diagram_fn(/*main_only=*/true);
1113+
auto main_real_diagram = get_diagram_fn(TxGraph::Level::MAIN);
11141114
auto main_implied_diagram = ChunkLinearization(sims[0].graph, vec1);
11151115
assert(CompareChunks(main_real_diagram, main_implied_diagram) == 0);
11161116

@@ -1141,7 +1141,7 @@ FUZZ_TARGET(txgraph)
11411141
std::greater{});
11421142
assert(main_cmp_diagram.size() + missing_main_cmp.size() == main_real_diagram.size());
11431143
// Do the same for chunks in stage_diagram missing from stage_cmp_diagram.
1144-
auto stage_real_diagram = get_diagram_fn(/*main_only=*/false);
1144+
auto stage_real_diagram = get_diagram_fn(TxGraph::Level::TOP);
11451145
std::vector<FeeFrac> missing_stage_cmp;
11461146
std::set_difference(stage_real_diagram.begin(), stage_real_diagram.end(),
11471147
stage_cmp_diagram.begin(), stage_cmp_diagram.end(),
@@ -1167,13 +1167,13 @@ FUZZ_TARGET(txgraph)
11671167

11681168
assert(real->HaveStaging() == (sims.size() > 1));
11691169

1170-
// Try to run a full comparison, for both main_only=false and main_only=true in TxGraph
1171-
// inspector functions that support both.
1172-
for (int main_only = 0; main_only < 2; ++main_only) {
1173-
auto& sim = main_only ? sims[0] : sims.back();
1170+
// Try to run a full comparison, for both TxGraph::Level::MAIN and TxGraph::Level::TOP in
1171+
// TxGraph inspector functions that support both.
1172+
for (auto level : {TxGraph::Level::TOP, TxGraph::Level::MAIN}) {
1173+
auto& sim = level == TxGraph::Level::TOP ? sims.back() : sims.front();
11741174
// Compare simple properties of the graph with the simulation.
1175-
assert(real->IsOversized(main_only) == sim.IsOversized());
1176-
assert(real->GetTransactionCount(main_only) == sim.GetTransactionCount());
1175+
assert(real->IsOversized(level) == sim.IsOversized());
1176+
assert(real->GetTransactionCount(level) == sim.GetTransactionCount());
11771177
// If the graph (and the simulation) are not oversized, perform a full comparison.
11781178
if (!sim.IsOversized()) {
11791179
auto todo = sim.graph.Positions();
@@ -1188,16 +1188,16 @@ FUZZ_TARGET(txgraph)
11881188
assert(sim.graph.FeeRate(i) == real->GetIndividualFeerate(*sim.GetRef(i)));
11891189
// Check its ancestors against simulation.
11901190
auto expect_anc = sim.graph.Ancestors(i);
1191-
auto anc = sim.MakeSet(real->GetAncestors(*sim.GetRef(i), main_only));
1191+
auto anc = sim.MakeSet(real->GetAncestors(*sim.GetRef(i), level));
11921192
assert(anc.Count() <= max_cluster_count);
11931193
assert(anc == expect_anc);
11941194
// Check its descendants against simulation.
11951195
auto expect_desc = sim.graph.Descendants(i);
1196-
auto desc = sim.MakeSet(real->GetDescendants(*sim.GetRef(i), main_only));
1196+
auto desc = sim.MakeSet(real->GetDescendants(*sim.GetRef(i), level));
11971197
assert(desc.Count() <= max_cluster_count);
11981198
assert(desc == expect_desc);
11991199
// Check the cluster the transaction is part of.
1200-
auto cluster = real->GetCluster(*sim.GetRef(i), main_only);
1200+
auto cluster = real->GetCluster(*sim.GetRef(i), level);
12011201
assert(cluster.size() <= max_cluster_count);
12021202
assert(sim.MakeSet(cluster) == component);
12031203
// Check that the cluster is reported in a valid topological order (its
@@ -1217,7 +1217,7 @@ FUZZ_TARGET(txgraph)
12171217
assert(total_size <= max_cluster_size);
12181218
// Construct a chunking object for the simulated graph, using the reported cluster
12191219
// linearization as ordering, and compare it against the reported chunk feerates.
1220-
if (sims.size() == 1 || main_only) {
1220+
if (sims.size() == 1 || level == TxGraph::Level::MAIN) {
12211221
cluster_linearize::LinearizationChunking simlinchunk(sim.graph, simlin);
12221222
DepGraphIndex idx{0};
12231223
for (unsigned chunknum = 0; chunknum < simlinchunk.NumChunksLeft(); ++chunknum) {

src/test/txgraph_tests.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,19 @@ BOOST_AUTO_TEST_CASE(txgraph_trim_zigzag)
6464
// Check that the graph is now oversized. This also forces the graph to
6565
// group clusters and compute the oversized status.
6666
graph->SanityCheck();
67-
BOOST_CHECK_EQUAL(graph->GetTransactionCount(), NUM_TOTAL_TX);
68-
BOOST_CHECK(graph->IsOversized(/*main_only=*/false));
67+
BOOST_CHECK_EQUAL(graph->GetTransactionCount(TxGraph::Level::TOP), NUM_TOTAL_TX);
68+
BOOST_CHECK(graph->IsOversized(TxGraph::Level::TOP));
6969

7070
// Call Trim() to remove transactions and bring the cluster back within limits.
7171
auto removed_refs = graph->Trim();
7272
graph->SanityCheck();
73-
BOOST_CHECK(!graph->IsOversized(/*main_only=*/false));
73+
BOOST_CHECK(!graph->IsOversized(TxGraph::Level::TOP));
7474

7575
// We only need to trim the middle bottom transaction to end up with 2 clusters each within cluster limits.
7676
BOOST_CHECK_EQUAL(removed_refs.size(), 1);
77-
BOOST_CHECK_EQUAL(graph->GetTransactionCount(), MAX_CLUSTER_COUNT * 2 - 2);
77+
BOOST_CHECK_EQUAL(graph->GetTransactionCount(TxGraph::Level::TOP), MAX_CLUSTER_COUNT * 2 - 2);
7878
for (unsigned int i = 0; i < refs.size(); ++i) {
79-
BOOST_CHECK_EQUAL(graph->Exists(refs[i]), i != (NUM_BOTTOM_TX / 2));
79+
BOOST_CHECK_EQUAL(graph->Exists(refs[i], TxGraph::Level::TOP), i != (NUM_BOTTOM_TX / 2));
8080
}
8181
}
8282

@@ -123,19 +123,19 @@ BOOST_AUTO_TEST_CASE(txgraph_trim_flower)
123123

124124
// Check that the graph is now oversized. This also forces the graph to
125125
// group clusters and compute the oversized status.
126-
BOOST_CHECK(graph->IsOversized(/*main_only=*/false));
126+
BOOST_CHECK(graph->IsOversized(TxGraph::Level::TOP));
127127

128128
// Call Trim() to remove transactions and bring the cluster back within limits.
129129
auto removed_refs = graph->Trim();
130130
graph->SanityCheck();
131-
BOOST_CHECK(!graph->IsOversized(/*main_only=*/false));
131+
BOOST_CHECK(!graph->IsOversized(TxGraph::Level::TOP));
132132

133133
// Since only the bottom transaction connects these clusters, we only need to remove it.
134134
BOOST_CHECK_EQUAL(removed_refs.size(), 1);
135-
BOOST_CHECK_EQUAL(graph->GetTransactionCount(false), MAX_CLUSTER_COUNT * 2);
136-
BOOST_CHECK(!graph->Exists(refs[0]));
135+
BOOST_CHECK_EQUAL(graph->GetTransactionCount(TxGraph::Level::TOP), MAX_CLUSTER_COUNT * 2);
136+
BOOST_CHECK(!graph->Exists(refs[0], TxGraph::Level::TOP));
137137
for (unsigned int i = 1; i < refs.size(); ++i) {
138-
BOOST_CHECK(graph->Exists(refs[i]));
138+
BOOST_CHECK(graph->Exists(refs[i], TxGraph::Level::TOP));
139139
}
140140
}
141141

@@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE(txgraph_trim_huge)
208208
graph->SanityCheck();
209209

210210
// Not oversized so far (just 1000 clusters of 64).
211-
BOOST_CHECK(!graph->IsOversized());
211+
BOOST_CHECK(!graph->IsOversized(TxGraph::Level::TOP));
212212

213213
// Construct the bottom transactions, and dependencies to the top chains.
214214
while (top_components.size() > 1) {
@@ -237,19 +237,19 @@ BOOST_AUTO_TEST_CASE(txgraph_trim_huge)
237237
graph->SanityCheck();
238238

239239
// Now we are oversized (one cluster of 64011).
240-
BOOST_CHECK(graph->IsOversized());
241-
const auto total_tx_count = graph->GetTransactionCount();
240+
BOOST_CHECK(graph->IsOversized(TxGraph::Level::TOP));
241+
const auto total_tx_count = graph->GetTransactionCount(TxGraph::Level::TOP);
242242
BOOST_CHECK(total_tx_count == top_refs.size() + bottom_refs.size());
243243
BOOST_CHECK(total_tx_count == NUM_TOTAL_TX);
244244

245245
// Call Trim() to remove transactions and bring the cluster back within limits.
246246
auto removed_refs = graph->Trim();
247-
BOOST_CHECK(!graph->IsOversized());
248-
BOOST_CHECK(removed_refs.size() == total_tx_count - graph->GetTransactionCount());
247+
BOOST_CHECK(!graph->IsOversized(TxGraph::Level::TOP));
248+
BOOST_CHECK(removed_refs.size() == total_tx_count - graph->GetTransactionCount(TxGraph::Level::TOP));
249249
graph->SanityCheck();
250250

251251
// At least 99% of chains must survive.
252-
BOOST_CHECK(graph->GetTransactionCount() >= (NUM_TOP_CHAINS * NUM_TX_PER_TOP_CHAIN * 99) / 100);
252+
BOOST_CHECK(graph->GetTransactionCount(TxGraph::Level::TOP) >= (NUM_TOP_CHAINS * NUM_TX_PER_TOP_CHAIN * 99) / 100);
253253
}
254254

255255
BOOST_AUTO_TEST_CASE(txgraph_trim_big_singletons)
@@ -277,17 +277,17 @@ BOOST_AUTO_TEST_CASE(txgraph_trim_big_singletons)
277277

278278
// Check that the graph is now oversized. This also forces the graph to
279279
// group clusters and compute the oversized status.
280-
BOOST_CHECK(graph->IsOversized(/*main_only=*/false));
280+
BOOST_CHECK(graph->IsOversized(TxGraph::Level::TOP));
281281

282282
// Call Trim() to remove transactions and bring the cluster back within limits.
283283
auto removed_refs = graph->Trim();
284284
graph->SanityCheck();
285-
BOOST_CHECK_EQUAL(graph->GetTransactionCount(), NUM_TOTAL_TX - 6);
286-
BOOST_CHECK(!graph->IsOversized(/*main_only=*/false));
285+
BOOST_CHECK_EQUAL(graph->GetTransactionCount(TxGraph::Level::TOP), NUM_TOTAL_TX - 6);
286+
BOOST_CHECK(!graph->IsOversized(TxGraph::Level::TOP));
287287

288288
// Check that all the oversized transactions were removed.
289289
for (unsigned int i = 0; i < refs.size(); ++i) {
290-
BOOST_CHECK_EQUAL(graph->Exists(refs[i]), i != 88 && i % 20 != 0);
290+
BOOST_CHECK_EQUAL(graph->Exists(refs[i], TxGraph::Level::TOP), i != 88 && i % 20 != 0);
291291
}
292292
}
293293

0 commit comments

Comments
 (0)