Skip to content

mantis-exchange/mantis-matching-engine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mantis-matching-engine

High-performance order matching engine for Mantis Exchange, written in Rust.

Features

  • Price-time priority matching — BTreeMap for price levels, VecDeque for FIFO within each level
  • Order types — Limit, Market
  • Time-in-force — GTC (Good 'Til Cancelled), IOC (Immediate or Cancel), FOK (Fill or Kill)
  • Multi-symbol — Independent order book per trading pair, single-threaded per symbol (no lock contention)
  • gRPC API — SubmitOrder, CancelOrder, GetDepth, StreamTrades (via tonic)
  • Write-Ahead Log — Crash recovery with WAL replay on startup
  • Zero floating pointrust_decimal for precise decimal arithmetic
  • No database in hot path — Pure in-memory matching, WAL for durability

Performance

Benchmark Result
Insert 1,000 limit orders ~1.2ms (~820K orders/sec)
Match against 100 price levels ~118µs

Measured on Apple Silicon. Run cargo bench to reproduce.

Architecture

┌──────────────────────────────────────────────┐
│                   Engine                     │
│  ┌─────────────┐  ┌─────────────┐           │
│  │  OrderBook  │  │  OrderBook  │  ...       │
│  │  BTC-USDT   │  │  ETH-USDT   │           │
│  │  ┌───────┐  │  │  ┌───────┐  │           │
│  │  │ Asks  │  │  │  │ Asks  │  │           │
│  │  │BTreeMap│  │  │  │BTreeMap│  │           │
│  │  └───────┘  │  │  └───────┘  │           │
│  │  ┌───────┐  │  │  ┌───────┐  │           │
│  │  │ Bids  │  │  │  │ Bids  │  │           │
│  │  │BTreeMap│  │  │  │BTreeMap│  │           │
│  │  └───────┘  │  │  └───────┘  │           │
│  └─────────────┘  └─────────────┘           │
│         │                                    │
│    ┌────▼────┐                               │
│    │   WAL   │  Write-ahead log for recovery │
│    └─────────┘                               │
└──────────────────────┬───────────────────────┘
                       │ gRPC (port 50051)
                       ▼
                  mantis-gateway

System Context (Mermaid)

graph TD
    Client([Client]) -->|REST / WebSocket| GW[mantis-gateway]
    GW -->|gRPC| ME[mantis-matching-engine]
    GW -->|gRPC| OS[mantis-order]
    OS -->|gRPC| ME
    ME -->|Trade Events| K[(Kafka)]
    K --> MD[mantis-market-data]
    K --> OS
    OS -->|HTTP| AC[mantis-account]

    subgraph mantis-matching-engine
        direction TB
        GRPC[gRPC Server :50051] --> ENG[Engine]
        ENG --> OB1[OrderBook\nBTC-USDT]
        ENG --> OB2[OrderBook\nETH-USDT]
        ENG --> WAL[Write-Ahead Log]
        OB1 --- ASKS1[Asks - BTreeMap]
        OB1 --- BIDS1[Bids - BTreeMap]
    end

    style ME fill:#e94560,color:#fff,stroke:#333
    style GW fill:#1e2329,color:#eee,stroke:#555
    style OS fill:#1e2329,color:#eee,stroke:#555
    style AC fill:#1e2329,color:#eee,stroke:#555
    style MD fill:#1e2329,color:#eee,stroke:#555
Loading

Order Matching Flow

sequenceDiagram
    participant C as Client
    participant G as Gateway
    participant E as Engine
    participant W as WAL
    participant K as Kafka

    C->>G: POST /api/v1/orders
    G->>E: gRPC SubmitOrder
    E->>W: Write WAL entry
    E->>E: Match against OrderBook
    alt Has match
        E-->>K: Publish Trade event
        E-->>G: Order FILLED + Trades
    else No match (limit order)
        E->>E: Rest on OrderBook
        E-->>G: Order NEW
    end
    G-->>C: JSON response
Loading

Modules

File Description
src/types.rs Core types: Order, Trade, Side, OrderType, TimeInForce, OrderStatus
src/orderbook.rs OrderBook — per-symbol matching with price-time priority
src/engine.rs Engine — multi-symbol manager, command/event pattern, WAL integration
src/wal.rs Write-ahead log: WalWriter, WalReader, WalEntry
src/grpc.rs gRPC service: SubmitOrder, CancelOrder, GetDepth, StreamTrades
src/main.rs Entry point — WAL recovery, gRPC server on 0.0.0.0:50051

Quick Start

Prerequisites

  • Rust (nightly or stable, edition 2024)
  • protoc (brew install protobuf on macOS)
  • mantis-common proto files (cloned as sibling directory)

Build & Run

git clone https://github.com/mantis-exchange/mantis-matching-engine.git
git clone https://github.com/mantis-exchange/mantis-common.git
cd mantis-matching-engine

cargo build --release
cargo test
cargo bench

# Run the gRPC server
./target/release/mantis-matching-engine
# Listening on 0.0.0.0:50051

Docker

# From parent directory (needs mantis-common for proto files)
docker build -f mantis-matching-engine/Dockerfile -t mantis-engine .
docker run -p 50051:50051 mantis-engine

API

gRPC (protobuf definitions in mantis-common)

service MatchingEngine {
  rpc SubmitOrder(SubmitOrderRequest) returns (SubmitOrderResponse);
  rpc CancelOrder(CancelOrderRequest) returns (CancelOrderResponse);
  rpc GetDepth(GetDepthRequest) returns (GetDepthResponse);
  rpc StreamTrades(StreamTradesRequest) returns (stream TradeEvent);
}

Example: Place an order via gateway

curl -X POST http://localhost:8080/api/v1/orders \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "symbol": "BTC-USDT",
    "side": "buy",
    "type": "limit",
    "price": "50000",
    "qty": "1.5",
    "time_in_force": "GTC"
  }'

Tests

$ cargo test

running 21 tests
test engine::tests::test_engine_full_flow ... ok
test engine::tests::test_engine_multi_symbol ... ok
test engine::tests::test_engine_recover_empty_wal ... ok
test engine::tests::test_engine_unknown_symbol ... ok
test engine::tests::test_engine_wal_with_cancel ... ok
test engine::tests::test_engine_wal_write_and_recover ... ok
test orderbook::tests::test_cancel_order ... ok
test orderbook::tests::test_depth ... ok
test orderbook::tests::test_exact_match ... ok
test orderbook::tests::test_fok_insufficient_liquidity ... ok
test orderbook::tests::test_ioc_cancel_remaining ... ok
test orderbook::tests::test_limit_order_rests_on_book ... ok
test orderbook::tests::test_market_order ... ok
test orderbook::tests::test_partial_fill ... ok
test orderbook::tests::test_price_time_priority ... ok
test orderbook::tests::test_spread ... ok
test wal::tests::test_append_after_reopen ... ok
test wal::tests::test_empty_wal ... ok
test wal::tests::test_truncate ... ok
test wal::tests::test_wal_exists ... ok
test wal::tests::test_write_and_read_entries ... ok

test result: ok. 21 passed; 0 failed

Part of Mantis Exchange

This is the core matching engine of Mantis Exchange — a cryptocurrency exchange built with Rust, Go, and React.

Service Language Description
mantis-matching-engine Rust Order matching (this repo)
mantis-gateway Go REST + WebSocket API gateway
mantis-order Go Order lifecycle management
mantis-account Go User auth, JWT, balance management
mantis-market-data Go K-line aggregation, market data
mantis-wallet Go Deposit/withdrawal, chain integration
mantis-risk Go Risk control, circuit breaker
mantis-web React/TS Trading UI
mantis-admin React/TS Admin dashboard

License

MIT

About

Mantis Exchange - Order matching engine

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors