| … | … | @@ -4191,6 +4191,34 @@ injected per layer: |
| 4191 | 4191 | and the l2 / m5g1a / m5g3a drill sets are deleted at R4c-4e, not here (they are l2's only direct gate |
| 4192 | 4192 | while core still uses it); the M4d kill-point hook moves into rn at R4c-4d (the appender writes through |
| 4193 | 4193 | core). |
| 4194 | - **R4c-4b DONE 2026-10-07** (keetd cc88cff, 7c4c2d3, 5c25b9d): the measurements, on Bare at |
| 4195 | `UV_THREADPOOL_SIZE=1`, every script run twice byte-identical. |
| 4196 | - **The seek-proof quirk (core:H9), MEASURED** (`tools/r4c4b/seek-proof.js`): `Hypercore#proof` with a |
| 4197 | seek that reaches `blockAndSeekProof` / `upgradeProof` (block + seek inside the subtree, hash + seek inside |
| 4198 | the subtree, seek + upgrade) REJECTS with `TypeError: Cannot read properties of null (reading 'get')` — |
| 4199 | generateProof awaits the seek, Hypercore#proof has already `tryFlush`ed, the node reads hit the freed |
| 4200 | CoreRX. No unhandled rejection (settleProof's allSettled). A seek outside the subtree is |
| 4201 | `INVALID_OPERATION: Invalid seek`; seek alone is an empty proof. The replicator awaits `MerkleTree.proof` |
| 4202 | before its `tryFlush` (replicator.js:925, 1036 / 1072), so peers never see it. **Ported as JS has it:** |
| 4203 | l3 keeps JS's order and hc::storage's `live(view)` already throws this exact TypeError. |
| 4204 | - **The merkle hop trace, JS side** (`tools/mt`: gen-mt.js + mt-trace.js; R4c-4c's gate gets the C++ |
| 4205 | twin): trees from hypercore's own `MerkleTreeBatch`, proofs from its own `MerkleTree.proof`, written into |
| 4206 | hypercore-storage, rulers at every native completion; every storage reader over a plain session |
| 4207 | `{ fork, length, roots, byteLength, signature, prologue, storage }` — getRootsFromStorage, upgradeable, |
| 4208 | get, missingNodes (sparse chains: 2, 2, 2, 2, 1), byteOffset, byteRange, ByteSeeker, truncate, the |
| 4209 | batch's downgrade / restore / get / byteRange / byteOffset, proofs in `Hypercore#proof`'s shape AND the |
| 4210 | replicator's (read at the fork, await, `destroy` on a throw, `tryFlush`, fulfill), verify (incl. |
| 4211 | INVALID_CHECKSUM), reorg's want → hash proof → `await batch.update` loop (four reorgs to completion, |
| 4212 | ancestors 8 / 3 / 30 / 0). 6 scripts, ~4200 lines; a one-by-one and an all-at-once (`readersBurst`) |
| 4213 | run of the readers. |
| 4214 | - **Core hop traces** (`tools/m4/core-ops.js` opt-in hops mode: `rulers`, `nowait`, `waitAll`; existing |
| 4215 | scripts unchanged, m4b gate PASS; scripts `tools/r4c4b/gen-core-hops.js`): single ops one at a time, and |
| 4216 | the concurrency JS allows that keetd refuses today — appends queued on the state mutex, four proofs |
| 4217 | verified concurrently (`_verifyShared`: blocks 9 / 11 settle before 1 / 5), a verify against a mutex held |
| 4218 | by `setUserData`, a close during an append (the append rejects `RocksDB session is closed`). These are |
| 4219 | the JS side of the core gate's hops mode (R4c-4d). |
| 4220 | - **Not measured here:** `waitForRecovery` with a pending op — it waits on a replicator's recovery peers |
| 4221 | (R4f's pipe scenarios). |
| 4194 | 4222 | - **Then 4e-4** (`createProtocolStream` / `replicate`): the first gate that composes the stack |
| 4195 | 4223 | is a COMPOSED trace against JS (secret-stream + protomux + replicator), now meaningful. |
| 4196 | 4224 | |