mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-10 22:58:40 +02:00
clusterlin: use 'cost' terminology instead of 'iters' (refactor)
This commit is contained in:
committed by
Pieter Wuille
parent
9e7129df29
commit
ecc9a84f85
@@ -984,7 +984,7 @@ FUZZ_TARGET(clusterlin_sfl)
|
||||
|
||||
// Verify that optimality is reached within an expected amount of work. This protects against
|
||||
// hypothetical bugs that hugely increase the amount of work needed to reach optimality.
|
||||
assert(sfl.GetCost() <= MaxOptimalLinearizationIters(depgraph.TxCount()));
|
||||
assert(sfl.GetCost() <= MaxOptimalLinearizationCost(depgraph.TxCount()));
|
||||
|
||||
// The result must be as good as SimpleLinearize.
|
||||
auto [simple_linearization, simple_optimal] = SimpleLinearize(depgraph, MAX_SIMPLE_ITERATIONS / 10);
|
||||
@@ -1011,15 +1011,15 @@ FUZZ_TARGET(clusterlin_linearize)
|
||||
{
|
||||
// Verify the behavior of Linearize().
|
||||
|
||||
// Retrieve an RNG seed, an iteration count, a depgraph, and whether to make it connected from
|
||||
// the fuzz input.
|
||||
// Retrieve an RNG seed, a maximum amount of work, a depgraph, and whether to make it connected
|
||||
// from the fuzz input.
|
||||
SpanReader reader(buffer);
|
||||
DepGraph<TestBitSet> depgraph;
|
||||
uint64_t rng_seed{0};
|
||||
uint64_t iter_count{0};
|
||||
uint64_t max_cost{0};
|
||||
uint8_t flags{7};
|
||||
try {
|
||||
reader >> VARINT(iter_count) >> Using<DepGraphFormatter>(depgraph) >> rng_seed >> flags;
|
||||
reader >> VARINT(max_cost) >> Using<DepGraphFormatter>(depgraph) >> rng_seed >> flags;
|
||||
} catch (const std::ios_base::failure&) {}
|
||||
bool make_connected = flags & 1;
|
||||
// The following 3 booleans have 4 combinations:
|
||||
@@ -1043,8 +1043,14 @@ FUZZ_TARGET(clusterlin_linearize)
|
||||
}
|
||||
|
||||
// Invoke Linearize().
|
||||
iter_count &= 0x7ffff;
|
||||
auto [linearization, optimal, cost] = Linearize(depgraph, iter_count, rng_seed, IndexTxOrder{}, old_linearization, /*is_topological=*/claim_topological_input);
|
||||
max_cost &= 0x7ffff;
|
||||
auto [linearization, optimal, cost] = Linearize(
|
||||
/*depgraph=*/depgraph,
|
||||
/*max_cost=*/max_cost,
|
||||
/*rng_seed=*/rng_seed,
|
||||
/*fallback_order=*/IndexTxOrder{},
|
||||
/*old_linearization=*/old_linearization,
|
||||
/*is_topological=*/claim_topological_input);
|
||||
SanityCheck(depgraph, linearization);
|
||||
auto chunking = ChunkLinearization(depgraph, linearization);
|
||||
|
||||
@@ -1056,8 +1062,8 @@ FUZZ_TARGET(clusterlin_linearize)
|
||||
assert(cmp >= 0);
|
||||
}
|
||||
|
||||
// If the iteration count is sufficiently high, an optimal linearization must be found.
|
||||
if (iter_count > MaxOptimalLinearizationIters(depgraph.TxCount())) {
|
||||
// If the maximum amount of work is sufficiently high, an optimal linearization must be found.
|
||||
if (max_cost > MaxOptimalLinearizationCost(depgraph.TxCount())) {
|
||||
assert(optimal);
|
||||
}
|
||||
|
||||
@@ -1145,7 +1151,7 @@ FUZZ_TARGET(clusterlin_linearize)
|
||||
|
||||
// Redo from scratch with a different rng_seed. The resulting linearization should be
|
||||
// deterministic, if both are optimal.
|
||||
auto [linearization2, optimal2, cost2] = Linearize(depgraph, MaxOptimalLinearizationIters(depgraph.TxCount()) + 1, rng_seed ^ 0x1337, IndexTxOrder{});
|
||||
auto [linearization2, optimal2, cost2] = Linearize(depgraph, MaxOptimalLinearizationCost(depgraph.TxCount()) + 1, rng_seed ^ 0x1337, IndexTxOrder{});
|
||||
assert(optimal2);
|
||||
assert(linearization2 == linearization);
|
||||
}
|
||||
|
||||
@@ -325,8 +325,8 @@ FUZZ_TARGET(txgraph)
|
||||
auto max_cluster_count = provider.ConsumeIntegralInRange<DepGraphIndex>(1, MAX_CLUSTER_COUNT_LIMIT);
|
||||
/** The maximum total size of transactions in a (non-oversized) cluster. */
|
||||
auto max_cluster_size = provider.ConsumeIntegralInRange<uint64_t>(1, 0x3fffff * MAX_CLUSTER_COUNT_LIMIT);
|
||||
/** The number of iterations to consider a cluster acceptably linearized. */
|
||||
auto acceptable_iters = provider.ConsumeIntegralInRange<uint64_t>(0, 10000);
|
||||
/** The amount of work to consider a cluster acceptably linearized. */
|
||||
auto acceptable_cost = provider.ConsumeIntegralInRange<uint64_t>(0, 10000);
|
||||
|
||||
/** The set of uint64_t "txid"s that have been assigned before. */
|
||||
std::set<uint64_t> assigned_txids;
|
||||
@@ -342,7 +342,7 @@ FUZZ_TARGET(txgraph)
|
||||
auto real = MakeTxGraph(
|
||||
/*max_cluster_count=*/max_cluster_count,
|
||||
/*max_cluster_size=*/max_cluster_size,
|
||||
/*acceptable_iters=*/acceptable_iters,
|
||||
/*acceptable_cost=*/acceptable_cost,
|
||||
/*fallback_order=*/fallback_order);
|
||||
|
||||
std::vector<SimTxGraph> sims;
|
||||
@@ -758,9 +758,9 @@ FUZZ_TARGET(txgraph)
|
||||
break;
|
||||
} else if (command-- == 0) {
|
||||
// DoWork.
|
||||
uint64_t iters = provider.ConsumeIntegralInRange<uint64_t>(0, alt ? 10000 : 255);
|
||||
bool ret = real->DoWork(iters);
|
||||
uint64_t iters_for_optimal{0};
|
||||
uint64_t max_cost = provider.ConsumeIntegralInRange<uint64_t>(0, alt ? 10000 : 255);
|
||||
bool ret = real->DoWork(max_cost);
|
||||
uint64_t cost_for_optimal{0};
|
||||
for (unsigned level = 0; level < sims.size(); ++level) {
|
||||
// DoWork() will not optimize oversized levels, or the main level if a builder
|
||||
// is present. Note that this impacts the DoWork() return value, as true means
|
||||
@@ -773,24 +773,24 @@ FUZZ_TARGET(txgraph)
|
||||
if (ret) {
|
||||
sims[level].real_is_optimal = true;
|
||||
}
|
||||
// Compute how many iterations would be needed to make everything optimal.
|
||||
// Compute how much work would be needed to make everything optimal.
|
||||
for (auto component : sims[level].GetComponents()) {
|
||||
auto iters_opt_this_cluster = MaxOptimalLinearizationIters(component.Count());
|
||||
if (iters_opt_this_cluster > acceptable_iters) {
|
||||
// If the number of iterations required to linearize this cluster
|
||||
// optimally exceeds acceptable_iters, DoWork() may process it in two
|
||||
auto cost_opt_this_cluster = MaxOptimalLinearizationCost(component.Count());
|
||||
if (cost_opt_this_cluster > acceptable_cost) {
|
||||
// If the amount of work required to linearize this cluster
|
||||
// optimally exceeds acceptable_cost, DoWork() may process it in two
|
||||
// stages: once to acceptable, and once to optimal.
|
||||
iters_for_optimal += iters_opt_this_cluster + acceptable_iters;
|
||||
cost_for_optimal += cost_opt_this_cluster + acceptable_cost;
|
||||
} else {
|
||||
iters_for_optimal += iters_opt_this_cluster;
|
||||
cost_for_optimal += cost_opt_this_cluster;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ret) {
|
||||
// DoWork can only have more work left if the requested number of iterations
|
||||
// DoWork can only have more work left if the requested amount of work
|
||||
// was insufficient to linearize everything optimally within the levels it is
|
||||
// allowed to touch.
|
||||
assert(iters <= iters_for_optimal);
|
||||
assert(max_cost <= cost_for_optimal);
|
||||
}
|
||||
break;
|
||||
} else if (sims.size() == 2 && !sims[0].IsOversized() && !sims[1].IsOversized() && command-- == 0) {
|
||||
@@ -1165,7 +1165,7 @@ FUZZ_TARGET(txgraph)
|
||||
auto real_redo = MakeTxGraph(
|
||||
/*max_cluster_count=*/max_cluster_count,
|
||||
/*max_cluster_size=*/max_cluster_size,
|
||||
/*acceptable_iters=*/acceptable_iters,
|
||||
/*acceptable_cost=*/acceptable_cost,
|
||||
/*fallback_order=*/fallback_order);
|
||||
/** Vector (indexed by SimTxGraph::Pos) of TxObjects in real_redo). */
|
||||
std::vector<std::optional<SimTxObject>> txobjects_redo;
|
||||
|
||||
Reference in New Issue
Block a user