How fluidex/dingir-exchange works
Purpose and Executables
Dingir Exchange is a Rust trading-server backend centered on a high-throughput, in-memory order-matching engine. It intentionally excludes account onboarding and cryptocurrency deposit/withdrawal. Runtime binaries separate core trading, durable event processing, HTTP-style REST access, and message inspection:
• src/bin/matchengine.rs
• src/bin/persistor.rs
• src/bin/restapi.rs
• src/bin/dump_unify_messages.rs
Core Matching Engine
The matching engine is a fully asynchronous but single-threaded state owner: order-book mutation, sequencing, trades, balances, and user state should remain within this boundary to preserve deterministic ordering and avoid concurrent state mutation.
• src/matchengine/server.rs
• src/matchengine/controller.rs
• src/matchengine/sequencer.rs
• src/matchengine/market/order.rs
• src/matchengine/market/trade.rs
Requests enter the engine server/controller, are sequenced, then mutate market and account state. Resulting order-state changes, trades, and market data become outbound messages and persistence inputs.
Market, User, and Asset Domains
Market state and trade execution are distinct from user/account balances. Asset management applies balance updates and controls how those updates are emitted or coordinated; user management owns user-level exchange state. This is the primary business-state boundary beneath the controller.
• src/matchengine/market/mod.rs
• src/matchengine/asset/asset_manager.rs
• src/matchengine/asset/balance_manager.rs
• src/matchengine/asset/update_controller.rs
• src/matchengine/user_manager.rs
Messaging and Event Boundary
The system has a dedicated producer/consumer/persistence messaging layer, likely used to decouple engine mutations from durable operation logs and downstream consumers. Kafka is a material external dependency: the project requires librdkafka, and examples include Kafka monitoring.
• src/message/producer.rs
• src/message/consumer.rs
• src/message/persist.rs
• examples/js/kafka_client.ts
This boundary should carry ordered engine outputs rather than allow consumers to directly mutate matching state.
Durability and Historical Storage
Durability combines append-style operation logging with Redis-like fork-and-save snapshots. The persistor component bridges engine/message outputs to durable state; SQL storage holds longer-lived relational records such as trades, kline data, markets, accounts, and transfers.
• src/matchengine/persist/persistor.rs
• src/matchengine/persist/state_save_load.rs
• src/storage/database.rs
• migrations/20200123090047_trade_log.sql
• migrations/20210114140803_kline.sql
PostgreSQL is the documented local dependency, launched alongside Kafka through the orchestration environment.
API Surfaces and Clients
gRPC is the documented primary server interface, implemented with Tokio/Hyper/Tonic. A separate REST API process exposes management, user, public/personal history, trading-view data, and state access; it should query or coordinate with the authoritative engine/persisted data rather than duplicate matching logic.
• src/restapi/mod.rs
• src/restapi/manage.rs
• src/restapi/public_history.rs
• src/restapi/personal_history.rs
• src/restapi/tradingview.rs
JavaScript and Python examples act as external clients and signing/integration references:
• examples/js/RESTClient.ts
• examples/js/ordersigner.proto
• examples/python/put_order.py
Configuration and Deployment
Configuration is layered by environment and service-specific REST settings. Local integration infrastructure is under orchestra; release packaging builds a Docker image.
• src/config.rs
• config/default.yaml
• config/restapi/default.yaml
• orchestra
• release/Dockerfile
Main entry points: sequencer.rs Sequencer · persistor.rs Persistence pipeline · mod.rs REST handlers · server.rs Engine server
Components 19
Runtime processes
- Match engine binary
src/bin/matchengine.rs - Persistor binary
src/bin/persistor.rs - REST API binary
src/bin/restapi.rs - Message dump tool · Inspects unified messages.
src/bin/dump_unify_messages.rs
Authoritative matching engine
Single-threaded owner of ordered exchange state.
- Engine server · Primary request entry point.
src/matchengine/server.rs - Engine controller
src/matchengine/controller.rs - Sequencer · Preserves deterministic mutation order.
src/matchengine/sequencer.rs - Market and order books
src/matchengine/market/mod.rs - Assets and balances
src/matchengine/asset/asset_manager.rs - User state
src/matchengine/user_manager.rs
Messaging and durability
- Event producer · Publishes ordered engine outputs.
src/message/producer.rs - Kafka · External durable consumer boundary.
- Event consumer
src/message/consumer.rs - Persistence pipeline · Bridges event outputs to durable state.
src/matchengine/persist/persistor.rs - Fork-and-save snapshots
src/matchengine/persist/state_save_load.rs
API access
- REST handlers · Management, trading, state, and history access.
src/restapi/mod.rs - JS and Python clients · Signing and integration examples.
examples/js/RESTClient.ts
Historical storage
- PostgreSQL records · Stores trades, klines, markets, accounts, and transfers.
src/storage/database.rs
Other components
- Local orchestration · Launches local Kafka and PostgreSQL dependencies.
orchestra
Connections 21
- Match engine binary → Engine server: runs
- Engine server → Engine controller: requests
- Engine controller → Sequencer: orders commands
- Sequencer → Market and order books: mutates
- Sequencer → Assets and balances: updates
- Sequencer → User state: updates
- Market and order books → Event producer: orders, trades, market data
- Assets and balances → Event producer: balance events
- Event producer → Kafka: publishes
- Kafka → Event consumer: consumes
- Event consumer → Persistence pipeline: persistence inputs
- Persistor binary → Persistence pipeline: runs
- Persistence pipeline → Fork-and-save snapshots: saves state
- Persistence pipeline → PostgreSQL records: writes records
- REST API binary → REST handlers: runs
- JS and Python clients → REST handlers: REST requests
- REST handlers → Engine server: coordinates trading and state
- REST handlers → PostgreSQL records: queries history
- Message dump tool → Kafka: inspects
- Local orchestration → Kafka: starts
- Local orchestration → PostgreSQL records: starts