clone

a self-hosted multitenant nostr relay with sites, file storage, git hosting, and inbox and outbox delivery

main
tinyrelay / scripts / qa / relay-stress.md
relay-stress.md 3.3K rendered
1# Relay stress checks23Run these checks against disposable combined or standalone relays. They publish signed events and retain them in the target database. Use a separate data directory and locally generated test identities.45Generate 20 identities without printing their secrets:67```sh8mkdir -p artifacts/relay-stress9node --input-type=module <<'JS'10import { writeFileSync } from "node:fs";11import { generateSecretKey, getPublicKey } from "nostr-tools/pure";12const actors = Array.from({ length: 20 }, (_, i) => {13 const key = generateSecretKey();14 return { name: `actor-${i}`, secret: Buffer.from(key).toString("hex"), pubkey: getPublicKey(key) };15});16writeFileSync("artifacts/relay-stress/identities.json", JSON.stringify({ actors }), { mode: 0o600, flag: "wx" });17JS18```1920Start the relay with a 1 MiB message limit and a 4 MiB pending-output limit, then run:2122```sh23node scripts/qa/relay-stress.mjs \24 --relay ws://127.0.0.1:7447 \25 --identities artifacts/relay-stress/identities.json \26 --out artifacts/relay-stress/result.json \27 --actors 16 --events 200 --seed 1 --slow-reader28```2930Add `--auth-required` when the standalone relay requires authentication. This also checks anonymous reads and writes, event author binding, incorrect relay and challenge proofs, multiple authenticated keys, and proof reuse across connections. A combined tenant with members-only reads needs a separate membership test; the stress actors are not automatically enrolled.3132The harness checks concurrent publication, exact fanout to four subscribers, duplicate suppression, historical ordering, overlapping filter limits, unique counts, replacement, deletion, protected events, invalid signatures, malformed input recovery and reconnects. Payloads range from empty to about 8 KiB. The slow-reader phase adds 192 unique events of about 64 KiB and checks that a healthy client remains responsive while the stalled client disconnects or catches up after resuming.3334The JSON report contains public actor identities, counts, failures and publish acknowledgment latency percentiles. It excludes signing secrets. Latencies measure each send through its acknowledgment, excluding the actor's local send queue. They reflect the test machine, relay and network conditions; this is a correctness stress check, not a capacity benchmark. Repeat with different seeds to vary signed payloads.3536Keep the identity file on the test client when using a remote relay. An SSH tunnel can connect the client to an isolated Docker instance without exposing a public port. Remove the temporary instance after collecting its logs and resource measurements.3738## Protocol fuzzing3940Go fuzz targets cover event and filter parsing, NIP-98 and Blossom proof parsing and request binding, and NIP-42 connection boundaries. For example:4142```sh43go test ./protocol/nostr -run '^$' -fuzz '^FuzzParseFilter$' -fuzztime=60s -parallel=244go test ./protocol/auth -run '^$' -fuzz '^FuzzNIP98Binding$' -fuzztime=60s -parallel=245go test ./protocol/auth -run '^$' -fuzz '^FuzzBlossomBinding$' -fuzztime=60s -parallel=246go test ./tinyrelay -run '^$' -fuzz '^FuzzStandaloneAuthTagParsing$' -fuzztime=60s -parallel=247```4849These targets use local keys and temporary storage. Run the [conformance suite](../conformance/README.md) separately for HTTP, MCP, Git, Blossom and cross-relay integration coverage.