mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-10 16:33:27 +00:00
geode's MirrorWorker mirrored `strfry router` (live REQ streaming) but had no `strfry sync` equivalent, so backfilling a large foreign relay from empty could not complete: a plain REQ dump of the history overruns the sink and strfry kills the slow client at its maxPendingOutboundBytes cap (see relayBench/plans/2026-07-04-sync-throughput-1m.md). MirrorWorker now runs a one-shot NIP-77 "sync" catch-up per down/both upstream before the live tail, using strfry's own vocabulary — one `[[mirror]]` entry, one `dir` driving both phases: - Catch-up reconciles the local set against the upstream over the [now - backfill_seconds, now] window and downloads only the diff via the existing INostrClient.negentropySyncOrFetch — client-paced (strfry can't overrun us) and it completes the pull. Reconcile-against-local means a warm restart re-fetches nothing it already holds, like `strfry sync`. - Either mode, transparently: negentropySyncOrFetch auto-falls back to paged REQ for an upstream without NIP-77 — no config toggle. - Live REQ tail unchanged; it starts at `now` when catch-up is on (history is the sync's job). The windows overlap at `now`; the store's unique-id constraint dedups the seam. Changes: - quartz: add a backward-compatible `localEntries` param to the public negentropySync / negentropySyncOrFetch (default empty = prior behavior) so the reconcile diffs against a caller-supplied local set. - geode MirrorWorker: `runCatchUp()` (bounded, backpressured ingest; same trusted-scope re-check as the live path; failure is non-fatal). New `store` + `negentropyBackfill` ctor params; default off so existing live-REQ tests are unchanged. Main opts production in. - Test: MirrorNegentropyCatchUpTest isolates catch-up from the live tail by preloading historical events a live-only sub cannot deliver, then proves the post-boot event still arrives (3000 catch-up + 1 live = 3001). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EZeWww5TJnzBZKPoc6mvU