@xmbl/simulator 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,784 @@
1
+ # XSIM - XMBL System Simulator Instructions
2
+
3
+ ## Overview
4
+
5
+ XSIM is a comprehensive system simulator that runs infinitely, generating random interactions and activities across the entire XMBL ecosystem. It simulates identity creation, transaction posting, validations, storage operations, compute tasks, state machine diffs, and app-centric state assembly. The simulator is essential for end-to-end testing, stress testing, and validating system behavior under various conditions.
6
+
7
+ ## Fundamentals
8
+
9
+ ### Key Concepts
10
+
11
+ - **Infinite Execution**: Simulator runs continuously until stopped
12
+ - **Random Generation**: Random qualities for all interaction types
13
+ - **Full System Coverage**: Simulates all XMBL modules
14
+ - **Realistic Behavior**: Mimics real user and node behavior
15
+ - **Metrics Collection**: Tracks performance and system health
16
+ - **Failure Injection**: Simulates network failures and node crashes
17
+
18
+ ### Dependencies
19
+
20
+ - **all XMBL modules**: xid, xn, xclt, xvsm, xpc, xsc
21
+ - **faker**: Generate realistic fake data
22
+ - **chance**: Random data generation
23
+
24
+ ### Architectural Decisions
25
+
26
+ - **Event-Driven**: Uses module events for realistic simulation
27
+ - **Configurable**: Adjustable rates and probabilities
28
+ - **Observable**: Emits metrics and events for monitoring
29
+ - **Deterministic Option**: Can run with seed for reproducible tests
30
+
31
+ ## Development Steps
32
+
33
+ ### Step 1: Project Setup
34
+
35
+ ```bash
36
+ cd xsim
37
+ npm init -y
38
+ npm install faker chance
39
+ npm install --save-dev jest @types/jest
40
+ ```
41
+
42
+ ### Step 2: Identity Simulator (TDD)
43
+
44
+ **Test First** (`__tests__/identity-sim.test.js`):
45
+
46
+ ```javascript
47
+ import { describe, test, expect } from 'jest';
48
+ import { IdentitySimulator } from '../src/identity-sim';
49
+
50
+ describe('Identity Simulator', () => {
51
+ test('should create random identity', async () => {
52
+ const sim = new IdentitySimulator();
53
+ const identity = await sim.createRandomIdentity();
54
+ expect(identity).toHaveProperty('address');
55
+ expect(identity).toHaveProperty('publicKey');
56
+ });
57
+
58
+ test('should create identities at specified rate', async () => {
59
+ const sim = new IdentitySimulator({ rate: 10 }); // 10 per second
60
+ const identities = [];
61
+ sim.on('identity:created', (id) => identities.push(id));
62
+ await sim.start();
63
+ await new Promise(resolve => setTimeout(resolve, 1100)); // 1.1 seconds
64
+ await sim.stop();
65
+ expect(identities.length).toBeGreaterThanOrEqual(10);
66
+ });
67
+ });
68
+ ```
69
+
70
+ **Implementation** (`src/identity-sim.js`):
71
+
72
+ ```javascript
73
+ import { EventEmitter } from 'events';
74
+ import { Identity } from 'xid';
75
+
76
+ export class IdentitySimulator extends EventEmitter {
77
+ constructor(options = {}) {
78
+ super();
79
+ this.rate = options.rate || 1; // identities per second
80
+ this.identities = [];
81
+ this.running = false;
82
+ this.interval = null;
83
+ }
84
+
85
+ async start() {
86
+ if (this.running) return;
87
+ this.running = true;
88
+
89
+ const delay = 1000 / this.rate;
90
+ this.interval = setInterval(async () => {
91
+ const identity = await Identity.create();
92
+ this.identities.push(identity);
93
+ this.emit('identity:created', identity);
94
+ }, delay);
95
+ }
96
+
97
+ async stop() {
98
+ if (!this.running) return;
99
+ this.running = false;
100
+ if (this.interval) {
101
+ clearInterval(this.interval);
102
+ this.interval = null;
103
+ }
104
+ }
105
+
106
+ getIdentities() {
107
+ return this.identities;
108
+ }
109
+ }
110
+ ```
111
+
112
+ ### Step 3: Transaction Simulator (TDD)
113
+
114
+ **Test** (`__tests__/transaction-sim.test.js`):
115
+
116
+ ```javascript
117
+ import { describe, test, expect } from 'jest';
118
+ import { TransactionSimulator } from '../src/transaction-sim';
119
+
120
+ describe('Transaction Simulator', () => {
121
+ test('should create random transaction', () => {
122
+ const sim = new TransactionSimulator();
123
+ const identities = [{ address: 'alice' }, { address: 'bob' }];
124
+ const tx = sim.createRandomTransaction(identities);
125
+ expect(tx).toHaveProperty('to');
126
+ expect(tx).toHaveProperty('from');
127
+ expect(tx).toHaveProperty('amount');
128
+ });
129
+
130
+ test('should generate transactions at specified rate', async () => {
131
+ const sim = new TransactionSimulator({ rate: 5 });
132
+ const transactions = [];
133
+ sim.on('transaction:created', (tx) => transactions.push(tx));
134
+ await sim.start();
135
+ await new Promise(resolve => setTimeout(resolve, 1100));
136
+ await sim.stop();
137
+ expect(transactions.length).toBeGreaterThanOrEqual(5);
138
+ });
139
+ });
140
+ ```
141
+
142
+ **Implementation** (`src/transaction-sim.js`):
143
+
144
+ ```javascript
145
+ import { EventEmitter } from 'events';
146
+ import faker from 'faker';
147
+
148
+ export class TransactionSimulator extends EventEmitter {
149
+ constructor(options = {}) {
150
+ super();
151
+ this.rate = options.rate || 1;
152
+ this.transactions = [];
153
+ this.running = false;
154
+ this.interval = null;
155
+ }
156
+
157
+ createRandomTransaction(identities) {
158
+ if (identities.length < 2) {
159
+ throw new Error('Need at least 2 identities');
160
+ }
161
+
162
+ const from = faker.random.arrayElement(identities);
163
+ const to = faker.random.arrayElement(identities.filter(i => i.address !== from.address));
164
+ const amount = parseFloat(faker.finance.amount(0.1, 100, 2));
165
+
166
+ return {
167
+ to: to.address,
168
+ from: from.address,
169
+ amount,
170
+ fee: amount * 0.1,
171
+ stake: amount * 0.2,
172
+ timestamp: Date.now()
173
+ };
174
+ }
175
+
176
+ async start(identities) {
177
+ if (this.running) return;
178
+ this.running = true;
179
+
180
+ const delay = 1000 / this.rate;
181
+ this.interval = setInterval(() => {
182
+ const tx = this.createRandomTransaction(identities);
183
+ this.transactions.push(tx);
184
+ this.emit('transaction:created', tx);
185
+ }, delay);
186
+ }
187
+
188
+ async stop() {
189
+ if (!this.running) return;
190
+ this.running = false;
191
+ if (this.interval) {
192
+ clearInterval(this.interval);
193
+ this.interval = null;
194
+ }
195
+ }
196
+ }
197
+ ```
198
+
199
+ ### Step 4: Validation Simulator (TDD)
200
+
201
+ **Test** (`__tests__/validation-sim.test.js`):
202
+
203
+ ```javascript
204
+ import { describe, test, expect } from 'jest';
205
+ import { ValidationSimulator } from '../src/validation-sim';
206
+
207
+ describe('Validation Simulator', () => {
208
+ test('should simulate validation tasks', async () => {
209
+ const sim = new ValidationSimulator();
210
+ const task = { rawTxId: 'tx1', task: 'validate_sig' };
211
+ const result = await sim.simulateValidation(task);
212
+ expect(result).toHaveProperty('complete');
213
+ expect(result).toHaveProperty('timestamp');
214
+ });
215
+
216
+ test('should simulate validation delays', async () => {
217
+ const sim = new ValidationSimulator({ avgDelay: 100 });
218
+ const start = Date.now();
219
+ await sim.simulateValidation({});
220
+ const elapsed = Date.now() - start;
221
+ expect(elapsed).toBeGreaterThan(50); // Some delay
222
+ });
223
+ });
224
+ ```
225
+
226
+ **Implementation** (`src/validation-sim.js`):
227
+
228
+ ```javascript
229
+ import { EventEmitter } from 'events';
230
+ import chance from 'chance';
231
+
232
+ export class ValidationSimulator extends EventEmitter {
233
+ constructor(options = {}) {
234
+ super();
235
+ this.avgDelay = options.avgDelay || 50; // milliseconds
236
+ this.successRate = options.successRate || 0.95; // 95% success
237
+ this.chance = new chance();
238
+ }
239
+
240
+ async simulateValidation(task) {
241
+ // Simulate validation delay
242
+ const delay = this.chance.normal({ mean: this.avgDelay, dev: this.avgDelay * 0.2 });
243
+ await new Promise(resolve => setTimeout(resolve, Math.max(0, delay)));
244
+
245
+ // Simulate success/failure
246
+ const success = this.chance.bool({ likelihood: this.successRate * 100 });
247
+
248
+ const result = {
249
+ task: task.task,
250
+ complete: success,
251
+ timestamp: Date.now(),
252
+ error: success ? null : 'Validation failed'
253
+ };
254
+
255
+ this.emit('validation:complete', result);
256
+ return result;
257
+ }
258
+ }
259
+ ```
260
+
261
+ ### Step 5: Storage/Compute Simulator (TDD)
262
+
263
+ **Test** (`__tests__/storage-compute-sim.test.js`):
264
+
265
+ ```javascript
266
+ import { describe, test, expect } from 'jest';
267
+ import { StorageComputeSimulator } from '../src/storage-compute-sim';
268
+
269
+ describe('Storage/Compute Simulator', () => {
270
+ test('should simulate storage operations', async () => {
271
+ const sim = new StorageComputeSimulator();
272
+ const operation = await sim.simulateStorageOperation();
273
+ expect(operation).toHaveProperty('type');
274
+ expect(['store', 'retrieve', 'delete']).toContain(operation.type);
275
+ });
276
+
277
+ test('should simulate compute operations', async () => {
278
+ const sim = new StorageComputeSimulator();
279
+ const operation = await sim.simulateComputeOperation();
280
+ expect(operation).toHaveProperty('functionName');
281
+ expect(operation).toHaveProperty('duration');
282
+ });
283
+ });
284
+ ```
285
+
286
+ **Implementation** (`src/storage-compute-sim.js`):
287
+
288
+ ```javascript
289
+ import { EventEmitter } from 'events';
290
+ import faker from 'faker';
291
+ import chance from 'chance';
292
+
293
+ export class StorageComputeSimulator extends EventEmitter {
294
+ constructor(options = {}) {
295
+ super();
296
+ this.storageRate = options.storageRate || 0.5;
297
+ this.computeRate = options.computeRate || 0.5;
298
+ this.chance = new chance();
299
+ }
300
+
301
+ async simulateStorageOperation() {
302
+ const types = ['store', 'retrieve', 'delete'];
303
+ const type = this.chance.pickone(types);
304
+ const size = this.chance.integer({ min: 100, max: 10000 });
305
+
306
+ const operation = {
307
+ type,
308
+ size,
309
+ timestamp: Date.now()
310
+ };
311
+
312
+ this.emit('storage:operation', operation);
313
+ return operation;
314
+ }
315
+
316
+ async simulateComputeOperation() {
317
+ const functionName = faker.hacker.verb() + '_' + faker.hacker.noun();
318
+ const duration = this.chance.normal({ mean: 100, dev: 20 });
319
+
320
+ const operation = {
321
+ functionName,
322
+ duration: Math.max(0, duration),
323
+ memory: this.chance.integer({ min: 10, max: 100 }),
324
+ timestamp: Date.now()
325
+ };
326
+
327
+ this.emit('compute:operation', operation);
328
+ return operation;
329
+ }
330
+ }
331
+ ```
332
+
333
+ ### Step 6: System Simulator (TDD)
334
+
335
+ **Test** (`__tests__/system-sim.test.js`):
336
+
337
+ ```javascript
338
+ import { describe, test, expect, beforeEach, afterEach } from 'jest';
339
+ import { SystemSimulator } from '../src/system-sim';
340
+
341
+ describe('System Simulator', () => {
342
+ let sim;
343
+
344
+ beforeEach(() => {
345
+ sim = new SystemSimulator();
346
+ });
347
+
348
+ afterEach(async () => {
349
+ await sim.stop();
350
+ });
351
+
352
+ test('should start simulator', async () => {
353
+ await sim.start();
354
+ expect(sim.isRunning()).toBe(true);
355
+ });
356
+
357
+ test('should stop simulator', async () => {
358
+ await sim.start();
359
+ await sim.stop();
360
+ expect(sim.isRunning()).toBe(false);
361
+ });
362
+
363
+ test('should collect metrics', async () => {
364
+ await sim.start();
365
+ await new Promise(resolve => setTimeout(resolve, 1000));
366
+ const metrics = sim.getMetrics();
367
+ expect(metrics).toHaveProperty('identitiesCreated');
368
+ expect(metrics).toHaveProperty('transactionsCreated');
369
+ });
370
+ });
371
+ ```
372
+
373
+ **Implementation** (`src/system-sim.js`):
374
+
375
+ ```javascript
376
+ import { EventEmitter } from 'events';
377
+ import { IdentitySimulator } from './identity-sim';
378
+ import { TransactionSimulator } from './transaction-sim';
379
+ import { ValidationSimulator } from './validation-sim';
380
+ import { StorageComputeSimulator } from './storage-compute-sim';
381
+
382
+ export class SystemSimulator extends EventEmitter {
383
+ constructor(options = {}) {
384
+ super();
385
+ this.options = {
386
+ identityRate: options.identityRate || 1,
387
+ transactionRate: options.transactionRate || 5,
388
+ ...options
389
+ };
390
+
391
+ this.identitySim = new IdentitySimulator({ rate: this.options.identityRate });
392
+ this.transactionSim = new TransactionSimulator({ rate: this.options.transactionRate });
393
+ this.validationSim = new ValidationSimulator();
394
+ this.storageComputeSim = new StorageComputeSimulator();
395
+
396
+ this.metrics = {
397
+ identitiesCreated: 0,
398
+ transactionsCreated: 0,
399
+ validationsCompleted: 0,
400
+ storageOperations: 0,
401
+ computeOperations: 0,
402
+ startTime: null
403
+ };
404
+
405
+ this.running = false;
406
+ this.setupEventHandlers();
407
+ }
408
+
409
+ setupEventHandlers() {
410
+ this.identitySim.on('identity:created', () => {
411
+ this.metrics.identitiesCreated++;
412
+ this.emit('metrics:update', this.metrics);
413
+ });
414
+
415
+ this.transactionSim.on('transaction:created', () => {
416
+ this.metrics.transactionsCreated++;
417
+ this.emit('metrics:update', this.metrics);
418
+ });
419
+
420
+ this.validationSim.on('validation:complete', () => {
421
+ this.metrics.validationsCompleted++;
422
+ this.emit('metrics:update', this.metrics);
423
+ });
424
+
425
+ this.storageComputeSim.on('storage:operation', () => {
426
+ this.metrics.storageOperations++;
427
+ this.emit('metrics:update', this.metrics);
428
+ });
429
+
430
+ this.storageComputeSim.on('compute:operation', () => {
431
+ this.metrics.computeOperations++;
432
+ this.emit('metrics:update', this.metrics);
433
+ });
434
+ }
435
+
436
+ async start() {
437
+ if (this.running) return;
438
+ this.running = true;
439
+ this.metrics.startTime = Date.now();
440
+
441
+ const identities = [];
442
+ this.identitySim.on('identity:created', (id) => identities.push(id));
443
+
444
+ await this.identitySim.start();
445
+ await this.transactionSim.start(identities);
446
+
447
+ // Start periodic storage/compute operations
448
+ this.storageInterval = setInterval(() => {
449
+ this.storageComputeSim.simulateStorageOperation();
450
+ }, 2000);
451
+
452
+ this.computeInterval = setInterval(() => {
453
+ this.storageComputeSim.simulateComputeOperation();
454
+ }, 2000);
455
+
456
+ this.emit('started');
457
+ }
458
+
459
+ async stop() {
460
+ if (!this.running) return;
461
+ this.running = false;
462
+
463
+ await this.identitySim.stop();
464
+ await this.transactionSim.stop();
465
+
466
+ if (this.storageInterval) clearInterval(this.storageInterval);
467
+ if (this.computeInterval) clearInterval(this.computeInterval);
468
+
469
+ this.emit('stopped');
470
+ }
471
+
472
+ isRunning() {
473
+ return this.running;
474
+ }
475
+
476
+ getMetrics() {
477
+ return { ...this.metrics };
478
+ }
479
+ }
480
+ ```
481
+
482
+ ## Interfaces/APIs
483
+
484
+ ### Exported Classes
485
+
486
+ ```javascript
487
+ export class SystemSimulator extends EventEmitter {
488
+ constructor(options?: SimulatorOptions);
489
+ async start(): Promise<void>;
490
+ async stop(): Promise<void>;
491
+ isRunning(): boolean;
492
+ getMetrics(): Metrics;
493
+ }
494
+
495
+ export class IdentitySimulator extends EventEmitter {
496
+ constructor(options?: IdentitySimOptions);
497
+ async start(): Promise<void>;
498
+ async stop(): Promise<void>;
499
+ async createRandomIdentity(): Promise<Identity>;
500
+ }
501
+
502
+ export class TransactionSimulator extends EventEmitter {
503
+ constructor(options?: TransactionSimOptions);
504
+ async start(identities: Identity[]): Promise<void>;
505
+ async stop(): Promise<void>;
506
+ createRandomTransaction(identities: Identity[]): Transaction;
507
+ }
508
+ ```
509
+
510
+ ## Testing
511
+
512
+ ### Test Scenarios
513
+
514
+ 1. **Identity Generation**
515
+ - Random identity creation
516
+ - Rate control
517
+ - Event emission
518
+
519
+ 2. **Transaction Generation**
520
+ - Random transaction creation
521
+ - Rate control
522
+ - Realistic amounts
523
+
524
+ 3. **Validation Simulation**
525
+ - Validation delays
526
+ - Success/failure rates
527
+ - Task completion
528
+
529
+ 4. **Storage/Compute Simulation**
530
+ - Operation types
531
+ - Resource usage
532
+ - Timing
533
+
534
+ 5. **System Integration**
535
+ - Full system simulation
536
+ - Metrics collection
537
+ - Event handling
538
+
539
+ ### Coverage Goals
540
+
541
+ - 90%+ code coverage
542
+ - All simulation types tested
543
+ - Rate control validation
544
+ - Metrics accuracy
545
+
546
+ ## Integration Notes
547
+
548
+ ### Module Dependencies
549
+
550
+ - **All XMBL modules**: xid, xn, xclt, xvsm, xpc, xsc
551
+ - **xv**: Visualizer module (consumes xsim events via bridge server)
552
+
553
+ ### Integration Pattern
554
+
555
+ ```javascript
556
+ import { SystemSimulator } from 'xsim';
557
+ import { XCLT } from 'xclt';
558
+ import { XPC } from 'xpc';
559
+ import { XID } from 'xid';
560
+ import { XN } from 'xn';
561
+ import { XSC } from 'xsc';
562
+ import { XVSM } from 'xvsm';
563
+
564
+ const sim = new SystemSimulator({
565
+ identityRate: 2,
566
+ transactionRate: 10,
567
+ stateDiffRate: 5
568
+ });
569
+
570
+ // Connect to real modules - xsim generates data, modules process it
571
+ sim.identitySim.on('identity:created', async (identity) => {
572
+ // Use actual xid module to create identity
573
+ const realIdentity = await XID.create(identity);
574
+ // Emit to xn for network topology
575
+ XN.addNode(realIdentity);
576
+ });
577
+
578
+ sim.transactionSim.on('transaction:created', async (tx) => {
579
+ // Submit to actual xpc module
580
+ await XPC.submitTransaction('leader1', tx);
581
+ });
582
+
583
+ sim.stateDiffSim.on('state:diff:created', async (diff) => {
584
+ // Submit to actual xvsm module
585
+ await XVSM.addStateDiff(diff);
586
+ });
587
+
588
+ sim.storageComputeSim.on('storage:operation', async (op) => {
589
+ // Submit to actual xsc module
590
+ await XSC.handleOperation(op);
591
+ });
592
+
593
+ sim.on('metrics:update', (metrics) => {
594
+ console.log('Metrics:', metrics);
595
+ });
596
+
597
+ await sim.start();
598
+ ```
599
+
600
+ ### Integration with XV Visualizer
601
+
602
+ xsim integrates with xv visualizer via the bridge server (`xv/server.js`):
603
+
604
+ 1. **Bridge Server Setup**:
605
+ - Bridge server runs on port 3000
606
+ - Connects to xsim SystemSimulator
607
+ - Connects to xclt Ledger
608
+ - Bridges events to visualizer via socket.io
609
+
610
+ 2. **Event Flow**:
611
+ ```
612
+ xsim → bridge server → socket.io → xv visualizer
613
+ xclt → bridge server → socket.io → xv visualizer
614
+ ```
615
+
616
+ 3. **Events Bridged**:
617
+ - `identity:created` → `xn:node:connected` (with real activity/ping from xn)
618
+ - `transaction:created` → `xpc:transaction:new`
619
+ - `state:diff:created` → `xvsm:state:diff`
620
+ - `state:assembled` → `xvsm:state:assembled`
621
+ - `storage:operation` → `xsc:operation`
622
+ - `compute:operation` → `xpc:compute:operation`
623
+
624
+ ### CRITICAL: Data Generation Policy
625
+
626
+ **xsim IS a simulator - it generates test data. However, it must coordinate with real modules.**
627
+
628
+ #### What xsim does:
629
+ - ✅ Generates test identities, transactions, state diffs, etc.
630
+ - ✅ Uses faker/chance for realistic test data generation
631
+ - ✅ Emits events that can be consumed by visualizer or real modules
632
+ - ✅ Provides deterministic mode for reproducible tests
633
+
634
+ #### What xsim must NOT do:
635
+ - ❌ Generate fake network topology data (must use xn module)
636
+ - ❌ Generate fake ping/latency data (must use xn module)
637
+ - ❌ Generate fake activity metrics (must use actual module metrics)
638
+ - ❌ Bypass real modules when they're available
639
+
640
+ #### Integration Requirements:
641
+
642
+ 1. **When used with real modules**:
643
+ - xsim generates test data (identities, transactions, etc.)
644
+ - Real modules process the data (xid, xpc, xclt, etc.)
645
+ - Real modules emit their own events with actual metrics
646
+ - Visualizer displays data from real modules, not xsim directly
647
+
648
+ 2. **When used standalone (simulation mode)**:
649
+ - xsim generates all test data
650
+ - Bridge server forwards xsim events to visualizer
651
+ - Visualizer displays simulated data
652
+ - This is acceptable for development/testing
653
+
654
+ 3. **Network data**:
655
+ - xsim should NOT generate fake ping/latency/activity
656
+ - When xn module is available, use real network metrics
657
+ - When xn is not available, xsim can generate basic test data
658
+ - Bridge server should enrich with real data when available
659
+
660
+ ### Required Integration Work
661
+
662
+ 1. **Connect to real modules**:
663
+ - xsim should optionally connect to real xid, xpc, xclt, xvsm, xsc modules
664
+ - When modules are available, use them instead of just emitting events
665
+ - Real modules provide actual metrics and processing
666
+
667
+ 2. **Bridge server enhancements**:
668
+ - Bridge server must connect to xn module for real network topology
669
+ - Bridge server must enrich xsim identity events with real xn node data
670
+ - Bridge server must use real ping/latency from xn, not generate fake values
671
+
672
+ 3. **Event coordination**:
673
+ - xsim events should trigger real module operations
674
+ - Real module events should be forwarded to visualizer
675
+ - Visualizer should prefer real module events over xsim events
676
+
677
+ 4. **Metrics collection**:
678
+ - Collect metrics from real modules when available
679
+ - Fall back to xsim metrics only when modules aren't connected
680
+ - Distinguish between simulated and real metrics in output
681
+
682
+ ## Outstanding Requirements
683
+
684
+ Based on `status.md`, the following work is still required:
685
+
686
+ ### Module Integration
687
+
688
+ - [ ] **Integrate with actual XMBL modules** (xid, xn, xclt, xvsm, xpc, xsc)
689
+ - Currently xsim generates data but doesn't always connect to real modules
690
+ - Must connect to real modules when available
691
+ - Must use real module metrics instead of simulated ones
692
+
693
+ - [ ] **Add failure injection** (network failures, node crashes)
694
+ - Currently missing failure simulation
695
+ - Must simulate network partitions
696
+ - Must simulate node crashes and recovery
697
+ - Must simulate validation failures
698
+
699
+ - [ ] **Add browser monitoring capabilities** (web dashboard)
700
+ - Currently only has terminal monitoring
701
+ - Must provide web interface for metrics
702
+ - Must integrate with xv visualizer
703
+
704
+ - [ ] **Add metrics export/visualization** (JSON, CSV, Prometheus)
705
+ - Currently only displays metrics in terminal
706
+ - Must export metrics in standard formats
707
+ - Must support Prometheus metrics endpoint
708
+
709
+ - [ ] **Add performance benchmarking**
710
+ - Currently missing performance benchmarks
711
+ - Must measure throughput (tx/s, identities/s)
712
+ - Must measure latency (validation time, state assembly time)
713
+ - Must measure resource usage (CPU, memory)
714
+
715
+ - [ ] **Add stress testing modes**
716
+ - Currently missing stress testing
717
+ - Must support high-rate simulation
718
+ - Must support large-scale simulation (many nodes)
719
+ - Must support long-running simulations
720
+
721
+ - [ ] **Add configuration file support**
722
+ - Currently only supports environment variables
723
+ - Must support JSON/YAML configuration files
724
+ - Must support per-simulator configuration
725
+
726
+ ### Bridge Server Integration
727
+
728
+ - [ ] **Enhance bridge server to use real module data**
729
+ - Bridge server must connect to xn module for real network topology
730
+ - Bridge server must enrich xsim events with real module metrics
731
+ - Bridge server must use real ping/latency from xn, not generate fake values
732
+
733
+ - [ ] **Coordinate events between xsim and real modules**
734
+ - xsim events should trigger real module operations
735
+ - Real module events should be forwarded to visualizer
736
+ - Must handle both simulated and real data sources
737
+
738
+ ## Terminal and Browser Monitoring
739
+
740
+ ### Terminal Output
741
+
742
+ - **Simulation Status**: Log simulation state
743
+ ```javascript
744
+ console.log(`Simulator running: ${sim.isRunning()}`);
745
+ ```
746
+
747
+ - **Metrics**: Periodic metrics display
748
+ ```javascript
749
+ console.log(`Identities: ${metrics.identitiesCreated}, Transactions: ${metrics.transactionsCreated}`);
750
+ ```
751
+
752
+ - **Rates**: Current operation rates
753
+ ```javascript
754
+ console.log(`Rate: ${txRate} tx/s, ${idRate} identities/s`);
755
+ ```
756
+
757
+ - **Module Connections**: Log which modules are connected
758
+ ```javascript
759
+ console.log(`Connected modules: ${connectedModules.join(', ')}`);
760
+ ```
761
+
762
+ - **Data Source**: Distinguish between simulated and real data
763
+ ```javascript
764
+ console.log(`Data source: ${isUsingRealModules ? 'real modules' : 'simulated'}`);
765
+ ```
766
+
767
+ ### Screenshot Requirements
768
+
769
+ Capture terminal output for:
770
+ - Simulation startup
771
+ - Real-time metrics
772
+ - Rate statistics
773
+ - Error logs
774
+ - Module connection status
775
+ - Metrics showing simulated vs real data
776
+
777
+ ### Console Logging
778
+
779
+ - Log all simulation events
780
+ - Include timing information
781
+ - Log metrics updates
782
+ - Include error details
783
+ - Log module connection/disconnection events
784
+ - **Distinguish between simulated and real data** in logs