Frontend: deep-book ladder placement (failure detection, ladder→batch per-rung hints, single-anchor, adaptive max_adjust_steps) #268

Closed
opened 2026-06-01 04:19:01 +00:00 by PlasticDigits · 10 comments
PlasticDigits commented 2026-06-01 04:19:01 +00:00 (Migrated from gitlab.com)

Summary

Make the dApp place ladders reliably and cheaply into deep, actively-traded books. Bundled frontend work (all consuming the indexer insert-hint APIs from the companion indexer issue — never direct LCD/RPC):

  1. Detect deep books where a ladder will likely fail/skip rungs and warn/adjust before submit.
  2. Convert ladder → batch with per-rung hint_after_order_id for deep-book placement.
  3. Single-anchor optimization: when the contract inserts in book order (companion contract issue), resolve just one boundary anchor and let on-chain chaining fill the rest.
  4. Adaptive max_adjust_steps sized from observed local depth, with a safety floor so churn on actively-traded books does not cause reverts/skips.

Current codebase

  • frontend-dapp/src/components/trade/LimitOrderLadderPanel.tsx — builds LimitOrderLadderSpecWire and calls placeLimitOrderLadderWithAllowance; success path polls getPairLimitPlacements for placed ids. No hints, no depth awareness.
  • frontend-dapp/src/services/terraclassic/pair.ts — LimitOrderPlacementItemWire (~L127, has hint_after_order_id), LimitOrderLadderSpecWire (~L135, no hint), placeLimitOrderBatch (~L163), placeLimitOrderLadder (~L181), placeLimitOrderWithAllowance (~L227, single-rung resolves a hint).
  • frontend-dapp/src/utils/limitBookInsertHint.ts — resolveLimitInsertHintAfter + flattenLimitBookPages; used today only by TradeOrderTicket.tsx (single order, ~L260) and LimitOrdersPage.tsx (~L107). Returns null on pagination gap.
  • frontend-dapp/src/hooks/useLimitBookInfinite.ts, frontend-dapp/src/utils/limitBookPagination.ts — paginated book; frontend-dapp/src/services/indexer/client.ts::getPairLimitBookPage (~L235).
  • frontend-dapp/src/hooks/useLimitLadderPlaceGates.ts, frontend-dapp/src/utils/limitOrderBatchGasSummary.ts, frontend-dapp/src/utils/limitOrderLadder.ts — ladder gates, gas summary, expansion preview.
  • Ladder expansion fixes a single shared max_adjust_steps via LimitOrderAdvancedLimitSettings (default 32).

Why the current shape is insufficient

  • Ladder sends no hints; on a deep book rung 1 head-walks and bid ladders near-miss/skip interior rungs (see contract tests). The user gets silent batch_skipped_count and partial fills with no warning.
  • The existing client resolver paginates the whole book and bails (null) across gaps — unusable for deep ladders.
  • A fixed max_adjust_steps is simultaneously too low for deep/churny books (reverts/skips) and wasteful on thin ones.

Why this is needed

Ladders are a headline feature for market makers, who operate on the deepest books. Today those are the books where ladders silently underperform. This issue gives the dApp depth-aware placement: warn when a ladder will skip, route deep ladders through the hinted batch path, and size the step budget so normal book churn does not revert transactions.


Constraints / guardrails

  • Indexer only. All depth/hint data comes from the indexer endpoints (companion issue): batch hint-resolver + price-window fetch. No direct LCD/RPC from the dApp.
  • Hints are advisory. A wrong/stale hint cannot corrupt the book (contract L14); the UI must treat resolver resolved:false as "no hint" (omit field) and fall back to on-chain chaining/head walk — never fabricate an id.
  • Adaptive steps must have a safety floor and ceiling. Floor must absorb realistic book churn between quote and execution on active books (so txs don't revert/skip); ceiling must respect MAX_ADJUST_STEPS_HARD_CAP and keep gas within the dApp's batch limit model (terraGas.ts: base 400_000 + 180_000×rungs). Never set steps so high that the gas estimate exceeds block/UX limits.
  • Single-anchor path depends on the contract book-order insertion (companion issue). Until that ships, fall back to per-rung hints. Feature-detect / version-gate.
  • Amount invariants unchanged: CW20 send amount = Σ rung amounts; sumLadderAmountsRaw must not string-concat (#233 regression).
  • All-or-nothing UX clarity: if hints reduce but don't eliminate skip risk, surface expected placed/skipped to the user before submit.
  • Do not duplicate useQuery logic (#231); reuse existing hooks.

Relevant files

  • frontend-dapp/src/components/trade/LimitOrderLadderPanel.tsx
  • frontend-dapp/src/services/terraclassic/pair.ts
  • frontend-dapp/src/utils/limitBookInsertHint.ts
  • frontend-dapp/src/hooks/useLimitBookInfinite.ts, frontend-dapp/src/utils/limitBookPagination.ts
  • frontend-dapp/src/services/indexer/client.ts
  • frontend-dapp/src/hooks/useLimitLadderPlaceGates.ts
  • frontend-dapp/src/utils/limitOrderLadder.ts, frontend-dapp/src/utils/limitOrderBatchGasSummary.ts
  • frontend-dapp/src/components/trade/LimitOrderAdvancedLimitSettings.tsx, LimitOrderExpiryField.tsx
  • Docs: skills/AGENTS_LIMIT_ORDER_BATCH_LADDER.md, skills/AGENTS_FRONTEND_DEEP_ORDER_BOOK.md, skills/AGENTS_FRONTEND_LIMIT_ORDER_PLACEMENT_GAS.md, docs/integrators.md

  1. Depth probe (indexer). Before submit, fetch the price-window covering the ladder band via the new indexer endpoint. Compute a "skip-risk" score = count of foreign orders interleaved between rung prices + head→first-rung distance vs per-rung steps.
  2. Hint resolution (indexer). Call the batch hint-resolver for all rung prices in one request. Map resolved:true → per-rung hint_after_order_id; resolved:false → omit (let chaining/head walk handle it).
  3. Ladder → batch. When skip-risk is non-trivial, expand the ladder client-side (reuse limitOrderLadder.ts) and submit via placeLimitOrderBatch with per-rung hints instead of placeLimitOrderLadder. Keep placeLimitOrderLadder for the cheap/thin-book path.
  4. Single anchor. When the contract advertises book-order insertion, send only the boundary-rung anchor (via the new LimitOrderLadderSpec.hint_after_order_id) and skip per-rung resolution — one indexer call.
  5. Adaptive steps. Derive max_adjust_steps per rung (or one conservative value) from the depth probe: clamp(observed_local_depth × safety_multiplier + churn_floor, FLOOR, HARD_CAP). Surface in advanced settings with the computed value as default.
  6. Pre-submit summary. Show expected placed/skipped and gas (extend limitOrderBatchGasSummary.ts).

Acceptance criteria

  • Ladder into a thin/empty book uses the cheap path (ladder message or minimal anchor) and places all rungs.
  • Ladder into a deep book resolves per-rung hints from the indexer and places all rungs that the contract can place; UI shows expected placed/skipped before submit.
  • resolved:false rungs omit the hint field (never fabricate an id) and still attempt placement.
  • Single-anchor path used when the contract supports it (feature/version gated), reducing indexer calls to one.
  • Adaptive max_adjust_steps default visibly scales with probed depth, with a documented floor that prevents skip/revert under normal churn on a busy book.
  • No regression in sumLadderAmountsRaw (#233) or escrow gates (#231).
  • All book/hint/depth data flows through the indexer client; no direct LCD/RPC added.

Test plan — all paths

  • Thin book: cheap path chosen; all rungs placed; one or zero indexer calls.
  • Deep book, ladder past depth: per-rung hints resolved; batch path; all placed.
  • Deep book, foreign orders between rungs: hints resolved where possible; UI predicts skips that match on-chain outcome (integration/e2e).
  • Pagination gap: some rungs resolved:false; those omit hints; placement still attempted; UI flags reduced confidence.
  • Single-anchor (contract supports): one anchor sent; all rungs placed via chaining; one indexer call.
  • Adaptive steps: thin book → low steps; deep book → higher (≤ cap); manual override respected.
  • Gas summary: predicted gas matches terraGas.ts model for chosen rung count and steps.
  • Bid vs ask ladder: both directions produce correct hint ordering (unit test against resolveLimitInsertHintAfter fixtures).
  • Success polling: placed-id reconciliation unchanged.

Test plan — attack / abuse / hack vectors

  • Malicious/wrong indexer hint (simulate resolver returning a bad id): contract falls back to head walk; placement still safe; UI does not crash on unexpected skip.
  • Indexer returns resolved:false for everything: graceful degradation to no-hint ladder; no fabricated ids.
  • Stale book between probe and submit (front-run / churn): adaptive floor absorbs realistic churn; if exceeded, rungs skip safely and UI reflects partial placement — no revert of the whole tx beyond contract semantics.
  • Oversized ladder (rungs > pair max_batch_rungs): client clamps to pair cap before submit (existing gate) and bounds the prices list sent to the resolver.
  • Decimal/locale parsing: rung prices and amounts parsed safely (no parseFloat precision/concat bugs; reuse decimal utils).
  • Gas inflation: adaptive steps cannot push the estimate past UX/block limits; ceiling enforced and asserted.
  • Indexer unavailability / timeout: fall back to cheap ladder path with conservative steps + warning; never block placement entirely on the optimization.

Verification criteria

  • cd frontend-dapp && npm test -- limitBookInsertHint limitOrderLadder limitOrderBatchGasSummary useLimitLadderPlaceGates LimitOrderLadderPanel green, incl. new depth/hint/adaptive-steps unit tests.
  • E2E (Playwright, 5 workers) ladder placement into a seeded deep book: all expected rungs land; predicted skip count matches actual; see skills/AGENTS_E2E_LIMIT_ORDERS_TX.md.
  • Network panel / mocks confirm book+hint+depth requests hit the indexer only (no LCD/RPC).
  • npm run lint && npm run typecheck clean.
  • Manual deep-book run on LocalTerra: deep bid ladder that skips rungs today now places all rungs (or shows an accurate pre-submit skip prediction).
  • Docs/playbooks updated (AGENTS_LIMIT_ORDER_BATCH_LADDER.md, AGENTS_FRONTEND_DEEP_ORDER_BOOK.md).
## Summary Make the dApp place ladders reliably and cheaply into deep, actively-traded books. Bundled frontend work (all consuming the indexer insert-hint APIs from the companion indexer issue — **never direct LCD/RPC**): 1. **Detect deep books where a ladder will likely fail/skip rungs** and warn/adjust before submit. 2. **Convert ladder → batch with per-rung `hint_after_order_id`** for deep-book placement. 3. **Single-anchor optimization**: when the contract inserts in book order (companion contract issue), resolve just one boundary anchor and let on-chain chaining fill the rest. 4. **Adaptive `max_adjust_steps`** sized from observed local depth, with a **safety floor** so churn on actively-traded books does not cause reverts/skips. --- ## Current codebase - `frontend-dapp/src/components/trade/LimitOrderLadderPanel.tsx` — builds `LimitOrderLadderSpecWire` and calls `placeLimitOrderLadderWithAllowance`; success path polls `getPairLimitPlacements` for placed ids. **No hints, no depth awareness.** - `frontend-dapp/src/services/terraclassic/pair.ts` — `LimitOrderPlacementItemWire` (~L127, has `hint_after_order_id`), `LimitOrderLadderSpecWire` (~L135, no hint), `placeLimitOrderBatch` (~L163), `placeLimitOrderLadder` (~L181), `placeLimitOrderWithAllowance` (~L227, single-rung resolves a hint). - `frontend-dapp/src/utils/limitBookInsertHint.ts` — `resolveLimitInsertHintAfter` + `flattenLimitBookPages`; used today only by `TradeOrderTicket.tsx` (single order, ~L260) and `LimitOrdersPage.tsx` (~L107). Returns `null` on pagination gap. - `frontend-dapp/src/hooks/useLimitBookInfinite.ts`, `frontend-dapp/src/utils/limitBookPagination.ts` — paginated book; `frontend-dapp/src/services/indexer/client.ts::getPairLimitBookPage` (~L235). - `frontend-dapp/src/hooks/useLimitLadderPlaceGates.ts`, `frontend-dapp/src/utils/limitOrderBatchGasSummary.ts`, `frontend-dapp/src/utils/limitOrderLadder.ts` — ladder gates, gas summary, expansion preview. - Ladder expansion fixes a single shared `max_adjust_steps` via `LimitOrderAdvancedLimitSettings` (default `32`). ### Why the current shape is insufficient - Ladder sends **no hints**; on a deep book rung 1 head-walks and bid ladders near-miss/skip interior rungs (see contract tests). The user gets silent `batch_skipped_count` and partial fills with no warning. - The existing client resolver paginates the whole book and bails (`null`) across gaps — unusable for deep ladders. - A fixed `max_adjust_steps` is simultaneously too low for deep/churny books (reverts/skips) and wasteful on thin ones. --- ## Why this is needed Ladders are a headline feature for market makers, who operate on the deepest books. Today those are the books where ladders silently underperform. This issue gives the dApp depth-aware placement: warn when a ladder will skip, route deep ladders through the hinted batch path, and size the step budget so normal book churn does not revert transactions. --- ## Constraints / guardrails - **Indexer only.** All depth/hint data comes from the indexer endpoints (companion issue): batch hint-resolver + price-window fetch. No direct LCD/RPC from the dApp. - **Hints are advisory.** A wrong/stale hint cannot corrupt the book (contract L14); the UI must treat resolver `resolved:false` as "no hint" (omit field) and fall back to on-chain chaining/head walk — never fabricate an id. - **Adaptive steps must have a safety floor and ceiling.** Floor must absorb realistic book churn between quote and execution on active books (so txs don't revert/skip); ceiling must respect `MAX_ADJUST_STEPS_HARD_CAP` and keep gas within the dApp's batch limit model (`terraGas.ts`: base `400_000` + `180_000`×rungs). Never set steps so high that the gas estimate exceeds block/UX limits. - **Single-anchor path depends on the contract book-order insertion** (companion issue). Until that ships, fall back to per-rung hints. Feature-detect / version-gate. - **Amount invariants unchanged**: CW20 send amount = Σ rung amounts; `sumLadderAmountsRaw` must not string-concat (#233 regression). - **All-or-nothing UX clarity**: if hints reduce but don't eliminate skip risk, surface expected placed/skipped to the user before submit. - Do not duplicate `useQuery` logic (#231); reuse existing hooks. --- ## Relevant files - `frontend-dapp/src/components/trade/LimitOrderLadderPanel.tsx` - `frontend-dapp/src/services/terraclassic/pair.ts` - `frontend-dapp/src/utils/limitBookInsertHint.ts` - `frontend-dapp/src/hooks/useLimitBookInfinite.ts`, `frontend-dapp/src/utils/limitBookPagination.ts` - `frontend-dapp/src/services/indexer/client.ts` - `frontend-dapp/src/hooks/useLimitLadderPlaceGates.ts` - `frontend-dapp/src/utils/limitOrderLadder.ts`, `frontend-dapp/src/utils/limitOrderBatchGasSummary.ts` - `frontend-dapp/src/components/trade/LimitOrderAdvancedLimitSettings.tsx`, `LimitOrderExpiryField.tsx` - Docs: `skills/AGENTS_LIMIT_ORDER_BATCH_LADDER.md`, `skills/AGENTS_FRONTEND_DEEP_ORDER_BOOK.md`, `skills/AGENTS_FRONTEND_LIMIT_ORDER_PLACEMENT_GAS.md`, `docs/integrators.md` --- ## Recommended direction 1. **Depth probe (indexer).** Before submit, fetch the price-window covering the ladder band via the new indexer endpoint. Compute a "skip-risk" score = count of foreign orders interleaved between rung prices + head→first-rung distance vs per-rung steps. 2. **Hint resolution (indexer).** Call the batch hint-resolver for all rung prices in one request. Map `resolved:true` → per-rung `hint_after_order_id`; `resolved:false` → omit (let chaining/head walk handle it). 3. **Ladder → batch.** When skip-risk is non-trivial, expand the ladder client-side (reuse `limitOrderLadder.ts`) and submit via `placeLimitOrderBatch` with per-rung hints instead of `placeLimitOrderLadder`. Keep `placeLimitOrderLadder` for the cheap/thin-book path. 4. **Single anchor.** When the contract advertises book-order insertion, send only the boundary-rung anchor (via the new `LimitOrderLadderSpec.hint_after_order_id`) and skip per-rung resolution — one indexer call. 5. **Adaptive steps.** Derive `max_adjust_steps` per rung (or one conservative value) from the depth probe: `clamp(observed_local_depth × safety_multiplier + churn_floor, FLOOR, HARD_CAP)`. Surface in advanced settings with the computed value as default. 6. **Pre-submit summary.** Show expected placed/skipped and gas (extend `limitOrderBatchGasSummary.ts`). --- ## Acceptance criteria - Ladder into a thin/empty book uses the cheap path (ladder message or minimal anchor) and places all rungs. - Ladder into a deep book resolves per-rung hints from the indexer and places all rungs that the contract can place; UI shows expected placed/skipped before submit. - `resolved:false` rungs omit the hint field (never fabricate an id) and still attempt placement. - Single-anchor path used when the contract supports it (feature/version gated), reducing indexer calls to one. - Adaptive `max_adjust_steps` default visibly scales with probed depth, with a documented floor that prevents skip/revert under normal churn on a busy book. - No regression in `sumLadderAmountsRaw` (#233) or escrow gates (#231). - All book/hint/depth data flows through the indexer client; no direct LCD/RPC added. --- ## Test plan — all paths - **Thin book**: cheap path chosen; all rungs placed; one or zero indexer calls. - **Deep book, ladder past depth**: per-rung hints resolved; batch path; all placed. - **Deep book, foreign orders between rungs**: hints resolved where possible; UI predicts skips that match on-chain outcome (integration/e2e). - **Pagination gap**: some rungs `resolved:false`; those omit hints; placement still attempted; UI flags reduced confidence. - **Single-anchor (contract supports)**: one anchor sent; all rungs placed via chaining; one indexer call. - **Adaptive steps**: thin book → low steps; deep book → higher (≤ cap); manual override respected. - **Gas summary**: predicted gas matches `terraGas.ts` model for chosen rung count and steps. - **Bid vs ask ladder**: both directions produce correct hint ordering (unit test against `resolveLimitInsertHintAfter` fixtures). - **Success polling**: placed-id reconciliation unchanged. ## Test plan — attack / abuse / hack vectors - **Malicious/wrong indexer hint** (simulate resolver returning a bad id): contract falls back to head walk; placement still safe; UI does not crash on unexpected skip. - **Indexer returns `resolved:false` for everything**: graceful degradation to no-hint ladder; no fabricated ids. - **Stale book between probe and submit** (front-run / churn): adaptive floor absorbs realistic churn; if exceeded, rungs skip safely and UI reflects partial placement — no revert of the whole tx beyond contract semantics. - **Oversized ladder** (rungs > pair `max_batch_rungs`): client clamps to pair cap before submit (existing gate) and bounds the prices list sent to the resolver. - **Decimal/locale parsing**: rung prices and amounts parsed safely (no `parseFloat` precision/concat bugs; reuse decimal utils). - **Gas inflation**: adaptive steps cannot push the estimate past UX/block limits; ceiling enforced and asserted. - **Indexer unavailability / timeout**: fall back to cheap ladder path with conservative steps + warning; never block placement entirely on the optimization. ## Verification criteria - `cd frontend-dapp && npm test -- limitBookInsertHint limitOrderLadder limitOrderBatchGasSummary useLimitLadderPlaceGates LimitOrderLadderPanel` green, incl. new depth/hint/adaptive-steps unit tests. - E2E (Playwright, 5 workers) ladder placement into a seeded deep book: all expected rungs land; predicted skip count matches actual; see `skills/AGENTS_E2E_LIMIT_ORDERS_TX.md`. - Network panel / mocks confirm book+hint+depth requests hit the **indexer** only (no LCD/RPC). - `npm run lint && npm run typecheck` clean. - Manual deep-book run on LocalTerra: deep bid ladder that skips rungs today now places all rungs (or shows an accurate pre-submit skip prediction). - Docs/playbooks updated (`AGENTS_LIMIT_ORDER_BATCH_LADDER.md`, `AGENTS_FRONTEND_DEEP_ORDER_BOOK.md`).
PlasticDigits commented 2026-06-01 04:19:16 +00:00 (Migrated from gitlab.com)

mentioned in issue #266

mentioned in issue #266
PlasticDigits commented 2026-06-01 04:19:17 +00:00 (Migrated from gitlab.com)

mentioned in issue #267

mentioned in issue #267
PlasticDigits commented 2026-06-01 04:19:18 +00:00 (Migrated from gitlab.com)

Depends on:

  • #266 — Contract book-order insertion + single anchor support (enables the single-anchor path; until shipped, use per-rung hints)
  • #267 — Indexer batch hint-resolver + price-window endpoints (all depth/hint data flows through these; no direct LCD/RPC)
Depends on: - #266 — Contract book-order insertion + single anchor support (enables the single-anchor path; until shipped, use per-rung hints) - #267 — Indexer batch hint-resolver + price-window endpoints (all depth/hint data flows through these; no direct LCD/RPC)
PlasticDigits commented 2026-06-01 04:46:41 +00:00 (Migrated from gitlab.com)

mentioned in commit 8c6832e349

mentioned in commit 8c6832e349caa5373e89d573f56c4aaa771bda59
PlasticDigits commented 2026-06-01 04:46:56 +00:00 (Migrated from gitlab.com)

Implementation summary (pushed to main @ 8c6832e)

Deep-book ladder placement is now wired in the dApp ladder panel. All depth/hint data flows through the indexer only (GET .../limit-book?price_from&price_to + GET .../limit-book/insert-hints) — no direct LCD/RPC added.

What changed

  1. Depth probe + skip-risk — useLimitLadderPlacementPlan probes the ladder price band and scores foreign orders / head→boundary distance before submit; UI shows expected placed/skipped and path notes.
  2. Path selection — thin_ladder (empty/thin book) · single_anchor_ladder (boundary hint_after_order_id only, #266) · deep_batch (per-rung hints via placeLimitOrderBatch).
  3. Hint safety (L14) — resolved:false / pagination_gap → hint field omitted (never fabricated).
  4. Adaptive max_adjust_steps — default scales from probed depth (floor 32, cap 256); manual override in advanced settings is preserved once touched.
  5. Indexer outage — degrades to conservative ladder path + warning; does not block placement.
  6. Docs/skills — invariant §12 in skills/AGENTS_LIMIT_ORDER_BATCH_LADDER.md, crosslinks in AGENTS_FRONTEND_DEEP_ORDER_BOOK.md and docs/integrators.md.

Key files

  • frontend-dapp/src/hooks/useLimitLadderPlacementPlan.ts
  • frontend-dapp/src/utils/limitLadderPlacementPlan.ts, limitLadderDepth.ts, limitLadderAdaptiveSteps.ts
  • frontend-dapp/src/components/trade/LimitOrderLadderPanel.tsx
  • frontend-dapp/src/services/indexer/client.ts (getPairLimitBookInsertHints, price-window params)

Verification checklist

  • Thin book: ladder panel shows "thin book" path; all rungs place via place_limit_order_ladder; zero or one indexer call pair.
  • Deep book: panel shows "hinted batch"; network tab hits insert-hints + price-window limit-book only (no LCD from browser).
  • Single-anchor: on LocalTerra with #266 wasm, moderate-depth ladder uses ladder message with one boundary anchor; interior rungs chain on-chain.
  • Unresolved hints: simulate pagination_gap (or budget exhausted) — hints omitted on wire, placement still attempted, UI flags reduced confidence.
  • Adaptive steps: deep seeded book raises recommended steps above 32; manual custom value respected after editing advanced settings.
  • Pre-submit summary: data-testid="ladder-placement-summary" shows path, expected rungs, gas estimate.
  • Amount invariant (#233): CW20 send total still equals Σ rung amounts (sumLadderAmountsRaw).
  • Unit tests: npm test -- limitBookInsertHint limitOrderLadder limitOrderBatchGasSummary limitLadderDepth limitLadderPlacementPlan useLimitLadderPlacementPlan green.
  • E2E: Playwright ladder tx on LocalTerra (5 workers) — existing limit-orders-tx.spec.ts ladder test still passes.

Tests run locally

  • Vitest: 34 tests across limitLadder*, limitOrderBatchGasSummary, useLimitLadderPlacementPlan, limitBookInsertHint, limitOrderLadder
  • ESLint: clean (pre-existing warnings only)

Follow-ups

  • E2E with a seeded deep book asserting predicted skip count matches on-chain outcome (outlined in issue test plan; not added in this pass).
  • Trade ticket / limits page single-rung path could migrate from client-side resolveLimitInsertHintAfter to indexer insert-hints (separate scope).

Requesting verification from the QA agent team when LocalTerra + indexer are available.

## Implementation summary (pushed to `main` @ 8c6832e) Deep-book ladder placement is now wired in the dApp ladder panel. All depth/hint data flows through the **indexer only** (`GET .../limit-book?price_from&price_to` + `GET .../limit-book/insert-hints`) — no direct LCD/RPC added. ### What changed 1. **Depth probe + skip-risk** — `useLimitLadderPlacementPlan` probes the ladder price band and scores foreign orders / head→boundary distance before submit; UI shows expected placed/skipped and path notes. 2. **Path selection** — `thin_ladder` (empty/thin book) · `single_anchor_ladder` (boundary `hint_after_order_id` only, #266) · `deep_batch` (per-rung hints via `placeLimitOrderBatch`). 3. **Hint safety (L14)** — `resolved:false` / `pagination_gap` → hint field omitted (never fabricated). 4. **Adaptive `max_adjust_steps`** — default scales from probed depth (floor **32**, cap **256**); manual override in advanced settings is preserved once touched. 5. **Indexer outage** — degrades to conservative ladder path + warning; does not block placement. 6. **Docs/skills** — invariant §12 in `skills/AGENTS_LIMIT_ORDER_BATCH_LADDER.md`, crosslinks in `AGENTS_FRONTEND_DEEP_ORDER_BOOK.md` and `docs/integrators.md`. ### Key files - `frontend-dapp/src/hooks/useLimitLadderPlacementPlan.ts` - `frontend-dapp/src/utils/limitLadderPlacementPlan.ts`, `limitLadderDepth.ts`, `limitLadderAdaptiveSteps.ts` - `frontend-dapp/src/components/trade/LimitOrderLadderPanel.tsx` - `frontend-dapp/src/services/indexer/client.ts` (`getPairLimitBookInsertHints`, price-window params) ### Verification checklist - [ ] **Thin book**: ladder panel shows "thin book" path; all rungs place via `place_limit_order_ladder`; zero or one indexer call pair. - [ ] **Deep book**: panel shows "hinted batch"; network tab hits `insert-hints` + price-window `limit-book` only (no LCD from browser). - [ ] **Single-anchor**: on LocalTerra with #266 wasm, moderate-depth ladder uses ladder message with one boundary anchor; interior rungs chain on-chain. - [ ] **Unresolved hints**: simulate `pagination_gap` (or budget exhausted) — hints omitted on wire, placement still attempted, UI flags reduced confidence. - [ ] **Adaptive steps**: deep seeded book raises recommended steps above 32; manual custom value respected after editing advanced settings. - [ ] **Pre-submit summary**: `data-testid="ladder-placement-summary"` shows path, expected rungs, gas estimate. - [ ] **Amount invariant (#233)**: CW20 send total still equals Σ rung amounts (`sumLadderAmountsRaw`). - [ ] **Unit tests**: `npm test -- limitBookInsertHint limitOrderLadder limitOrderBatchGasSummary limitLadderDepth limitLadderPlacementPlan useLimitLadderPlacementPlan` green. - [ ] **E2E**: Playwright ladder tx on LocalTerra (5 workers) — existing `limit-orders-tx.spec.ts` ladder test still passes. ### Tests run locally - Vitest: 34 tests across `limitLadder*`, `limitOrderBatchGasSummary`, `useLimitLadderPlacementPlan`, `limitBookInsertHint`, `limitOrderLadder` - ESLint: clean (pre-existing warnings only) ### Follow-ups - E2E with a **seeded deep book** asserting predicted skip count matches on-chain outcome (outlined in issue test plan; not added in this pass). - Trade ticket / limits page single-rung path could migrate from client-side `resolveLimitInsertHintAfter` to indexer `insert-hints` (separate scope). --- Requesting verification from the QA agent team when LocalTerra + indexer are available.
PlasticDigits commented 2026-06-02 06:59:58 +00:00 (Migrated from gitlab.com)

mentioned in issue #270

mentioned in issue #270
Brouie commented 2026-06-02 17:23:03 +00:00 (Migrated from gitlab.com)

mentioned in issue #246

mentioned in issue #246
Brouie commented 2026-06-02 17:23:32 +00:00 (Migrated from gitlab.com)

mentioned in merge request !737

mentioned in merge request !737
Brouie commented 2026-06-02 17:23:54 +00:00 (Migrated from gitlab.com)

#268 deep-book ladder verified at the unit/source layer; aligned to the acceptance + verification criteria.

Acceptance criteria:

  • Unit set (exact): npm test limitBookInsertHint limitOrderLadder limitOrderBatchGasSummary limitLadderDepth limitLadderPlacementPlan useLimitLadderPlacementPlan -> 6 files, 28 passed.
  • Path selection: LimitLadderPlacementPath = 'thin_ladder' | 'single_anchor_ladder' | 'deep_batch' with the selection logic in limitLadderPlacementPlan.ts (thin/empty -> ladder msg; deep -> per-rung hints; single-anchor when #266 supported).
  • resolved:false / pagination_gap -> hint field omitted (never fabricated) -> resolver + plan; covered by limitBookInsertHint + limitLadderPlacementPlan tests.
  • Adaptive max_adjust_steps: floor 32 (LIMIT_ORDER_MAX_ADJUST_STEPS_DEFAULT), cap 256 (MAX_ADJUST_STEPS_HARD_CAP), clamp(observed x mult + floor, FLOOR, HARD_CAP).
  • No #233 regression: sumLadderAmountsRaw reduces with BigInt (no string concat).
  • Indexer-only: zero direct LCD/RPC in the new ladder files (limitLadder*.ts, useLimitLadderPlacementPlan.ts) — all depth/hint via the indexer client.
  • Pre-submit summary: data-testid="ladder-placement-summary" in LimitOrderLadderPanel; docs/skills (AGENTS_LIMIT_ORDER_BATCH_LADDER, AGENTS_FRONTEND_DEEP_ORDER_BOOK, integrators.md) cross-link.

Verification criteria:

  • Unit set green (above).
  • [~] npm run typecheck clean: tsc -b was RED on main, but NOT for anything in the ladder code — it was a pre-existing build breakage from #246 (cancelLimitOrderMutation prop typed number vs the number|number[] hook). Fixed in MR !737; with that, tsc -b exits clean.
  • [~] E2E Playwright (5 workers) ladder into a seeded deep book + manual deep-book LocalTerra run = clean-host / agent-QA layer (not run here). The plan/path/hint/adaptive-steps logic is fully unit-covered.

So the ladder feature is verified here; the only gate that wasn't clean was typecheck, and that was an unrelated #246-era build break now fixed in !737. Good to close from my side once !737 lands and the e2e-tx ladder run is signed off on a clean host. @PlasticDigits

#268 deep-book ladder verified at the unit/source layer; aligned to the acceptance + verification criteria. Acceptance criteria: - [x] Unit set (exact): npm test limitBookInsertHint limitOrderLadder limitOrderBatchGasSummary limitLadderDepth limitLadderPlacementPlan useLimitLadderPlacementPlan -> 6 files, 28 passed. - [x] Path selection: LimitLadderPlacementPath = 'thin_ladder' | 'single_anchor_ladder' | 'deep_batch' with the selection logic in limitLadderPlacementPlan.ts (thin/empty -> ladder msg; deep -> per-rung hints; single-anchor when #266 supported). - [x] resolved:false / pagination_gap -> hint field omitted (never fabricated) -> resolver + plan; covered by limitBookInsertHint + limitLadderPlacementPlan tests. - [x] Adaptive max_adjust_steps: floor 32 (LIMIT_ORDER_MAX_ADJUST_STEPS_DEFAULT), cap 256 (MAX_ADJUST_STEPS_HARD_CAP), clamp(observed x mult + floor, FLOOR, HARD_CAP). - [x] No #233 regression: sumLadderAmountsRaw reduces with BigInt (no string concat). - [x] Indexer-only: zero direct LCD/RPC in the new ladder files (limitLadder*.ts, useLimitLadderPlacementPlan.ts) — all depth/hint via the indexer client. - [x] Pre-submit summary: data-testid="ladder-placement-summary" in LimitOrderLadderPanel; docs/skills (AGENTS_LIMIT_ORDER_BATCH_LADDER, AGENTS_FRONTEND_DEEP_ORDER_BOOK, integrators.md) cross-link. Verification criteria: - [x] Unit set green (above). - [~] npm run typecheck clean: tsc -b was RED on main, but NOT for anything in the ladder code — it was a pre-existing build breakage from #246 (cancelLimitOrderMutation prop typed number vs the number|number[] hook). Fixed in MR !737; with that, tsc -b exits clean. - [~] E2E Playwright (5 workers) ladder into a seeded deep book + manual deep-book LocalTerra run = clean-host / agent-QA layer (not run here). The plan/path/hint/adaptive-steps logic is fully unit-covered. So the ladder feature is verified here; the only gate that wasn't clean was typecheck, and that was an unrelated #246-era build break now fixed in !737. Good to close from my side once !737 lands and the e2e-tx ladder run is signed off on a clean host. @PlasticDigits
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-03 02:05:20 +00:00
PlasticDigits commented 2026-08-17 10:26:07 +00:00 (Migrated from gitlab.com)

mentioned in issue #546

mentioned in issue #546
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#268
No description provided.