From ed90ddc2bb78daad87d2863535a99f98aa499b8c Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Fri, 12 Jun 2026 20:30:46 -0400 Subject: [PATCH] perf(feed): trust relays for the public feed (drop off-thread verification) Per decision: the off-thread signature-verification worker added feed latency (the worker can hang loading nostr-tools, costing up to its timeout on the first batch) and fragility (it could blank the feed) for little benefit on a PUBLIC video feed. Default the VideoEventBuffer verifier to trust-all (the relay pool already does not verify), so feed events commit immediately. Verification is now opt-in via the verifyEvents option (the worker client remains for that). Security note: a malicious relay could serve events with forged authorship for the read feed; verify on sensitive actions instead. Reversible. Co-Authored-By: Claude Opus 4.8 --- js/nostr/videoEventBuffer.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/js/nostr/videoEventBuffer.js b/js/nostr/videoEventBuffer.js index b0c2f9af..46f13e01 100644 --- a/js/nostr/videoEventBuffer.js +++ b/js/nostr/videoEventBuffer.js @@ -8,15 +8,21 @@ import { isDevMode } from "../config.js"; import { devLogger, userLogger } from "../utils/logger.js"; import { convertEventToVideo } from "./nip71.js"; -import { verifyEventsInWorker } from "./signatureVerifyWorkerClient.js"; + +// Default: trust relays for the public video feed (no per-event signature +// verification). Verifying every feed event off-thread proved fragile (it could +// hang/blank the feed and added load latency), so it is opt-in: pass a +// `verifyEvents` function (e.g. verifyEventsInWorker) to re-enable it. +const trustAllVerifier = (events) => + Promise.resolve(new Set((events || []).map((e) => e && e.id).filter(Boolean))); export class VideoEventBuffer { /** * @param {import("./client.js").NostrClient} client - The parent client instance (for state access). * @param {function(object[]): void} onVideo - The UI callback to fire with batched updates. * @param {{ verifyEvents?: (events: object[]) => Promise> }} [options] - * Injectable signature verifier (returns the set of valid event ids). - * Defaults to the off-main-thread worker; tests can pass a passthrough. + * Optional signature verifier (returns the set of valid event ids). Defaults + * to trusting relays (no verification) for the public feed. */ constructor(client, onVideo, options = {}) { this.client = client; @@ -28,7 +34,7 @@ export class VideoEventBuffer { this._verifyEvents = typeof options.verifyEvents === "function" ? options.verifyEvents - : verifyEventsInWorker; + : trustAllVerifier; // Tracks the in-flight verify+commit so callers/tests can await a flush. this._flushPromise = Promise.resolve();