Context
PR #76 added unit tests for Connection.matchesEvent, but the actual filter-matching logic (nostr.filtersMatch) lives upstream in libnostr-z, and wisp's end-to-end query path (REQ filter -> LMDB scan -> results) has no automated differential coverage. The integration scripts check specific queries, not randomized filter/event combinations.
The repo previously carried strfry-derived Perl harnesses for this (filterFuzzTest.pl + dumbFilter.pl, an independent filter-matching oracle), but they were bit-rotted (depended on a missing nostril signer and stale --db/scan CLI flags, not wired into CI) and were removed in PR #76 rather than repaired.
Proposal
Build a native differential fuzzer with no external (Perl/nostril) dependencies:
- Generate a corpus of random events (varied kinds, authors, tags, timestamps), signed via libnostr-z (
EventBuilder + Keypair), and load them with wisp import.
- Generate random filters (ids/authors/kinds/tags/since/until/limit combinations).
- For each filter, compare the relay's query results against an independent in-test reference matcher (a deterministic reimplementation of NIP-01 filter semantics, mirroring the old
dumbFilter.pl oracle).
- Flag any divergence; run deterministically from a seed so failures reproduce.
Can be a Zig test (zig build test, reusing the parse/build helpers from PR #76) or a self-contained shell+jq script driving the built binary. Wire it into CI once stable.
Value
Catches filter-matching and query-scan divergences that single-case unit and integration tests miss. Independent oracle == real coverage of the query engine, the relay's core read path.
Context
PR #76 added unit tests for
Connection.matchesEvent, but the actual filter-matching logic (nostr.filtersMatch) lives upstream in libnostr-z, and wisp's end-to-end query path (REQ filter -> LMDB scan -> results) has no automated differential coverage. The integration scripts check specific queries, not randomized filter/event combinations.The repo previously carried strfry-derived Perl harnesses for this (
filterFuzzTest.pl+dumbFilter.pl, an independent filter-matching oracle), but they were bit-rotted (depended on a missingnostrilsigner and stale--db/scanCLI flags, not wired into CI) and were removed in PR #76 rather than repaired.Proposal
Build a native differential fuzzer with no external (Perl/nostril) dependencies:
EventBuilder+Keypair), and load them withwisp import.dumbFilter.ploracle).Can be a Zig test (
zig build test, reusing the parse/build helpers from PR #76) or a self-contained shell+jq script driving the built binary. Wire it into CI once stable.Value
Catches filter-matching and query-scan divergences that single-case unit and integration tests miss. Independent oracle == real coverage of the query engine, the relay's core read path.