Architecture Overview
A six-crate Rust workspace with a single-threaded matching engine at its core.
System Diagram
┌──────────────────────────────────────────────────────────────────────┐ │ Vela Architecture │ ├──────────────────────────────────────────────────────────────────────┤ │ │ │ Clients (HTTP / WebSocket) │ │ │ │ │ ▼ │ │ ┌──────────┐ ECDSA verify ┌────────────────────────────────┐ │ │ │ api │ ─────────────▶ │ engine │ │ │ │ (axum) │ │ (single-threaded event loop) │ │ │ └──────────┘ └──────────────┬─────────────────┘ │ │ │ CommitBatch │ │ ▼ │ │ ┌─────────────────────────────────┐ │ │ │ committer │ │ │ │ (async channel) │ │ │ └────────┬──────────┬─────────────┘ │ │ │ │ │ │ ┌─────────────┘ └───────────┐ │ │ ▼ ▼ │ │ ┌────────────────────┐ ┌─────────────────┐ │ │ │ state │ │ DA Layer │ │ │ │ (MPT in-memory │ │ (Celestia / │ │ │ │ + trie root) │ │ local file) │ │ │ └────────────────────┘ └────────┬────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────┐ │ │ │ zkvm │ │ │ │ (fraud proofs) │ │ │ └──────────────────┘ │ └──────────────────────────────────────────────────────────────────────┘
Crates
types
Shared type definitions used across the entire workspace. All prices and quantities are stored as 64-bit unsigned integers scaled by 1,000,000 — a fixed-point representation that eliminates floating-point rounding errors entirely. A price of 3200.50 is stored as 3200500000. This crate also defines the wire protocol: the request and response structures that flow between the API layer and the matching engine, and from the committer to downstream consumers.
engine
The matching engine. A single-threaded event loop that processes requests in strict arrival order. The engine maintains a price-time priority order book for each market, a copy-on-write (CoW) cache for atomic execution, and a credit ledger for market maker accounts. Supported order types are GTC, IOC, FOK, and Post-Only limit orders, plus market orders. The engine never performs I/O — all state mutations are in-memory and deterministic.
state
The MPT (Merkle Patricia Trie) state layer. Account balances and order states are stored in a trie that produces a cryptographic root after each committed batch. To eliminate trie traversal from the hot path, all reads and writes during matching go through an in-memory HashMap cache. The trie root is computed only at batch commit time, after the engine has finished processing a batch of orders. This design means the trie is never on the critical path for latency.
api
The HTTP and WebSocket server. Built on Axum, Rust's composable async web framework. Every mutating request — place order, cancel order, withdrawal — requires an ECDSA signature from the account owner. The api crate verifies signatures using the k256 crate (secp256k1 curve), recovers the signer address, and forwards valid requests to the engine. WebSocket connections support both public channels (order book, trades) and authenticated private channels (fills, order updates, balance changes).
committer
The async batch committer, fully decoupled from the matching engine hot path via a Tokio channel. When the engine completes a batch of operations, it sends a CommitBatch message through the channel and immediately continues processing the next request. The committer thread receives the batch, computes the MPT root over the new state, and publishes the root and transaction log to the configured data availability backend. This decoupling ensures that DA publishing latency never affects match latency.
zkvm
The optimistic-ZK fraud proof component. Given a pre-batch state snapshot, the zkvm crate seeds a fresh matching engine instance, re-executes all requests in the batch, and compares the resulting state root and balance deltas to what the committer published. If they match, execution was correct. If they diverge, a fraud proof is generated. The on-chain verification contract (M6 roadmap) will allow any party to submit this fraud proof and slash the operator.
Data Flow
A typical order lifecycle: the client signs an order with their Ethereum wallet and sends it via HTTP POST to /orders. The api crate verifies the ECDSA signature and forwards the order to the engine. The engine executes the order against the book, produces fills, updates balances in the CoW cache, and commits the delta. The delta is sent to the committer, which appends it to the MPT and publishes to DA. Concurrently, the api crate pushes fills and order updates to subscribed WebSocket clients.