Files
salvium-rs/test/legacy-js/test-randomx-parallel.js
T
Matt Hess 733ecd2681 Migrate all JS tests to Rust: 9-crate workspace, 703 tests, 0 JS remaining
Add root Cargo workspace with 9 crates: salvium-crypto (extended),
  salvium-types, salvium-consensus, salvium-wallet, salvium-tx,
  salvium-rpc, salvium-miner (extended), salvium-cli, salvium-multisig.

  New modules: chain_state, block_weight, alt_chain, validation,
  offline signing, stake lifecycle, wallet sync/query/encryption/utxo,
  randomx utilities, and full multisig crate with CARROT support.

  Delete 188 JS test/helper/debug files; archive integration test
  scripts to test/legacy-js/ for live testnet use. Testnet integration
  tests (transfer, stake, burn, convert, sweep) remain as #[ignore]-
  gated Rust tests runnable with --ignored against a live daemon.
2026-02-17 23:09:35 +00:00

134 lines
4.0 KiB
JavaScript

/**
* Test RandomX Parallel Hashing
*
* Verifies that RandomX hashing scales across worker threads.
*/
import { Worker, isMainThread, parentPort, workerData } from 'worker_threads';
import { fileURLToPath } from 'url';
if (!isMainThread) {
// Worker code
const { workerId, duration } = workerData;
// Dynamic import to ensure fresh module load
const { randomx_init_cache, randomx_create_vm } = await import('../src/randomx/vendor/index.js');
// Initialize RandomX
const seedHash = new TextEncoder().encode('test seed hash');
const cache = randomx_init_cache(seedHash);
const vm = randomx_create_vm(cache);
parentPort.postMessage({ type: 'ready', workerId });
// Wait for start signal
await new Promise(resolve => {
parentPort.on('message', (msg) => {
if (msg.type === 'start') resolve();
});
});
// Hash for specified duration
let hashCount = 0;
const template = new Uint8Array(76);
const view = new DataView(template.buffer);
const start = Date.now();
while (Date.now() - start < duration) {
view.setUint32(39, hashCount, true);
vm.calculate_hash(template);
hashCount++;
}
parentPort.postMessage({ type: 'done', workerId, hashCount });
} else {
// Main thread
async function runTest(numWorkers, durationMs = 5000) {
console.log(`\nTesting with ${numWorkers} worker(s) for ${durationMs / 1000}s...`);
const workerPath = fileURLToPath(import.meta.url);
const workers = [];
const readyPromises = [];
// Create workers
for (let i = 0; i < numWorkers; i++) {
const worker = new Worker(workerPath, {
workerData: { workerId: i, duration: durationMs }
});
const ready = new Promise((resolve) => {
worker.on('message', (msg) => {
if (msg.type === 'ready') {
console.log(` Worker ${i} initialized`);
resolve();
}
});
});
workers.push(worker);
readyPromises.push(ready);
}
// Wait for all workers to initialize
await Promise.all(readyPromises);
console.log(' All workers ready, starting hash test...');
// Start all workers simultaneously
const start = Date.now();
for (const worker of workers) {
worker.postMessage({ type: 'start' });
}
// Collect results
const results = await Promise.all(workers.map((worker, i) => {
return new Promise((resolve) => {
worker.on('message', (msg) => {
if (msg.type === 'done') {
resolve(msg);
worker.terminate();
}
});
});
}));
const elapsed = (Date.now() - start) / 1000;
let totalHashes = 0;
for (const { workerId, hashCount } of results) {
const hps = (hashCount / elapsed).toFixed(2);
console.log(` Worker ${workerId}: ${hashCount} hashes (${hps} H/s)`);
totalHashes += hashCount;
}
const totalHps = totalHashes / elapsed;
console.log(` Total: ${totalHashes} hashes (${totalHps.toFixed(2)} H/s)`);
return { totalHashes, hps: totalHps, elapsed };
}
async function main() {
console.log('RandomX Parallel Hashing Test');
console.log('=============================');
console.log('Testing if RandomX WASM runs in parallel across workers');
console.log('(Each hash takes ~100ms, using 3s test windows)\n');
const result1 = await runTest(1, 3000);
const result2 = await runTest(2, 3000);
const result4 = await runTest(4, 3000);
console.log('\n=== Results ===');
console.log(` 1 worker: ${result1.hps.toFixed(2)} H/s (baseline)`);
console.log(` 2 workers: ${result2.hps.toFixed(2)} H/s (${(result2.hps / result1.hps).toFixed(2)}x)`);
console.log(` 4 workers: ${result4.hps.toFixed(2)} H/s (${(result4.hps / result1.hps).toFixed(2)}x)`);
if (result4.hps >= result1.hps * 2) {
console.log('\n✓ RandomX hashing scales across workers!');
} else {
console.log('\n✗ RandomX hashing does NOT scale across workers');
console.log(' This indicates the WASM module may have shared state');
}
}
main().catch(console.error);
}