From cec48811bee6d8be3bffc3661e45186e9151c6d3 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 19:41:50 +0000 Subject: [PATCH] feat(scripts): enhance load test script for multi-part events (agent) - Updated `scripts/agent/load-test.mjs` to simulate realistic video publishing flows by generating Video Post (Kind 30078), Video Mirror (Kind 1063), and NIP-71 Metadata (Kind 21/22) events for "heavy" load scenarios. - Refactored the load generation loop to strictly separate cryptographic signing time from network transmission time, ensuring accurate performance metrics. - Generated a baseline `artifacts/load-report.json` demonstrating ~100 events/sec throughput and sub-10ms signing latency. - Verified execution against a local relay to prevent public network stress. Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- artifacts/load-report.json | 112 ++++++++++++++++++------------------ scripts/agent/load-test.mjs | 66 ++++++++++++++++++--- 2 files changed, 114 insertions(+), 64 deletions(-) diff --git a/artifacts/load-report.json b/artifacts/load-report.json index 50c7814c..7fcefddb 100644 --- a/artifacts/load-report.json +++ b/artifacts/load-report.json @@ -1,93 +1,93 @@ { - "timestamp": "2026-01-25T19:12:13.640Z", + "timestamp": "2026-01-26T19:39:32.887Z", "config": { "duration": 60, - "clients": 100, - "rate": 1, + "clients": 1000, + "rate": 0.1, "relay": "ws://localhost:8889", "force": false }, "metrics": { - "total_sent": 6219, - "total_received": 6219, + "total_sent": 6467, + "total_received": 6467, "errors": 0, - "throughput_sent": 103.65, - "throughput_recv": 103.65, + "throughput_sent": 107.78333333333333, + "throughput_recv": 107.78333333333333, "latency_ms": { - "p50": 0.4525159999998323, - "p95": 0.9470979999969131, - "p99": 7.444698999999673 + "p50": 0.9700979999979609, + "p95": 14.598196999999345, + "p99": 27.9113440000001 }, "operation_times_ms": { - "build_avg": 0.05414333365494229, - "sign_avg": 5.486003140054635 + "build_avg": 0.10325683753031617, + "sign_avg": 6.474848927014066 }, "resource_usage": [ { - "timestamp": 1769368278643, - "cpuPercent": 63.94, - "rss": 97239040, - "heapUsed": 16337816 + "timestamp": 1769456317885, + "cpuPercent": 74.54, + "rss": 129236992, + "heapUsed": 26275344 }, { - "timestamp": 1769368283643, - "cpuPercent": 64.36, - "rss": 98402304, - "heapUsed": 20259576 + "timestamp": 1769456322898, + "cpuPercent": 71.77, + "rss": 130256896, + "heapUsed": 30151424 }, { - "timestamp": 1769368288642, - "cpuPercent": 63.86, - "rss": 98762752, - "heapUsed": 17659632 + "timestamp": 1769456327916, + "cpuPercent": 70.52, + "rss": 131235840, + "heapUsed": 30829208 }, { - "timestamp": 1769368293643, - "cpuPercent": 61.32, - "rss": 99790848, - "heapUsed": 18155016 + "timestamp": 1769456332917, + "cpuPercent": 72.98, + "rss": 131637248, + "heapUsed": 38053280 }, { - "timestamp": 1769368298645, - "cpuPercent": 61.19, - "rss": 100999168, - "heapUsed": 15496016 + "timestamp": 1769456337917, + "cpuPercent": 78.13, + "rss": 132292608, + "heapUsed": 25903752 }, { - "timestamp": 1769368303646, - "cpuPercent": 63.12, - "rss": 102313984, - "heapUsed": 16290368 + "timestamp": 1769456342918, + "cpuPercent": 92.71, + "rss": 133566464, + "heapUsed": 28111320 }, { - "timestamp": 1769368308649, - "cpuPercent": 61.61, - "rss": 105914368, - "heapUsed": 22963352 + "timestamp": 1769456347922, + "cpuPercent": 94.4, + "rss": 133959680, + "heapUsed": 33235048 }, { - "timestamp": 1769368313653, - "cpuPercent": 60.4, - "rss": 106831872, - "heapUsed": 21787144 + "timestamp": 1769456352924, + "cpuPercent": 77.78, + "rss": 134717440, + "heapUsed": 27477160 }, { - "timestamp": 1769368318653, - "cpuPercent": 60.86, - "rss": 120463360, - "heapUsed": 17511208 + "timestamp": 1769456357925, + "cpuPercent": 86.22, + "rss": 135241728, + "heapUsed": 36644992 }, { - "timestamp": 1769368323657, - "cpuPercent": 60.52, - "rss": 120987648, - "heapUsed": 19454880 + "timestamp": 1769456362926, + "cpuPercent": 79.21, + "rss": 136028160, + "heapUsed": 28313856 }, { - "timestamp": 1769368328657, - "cpuPercent": 59.65, - "rss": 121643008, - "heapUsed": 21375032 + "timestamp": 1769456367927, + "cpuPercent": 71.57, + "rss": 136814592, + "heapUsed": 39710304 } ], "error_breakdown": {} diff --git a/scripts/agent/load-test.mjs b/scripts/agent/load-test.mjs index 8b5aa863..86b17196 100644 --- a/scripts/agent/load-test.mjs +++ b/scripts/agent/load-test.mjs @@ -12,7 +12,8 @@ import { performance } from 'node:perf_hooks'; global.NostrTools = NostrTools; // Import Schema Builders -import { buildVideoPostEvent, buildViewEvent } from '../../js/nostrEventSchemas.js'; +import { buildVideoPostEvent, buildViewEvent, buildVideoMirrorEvent } from '../../js/nostrEventSchemas.js'; +import { buildNip71VideoEvent } from '../../js/nostr/nip71.js'; // --- Configuration --- const ARTIFACTS_DIR = 'artifacts'; @@ -253,6 +254,8 @@ async function run() { const now = Math.floor(Date.now() / 1000); const hexPk = client.pk; + const eventsToSend = []; + if (isHeavy) { // Video Post const content = { @@ -260,17 +263,56 @@ async function run() { title: `Load Test Video ${Date.now()}`, description: 'A description for load testing purposes. '.repeat(50), magnet: `magnet:?xt=urn:btih:${Math.random().toString(16).slice(2).repeat(10)}`, + url: `https://example.com/video-${Date.now()}.mp4`, + thumbnail: `https://example.com/thumb-${Date.now()}.jpg`, mode: 'live', videoRootId: `load-${Date.now()}-${Math.random()}`, isNsfw: false, isForKids: false, }; - event = buildVideoPostEvent({ + + const rootEvent = buildVideoPostEvent({ pubkey: hexPk, created_at: now, content, dTagValue: content.videoRootId }); + eventsToSend.push(rootEvent); + + // Mirror Event (NIP-94) + const mirrorEvent = buildVideoMirrorEvent({ + pubkey: hexPk, + created_at: now, + tags: [['e', rootEvent.id], ['d', content.videoRootId]], + content: { + url: content.url, + magnet: content.magnet, + thumbnail: content.thumbnail, + title: content.title + } + }); + eventsToSend.push(mirrorEvent); + + // NIP-71 Metadata + const nip71Event = buildNip71VideoEvent({ + metadata: { + kind: 21, + title: content.title, + summary: content.description.slice(0, 200), + publishedAt: now, + hashtags: ['loadtest', 'stress'], + }, + pubkey: hexPk, + title: content.title, + createdAt: now, + pointerIdentifiers: { + videoRootId: content.videoRootId, + dTag: content.videoRootId, + eventId: rootEvent.id + } + }); + if (nip71Event) eventsToSend.push(nip71Event); + } else { // View Event event = buildViewEvent({ @@ -279,18 +321,26 @@ async function run() { pointerValue: `load-video-${Math.random()}`, pointerTag: ['d', `load-video-${Math.random()}`] }); + eventsToSend.push(event); } metrics.operationTimes.build.push(performance.now() - buildStart); // Sign - const signStart = performance.now(); - const signedEvent = NostrTools.finalizeEvent(event, client.sk); - metrics.operationTimes.sign.push(performance.now() - signStart); + const signedEvents = []; + for (const ev of eventsToSend) { + const t0 = performance.now(); + const signed = NostrTools.finalizeEvent(ev, client.sk); + const t1 = performance.now(); + metrics.operationTimes.sign.push(t1 - t0); + signedEvents.push(signed); + } // Publish - client.pendingEvents.set(signedEvent.id, performance.now()); - client.ws.send(JSON.stringify(['EVENT', signedEvent])); - metrics.sent++; + for (const signedEvent of signedEvents) { + client.pendingEvents.set(signedEvent.id, performance.now()); + client.ws.send(JSON.stringify(['EVENT', signedEvent])); + metrics.sent++; + } } catch (e) { console.error('Error generating/sending event:', e);