tools/harness runs the standard consensus-attack catalogue against a private test network of our own igneumd nodes (127.0.0.1 ports 27200+, /tmp/igneum-harness, never the live devnet or the PC node), with a pass criterion per scenario from the spec and a measured result each. Built on the node fork's own crates (igneum-harness-sim on kaspa_utils::sim as simpa does; igneum-p2p-probe for the wire). Scenarios: 1 withholding, 2 timestamp edges and drift, 3 partition and heal, 4 eclipse, 5 malformed and boundary inputs on every p2p and RPC surface, 6 resource exhaustion, 7 fast-miner flood. Finality and difficulty-controller scenarios are stubs with their criteria written. bench-log: one dated entry, a row per scenario (criterion, measured, pass or fail). First run: 19 of 20 measured rows pass. Findings recorded in the entry: scenario 5 reproduces ledger M15 on HEAD (bogus past-day or DAA headers build a 256 MiB cache before rejection; the r3-fixes branch removes it); scenario 1 at 45% hash with burst withholding shows a selfish-mining blue-share gain (50.7% of blues), the one failing row. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
45 lines
1.5 KiB
JavaScript
45 lines
1.5 KiB
JavaScript
// Results: one JSON per scenario run under /tmp/igneum-harness/results, and one dated bench-log entry with a row per
|
|
// scenario (criterion, result, pass or fail). `run.mjs` calls writeBenchLog once at the end of a batch.
|
|
|
|
import { mkdirSync, writeFileSync, readFileSync, appendFileSync, existsSync } from 'node:fs';
|
|
import { ROOT, TMP } from './net.mjs';
|
|
|
|
export const RESULTS = `${TMP}/results`;
|
|
|
|
export function saveResult(name, data) {
|
|
mkdirSync(RESULTS, { recursive: true });
|
|
const file = `${RESULTS}/${name}.json`;
|
|
writeFileSync(file, JSON.stringify(data, null, 2));
|
|
return file;
|
|
}
|
|
|
|
export function loadResults(names) {
|
|
const out = {};
|
|
for (const n of names) {
|
|
const f = `${RESULTS}/${n}.json`;
|
|
if (existsSync(f)) out[n] = JSON.parse(readFileSync(f, 'utf8'));
|
|
}
|
|
return out;
|
|
}
|
|
|
|
/// rows: [{ scenario, criterion, result, pass: true|false|null }]
|
|
export function benchLogEntry({ date, title, machine, rows, notes = [] }) {
|
|
const lines = [];
|
|
lines.push('', `## ${date}, ${title}`, '');
|
|
lines.push(machine);
|
|
lines.push('');
|
|
lines.push('| Scenario | Criterion (spec) | Measured | Pass |');
|
|
lines.push('|---|---|---|---|');
|
|
for (const r of rows) {
|
|
const pass = r.pass === true ? 'pass' : r.pass === false ? 'FAIL' : 'stub';
|
|
lines.push(`| ${r.scenario} | ${r.criterion} | ${r.result} | ${pass} |`);
|
|
}
|
|
for (const n of notes) { lines.push(''); lines.push(n); }
|
|
return lines.join('\n') + '\n';
|
|
}
|
|
|
|
export function appendBenchLog(text) {
|
|
const f = `${ROOT}docs/bench-log.md`;
|
|
appendFileSync(f, text);
|
|
return f;
|
|
}
|