Repository navigation
Conversation
Titan replaced the V1 price level socket with a V2 socket. The stream now reads the V2 wire, and the V1 path and its fixture are removed. V2 books name their venue by quote address and their assets by symbol, and they carry float price and cumulative volume levels. A conversion step rebuilds the integer ladders that the quoting model uses. Symbols resolve only through the trusted binding table before admission, and skipped books and dropped sides are counted. A new solver page documents the wire, the conversion, and the freshness contract. The module suite grows from 129 to 151 tests.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pamm_price_levels_v2. The V1 socket is onits way out.
What changes is the payload it reads and the arithmetic needed to get from it to a ladder.
Terms used below
bidslist and anaskslist.amount_in/amount_outform the stream serves. Quoting interpolatesbetween levels.
Counter names below are written without their
price_level_stream_prefix.What changed in the message, side by side
pamm_price_levelspamm_price_levels_v2pamms[]→pairs[], one entry per directionbooks[], one per venue and pair, each withbidsandaskstokenIn,tokenOut)token1,token2)amountIn/amountOut, hex, absolutepriceandcumVolume, human unitsvariant: Simulated | InterpolatedblockNumber,timestampblock,tscalculated_from,makerThe same two books, as each version sends them (levels trimmed to two, both captures are in
test_responses/):Two V2 fields need no review here:
calculated_fromnames the pair version the venue priced the book at. This change parses andvalidates it. Nothing reads it. The stacked PR joins it to a state snapshot.
slotreaches the DEBUG logs and nothing else. No freshness decision rests on it.What the stream does with a book
flowchart TD B["one V2 book"] --> V{"venue known?"} V -- no --> U["skip<br/>unregistered_pamm_entries_total"] V -- yes --> S{"both symbols bound,<br/>both tokens admitted?"} S -- no --> K["skip<br/>skipped_books_total{reason}"] S -- yes --> C["convert each side:<br/>floats → integer ladder"] C --> R{"side prices a<br/>usable curve?"} R -- no --> D["drop that side<br/>rejected_sides_total{reason}"] R -- yes --> P["served under fallback:{venue}"]Floats to integer ladders
priceistoken2pertoken1: the average execution price of the level's whole cumulativesize.
cumVolumeis wholetoken1, cumulated from the top of the book.token1, and asks selltoken2.amount_outalready contains every smaller level.the interpretation on the levels the capture measured, and no further: it is not proof of parity
with what the venue computes internally. Titan also rounds
priceandcumVolumetof64before sending, so a ladder carries Titan's precision and nothing tighter.
Rules worth a reviewer's attention
it did, any token calling itself
WBTCwould capture the real one's quotes. A symbol prices apair only when a trusted binding names an address for it and your
with_tokensmetadatacarries that address. Exact match, case included. Defaults bind WETH, USDC, USDT, WBTC and
cbBTC;
with_symbol_bindingsreplaces a default or adds a symbol.would leave the ladder interpolating across the gap, inventing a plausible price.
rejected_sides_total{reason}counts the four reasons. Two are new arithmetic on this format:zero_amount(a level rounds to zero in or out) andconflicting_knots(two levels round toone
amount_inbut disagree onamount_out). A drop costs one direction; the other side of thebook keeps serving.
to, but Titan streams some venues under a different
quoteAddress, which is a join key ratherthan an executable address. Every such address is normalized through the alias map at each
boundary, so component ids, venue names and
pamm_addressalways carry the public identity.Kipseli is today's only case.
DEBUG logs. Every counter is pre-initialized at zero.
Rollout
TITAN_PAMM_PRICE_LEVEL_URLto a V1 regional URL keeps running afterthis upgrade, feeding V1 frames to a V2 parser that rejects them. Update or unset that
variable at rollout.
pamm_price_levels_1784126589047308938.jsonis replaced by a byte-faithful V2capture.
Docs and tests
docs/for-solvers/price-level-stream.mdis a new solver page covering the message, the conversion,symbol resolution, venue identity, freshness and the metrics.
request-for-quote-protocols.mdkeeps a pointer to it instead of its inline section.a live endpoint.