Files
salvium-rs/test/parse-blocks-test.js
T
Matt Hess 56ab4ec3fe Convert debug-full-carrot-scan.js and verify-real-carrot.js to use
environment variables instead of hardcoded SPEND_SECRET values.

  Required env vars: SPEND_SECRET, TX_HASH
  Optional: DAEMON_URL (defaults to seed01.salvium.io:19081)
2026-01-22 03:24:00 +00:00

101 lines
3.2 KiB
JavaScript

#!/usr/bin/env bun
// Test parsing many blocks to ensure transaction parsing is robust
import { createDaemonRPC } from '../src/rpc/index.js';
import { parseTransaction } from '../src/transaction.js';
import { hexToBytes } from '../src/address.js';
const daemon = createDaemonRPC({ url: 'http://seed01.salvium.io:19081', timeout: 30000 });
async function test() {
console.log('=== Block parsing test ===\n');
const info = await daemon.getInfo();
const currentHeight = info.result.height;
console.log(`Current chain height: ${currentHeight}`);
const startHeight = 0;
const endHeight = Math.min(10000, currentHeight);
const batchSize = 100;
let totalTxs = 0;
let parsedTxs = 0;
let failedTxs = 0;
let startTime = Date.now();
console.log(`\nParsing blocks ${startHeight} to ${endHeight}...\n`);
for (let height = startHeight; height < endHeight; height += batchSize) {
const endBatch = Math.min(height + batchSize, endHeight);
// Get block headers for this batch
const headers = await daemon.getBlockHeadersRange(height, endBatch - 1);
if (!headers.result?.headers) continue;
// Collect all tx hashes from these blocks
const txHashes = [];
for (const header of headers.result.headers) {
// Get full block
const block = await daemon.getBlock(header.hash);
if (block.result?.tx_hashes) {
txHashes.push(...block.result.tx_hashes);
}
}
if (txHashes.length === 0) continue;
// Get transactions in batches of 100
for (let i = 0; i < txHashes.length; i += 100) {
const batch = txHashes.slice(i, i + 100);
const txResp = await daemon.getTransactions(batch, { decode_as_json: false });
if (!txResp.result?.txs) continue;
for (const txData of txResp.result.txs) {
totalTxs++;
try {
const tx = parseTransaction(hexToBytes(txData.as_hex));
parsedTxs++;
// Basic validation
if (!tx.prefix) throw new Error('Missing prefix');
if (tx.prefix.version === 2 && !tx.rct) throw new Error('Missing RCT for v2 tx');
} catch (e) {
failedTxs++;
if (failedTxs <= 10) {
console.log(` FAILED tx at height ~${height}: ${e.message}`);
}
}
}
}
// Progress update
const elapsed = (Date.now() - startTime) / 1000;
const rate = totalTxs / elapsed;
const memMB = Math.round(process.memoryUsage().heapUsed / 1024 / 1024);
console.log(`Height ${endBatch}: ${totalTxs} txs (${parsedTxs} ok, ${failedTxs} failed), ${rate.toFixed(1)} tx/s, ${memMB} MB`);
// Memory check
if (memMB > 500) {
console.log('\nWARNING: Memory usage > 500 MB, stopping');
break;
}
// Force GC if available
if (global.gc) global.gc();
}
const elapsed = (Date.now() - startTime) / 1000;
console.log(`\n=== Results ===`);
console.log(`Total transactions: ${totalTxs}`);
console.log(`Successfully parsed: ${parsedTxs}`);
console.log(`Failed: ${failedTxs}`);
console.log(`Success rate: ${(parsedTxs / totalTxs * 100).toFixed(2)}%`);
console.log(`Time: ${elapsed.toFixed(1)} seconds`);
console.log(`Rate: ${(totalTxs / elapsed).toFixed(1)} tx/s`);
}
test().catch(console.error);