Limit order insert: honor hint_after for O(1) placement when valid #256
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:implement
agent:implement
agent:open_issues
agent:ready
agent:research
agent:security_audit
agent:verify
architecture
backend
blocker:hybrid
blocker:launch
blocker:limit-orders
blocker:v2
block:log_only
block:security
bug
ci
contracts
correctness
deploy
dev
devops
docs
documentation
duplicate
e2e
enhancement
epic
feature
frontend
functional-completion
gas
good first issue
governance
help wanted
high-risk
hooks
hybrid
indexer
infra
infrastructure
integrators
invalid
launch-blocker
limit-orders
localnet
localterra
low priority
missing-implementation
needs-design
ops
performance
priority
high
priority
medium
product
qa
QA
question
ready
ready
research
scripts
security
security-hardening
smartcontracts
tech-debt
testing
ux
UX
v2
verification
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/cl8y-dex-terraclassic#256
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Use the
hint_after/hint_after_order_idparameter on limit placement and price updates to achieve O(1) insertion when the hint is valid, falling back to the existing head walk capped bymax_adjust_steps.Current codebase
HEAD_BID/HEAD_ASK,ORDERSmap) insmartcontracts/contracts/pair/src/orderbook.rs.find_insert_bid/find_insert_askaccepthint_after: Option<u64>but parameter is_hint_after— always linear walk from head, incrementingstepsuntilmax_adjust_steps(min withMAX_ADJUST_STEPS_HARD_CAP= 256) or insert position found.hint_after:insert_bid_with_id/insert_ask_with_id(placement, batch — currentlyNoneinlimit_placement.rs),relink_limit_order_price/UpdateLimitOrderPrice(hint_after_order_id).LimitInsertStepsExceeded, batch placement skips rung (limit_placement.rs); single placement errors.Why this is needed
Constraints and guardrails
(price, id)sorts after hint perbid_before/ask_beforeand before hint’snextneighbor (or tail).max_adjust_stepsaccounting).dex-common/docs/limit-orders.md).Relevant files
smartcontracts/contracts/pair/src/orderbook.rs(find_insert_*,link_*,relink_limit_order_price)smartcontracts/contracts/pair/src/limit_placement.rssmartcontracts/contracts/pair/src/contract.rs(execute_update_limit_order_price)smartcontracts/packages/dex-common/src/limit_placement.rs,pair.rsdocs/limit-orders.md,skills/AGENTS_FRONTEND_LIMIT_ORDER_PLACEMENT_GAS.mdorderbook.rsunit tests,limit_order_tests.rsRecommended direction
try_insert_after_hint(side, hint_id, new_price, new_id) -> Option<(prev, next)>with O(1) loads (hint + at most next).find_insert_bid/find_insert_ask: ifSome(hint)and try succeeds, return; else existing while loop from head.hint_afterfrom batch API when frontend/indexer supplies previous rung id.Acceptance criteria
hint_afterinserts in constant steps (≤ 3 order loads) without head walk.LimitInsertStepsExceededunchanged.UpdateLimitOrderPricebenefits when hint provided.Test plan (functional paths)
max_adjust_steps = 1with bad hintTest plan (attack / abuse / hack vectors)
max_adjust_stepson fallbackVerification criteria
cargo testorderbook + limit placement tests green.docs/limit-orders.md.mentioned in commit
7f9e962d04Implementation complete (pushed to
main—7f9e962)Implemented verified O(1) limit-order insertion via
hint_after/hint_after_order_idwith bounded fallback to the existing head walk.What changed
orderbook.rs: Addedtry_insert_after_hint_bid/try_insert_after_hint_ask— load hint (+ optionalnext), verify side, on-book linkage, and price-time order; wired intofind_insert_bid/find_insert_ask. Invalid/stale hints fall back unchanged;LimitInsertStepsExceededsemantics preserved.limit_placement.rs: Batch/ladder placement chains each successful rung id ashint_afterfor the next rung (helps monotonic ladders).UpdateLimitOrderPrice: Already forwardedhint_after_order_id; now benefits from the fast path.orderbook::tests+ adjustedlimit_batch_partial_success_skips_book_walk_failures(middle rung price must beat prior rung so hint cannot bypass step cap).docs/limit-orders.md, invariant L14 + L5 indocs/contracts-security-audit.md, cross-linkedskills/AGENTS_FRONTEND_LIMIT_ORDER_PLACEMENT_GAS.mdandskills/AGENTS_LIMIT_ORDER_BATCH_LADDER.md.Verification checklist
cd smartcontracts && cargo test -p cl8y-dex-pair hintcd smartcontracts && cargo test -p cl8y-dex-tests limit_orderhint_after_order_idfrom indexerlimit-bookwalk — confirm placement succeeds with Low (16) steps where head walk would failUpdateLimitOrderPricewith hint from book neighbor — confirm relink without extra head walk gasFollow-ups
hint_after_order_idon single placement and price-edit txs when deep-book UI knows the predecessor id (wire already exists inpair.tsfor price updates).@qa-agent-team — please verify the checklist above on LocalTerra (or staging) and confirm book ordering invariants (head = best price, FIFO at price) after hint-assisted inserts. Issue left open pending QA sign-off.
mentioned in issue #261
Verified #256 on
main@6b22feb(7f9e962, live on LocalTerra). Source + the 7 new hint tests + live A/B demos. All acceptance criteria covered, ordering invariants hold, security checks confirmed.Headline — live A/B (the O(1) benefit, proven functionally)
On a deep book, a valid hint places/relinks at a low
max_adjust_stepswhere the no-hint head walk hits the cap and reverts — same operation, same cap, hint succeeds:max_adjust_steps=16:hint=407(run tail) → placed id 408 @1.70,prev=407— O(1) insert under the same capmax_adjust_steps=2:hint=408→code=0, relinked to 1.70This is a stronger benefit proof than a gas delta: it shows the hint path completing work the bounded head walk physically can't, at the same step budget.
Acceptance criteria
try_insert_after_hint_{bid,ask}returns the position from ≤2 loads;find_insert_*returns immediately. Testsinsert_bid_with_valid_hint_after_is_o1,insert_ask_with_valid_hint_after. Live: 3b + 5b.LimitInsertStepsExceededunchanged: source — failed verify returnsNoneand the head walk runs on the shared*stepscounter, so a bad hint's loads count towardmax_adjust_steps(can't bypass the cap). Testsinsert_bid_stale_hint_falls_back_to_head_walk,insert_bid_bad_hint_with_max_steps_one_errors. Live: 4 (stale), 3a/5a (cap hit → revert).hint_after_order_id→relink_limit_order_price→ fast path. Testrelink_limit_order_price_uses_hint. Live: 5b atmax_adjust_steps=2.bid_before/ask_beforecomposite-key comparators as the walk (total order not weakened). Live: post-demo book walk — head=best (1.60), prices non-increasing, FIFO (ascending id) at equal price, no violations.Security — the hint is verified, never trusted (prominent)
try_insert_after_hint_*loads the hint (+ at most itsnext) and rejects unless: it exists, correct side, on-book linkage (prevset or it is the head — not a dangling/cancelled row), and price-time order on both sides (newsorts after the hint and before the hint'snext). Any failure →None→ bounded head-walk fallback on the shared step counter. So the worst case for a bogus hint is today's bounded walk; it can neither insert at a wrong level nor exceed the step budget. Confirmed live:999999999→ fallback → correct 1.55 levelprev= the surviving neighborPlus tests
insert_bid_wrong_side_hint_falls_back,insert_bid_stale_hint_falls_back_to_head_walk,insert_bid_bad_hint_with_max_steps_one_errors.Functional + attack plans
max_adjust_steps=1bad hint, relink across levels): 7 hint unit tests +limit_batch_item_explicit_hint_places_on_deep_book+ live 3/4/5/7.Dev checklist
cargo test -p cl8y-dex-pair hint— 7/0cargo test -p cl8y-dex-tests limit_order— 55/0 (incl. adjustedlimit_batch_partial_success_skips_book_walk_failures)hint_after_order_id→ places at low steps where head walk fails — live 3a/3bUpdateLimitOrderPricewith book-neighbor hint → relink without head-walk gas — live 5bmax_adjust_steps=2) → all rungs place (chainingitem.hint_after_order_id.or(last_placed_hint)) — live 6Layer honesty + transparency
One open item (flagged, not chased)
Gas vs a pre-hint baseline can't be shown as a numeric before/after — no pre-#256 build deployed (same structural gap as #252/#254/#255). The A/B above demonstrates the benefit more strongly than a gas delta would, so I'm not chasing it.
@PlasticDigits — verified and signed off from my side, no issues found (O(1) fast path, verified-never-trusted hint, ordering invariants all hold live); over to you to close.
Instead of head walk fallback, the fallback should be to walk from the hint up/down depending on which direction the hint is incorrect. This is because usually an invalid hint is off by only a few units due to other tx arriving between when the user signed and when his tx is executed onchain.
No need for gas vs prehint baseline - current gas expenditure is acceptable.
mentioned in issue #265
Closing #256 — O(1) verified hint insertion shipped on
main(7f9e962) and QA-signed off by @Brouie.Follow-up: directional hint fallback (walk from hint toward head/tail on near-miss verify failure instead of always restarting from book head) is tracked in #265 — per near-miss fallback requirement.
mentioned in issue #257
mentioned in issue #258