spec-first perpetuals exchange in rust · spec phase
RSX started with a simple question: what if you wrote all the specs before any code?
impl block.
The spec-first approach meant we discovered protocol mismatches at spec review time, not integration time. The CRITIQUE.md identified 36 design gaps. All 36 were resolved before writing code.
Six process types. Nine Rust crates. One wire format.
Internet
|
[WebSocket]
|
+----------+
| Gateway | auth, rate limit, validation
+----+-----+
|
[CMP/UDP]
|
+----------+
| Risk | margin, positions, liquidation
| (shard) | per user_id hash
+----+-----+
|
[CMP/UDP]
|
+------------+------------+
| | |
+----+----+ +----+----+ +---+-----+
| ME: BTC | | ME: ETH | | ME: ... |
+---------+ +---------+ +---------+
Price, Qty, Side, SymbolConfig. Fixed-point i64 newtypes. Zero-cost abstractions.
Orderbook with slab allocator. CompressionMap turns 20M price levels into 617K slots.
Single-threaded matching engine. FIFO price-time priority. GTC, IOC, FOK, post-only.
Portfolio margin. Position tracking. Liquidation triggers. Funding payments.
WAL writer/reader. CMP protocol. DXS replay service. No Kafka, no NATS.
WebSocket ingress. JWT auth. Rate limiting. Circuit breaker. CMP bridge to risk.
Slab allocators for orders. CompressionMap for price levels. Pre-allocated event buffers. No malloc during matching. The matching engine sees 100-500ns per order.
All values are i64 in smallest units. No floats, anywhere. Deterministic across architectures. Type-safe newtypes prevent mixing Price and Qty at compile time.
WAL bytes = disk bytes = wire bytes = memory bytes
No serialization layer. No protobuf. No FlatBuffers.
Just #[repr(C, align(64))] and CRC32.
When a buffer fills, the producer stalls. Never drop data silently. A delayed fill is acceptable. A lost fill means incorrect positions.
Fills: 0ms loss (fsync before send). Orders: ephemeral (user retries on crash). Positions: derived (replay fills to rebuild).
RSX is a design study, not a production system. The architecture is validated through specs and unit tests. No E2E integration. No load testing. No security audit. This is research-grade code exploring exchange architecture patterns.
| Metric | Value |
|---|---|
| Rust LOC | ~34,000 |
| Tests | 960 Rust + 156 Playwright |
| Spec docs | 35 files, 5k lines |
| Crates | 9 |
| V1 spec coverage | ~99% (unit level) |
| E2E integration | not yet |
| Production ready | no |
19 engineering posts document the journey. Design philosophy, matching engine internals, wire protocols, hostile testing, and the bugs we found.