Skip to main content
Matching is a stage inside kernel execution, not a service the chain talks to. It takes the block’s orders in their committed sequence, walks them against the book, and produces fills. It does not move anyone’s balance — that is the Clearinghouse’s job, and it happens after matching completes. Keeping those two apart is what makes the engine testable. Matching answers what traded against what. The Clearinghouse answers what that costs and who now owes whom.

The book

Each instrument has its own book, held in memory as three cooperating structures:
Slab arena — one preallocated region of order slots
Price levelsan ordered map, price → levelthe touch is found by walking to the end, not scanning
Order indexorder id → slotcancel and amend are constant time
order
order
order
order
order
A doubly-linked chain in arrival sequence, so priority within a level is positional rather than computed.
Why the reuse order is fixedFreed slots are reused in a fixed order and the index is seeded fixed. Not a performance choice: two validators reusing slots in different orders would fork.
head of each level
direct lookup
Orders live in a slab arena — a preallocated region with constant-time allocation and release. Order book operations therefore do not allocate on the hot path, and freed slots are reused in a fixed order rather than wherever the allocator happens to put them. That last detail is not a performance choice: if two validators reused slots in different orders, anything that observed slot layout would diverge. The same discipline applies to the order index, which is seeded fixed rather than randomly. A hash map with per-process seeding is a standard defense against collision attacks; on a consensus execution path it is a fork. Prices are integers throughout — subtick units, not decimals. See Precision for how that maps to what you submit.

Priority

Priority is price first, then position in the chain at that price. “Time” is the order’s canonical position in the committed block sequence, not when it arrived at a node. This is what removes the intra-block latency race. Two orders in the same block have a defined precedence that every validator computes identically, and no amount of proximity to a particular node changes it. Between blocks, arrival still matters — but the unit of competition is the block, not the microsecond. The kernel’s stage order compounds this: cancellations execute before aggressive placements within a block, so a resting quote cannot be taken by an order that landed in the same block as its cancel.

Matching an order

Incoming order
Crosses the book?
Consume the best opposing level
Emit a fill
Done
Rest or reject the remainder, per time-in-forceGTC rests · IOC cancels it · FOK executes nothing unless it fills in full · post-only is rejected rather than crossing
remainder — take the next level
nothing left
The matcher repeatedly consumes the head of the opposing side, emitting a fill for each maker it takes, until the incoming order is exhausted or the book no longer crosses. What happens to any remainder is decided by time-in-force:
  • GTC — rest the remainder on the book.
  • IOC — cancel the remainder.
  • FOK — if the order cannot be filled in full, nothing executes at all.
  • ALO — post-only: if the order would take liquidity, it is rejected rather than crossing.
Fills carry attribution as they are produced. Each fill records where it sits in the sequence of fills for its instrument, and those per-instrument positions are resolved into a single ordering across the block when output is assembled. This is what allows an event, later, to be traced back to the exact transaction and the exact point in the block that caused it.

Self-trade prevention

When an incoming order would match against resting liquidity from the same owner, the match is suppressed rather than executed. Which side gives way is configurable: Makers cancelled this way are collected during matching and removed as part of the same block, so the book does not carry an order that has already been suppressed. Ownership for this check is resolved at the account level the book tracks. See Self-trade prevention for the trading-side view.

What matching does not do

It does not compute fees, realize profit and loss, adjust positions, or check margin. Those happen after matching, in the Clearinghouse, driven by the fills matching produced. It also does not decide whether an order was allowed to exist. Margin adequacy, open-order limits, reduce-only constraints, and market-to-limit conversion are resolved before an order reaches the book. By the time the matcher sees an order, the question is only where it belongs in the book.

Where to go next

Clearinghouse

What happens to balances and positions once fills exist.

Order types

The trading-side view: what you can submit and how each behaves.

Order book

Depth, levels, and reading the book as a trader.

IntentionKernel

Where matching sits in block execution.