/** * Test that full mode produces the same hashes as light mode */ import { RandomXContext } from '../src/randomx/index.js'; import { randomx_init_cache, randomx_superscalarhash, randomx_machine_id } from '../src/randomx/vendor/index.js'; const TEST_KEY = 'test key for RandomX'; const TEST_INPUT = 'hello world'; const VM_WASM_PAGES = 33; // From vendored library // JIT feature constants const JIT_BASELINE = 0; const JIT_RELAXED_SIMD = 1; const JIT_FMA = 2; // Parse machine ID to get feature function getFeatureFromMachineId() { const machineId = randomx_machine_id(); console.log('Machine ID:', machineId); // Parse features from machine ID like "CPU [rx/0+relaxed-simd+fma] UA" if (machineId.includes('+fma')) { return JIT_FMA | JIT_RELAXED_SIMD; } else if (machineId.includes('+relaxed-simd')) { return JIT_RELAXED_SIMD; } return JIT_BASELINE; } async function main() { console.log('=== RandomX Full Mode vs Light Mode Test ===\n'); const feature = getFeatureFromMachineId(); console.log('JIT Feature:', feature, '\n'); // Initialize light mode console.log('Initializing light mode...'); const lightCtx = new RandomXContext(); await lightCtx.init(TEST_KEY); console.log('Light mode ready\n'); // Compute hash with light mode console.log('Computing hash with light mode...'); const lightStart = performance.now(); const lightHash = lightCtx.hashHex(TEST_INPUT); const lightTime = performance.now() - lightStart; console.log('Light mode hash:', lightHash); console.log('Light mode time:', lightTime.toFixed(2) + 'ms\n'); // Test our VM creation code manually console.log('Creating full mode VM (using superscalar for testing)...'); const cache = randomx_init_cache(TEST_KEY); const superscalarhash = randomx_superscalarhash(cache); const SCRATCH_SIZE = 16 * 1024; const memory = new WebAssembly.Memory({ initial: VM_WASM_PAGES, maximum: VM_WASM_PAGES }); const vmImports = { env: { memory } }; const vmInstance = new WebAssembly.Instance(cache.vm, vmImports); const vmExports = vmInstance.exports; const scratchPtr = vmExports.i(feature); // Use detected feature const scratch = new Uint8Array(memory.buffer, scratchPtr, SCRATCH_SIZE); // Use superscalar hash (same as light mode - this tests our VM code) const jitImports = { e: { m: memory, d: superscalarhash } }; const hashFn = (input, isHex) => { if (typeof input === 'string') { input = new TextEncoder().encode(input); } vmExports.I(isHex); if (input.length <= SCRATCH_SIZE) { scratch.set(input); vmExports.H(input.length); } else { let p = 0; while (p < input.length) { const chunk = input.subarray(p, p + SCRATCH_SIZE); p += SCRATCH_SIZE; scratch.set(chunk); vmExports.H(chunk.length); } } let jitSize; while (true) { jitSize = vmExports.R(); if (jitSize === 0) break; const jitModule = new WebAssembly.Module(scratch.subarray(0, jitSize)); const jitInstance = new WebAssembly.Instance(jitModule, jitImports); jitInstance.exports.d(); } }; const fullVM = { calculate_hash: (input) => { hashFn(input, false); return new Uint8Array(scratch.subarray(0, 32)); }, calculate_hex_hash: (input) => { hashFn(input, true); return new TextDecoder().decode(scratch.subarray(0, 64)); } }; console.log('Full mode VM ready\n'); // Compute hash with full mode console.log('Computing hash with full mode VM...'); const fullStart = performance.now(); const fullHash = fullVM.calculate_hex_hash(TEST_INPUT); const fullTime = performance.now() - fullStart; console.log('Full mode hash: ', fullHash); console.log('Full mode time: ', fullTime.toFixed(2) + 'ms\n'); // Compare console.log('=== Comparison ==='); if (lightHash === fullHash) { console.log('SUCCESS: Hashes match!'); console.log('Our VM creation code produces correct results.'); console.log('Full mode with pre-computed dataset will work correctly.'); } else { console.log('FAILURE: Hashes do not match!'); console.log('Expected:', lightHash); console.log('Got: ', fullHash); process.exit(1); } } main().catch(console.error);