The tip cluster proves each new block as it is mined, then waits. A block arrives every ~10 minutes and proving one takes well under that (966,256 proved in 544 s on rented 4090s), so the cluster is idle most of the time. Anchor warp spends that idle time proving the block below the anchor and folding it in, so the anchor walks backwards toward genesis one block at a time.
This is the plan already published on hazync.org ("Proving the whole chain"): the proof party climbs from genesis, the tip cluster works down from an anchor, and the gap closes from both ends. Until they meet, a proof starting at the anchor rests on that checkpoint, much as Core's assumeutxo rests on a snapshot hash. When they meet, the checkpoint stops being something anyone has to trust.
What already exists
- The fold is the same operation, in the other direction.
fold-range takes two adjacent ranges and checks the seam in the guest: [N..N] + [N+1..M] -> [N..M]. Prepending a block below a range needs no new proving mode. extend-spine is just the genesis-pinned specialisation of it.
- Submissions already accept arbitrary widths.
parse_any_range takes any lo-hi, and the board labels a range anchored only if it starts at block 1 — a warped range is honestly labelled unanchored until it meets the spine.
- The pre-state format is right. Each bundle carries
height, in_tip, in_roots, in_leaves, in_nbits, in_time, in_epoch_start, in_recent plus the witness — exactly what proving that block needs.
What is missing
- A work source that goes downward.
claim() scans upward from block 1 and hands out the earliest unproven block; there is no way to ask for "anchor − 1". Needs an endpoint (or claim mode) that serves the block below a named anchor, and coordinator state tracking each anchor's current low-water mark.
- Idle detection in the worker. The cluster should warp only while waiting for the next block, and drop it the moment a new tip block arrives — tip blocks always win.
- Fold-in and bookkeeping. After proving anchor−1, fold it into the anchored range and publish the new, lower anchor. Same shape as the spine's absorb step, so the same failure modes apply: a lost race should self-heal, not abort.
⛔ The blocker is pre-state, not proving
To prove block N you need the accumulator as of N−1. The bridge keeps one forward-walking checkpoint (bridge_load_state → a single st.height) and the accumulator only advances by applying blocks; the snapshot format notes that leaf order depends on deletion history, so it is not trivially invertible.
Measured on the coordinator today:
- 230,000 bundles on disk, heights 1..230,000, 95 GB. Nothing prunes them — there is no bundle deletion path anywhere in the coordinator.
- Disk: 1.5 TB used, 495 GB free.
- Earlier measurement (2026-09-08): the bridge walks at 15.6 blocks/s and costs ~2.05 MB/block at the 220k era, projecting ~1.5 TB to reach the tip — and that is an under-estimate, since bundles grow with block size.
So:
- Below 230,000, anchor warp would work today — every block's pre-state is already on disk.
- An anchor near the tip has no bundles beneath it, and producing them means walking the bridge from 230k upward through ~736k blocks, which is the retention/disk problem, not a proving problem.
⇒ Either the anchor starts where bundles exist, or this needs a second bridge cursor (walk forward from a lower snapshot, retaining a window below the anchor), or a way to reconstruct pre-state downward. That choice should be made before any code is written.
Open questions
- Where does the anchor start, and who publishes the checkpoint it rests on?
- One anchor or several (each cluster warping its own region, folding when they touch)?
- How is warp work shared without two cards proving the same block? The existing
foldable pattern (advisory, duplicates discarded) probably transfers.
- What does the board show for a range that is verified but not genesis-anchored, so nobody reads it as "proven from genesis"?
How to know it works
An anchor at height A, left idle for an hour, should sit at A − (number of idle slots), with one verified range [A−k..tip] and no gaps. Cheapest first test: pick an anchor inside the bundled region (say 200,000), warp it down 20 blocks, and check the folded range verifies and the seam holds at every step.
The tip cluster proves each new block as it is mined, then waits. A block arrives every ~10 minutes and proving one takes well under that (966,256 proved in 544 s on rented 4090s), so the cluster is idle most of the time. Anchor warp spends that idle time proving the block below the anchor and folding it in, so the anchor walks backwards toward genesis one block at a time.
This is the plan already published on hazync.org ("Proving the whole chain"): the proof party climbs from genesis, the tip cluster works down from an anchor, and the gap closes from both ends. Until they meet, a proof starting at the anchor rests on that checkpoint, much as Core's
assumeutxorests on a snapshot hash. When they meet, the checkpoint stops being something anyone has to trust.What already exists
fold-rangetakes two adjacent ranges and checks the seam in the guest:[N..N] + [N+1..M] -> [N..M]. Prepending a block below a range needs no new proving mode.extend-spineis just the genesis-pinned specialisation of it.parse_any_rangetakes anylo-hi, and the board labels a rangeanchoredonly if it starts at block 1 — a warped range is honestly labelled unanchored until it meets the spine.height, in_tip, in_roots, in_leaves, in_nbits, in_time, in_epoch_start, in_recentplus the witness — exactly what proving that block needs.What is missing
claim()scans upward from block 1 and hands out the earliest unproven block; there is no way to ask for "anchor − 1". Needs an endpoint (or claim mode) that serves the block below a named anchor, and coordinator state tracking each anchor's current low-water mark.⛔ The blocker is pre-state, not proving
To prove block N you need the accumulator as of N−1. The bridge keeps one forward-walking checkpoint (
bridge_load_state→ a singlest.height) and the accumulator only advances by applying blocks; the snapshot format notes that leaf order depends on deletion history, so it is not trivially invertible.Measured on the coordinator today:
So:
⇒ Either the anchor starts where bundles exist, or this needs a second bridge cursor (walk forward from a lower snapshot, retaining a window below the anchor), or a way to reconstruct pre-state downward. That choice should be made before any code is written.
Open questions
foldablepattern (advisory, duplicates discarded) probably transfers.How to know it works
An anchor at height A, left idle for an hour, should sit at A − (number of idle slots), with one verified range
[A−k..tip]and no gaps. Cheapest first test: pick an anchor inside the bundled region (say 200,000), warp it down 20 blocks, and check the folded range verifies and the seam holds at every step.