eleven / messenger Public

Clone
git clone https://amadan.net/eleven/messenger

Plain git — no account needed to clone.

Download

Download this file

1#!/usr/bin/env node
2// 🤖 Verify a ledger stream end-to-end (issue #1224): fetch HEAD, walk the
3// prev-hash chain newest→oldest re-hashing every entry's exact bytes, and
4// fail loudly on the first broken link. Needs no credentials — the whole
5// walk rides the bucket's public https door, so anyone can run it.
6//
7// node tools/ledger-verify.mjs <ledger>
8import { fetchPublic, getHead } from "./ledgerstream.mjs";
9import { verifyLink } from "./ledgerchain.mjs";
10
11const ledger = process.argv[2];
12if (!ledger) { console.error("usage: node tools/ledger-verify.mjs <ledger>"); process.exit(1); }
13
14const head = await getHead(ledger);
15if (!head) { console.error(ledger + ": no HEAD — stream doesn't exist"); process.exit(1); }
16
17let key = head.head_key, claimedSha = head.head_sha256, walked = 0;
18while (key) {
19 const bytes = await fetchPublic(key);
20 if (!bytes) { console.error("BROKEN: " + key + " is missing"); process.exit(1); }
21 const v = verifyLink({ bytes, key, claimedSha });
22 if (!v.ok) { console.error("BROKEN at " + key + ": " + v.reason); process.exit(1); }
23 walked++;
24 key = v.entry.prev_key;
25 claimedSha = v.entry.prev_sha256;
26}
27if (walked !== head.count) {
28 console.error("BROKEN: HEAD counts " + head.count + " but the chain walks " + walked);
29 process.exit(1);
30}
31console.log(ledger + ": chain OK — " + walked + " entr" + (walked === 1 ? "y" : "ies") + ", head " + head.head_sha256.slice(0, 12) + "…");
32