Activity
Submissions and contributions over the last year
prsweet
backend engineer
A crypto exchange, split the way production exchanges are. A stateless gateway authenticates and validates orders. Kafka carries them as commands. A Rust engine owns the order books and balances, and nothing else can touch them.
Each symbol's book belongs to a single Tokio task fed by an mpsc channel. The hot path needs no mutexes, and separate markets run on separate cores. Actors are spawned lazily the first time a symbol appears.
Every order first goes to the BalanceActor as CheckAndLock, which replies over a oneshot channel. Only approved orders reach the book. Fills settle from locked into the counterparty's available balance, and a cancel releases the lock.
Bids and asks are BTreeMap<u64, PriceLevel>. Each level is a doubly linked FIFO indexed by order ID in a HashMap, so removing an order from the middle of the queue never means a scan.
Prices and quantities are u64 ticks. There are no floats anywhere near a balance.
State in memory is fast but disposable. A snapshot plus Kafka replay rebuilds it exactly, so the database can lag behind on an interval without ever being wrong. The gateway stays stateless, and malformed messages are logged and skipped instead of crashing the loop.
This is the engine's match_order, ported line for line to TypeScript and running in your browser. It uses the same rules: price-time priority, limit remainders rest on the book, and market remainders are cancelled.
Order books, priority queues and routing started out as contest problems for me. Every number below is pulled live from the judges' APIs through this site's /api/cp.
Every tool here is linked to the section where it's used.