moq-lite: fix AnnounceInterest.exclude_hop overflow on JS side#1427
Conversation
The Rust relay encodes `AnnounceInterest.exclude_hop` as a 62-bit Origin id, but the JS client was decoding it via `r.u53()`, which throws "value larger than 53-bits" for any peer Origin > 2^53-1. The throw inside `#runBidi` was caught by `stream.writer.reset(err)` with an Error object as the reason, which Chrome's WebTransport surfaces as a session-level abort (`remote error: code=0`). The resulting cascade tore down the entire connection right after the announce handshake. JS: - `AnnounceInterest.excludeHop` is now `bigint`, encoded/decoded via `u62` to match the wire format and the Rust struct. - `Subscriber.#runAnnounced` passes `this.origin` as `excludeHop`, matching the Rust subscriber's `self.self_origin.id` behavior. - `Reader.u53` / `Writer.u53` downgrade overflow from throw to warn so a stray u64 on the wire can never tear down a stream/session again. Precision is lost; the warning surfaces the value. Rust: - `Origin::random` temporarily caps the random id at 53 bits so older `@moq/lite` bundles (still on the buggy u53 decoder) survive a fresh relay. Restore to 62 bits once the JS fix has propagated. Version bumps: - @moq/lite 0.2.3 -> 0.2.4 - moq-lite 0.16.2 -> 0.16.3 - moq-relay 0.11.2 -> 0.11.3 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (7)
WalkthroughThis PR extends AnnounceInterest to support 62-bit excludeHop values as 64-bit JavaScript bigints while maintaining temporary 53-bit compatibility with existing JS clients. The core type change updates serialization to u62 varint encoding. Subscriber integration passes the connection's origin field for hop-chain self-exclusion. Stream reader/writer u53 methods now warn instead of throwing on overflow. Rust origin generation is capped to 53 bits for JS compatibility. All package versions are incremented to reflect the changes. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Browsers connecting to a fresh relay over `moq-lite-04` were getting their session torn down ~7ms after the handshake, with `WebTransportError: The session is closed` cascading through every in-flight stream. Root cause was a field-width mismatch in JS.
The Rust relay sends its session-level Origin id (62-bit, ~10^18) as `AnnounceInterest.exclude_hop` so peers can skip reflected announces. The JS decoder read it via `r.u53()`, which throws on anything > `2^53-1`. The throw inside `#runBidi` was caught by `stream.writer.reset(err)` with an `Error` object as the reason, which Chrome's WebTransport surfaces as a session-level abort (`remote error: code=0`). Everything else followed from there.
JS
Rust
Version bumps
Test plan
🤖 Generated with Claude Code