mirror of
https://github.com/morluto/rea
synced 2026-10-28 15:07:26 -04:00
f161952ffd
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
133 lines
3.9 KiB
JavaScript
133 lines
3.9 KiB
JavaScript
// Equivalent complete span occurrences through the existing exact-address API.
|
|
import assert from "node:assert/strict";
|
|
import { createHash } from "node:crypto";
|
|
import { writeFile } from "node:fs/promises";
|
|
import { AtomicSession } from "./session.mjs";
|
|
import { familyCounters } from "./family-counters.mjs";
|
|
import {
|
|
createVerifierRun,
|
|
completeVerifierRun,
|
|
assertVerifierCleanupComplete,
|
|
} from "../../scripts/lib/verifier-run.mjs";
|
|
const [binary, output] = process.argv.slice(2);
|
|
assert(
|
|
binary && output,
|
|
"Usage: node measure-reference-spans.mjs BINARY NEW_OUTPUT_JSON",
|
|
);
|
|
const session = new AtomicSession(),
|
|
verifier = createVerifierRun(),
|
|
failures = [];
|
|
const observations = [],
|
|
phases = [],
|
|
sources = new Map();
|
|
const call = async (method, input) => {
|
|
const r = await session.call(method, input);
|
|
assert.equal(r.ok, true, JSON.stringify(r));
|
|
for (const d of r.data.results ?? [r.data]) {
|
|
if (Object.hasOwn(d, "ok")) assert.equal(d.ok, true, JSON.stringify(d));
|
|
if (d.source) sources.set(d.source.evidence_id, d.source);
|
|
}
|
|
observations.push({ method, input, data: r.data });
|
|
return r.data;
|
|
};
|
|
const measure = async (phase, work) => {
|
|
const a = await familyCounters(),
|
|
start = performance.now();
|
|
const result = await work(),
|
|
b = await familyCounters();
|
|
phases.push({
|
|
phase,
|
|
elapsed_ms: performance.now() - start,
|
|
family_cpu_seconds: (b.cpu - a.cpu) / 1e6,
|
|
peak_bytes: b.peak,
|
|
});
|
|
return result;
|
|
};
|
|
let context, spans;
|
|
try {
|
|
await session.open(binary);
|
|
context = session.context;
|
|
assert.equal(
|
|
context.artifact_sha256,
|
|
"2e6eef9a727f081f0d453b4e5e6cbd8b9ef8b6f86cbf7681cbad444d3b0b55c8",
|
|
);
|
|
spans = [];
|
|
for (const text of ["no such table", "sqlite_schema"]) {
|
|
const inventory = await call("strings", { query: text, limit: 128 });
|
|
const selected = inventory.items.filter((s) => s.value === text);
|
|
assert.equal(selected.length, 1);
|
|
const row = selected[0];
|
|
assert.equal(row.string.encoding, "ascii");
|
|
assert.equal(row.string.byte_length, 14);
|
|
const addresses = Array.from(
|
|
{ length: row.string.byte_length },
|
|
(_, i) => "0x" + (BigInt(row.address) + BigInt(i)).toString(16),
|
|
);
|
|
const input = {
|
|
addresses,
|
|
kinds: ["data"],
|
|
fields: ["fromFunction", "instruction"],
|
|
limit: 128,
|
|
};
|
|
const cold = await measure("cold-enumeration:" + text, () =>
|
|
call("references", input),
|
|
);
|
|
assert(cold.results.every((r) => r.next_offset === null));
|
|
const warm = await measure("warm-enumeration:" + text, () =>
|
|
call("references", input),
|
|
);
|
|
assert.deepEqual(warm, cold);
|
|
spans.push({
|
|
text,
|
|
start: row.address,
|
|
end_inclusive: addresses.at(-1),
|
|
rows: cold.results.flatMap((r) => r.items),
|
|
counts: cold.results.map((r) => [r.address, r.total]),
|
|
});
|
|
}
|
|
for (const source of sources.values()) {
|
|
let text = "",
|
|
offset = 0;
|
|
do {
|
|
const p = await session.call("evidence", {
|
|
evidence_id: source.evidence_id,
|
|
offset,
|
|
limit: 16384,
|
|
});
|
|
assert.equal(p.ok, true);
|
|
text += p.data.text;
|
|
offset = p.data.next_offset;
|
|
} while (offset !== null);
|
|
assert.equal(Buffer.byteLength(text), source.bytes);
|
|
assert.equal(
|
|
createHash("sha256").update(text).digest("hex"),
|
|
source.sha256,
|
|
);
|
|
}
|
|
} catch (error) {
|
|
failures.push(error.stack ?? String(error));
|
|
} finally {
|
|
session.abort();
|
|
try {
|
|
await session.close();
|
|
} catch (error) {
|
|
failures.push(error.stack ?? String(error));
|
|
}
|
|
}
|
|
const lifecycle = await completeVerifierRun(verifier);
|
|
assertVerifierCleanupComplete(lifecycle.process_lineage);
|
|
assert.deepEqual(failures, []);
|
|
await writeFile(
|
|
output,
|
|
JSON.stringify({
|
|
context,
|
|
spans,
|
|
phases,
|
|
observations,
|
|
source_count: sources.size,
|
|
lifecycle,
|
|
}),
|
|
{ flag: "wx" },
|
|
);
|
|
console.log(JSON.stringify({ spans, phases, source_count: sources.size }));
|