Wire hint_after_order_id for single limit placement (frontend + batch wire + integrators) #261

Closed
opened 2026-05-31 14:03:07 +00:00 by PlasticDigits · 4 comments
PlasticDigits commented 2026-05-31 14:03:07 +00:00 (Migrated from gitlab.com)

Summary

Expose hint_after_order_id on single-rung limit placement (retail batch hook) and wire the dApp deep book to compute and pass the predecessor order id. On-chain O(1) insert verification landed in #256; UpdateLimitOrderPrice and book Edit already pass hints in pair.ts. Single Place limit still omits the hint, and the batch wire schema has no per-rung hint field — so clients cannot benefit from deep-book topology on new orders.

Current codebase

On-chain (post-#256)

  • find_insert_bid / find_insert_ask honor hint_after with verified O(1) fast path + bounded head-walk fallback (orderbook.rs).
  • UpdateLimitOrderPrice accepts hint_after_order_id (pair.rs ExecuteMsg).
  • Batch/ladder chains last_placed_hint from the prior successful rung id internally (limit_placement.rs) — helps monotonic multi-rung txs only.
  • LimitOrderPlacementItem has no hint_after_order_id field (dex-common/limit_placement.rs) — external clients cannot pass a hint on a single batch rung.

Frontend dApp

  • updateLimitOrderPrice(..., hintAfterOrderId?) encodes hint_after_order_id (pair.ts).
  • placeLimitOrderWithAllowance / LimitOrderPlacementItemWire omit hint; retail path sends batch with one item, no predecessor (pair.ts).
  • Book Edit flow: OrderBookPanel sets hintAfterOrderId from the prior row index → LimitBookTicketDraft → useLimitOrderUpdatePriceMutation (OrderBookPanel.tsx, TradeOrderTicket.tsx).
  • New placement from ticket (TradeOrderTicket, LimitOrdersPage.tsx) never passes a hint regardless of loaded deep-book pages (useLimitBookInfinite).

Indexer / integrators

  • GET /api/v1/pairs/{addr}/limit-book returns paginated resting orders with order_id, price, prev/next from LCD (limit_book_lcd.rs) — sufficient to compute predecessor off-chain.
  • No documented batch-wire field for per-rung hints; integrators.md / limit-orders.md describe hint semantics (L14) but not client placement wiring.

Why this is needed

  • Deep books: Makers on busy pairs often need Low (16) or Medium (32) max_adjust_steps; head-only walks fail with LimitInsertStepsExceeded even when the UI/indexer already loaded the local book neighborhood.
  • Gas / UX: Valid hints reduce placement gas vs walking up to 256 steps; fewer skipped batch rungs and less pressure to pick High (128) presets.
  • Parity: Price-edit already uses hints from the visible book; new placement at a known level should behave the same.
  • Integrators: Third-party bots/indexers placing via PlaceLimitOrderBatch (single item) need a stable wire field, not only internal batch chaining.

Constraints and guardrails

  • Never trust hint without on-chain verify — already enforced in #256; client bugs must not weaken FIFO / total order.
  • Advisory only: stale hint (cancel, fill, relink elsewhere) → safe fallback; must not error unless head walk exceeds max_adjust_steps.
  • Optional wire field: #[serde(default)] on new batch item field — null/omit preserves today’s behavior.
  • Predecessor resolution is client-side: use loaded book pages + price-time rules from limit-orders.md § Ordering; if book incomplete (pagination gap), omit hint rather than guess.
  • Do not block submit when hint unavailable — placement proceeds with null hint (current behavior).
  • No simulation path — execute-only; quotes unchanged.
  • Migration: none (optional serde field on batch items).

Relevant files

Area Path
Batch wire type smartcontracts/packages/dex-common/src/limit_placement.rs
Batch execute smartcontracts/contracts/pair/src/limit_placement.rs
Insert verify smartcontracts/contracts/pair/src/orderbook.rs
Terra msgs frontend-dapp/src/services/terraclassic/pair.ts
Predecessor util (new) e.g. frontend-dapp/src/utils/limitBookInsertHint.ts
Trade ticket frontend-dapp/src/components/trade/TradeOrderTicket.tsx
Limits page frontend-dapp/src/pages/LimitOrdersPage.tsx
Deep book data frontend-dapp/src/hooks/useLimitBookInfinite.ts, OrderBookPanel.tsx
Docs docs/limit-orders.md, docs/frontend.md, docs/integrators.md
Invariants docs/contracts-security-audit.md L14
Agent skills skills/AGENTS_FRONTEND_DEEP_ORDER_BOOK.md, skills/AGENTS_FRONTEND_LIMIT_ORDER_PLACEMENT_GAS.md, skills/AGENTS_LIMIT_ORDER_BATCH_LADDER.md
Tests pair.test.ts, limit_order_tests.rs, new Vitest for hint resolver
  1. Contract (minimal): Add #[serde(default)] hint_after_order_id: Option<u64> to LimitOrderPlacementItem. In execute_place_limit_orders_batch, pass item.hint_after_order_id.or(last_placed_hint) into insert_*_with_id (explicit client hint wins over internal chain).
  2. Frontend wire: Extend LimitOrderPlacementItemWire + placeLimitOrderWithAllowance(..., hintAfterOrderId?) to encode the field on the single-rung batch item.
  3. Predecessor resolver: Pure function resolveLimitInsertHintAfter(side, price, loadedOrders[]) using bid/ask sort rules — return order_id of the order immediately before the insert slot, or null if head insert / insufficient loaded depth / ambiguous gap across pagination.
  4. UI wiring: On place submit, if useLimitBookInfinite pages cover the insert neighborhood for the ticket side+price, pass resolved hint; otherwise null. Share resolver between /trade and /limits.
  5. Integrator docs: Document batch item field + resolver algorithm in integrators.md and cross-link L14; update agent skills. Indexer HTTP API unchanged unless follow-up adds optional suggested_hint_after (not required for this issue).
  6. Tests: Contract unit/integration for explicit batch-item hint; Vitest for resolver edge cases; extend pair.test.ts encode assertion.

Acceptance criteria

  • LimitOrderPlacementItem accepts optional hint_after_order_id; single-rung batch txs can carry it on-chain.
  • placeLimitOrderWithAllowance accepts and encodes optional hint.
  • dApp passes hint on new placement when deep book data yields a valid predecessor; omits hint when unknown.
  • Price-edit path unchanged (still passes row hint).
  • Invalid/stale client hints do not break placement (on-chain fallback).
  • Docs + skills updated with wire shape and resolver rules.

Test plan (functional paths)

Path Expectation
Empty book Hint omitted or ignored; head insert
Loaded book, price between two visible rows Hint = predecessor row order_id; placement succeeds with Low steps
Price better than head (bid higher / ask lower) Resolver returns null; head insert
Price worse than last loaded row (tail) Hint = last loaded row on side if sort-valid
Book page gap (price slot not in loaded set) Hint omitted; fallback head walk
Batch multi-rung with per-item hints Explicit item hint used; chain still updates last_placed_hint
/limits standalone page Same hint behavior as /trade

Test plan (attack / abuse / hack vectors)

Vector Verification
Client sends hint for wrong side On-chain verify fails → head walk; ordering preserved
Hint to cancelled order id Fallback walk; no corrupt DLL
Malicious integrator: hint skips ahead in queue Verify rejects; bounded walk or steps exceeded
Race: book changes between UI load and tx Stale hint safe fallback; final book order correct
Forged hint on another maker’s order Verify uses price-time only, not owner — placement still valid if sort order correct

Verification criteria

  • cargo test — batch item hint + existing #256 hint tests green.
  • cd frontend-dapp && npm test — resolver unit tests + pair.test.ts encode hint.
  • LocalTerra: seed deep book (10+ levels), place with Medium steps + hint → success; same without hint on deep book → LimitInsertStepsExceeded or skip (document observed gas delta).
  • Manual: /trade deep book loaded → place at mid-book price → confirm tx succeeds with Low/Medium preset.
  • #256 — on-chain hint verify (done)
  • #194 — deep book pagination (data source for resolver)
  • #204 — placement gas presets
  • #247 — price update hint wiring (reference implementation)
## Summary Expose **`hint_after_order_id`** on **single-rung limit placement** (retail batch hook) and wire the dApp deep book to compute and pass the predecessor order id. On-chain O(1) insert verification landed in **#256**; **`UpdateLimitOrderPrice`** and book **Edit** already pass hints in `pair.ts`. Single **Place limit** still omits the hint, and the batch wire schema has no per-rung hint field — so clients cannot benefit from deep-book topology on new orders. ## Current codebase ### On-chain (post-#256) - `find_insert_bid` / `find_insert_ask` honor `hint_after` with verified O(1) fast path + bounded head-walk fallback ([`orderbook.rs`](../smartcontracts/contracts/pair/src/orderbook.rs)). - **`UpdateLimitOrderPrice`** accepts `hint_after_order_id` ([`pair.rs` ExecuteMsg](../smartcontracts/packages/dex-common/src/pair.rs)). - **Batch/ladder** chains `last_placed_hint` from the prior **successful** rung id internally ([`limit_placement.rs`](../smartcontracts/contracts/pair/src/limit_placement.rs)) — helps monotonic multi-rung txs only. - **`LimitOrderPlacementItem`** has **no** `hint_after_order_id` field ([`dex-common/limit_placement.rs`](../smartcontracts/packages/dex-common/src/limit_placement.rs)) — external clients cannot pass a hint on a single batch rung. ### Frontend dApp - **`updateLimitOrderPrice(..., hintAfterOrderId?)`** encodes `hint_after_order_id` ([`pair.ts`](../frontend-dapp/src/services/terraclassic/pair.ts)). - **`placeLimitOrderWithAllowance`** / **`LimitOrderPlacementItemWire`** omit hint; retail path sends batch with one item, no predecessor ([`pair.ts`](../frontend-dapp/src/services/terraclassic/pair.ts)). - **Book Edit** flow: `OrderBookPanel` sets `hintAfterOrderId` from the prior row index → `LimitBookTicketDraft` → **`useLimitOrderUpdatePriceMutation`** ([`OrderBookPanel.tsx`](../frontend-dapp/src/components/trade/OrderBookPanel.tsx), [`TradeOrderTicket.tsx`](../frontend-dapp/src/components/trade/TradeOrderTicket.tsx)). - **New placement** from ticket (`TradeOrderTicket`, [`LimitOrdersPage.tsx`](../frontend-dapp/src/pages/LimitOrdersPage.tsx)) never passes a hint regardless of loaded deep-book pages ([`useLimitBookInfinite`](../frontend-dapp/src/hooks/useLimitBookInfinite.ts)). ### Indexer / integrators - **`GET /api/v1/pairs/{addr}/limit-book`** returns paginated resting orders with `order_id`, `price`, `prev`/`next` from LCD ([`limit_book_lcd.rs`](../indexer/src/api/limit_book_lcd.rs)) — sufficient to compute predecessor off-chain. - No documented batch-wire field for per-rung hints; [integrators.md](../docs/integrators.md) / [limit-orders.md](../docs/limit-orders.md) describe hint semantics (**L14**) but not client placement wiring. ## Why this is needed - **Deep books:** Makers on busy pairs often need **Low (16)** or **Medium (32)** `max_adjust_steps`; head-only walks fail with `LimitInsertStepsExceeded` even when the UI/indexer already loaded the local book neighborhood. - **Gas / UX:** Valid hints reduce placement gas vs walking up to 256 steps; fewer skipped batch rungs and less pressure to pick **High (128)** presets. - **Parity:** Price-edit already uses hints from the visible book; new placement at a known level should behave the same. - **Integrators:** Third-party bots/indexers placing via `PlaceLimitOrderBatch` (single item) need a stable wire field, not only internal batch chaining. ## Constraints and guardrails - **Never trust hint without on-chain verify** — already enforced in #256; client bugs must not weaken FIFO / total order. - **Advisory only:** stale hint (cancel, fill, relink elsewhere) → safe fallback; must not error unless head walk exceeds `max_adjust_steps`. - **Optional wire field:** `#[serde(default)]` on new batch item field — `null`/omit preserves today’s behavior. - **Predecessor resolution is client-side:** use loaded book pages + price-time rules from [limit-orders.md § Ordering](../docs/limit-orders.md#ordering-composite-key-fifo); if book incomplete (pagination gap), omit hint rather than guess. - **Do not** block submit when hint unavailable — placement proceeds with `null` hint (current behavior). - **No simulation path** — execute-only; quotes unchanged. - **Migration:** none (optional serde field on batch items). ## Relevant files | Area | Path | |------|------| | Batch wire type | [`smartcontracts/packages/dex-common/src/limit_placement.rs`](../smartcontracts/packages/dex-common/src/limit_placement.rs) | | Batch execute | [`smartcontracts/contracts/pair/src/limit_placement.rs`](../smartcontracts/contracts/pair/src/limit_placement.rs) | | Insert verify | [`smartcontracts/contracts/pair/src/orderbook.rs`](../smartcontracts/contracts/pair/src/orderbook.rs) | | Terra msgs | [`frontend-dapp/src/services/terraclassic/pair.ts`](../frontend-dapp/src/services/terraclassic/pair.ts) | | Predecessor util (new) | e.g. `frontend-dapp/src/utils/limitBookInsertHint.ts` | | Trade ticket | [`frontend-dapp/src/components/trade/TradeOrderTicket.tsx`](../frontend-dapp/src/components/trade/TradeOrderTicket.tsx) | | Limits page | [`frontend-dapp/src/pages/LimitOrdersPage.tsx`](../frontend-dapp/src/pages/LimitOrdersPage.tsx) | | Deep book data | [`frontend-dapp/src/hooks/useLimitBookInfinite.ts`](../frontend-dapp/src/hooks/useLimitBookInfinite.ts), [`OrderBookPanel.tsx`](../frontend-dapp/src/components/trade/OrderBookPanel.tsx) | | Docs | [`docs/limit-orders.md`](../docs/limit-orders.md), [`docs/frontend.md`](../docs/frontend.md), [`docs/integrators.md`](../docs/integrators.md) | | Invariants | [`docs/contracts-security-audit.md`](../docs/contracts-security-audit.md) **L14** | | Agent skills | [`skills/AGENTS_FRONTEND_DEEP_ORDER_BOOK.md`](../skills/AGENTS_FRONTEND_DEEP_ORDER_BOOK.md), [`skills/AGENTS_FRONTEND_LIMIT_ORDER_PLACEMENT_GAS.md`](../skills/AGENTS_FRONTEND_LIMIT_ORDER_PLACEMENT_GAS.md), [`skills/AGENTS_LIMIT_ORDER_BATCH_LADDER.md`](../skills/AGENTS_LIMIT_ORDER_BATCH_LADDER.md) | | Tests | [`pair.test.ts`](../frontend-dapp/src/services/terraclassic/__tests__/pair.test.ts), `limit_order_tests.rs`, new Vitest for hint resolver | ## Recommended direction 1. **Contract (minimal):** Add `#[serde(default)] hint_after_order_id: Option<u64>` to `LimitOrderPlacementItem`. In `execute_place_limit_orders_batch`, pass `item.hint_after_order_id.or(last_placed_hint)` into `insert_*_with_id` (explicit client hint wins over internal chain). 2. **Frontend wire:** Extend `LimitOrderPlacementItemWire` + `placeLimitOrderWithAllowance(..., hintAfterOrderId?)` to encode the field on the single-rung batch item. 3. **Predecessor resolver:** Pure function `resolveLimitInsertHintAfter(side, price, loadedOrders[])` using bid/ask sort rules — return `order_id` of the order immediately before the insert slot, or `null` if head insert / insufficient loaded depth / ambiguous gap across pagination. 4. **UI wiring:** On place submit, if `useLimitBookInfinite` pages cover the insert neighborhood for the ticket side+price, pass resolved hint; otherwise `null`. Share resolver between `/trade` and `/limits`. 5. **Integrator docs:** Document batch item field + resolver algorithm in `integrators.md` and cross-link **L14**; update agent skills. Indexer HTTP API unchanged unless follow-up adds optional `suggested_hint_after` (not required for this issue). 6. **Tests:** Contract unit/integration for explicit batch-item hint; Vitest for resolver edge cases; extend `pair.test.ts` encode assertion. ## Acceptance criteria - [ ] `LimitOrderPlacementItem` accepts optional `hint_after_order_id`; single-rung batch txs can carry it on-chain. - [ ] `placeLimitOrderWithAllowance` accepts and encodes optional hint. - [ ] dApp passes hint on new placement when deep book data yields a valid predecessor; omits hint when unknown. - [ ] Price-edit path unchanged (still passes row hint). - [ ] Invalid/stale client hints do not break placement (on-chain fallback). - [ ] Docs + skills updated with wire shape and resolver rules. ## Test plan (functional paths) | Path | Expectation | |------|-------------| | Empty book | Hint omitted or ignored; head insert | | Loaded book, price between two visible rows | Hint = predecessor row `order_id`; placement succeeds with Low steps | | Price better than head (bid higher / ask lower) | Resolver returns `null`; head insert | | Price worse than last loaded row (tail) | Hint = last loaded row on side if sort-valid | | Book page gap (price slot not in loaded set) | Hint omitted; fallback head walk | | Batch multi-rung with per-item hints | Explicit item hint used; chain still updates `last_placed_hint` | | `/limits` standalone page | Same hint behavior as `/trade` | ## Test plan (attack / abuse / hack vectors) | Vector | Verification | |--------|----------------| | Client sends hint for wrong side | On-chain verify fails → head walk; ordering preserved | | Hint to cancelled order id | Fallback walk; no corrupt DLL | | Malicious integrator: hint skips ahead in queue | Verify rejects; bounded walk or steps exceeded | | Race: book changes between UI load and tx | Stale hint safe fallback; final book order correct | | Forged hint on another maker’s order | Verify uses price-time only, not owner — placement still valid if sort order correct | ## Verification criteria - `cargo test` — batch item hint + existing #256 hint tests green. - `cd frontend-dapp && npm test` — resolver unit tests + `pair.test.ts` encode hint. - LocalTerra: seed deep book (10+ levels), place with Medium steps + hint → success; same without hint on deep book → `LimitInsertStepsExceeded` or skip (document observed gas delta). - Manual: `/trade` deep book loaded → place at mid-book price → confirm tx succeeds with Low/Medium preset. ## Related - **#256** — on-chain hint verify (done) - **#194** — deep book pagination (data source for resolver) - **#204** — placement gas presets - **#247** — price update hint wiring (reference implementation)
PlasticDigits commented 2026-05-31 14:43:07 +00:00 (Migrated from gitlab.com)

mentioned in commit 6b22febcdb

mentioned in commit 6b22febcdb45e0cc31450c1e51bfc43956d7f384
PlasticDigits commented 2026-05-31 14:43:18 +00:00 (Migrated from gitlab.com)

Implementation summary (merged to main @ 6b22feb)

Wired hint_after_order_id for single-rung limit placement end-to-end per issue scope.

On-chain

  • Added optional #[serde(default)] hint_after_order_id: Option<u64> to LimitOrderPlacementItem (dex-common).
  • Batch execute uses item.hint_after_order_id.or(last_placed_hint) — explicit client hint wins over internal ladder chaining.
  • Integration test: limit_batch_item_explicit_hint_places_on_deep_book.

Frontend

  • LimitOrderPlacementItemWire + placeLimitOrderWithAllowance(..., hintAfterOrderId?) encode the batch item field.
  • New resolveLimitInsertHintAfter / flattenLimitBookPages in frontend-dapp/src/utils/limitBookInsertHint.ts.
  • /trade (TradeOrderTicket) and /limits (LimitOrdersPage) resolve hint from merged useLimitBookInfinite pages at submit; omit when head insert or pagination gap.
  • Price-edit path (#247) unchanged.

Docs / invariants

  • L14 updated in docs/contracts-security-audit.md with #261 cross-links.
  • docs/limit-orders.md, docs/frontend.md, docs/integrators.md (new § Batch placement insert hints).
  • Agent skills: AGENTS_FRONTEND_DEEP_ORDER_BOOK, AGENTS_FRONTEND_LIMIT_ORDER_PLACEMENT_GAS, AGENTS_LIMIT_ORDER_BATCH_LADDER.

Tests run locally

  • cargo test limit_batch_item_explicit_hint
  • npx vitest --run limitBookInsertHint.test.ts pair.test.ts (hint encode + resolver cases)

Verification checklist

  • cargo test limit_batch_item_explicit_hint_places_on_deep_book passes
  • cd frontend-dapp && npx vitest --run src/utils/__tests__/limitBookInsertHint.test.ts src/services/terraclassic/__tests__/pair.test.ts passes
  • LocalTerra: seed 10+ bid levels, place mid-book with Medium (32) steps — tx succeeds; LCD batch msg includes hint_after_order_id when book loaded
  • Same deep book, placement without loaded pages (fresh tab / different pair) still places (null hint, head walk)
  • /trade: deep book loaded → place at price between two visible rows → succeeds with Low (16) where head-only walk would fail
  • /limits standalone page: same hint behavior as /trade
  • Book Edit → Update price still passes row hintAfterOrderId (#247 regression)
  • Stale/wrong hint (cancel order between UI load and tx) → placement still succeeds via on-chain fallback

Follow-ups (optional, not in scope)

  • Indexer optional suggested_hint_after on limit-book rows — not required; clients can compute from paginated walk.
  • Contract redeploy needed on live pairs before on-chain batch item field is available (serde-compatible; no migration).

Requesting verification from the QA agent team when convenient.

## Implementation summary (merged to `main` @ 6b22feb) Wired **`hint_after_order_id`** for single-rung limit placement end-to-end per issue scope. ### On-chain - Added optional `#[serde(default)] hint_after_order_id: Option<u64>` to `LimitOrderPlacementItem` (`dex-common`). - Batch execute uses `item.hint_after_order_id.or(last_placed_hint)` — explicit client hint wins over internal ladder chaining. - Integration test: `limit_batch_item_explicit_hint_places_on_deep_book`. ### Frontend - `LimitOrderPlacementItemWire` + `placeLimitOrderWithAllowance(..., hintAfterOrderId?)` encode the batch item field. - New `resolveLimitInsertHintAfter` / `flattenLimitBookPages` in `frontend-dapp/src/utils/limitBookInsertHint.ts`. - `/trade` (`TradeOrderTicket`) and `/limits` (`LimitOrdersPage`) resolve hint from merged `useLimitBookInfinite` pages at submit; omit when head insert or pagination gap. - Price-edit path (#247) unchanged. ### Docs / invariants - **L14** updated in `docs/contracts-security-audit.md` with #261 cross-links. - `docs/limit-orders.md`, `docs/frontend.md`, `docs/integrators.md` (new § Batch placement insert hints). - Agent skills: `AGENTS_FRONTEND_DEEP_ORDER_BOOK`, `AGENTS_FRONTEND_LIMIT_ORDER_PLACEMENT_GAS`, `AGENTS_LIMIT_ORDER_BATCH_LADDER`. ### Tests run locally - `cargo test limit_batch_item_explicit_hint` - `npx vitest --run limitBookInsertHint.test.ts pair.test.ts` (hint encode + resolver cases) --- ## Verification checklist - [ ] `cargo test limit_batch_item_explicit_hint_places_on_deep_book` passes - [ ] `cd frontend-dapp && npx vitest --run src/utils/__tests__/limitBookInsertHint.test.ts src/services/terraclassic/__tests__/pair.test.ts` passes - [ ] LocalTerra: seed 10+ bid levels, place mid-book with **Medium (32)** steps — tx succeeds; LCD batch msg includes `hint_after_order_id` when book loaded - [ ] Same deep book, placement **without** loaded pages (fresh tab / different pair) still places (null hint, head walk) - [ ] `/trade`: deep book loaded → place at price between two visible rows → succeeds with **Low (16)** where head-only walk would fail - [ ] `/limits` standalone page: same hint behavior as `/trade` - [ ] Book **Edit** → **Update price** still passes row `hintAfterOrderId` (#247 regression) - [ ] Stale/wrong hint (cancel order between UI load and tx) → placement still succeeds via on-chain fallback --- ## Follow-ups (optional, not in scope) - Indexer optional `suggested_hint_after` on `limit-book` rows — not required; clients can compute from paginated walk. - Contract redeploy needed on live pairs before on-chain batch item field is available (serde-compatible; no migration). --- Requesting verification from the QA agent team when convenient.
PlasticDigits commented 2026-06-01 03:56:56 +00:00 (Migrated from gitlab.com)

mentioned in issue #265

mentioned in issue #265
Brouie commented 2026-06-02 16:59:26 +00:00 (Migrated from gitlab.com)

#261 verified — good to close. hint_after_order_id wired end to end for single-rung placement.

Checklist:

  • cargo test limit_batch_item_explicit_hint_places_on_deep_book — 1 passed (explicit batch-item hint inserts on a deep book; item.hint_after_order_id.or(last_placed_hint), client hint wins).
  • frontend vitest limitBookInsertHint.test.ts + pair.test.ts — 31 passed.
  • Wire encode: pair.test.ts "encodes optional hint_after_order_id on batch item (#261)" asserts placeLimitOrderWithAllowance(..., 42) -> batch item hint_after_order_id: 42.
  • Resolver covers every functional path (resolveLimitInsertHintAfter): empty book -> null; head insert (bid better than head / ask lower) -> null; mid-book -> predecessor order_id; equal-price level -> last same-price order; tail when fully loaded -> last loaded; tail when pagination has_more -> null (gap omit); invalid price -> null; both bid and ask sides; flattenLimitBookPages concatenates pages + tracks tail has_more.
  • Price-edit (#247) path unchanged: updateLimitOrderPrice still encodes hint_after_order_id (test asserts hint: 6).
  • Stale/invalid client hint is advisory only -> on-chain verify + bounded fallback (#256); never weakens FIFO. Covered by the deep-book insert test + #256 verify path.
  • Docs + skills: integrators.md (Batch placement insert hints), limit-orders.md, contracts-security-audit.md L14 cross-link #261.

Live deep-book placement (/trade + /limits, place mid-book with Low/Medium steps where a head-only walk would hit LimitInsertStepsExceeded) is the browser layer. The logic is fully covered here: the contract test proves the deep-book hint insert, and the resolver+encode tests prove the UI resolves the predecessor from the loaded book pages and passes it on the wire.

Verified end to end. @PlasticDigits

#261 verified — good to close. hint_after_order_id wired end to end for single-rung placement. Checklist: - [x] cargo test limit_batch_item_explicit_hint_places_on_deep_book — 1 passed (explicit batch-item hint inserts on a deep book; item.hint_after_order_id.or(last_placed_hint), client hint wins). - [x] frontend vitest limitBookInsertHint.test.ts + pair.test.ts — 31 passed. - [x] Wire encode: pair.test.ts "encodes optional hint_after_order_id on batch item (#261)" asserts placeLimitOrderWithAllowance(..., 42) -> batch item hint_after_order_id: 42. - [x] Resolver covers every functional path (resolveLimitInsertHintAfter): empty book -> null; head insert (bid better than head / ask lower) -> null; mid-book -> predecessor order_id; equal-price level -> last same-price order; tail when fully loaded -> last loaded; tail when pagination has_more -> null (gap omit); invalid price -> null; both bid and ask sides; flattenLimitBookPages concatenates pages + tracks tail has_more. - [x] Price-edit (#247) path unchanged: updateLimitOrderPrice still encodes hint_after_order_id (test asserts hint: 6). - [x] Stale/invalid client hint is advisory only -> on-chain verify + bounded fallback (#256); never weakens FIFO. Covered by the deep-book insert test + #256 verify path. - [x] Docs + skills: integrators.md (Batch placement insert hints), limit-orders.md, contracts-security-audit.md L14 cross-link #261. Live deep-book placement (/trade + /limits, place mid-book with Low/Medium steps where a head-only walk would hit LimitInsertStepsExceeded) is the browser layer. The logic is fully covered here: the contract test proves the deep-book hint insert, and the resolver+encode tests prove the UI resolves the predecessor from the loaded book pages and passes it on the wire. Verified end to end. @PlasticDigits
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-03 02:00:11 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic#261
No description provided.