Skip to content

Commit 84792e4

Browse files
committed
feat: enhance CLI argument parsing and spammer logic for improved error handling
1 parent 35eaa50 commit 84792e4

1 file changed

Lines changed: 55 additions & 9 deletions

File tree

scripts/security-load-test.js

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,41 @@ const crypto = require('crypto');
2121
const secp256k1 = require('@noble/secp256k1');
2222

2323
// ── CLI Args ─────────────────────────────────────────────────────────────────
24-
const args = process.argv.slice(2).reduce((acc, arg, i, arr) => {
25-
if (arg.startsWith('--')) acc[arg.slice(2)] = arr[i + 1];
24+
function parseCliArgs(argv) {
25+
const acc = {};
26+
for (let i = 0; i < argv.length; i++) {
27+
const arg = argv[i];
28+
if (!arg.startsWith('--')) continue;
29+
30+
const key = arg.slice(2);
31+
const value = argv[i + 1];
32+
33+
if (value === undefined || value.startsWith('--')) {
34+
console.error(`Missing value for --${key}`);
35+
process.exit(1);
36+
}
37+
38+
acc[key] = value;
39+
i++;
40+
}
2641
return acc;
27-
}, {});
42+
}
43+
44+
function parseIntegerArg(value, defaultValue, flagName) {
45+
if (value === undefined) return defaultValue;
46+
const parsed = parseInt(value, 10);
47+
if (isNaN(parsed)) {
48+
console.error(`Invalid value for --${flagName}: ${value}. Expected an integer.`);
49+
process.exit(1);
50+
}
51+
return parsed;
52+
}
53+
54+
const args = parseCliArgs(process.argv.slice(2));
2855

2956
const RELAY_URL = args.url || 'ws://localhost:8008';
30-
const TOTAL_ZOMBIES = parseInt(args.zombies || '5000', 10);
31-
const SPAM_RATE = parseInt(args['spam-rate'] || '0', 10);
57+
const TOTAL_ZOMBIES = parseIntegerArg(args.zombies, 5000, 'zombies');
58+
const SPAM_RATE = parseIntegerArg(args['spam-rate'], 0, 'spam-rate');
3259
const BATCH_SIZE = 100;
3360
const BATCH_DELAY_MS = 50;
3461

@@ -70,22 +97,38 @@ function startSpammer() {
7097
const ws = new WebSocket(RELAY_URL);
7198
const spammerPrivKey = secp256k1.utils.bytesToHex(secp256k1.utils.randomPrivateKey());
7299
const intervalMs = 1000 / SPAM_RATE;
100+
let spammerInterval = null;
101+
102+
function clearSpammerInterval() {
103+
if (spammerInterval !== null) {
104+
clearInterval(spammerInterval);
105+
spammerInterval = null;
106+
}
107+
}
73108

74109
ws.on('open', () => {
75110
console.log(`\n[SPAMMER] Connected. Flooding ${SPAM_RATE} events/sec...`);
76-
setInterval(async () => {
111+
clearSpammerInterval();
112+
spammerInterval = setInterval(async () => {
113+
if (ws.readyState !== WebSocket.OPEN) return;
114+
77115
const event = await createValidEvent(spammerPrivKey);
78-
ws.send(JSON.stringify(['EVENT', event]));
79-
spamSent++;
116+
if (ws.readyState === WebSocket.OPEN) {
117+
ws.send(JSON.stringify(['EVENT', event]));
118+
spamSent++;
119+
}
80120
}, intervalMs);
81121
});
82122

83123
ws.on('close', () => {
124+
clearSpammerInterval();
84125
console.log('[SPAMMER] Disconnected. Reconnecting...');
85126
setTimeout(startSpammer, 1000);
86127
});
87128

88-
ws.on('error', () => { });
129+
ws.on('error', () => {
130+
clearSpammerInterval();
131+
});
89132
}
90133

91134
// ── Zombie Logic ─────────────────────────────────────────────────────────────
@@ -107,6 +150,8 @@ function openZombie() {
107150
if (ws._receiver) {
108151
ws._receiver.removeAllListeners('ping');
109152
ws._receiver.on('ping', () => { });
153+
} else {
154+
console.warn('[ZOMBIES] Warning: ws._receiver not found. Pong suppression might fail.');
110155
}
111156
ws.pong = function () { };
112157

@@ -117,6 +162,7 @@ function openZombie() {
117162

118163
ws.on('error', (err) => {
119164
errors++;
165+
ws.terminate();
120166
resolve(null);
121167
});
122168

0 commit comments

Comments
 (0)