What a stranger sees: paste a chain block hash on /proof, the page downloads the captured proof bytes (1,272,897 bytes), hashes them in the tab against the proof_hash the signed record carries, parses the 328-byte public values out of the SP1 container and checks keccak against the record's statement and the decoded fields against the block (site/lib/proof.mjs, no library). The STARK is verified by this site's node (the observer runs igneum-prove-host --mode verify with the pinned key on each capture: 29 ms verify, 197 ms key setup on the fixture proof); the page says so and labels the in-browser STARK verifier as coming. docs/plans/explorer.md section 8 carries the size and time numbers and the two routes (Groth16 wrap plus sp1-verifier in wasm, or the compressed verifier ported to wasm32). Observer: a sample of pool proofs captured through igneum_getProofBytes while the node holds them (PROOF_CAPTURE_EVERY_MS, PROOF_BYTES_KEEP), checked and verified, written to live_proof_bytes; every live_proofs row carries the record (key_hash, payout, statement, proof_hash); getBlockTemplate.powEpoch read every 10 s into live_state.pow_epoch. RPC load: wrpc 230 to 248 per minute against 222 to 224 before, evm unchanged. P17: the node release 0.3.13 (bb43e9a8) does not carry the state field (it is on ledger-fixes-0311 fbb0082a), so the explorer cuts the one word from the observer's tables by the design 2.4 rule and takes the node's word per transaction when the fork answers one. A block that left the selected chain reads included with a note, never reorged out. C46: /api/stats algorithm reads "class v3 / generator 3 (epoch 55; ...)" from the node's epoch line, v4 when the node reports 4, "unknown" before the observer has read it; new lottery field. Tests: site/lib/proof.test.mjs (the real tail of block 59199's proof reproduces the host's statement), site/api/verify.test.mjs, tools/observer/proof-capture.test.mjs (the native verifier refusing a pre-pin proof), site/api/public-stats.test.mjs. Dry run on the fixture proof of block 56 through the local preview: VERIFIED, 5.8 ms of checks and 139 ms of download in the browser, STARK 29 ms on the node. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
18 lines
1.6 KiB
JSON
18 lines
1.6 KiB
JSON
{
|
|
"cleanUrls": true,
|
|
"trailingSlash": false,
|
|
"redirects": [{"source": "/ledger", "destination": "/", "permanent": false}],
|
|
"rewrites": [{"source": "/block/:id", "destination": "/block"}, {"source": "/address/:addr", "destination": "/address"}, {"source": "/proof/:id", "destination": "/proof"}],
|
|
"headers": [
|
|
{"source": "/(.*)", "headers": [{"key": "X-Content-Type-Options", "value": "nosniff"}, {"key": "X-Frame-Options", "value": "DENY"}, {"key": "Referrer-Policy", "value": "strict-origin-when-cross-origin"}, {"key": "Strict-Transport-Security", "value": "max-age=63072000; includeSubDomains; preload"}]},
|
|
{"source": "/fonts/(.*)", "headers": [{"key": "Cache-Control", "value": "public, max-age=31536000, immutable"}]},
|
|
{"source": "/(.*)\\.(png|ico)", "headers": [{"key": "Cache-Control", "value": "public, max-age=86400, stale-while-revalidate=604800"}]},
|
|
{"source": "/site.webmanifest", "headers": [{"key": "Cache-Control", "value": "public, max-age=86400, stale-while-revalidate=604800"}]},
|
|
{"source": "/journey.json", "headers": [{"key": "Cache-Control", "value": "public, max-age=300"}]},
|
|
{"source": "/api/live", "headers": [{"key": "Cache-Control", "value": "public, max-age=1"}]},
|
|
{"source": "/api/stats", "headers": [{"key": "Cache-Control", "value": "public, max-age=10, s-maxage=10"}]},
|
|
{"source": "/api/supply", "headers": [{"key": "Cache-Control", "value": "public, max-age=10, s-maxage=10"}]},
|
|
{"source": "/api/explorer", "headers": [{"key": "Cache-Control", "value": "public, max-age=5, s-maxage=5"}]},
|
|
{"source": "/api/verify", "headers": [{"key": "Cache-Control", "value": "public, max-age=5, s-maxage=5"}]}
|
|
]
|
|
}
|