Skip to main content

Order Book Resynchronisation and initialState

This page explains how to tell a genuine XBID reset apart from an ETPA resynchronisation, and how your client should rebuild its order book in each case.

Background​

ETPA forwards XBID order book updates to you. Each update carries a revisionNo, which is assigned by XBID, not by ETPA. ETPA passes it through unchanged.

You may see a "restate" (orders republished with initialState: true) in two different situations. They look alike, but you should tell them apart and handle them differently.

Case 1: XBID resetCase 2: ETPA resync
CauseXBID itself resets its stateETPA briefly disconnects from XBID (e.g. a deployment on ETPA's side)
XBID during the eventResetsStays up; revisionNo keeps advancing
revisionNo behaviourRestarts at 0Continues / jumps ahead from the running stream
What to doYour existing reset handlingClear your book and rebuild from the initialState: true batch

Case 1: Genuine XBID reset​

XBID resets and revisionNo restarts at 0. Handle this with your existing XBID reset logic.

Case 2: ETPA resynchronisation​

What happens​

  1. ETPA disconnects from XBID, for example during a deployment on our side.
  2. XBID stays up and keeps processing. Its revisionNo keeps advancing, but ETPA is offline and can't store or forward those updates.
  3. When ETPA reconnects, your view of the book is out of date.
  4. ETPA fetches the current XBID state and republishes it to you with initialState: true.

Why revisionNo jumps​

revisionNo comes from XBID, so it does not reset to 0 during an ETPA resync. It carries on from wherever XBID has got to. You'll see it jump ahead by however many revisions happened while ETPA was disconnected. This is expected and does not mean data is corrupted.

How to process the resync​

An initialState: true event is not a complete book on its own. Each event holds one order. All the initialState: true orders together make up the new authoritative book.

Recommended handling:

  1. Spot the start of the resync. The first initialState: true event arrives, and its revisionNo continues from or jumps ahead of the running stream instead of restarting at 0.
  2. Clear the order book state you were holding.
  3. Rebuild the book from the initialState: true orders. Ignore everything you received before them.
  4. Go back to normal delta processing after the batch. Because you rebuild the whole book from the whole batch, you don't need a separate boundary for each contract. Orders for different contracts may arrive mixed together in the batch, and that's fine, because the batch as a whole is the book.

Quick reference: telling the cases apart​

revisionNo is the signal that separates the two cases:

  • revisionNo restarts at 0 → genuine XBID reset → use your existing reset handling.
  • initialState: true and revisionNo continues or jumps ahead → ETPA resync → clear the book and rebuild from the initialState batch.
on event:
if event.revisionNo == 0 and lastRevisionNo > 0:
handleXbidReset() # Case 1
else if event.initialState and not inResync:
inResync = true
clearOrderBook() # Case 2: start of batch
applyOrder(event)
else if event.initialState and inResync:
applyOrder(event) # Case 2: rest of batch
else:
inResync = false
applyDelta(event) # normal processing
lastRevisionNo = event.revisionNo

This pseudocode is only an illustration. Adapt it to your own client and how it processes contracts.