Files
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

136 lines
4.2 KiB
JavaScript

/**
* 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);