mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 11:48:24 +00:00
docs(relayBench): note the NIP-62/09/40 sync-fairness gap in effectiveEvents
The harness's reconcile reference only collapses replaceable kinds; it ignores NIP-62 Request to Vanish, NIP-09 deletions, and NIP-40 expiration. So a compliant relay (geode, which honors NIP-62) is falsely flagged "did not converge" and the phantom events inflate its reconcile round count, masking negentropy speedups at the wire. Documents the symptom (traced to one ALL_RELAYS vanish pubkey in the damus corpus), the census (7 vanish pubkeys, 381 expiry events, 0 deletions in the first 200k), and the fix design for whoever implements it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EZeWww5TJnzBZKPoc6mvU
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# relayBench sync fairness: account for NIP-62 / NIP-09 / NIP-40
|
||||
|
||||
**Status: note / not yet implemented.** Captures a measurement bug found while
|
||||
validating the negentropy work, so the next person doesn't re-derive it.
|
||||
|
||||
## The problem
|
||||
|
||||
`SyncBenchmark.effectiveEvents` builds the "reference" set the harness
|
||||
reconciles against by collapsing **replaceable/addressable** kinds to their
|
||||
newest version — and nothing else. But a spec-compliant relay stores strictly
|
||||
*less* than that, because it also honors:
|
||||
|
||||
- **NIP-62 Request to Vanish** (kind 62). A `["relay","ALL_RELAYS"]` (or
|
||||
this-relay) vanish request means the relay deletes **all** events from that
|
||||
pubkey. geode implements this (`RightToVanishModule`); strfry does not.
|
||||
- **NIP-09 deletions** (kind 5). Both geode and strfry apply these, but the
|
||||
harness reference keeps the deleted events *and* the deletion.
|
||||
- **NIP-40 expiration** (`expiration` tag). geode drops expired events; strfry's
|
||||
support differs.
|
||||
|
||||
So the harness reference over-counts: it retains events a compliant relay is
|
||||
*required* to have removed.
|
||||
|
||||
## The symptom
|
||||
|
||||
The sync pair is flagged **"did not converge ✗"** even when the relays are
|
||||
behaving correctly. In the 1M-corpus run this showed as geode "missing" 28
|
||||
events vs the reference — all traced to a **single NIP-62 vanish pubkey**
|
||||
(`fa0778c1ccbb…`, `["relay","ALL_RELAYS"]`): geode correctly purged that user's
|
||||
31 events, strfry kept them, and the harness expected them present.
|
||||
|
||||
Two concrete distortions:
|
||||
|
||||
1. **False non-convergence.** `converged` (SyncBenchmark ~line 273) compares
|
||||
the relays' stored sets to the unfiltered reference, so a NIP-62/40-compliant
|
||||
relay can never converge against a corpus that contains vanish/expiry events.
|
||||
2. **Inflated reconcile cost.** The identical-set reconcile uses the unfiltered
|
||||
`effective` as the *initiator's local set*. Those phantom events are real
|
||||
leaves negentropy must hunt, so geode's steady-state reconcile ran **3 rounds
|
||||
/ ~520 ms** instead of the **1 round / ~110 ms** it would take against a
|
||||
matching set — which masks negentropy speedups (v1.1.1/v1.2.0) at the wire
|
||||
behind the extra round-trips.
|
||||
|
||||
## The census (first 200k of the damus 1M corpus)
|
||||
|
||||
- NIP-62 vanish requests: **7 distinct pubkeys**
|
||||
- NIP-09 deletions: **0**
|
||||
- NIP-40 expiration-tagged events: **381**
|
||||
|
||||
## The fix (when someone picks this up)
|
||||
|
||||
Make the reference model what a compliant relay actually stores, in
|
||||
`effectiveEvents` (or a new `compliantEffective`):
|
||||
|
||||
1. Collect vanish pubkeys (kind 62); drop every event from them, and the vanish
|
||||
request itself, whose `created_at` is at/under the vanish request's time (or
|
||||
unconditionally for `ALL_RELAYS`).
|
||||
2. Apply kind-5 deletions: drop referenced `e`/`a` targets authored by the same
|
||||
pubkey.
|
||||
3. Drop events whose `expiration` tag is in the past (needs a fixed "now").
|
||||
|
||||
Then a compliant relay (geode) converges cleanly, and a relay that ignores these
|
||||
NIPs (strfry) is correctly flagged as retaining events it should have dropped —
|
||||
which is the honest comparison, not a geode penalty. The steady-state reconcile
|
||||
also becomes a real 1-round measurement, so negentropy improvements show at the
|
||||
wire.
|
||||
|
||||
Until then, a clean wire-level sync measurement needs a **pre-filtered corpus**
|
||||
(drop vanish-pubkey events + expiry-tagged events); see the geode↔geode run that
|
||||
accompanies this note.
|
||||
Reference in New Issue
Block a user