You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Act ⑫ SwiftSync at scale: the full UTXO set in 32 bytes
tools/swiftsync-commit.mjs streams the full real testnet4 UTXO set (14,129,063
coins / 826 MB) through the accumulator -> 32-byte commitment af37b01d…, RSS flat
at 0.90 GB (the input file, not a 25 GB Map). Act ⑫ streams 3M outpoints through
the accumulator in the worker -> 32-byte state, UI responsive. The 25 GB memory
ceiling is now demonstrably gone, in Node and in the tab.
Remaining frontier: full hints-based stateless IBD (generate hints + stream
blocks/prevouts, holding only the accumulator + a bounded working set).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+7-7Lines changed: 7 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -46,6 +46,7 @@ and the browser-node design ([`bitcoin-kernel/node`](https://github.com/bitcoin-
46
46
| ⑨ |**WASM signature verification**| a WASM libsecp256k1 backend swapped in via `setVerifyBackend`, gated by verdict-equivalence |**GitHub Pages**| block #26000: ~1,161 → ~4,895 verifies/s (4.2× at block level), verdicts identical |
47
47
| ⑩ |**Run the node in a Web Worker (scale)**| engine + WASM secp + UTXO store + OPFS sync-handles run off the main thread, so validation/checkpoints don't freeze the UI |**GitHub Pages**| follow 21 blocks in a Worker: UI responsive (16 ms frame gap) vs frozen on the main thread (~1063 ms) |
48
48
| ⑪ |**SwiftSync — stateless validation**| set-consistency via a **32-byte accumulator** (add created, subtract spent) instead of the ~25 GB UTXO set |**GitHub Pages**| blocks 26000–26020 cancel to **ZERO** with 32 bytes of state; a fabricated spend is detected; 72 ms |
49
+
| ⑫ |**SwiftSync at scale**| the **full** real UTXO set committed via the accumulator with set-state held at **32 bytes**, not 25 GB |**GitHub Pages**| Node: **14.1M coins → 0.9 GB RSS** (the file), 32-byte commitment; tab: 3M coins streamed in the worker → 32 bytes, UI responsive |
49
50
50
51
Acts ③ ④ ⑥ are fully static and work on GitHub Pages. Acts ① (torrent seeding) and ⑤ (the bridge) need a
51
52
local server — see below.
@@ -131,13 +132,12 @@ background re-validation from genesis (not included in this demo) confirms it.
131
132
132
133
## Not done yet
133
134
134
-
-**Use SwiftSync in the running node** — stateless validation is **proven** (act ⑪: set-consistency with a
135
-
32-byte accumulator, not the ~25 GB UTXO set). The remaining work is wiring it into the worker's
136
-
forward-validation loop with a **WebTorrent-distributed hints file** (<100 MB) + streaming prevout data for
137
-
scripts, so `node.html` validates to the live tip without ever holding the full set. (`tools/reach-tip.mjs`
138
-
already reaches the tip — verified snapshot #141,574 → tip #141,680, incl. a 1,513-input block and blocks
139
-
mined during the run — by keeping only the coins the forward blocks spend; the full 14.1M set is ~25 GB,
140
-
over a tab's limit, which is exactly what SwiftSync removes.) Large snapshots/hints go via **WebTorrent**, never git.
135
+
-**Full hints-based stateless IBD** — the memory ceiling is **gone** (act ⑫ / `tools/swiftsync-commit.mjs`:
136
+
the full 14.1M-coin UTXO set commits with **32 bytes of state**), and SwiftSync is wired into the running
137
+
node (act ⑪ + `node.html`). The deepest remaining piece is a complete stateless forward-validation over a
138
+
large range / genesis→tip: generate a **SwiftSync hints file** (<100 MB, WebTorrent-distributed), stream
139
+
blocks + prevout data, and validate holding only the accumulator + a bounded working set — a full IBD that
140
+
never materializes the UTXO set. Large snapshots/hints go via **WebTorrent**, never git.
<tr><td>coins streamed</td><td class="n">${fmt(r.n)}</td><td class="dim">synthetic outpoints, in the worker</td></tr>
536
+
<tr><td>accumulator state</td><td class="n">${r.stateBytes} bytes</td><td class="dim">vs ~${heldGB} GB to hold them · digest ${r.digest}…</td></tr>
537
+
<tr><td>throughput</td><td class="n">${fmt(r.perSec)}/s</td><td class="dim">${(r.ms/1000).toFixed(1)}s · UI responsive (max gap ${maxGap.toFixed(0)}ms)</td></tr>
538
+
</table><p class="ok">✅ ${fmt(r.n)} coins committed with 32 bytes of state, UI never froze. The real full set — 14.1M coins — commits the same way (0.9 GB RSS = the file, not 25 GB).</p>`;
"verified": { "browser": "blocks 26000..26020: 249 + 2,203 - 1,091 - 1,361 cancels to ZERO with 32 bytes of state (vs ~25 GB); a fabricated spend yields a non-zero digest (rejected); 72ms", "node": "swiftsync-test.mjs", "provenance": "the repo's own SwiftSync accumulator (kernel/packages/swiftsync), verified across all of testnet4 by its _sscapstone.mjs" }
90
+
},
91
+
{
92
+
"id": 12, "name": "SwiftSync at scale — full UTXO set in 32 bytes", "ui": ["⑫"],
93
+
"proves": "The 25 GB ceiling is gone: the full real UTXO set is committed via the SwiftSync accumulator with the set-state held at a constant 32 bytes, not a multi-GB Map.",
"verified": { "node": "tools/swiftsync-commit.mjs: 14,129,063 real coins (826 MB snapshot) -> 32-byte commitment af37b01d…, RSS flat at 0.90 GB (the input file, not 25 GB), 73s", "browser": "3,000,000 outpoints streamed through the accumulator in the worker -> 32-byte state (vs ~5.3 GB to hold), 302k/s, UI responsive (16ms gap)" }
90
97
}
91
98
],
92
99
"servers": [
@@ -103,6 +110,6 @@
103
110
},
104
111
"trust_model": "The bridge and torrent/HTTP transports are untrusted: they cannot forge valid blocks or headers because the tab validates everything (PoW, difficulty, scripts, signatures, fees). Their only powers are withholding and eclipsing. assumeUTXO trusts the snapshot's UTXO set until background validation (not included here) re-derives it from genesis.",
105
112
"remaining": [
106
-
"Use SwiftSync in the running node (node.html). SwiftSync stateless validation is proven (act ⑪ — set-consistency via a 32-byte accumulator instead of the ~25 GB UTXO set). The remaining work is wiring it into the worker's forward-validation loop with a WebTorrent-distributed hints file (<100 MB) plus streaming prevout data for script checks, so node.html validates to the live tip without ever holding the full set. (tools/reach-tip.mjs already reaches the tip by keeping only the coins the forward blocks spend.) Large snapshots / hints go over WebTorrent, never git."
113
+
"Full hints-based stateless IBD. The memory ceiling is gone (act ⑫: 14.1M-coin UTXO set committed with 32 bytes of state; tools/swiftsync-commit.mjs), and SwiftSync is wired into the running node (act ⑪ + node.html). The deepest remaining piece is a complete stateless forward-validation over a large range / genesis->tip: generate a SwiftSync hints file (kernel/packages/swiftsync hint.js, <100 MB, WebTorrent-distributed), stream blocks + prevout data, and validate holding only the accumulator + a bounded working set — turning the proven pieces into a full IBD that never materializes the UTXO set. Large snapshots / hints go over WebTorrent, never git."
0 commit comments