The minisketch harness has low stability due to:
- Rng internal to minisketch
- Benchmarkning for the best minisketch impl
Fix this by seeding the rng and letting the fuzzer choose the impl.
Also see #29018.
<!--e57a25ab6845829454e8d69fc972939a-->
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
<!--006a51241073e994b41acfe9ec718e94-->
For detailed information about the code coverage, see the test coverage report.
<!--021abf342d371248e50ceaed478a90ca-->
See the guideline for information on the review process.
| Type | Reviewers |
|---|---|
| ACK | maflcko |
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.
11 | @@ -12,14 +12,21 @@ 12 | #include <map> 13 | #include <numeric> 14 | 15 | -using node::MakeMinisketch32; 16 | +namespace { 17 | +Minisketch MakeFuzzMinisketch32(size_t capacity) 18 | +{ 19 | + return Minisketch(32, 0, capacity);
Why hardcode this to 0? Wouldn't it be better to let the fuzz engine pick one of MaxImplementation()?
25 | FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
26 | const auto capacity{fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 200)};
27 | - Minisketch sketch_a{Assert(MakeMinisketch32(capacity))};
28 | - Minisketch sketch_b{Assert(MakeMinisketch32(capacity))};
29 | + Minisketch sketch_a{Assert(MakeFuzzMinisketch32(capacity))};
30 | + Minisketch sketch_b{Assert(MakeFuzzMinisketch32(capacity))};
When touching this, maybe move the Assert into the helper?
63 | + 64 | sketch_ar.Deserialize(sketch_a.Serialize()); 65 | sketch_br.Deserialize(sketch_b.Serialize()); 66 | 67 | Minisketch sketch_diff{std::move(fuzzed_data_provider.ConsumeBool() ? sketch_a : sketch_ar)}; 68 | + sketch_diff.SetSeed(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
Is this needed? Both should have been seeded already, no?
lgtm
lgtm. Could squash the simple test fix into one commit?
Fuzzer now crashes on:
$ echo "HwoKCQoKCgoKCgoKCgkKCgoKvQoLCgoKCgkKCgoKvQoLCgoKCgoJCgoKCgpBCgoKCgpBDg==" | base64 --decode > minisketch.crash
$ FUZZ=minisketch ./src/test/fuzz/fuzz minisketch.crash
test/fuzz/minisketch.cpp:73 minisketch_fuzz_target: Assertion `dec.size() == num_diff' failed.
I think this stems from the fact that the minisketch implementation now might differ between the sketches in the test.
@dergoegge I believe that what's going on is that the new fuzz test invokes Merge on sketches with different implementation values. The library detects this and returns 0 from minisketch_merge, but the C++ wrapper Minisketch::Merge ignores the library result.
This fixes it I think:
--- a/src/test/fuzz/minisketch.cpp
+++ b/src/test/fuzz/minisketch.cpp
@@ -65,7 +65,9 @@ FUZZ_TARGET(minisketch)
sketch_br.Deserialize(sketch_b.Serialize());
Minisketch sketch_diff{std::move(fuzzed_data_provider.ConsumeBool() ? sketch_a : sketch_ar)};
- sketch_diff.Merge(fuzzed_data_provider.ConsumeBool() ? sketch_b : sketch_br);
+ auto& sketch_merge = fuzzed_data_provider.ConsumeBool() ? sketch_b : sketch_br;
+ if (sketch_diff.GetImplementation() != sketch_merge.GetImplementation()) return;
+ sketch_diff.Merge(sketch_merge);
if (capacity >= num_diff) {
const auto max_elements{fuzzed_data_provider.ConsumeIntegralInRange<size_t>(num_diff, capacity)};
That may not be the fix you actually want to use, as it's probably better to decode fuzzer data in such a way that the merge is guaranteed to be between consistent implementations, rather than bailing out when it isn't. But it at least demonstrates the problem.
* Seed minisketch rng
* Use fuzzer chosen minisketch impl instead of benchmarking for the best
impl
review ACK b2fc7a2eda103724ac8cbeaf99df3ce6f5b7d974