Limit insert hint fallback: walk from hint toward head/tail when verify fails #265
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#265
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
When
hint_after/hint_after_order_idfails O(1) verification but the hinted order still exists on the correct side and is linked in the DLL, fall back by walking from the hint toward the head or tail (whichever direction the price-time order says is correct) instead of restarting from the book head. Stale, wrong-side, or unlinked hints keep today's head walk.Supersedes the head-only fallback described in #256 (O(1) fast path shipped; this issue is the follow-up from PlasticDigits' comment on #256).
Current codebase
try_insert_after_hint_bid/try_insert_after_hint_askinorderbook.rsload the hint (+ optionalnext), verify side, on-book linkage, and price-time order (bid_before/ask_beforecomposite key). On success,find_insert_*returns in O(1).find_insert_bid/find_insert_askdiscards the hint anchor and walks fromHEAD_BID/HEAD_ASK, counting every load against the sharedstepscounter untilmax_adjust_steps(min withMAX_ADJUST_STEPS_HARD_CAP= 256) or insert position found.insert_bid_with_id/insert_ask_with_id, batch/ladder placement (limit_placement.rs— chainslast_placed_hint),UpdateLimitOrderPrice→relink_limit_order_price(contract.rs).limitBookInsertHint.ts; batch wire fieldhint_after_order_id(#261).docs/contracts-security-audit.mdanddocs/limit-orders.mddocument "stale/wrong hints → bounded head walk". This issue updates that contract.Why this is needed
max_adjust_stepseven when the true slot is 1–3 nodes from the hinted order — the live A/B in #256 showed valid hints succeeding where head walk reverts, but stale near-miss hints still pay the full prefix cost.Constraints and guardrails
bid_before/ask_before; head = best price, FIFO byorder_id).prevset or id == head). Otherwise → head walk (unchanged).prevwalk): new sorts before hint (too good to sit after hint) — e.g. bid price higher than hint, or same price with lowerorder_id.nextwalk): new sorts after hint'snextneighbor (too bad for the hinted slot) — walk forward fromhint.next(or from hint whennextmissing/wrong-side).stepscounter: O(1) hint loads + directional walk + any head-walk fallback all count towardmax_adjust_steps;LimitInsertStepsExceededsemantics unchanged.hint_after_order_idfields.Relevant files
smartcontracts/contracts/pair/src/orderbook.rs(try_insert_after_hint_*,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,docs/contracts-security-audit.md(L5, L14),docs/integrators.mdskills/AGENTS_FRONTEND_LIMIT_ORDER_PLACEMENT_GAS.md,skills/AGENTS_LIMIT_ORDER_BATCH_LADDER.mdfrontend-dapp/src/utils/limitBookInsertHint.tsorderbook.rsunit tests,smartcontracts/tests/src/limit_order_tests.rsRecommended direction
try_insert_after_hint_*to return a richer result, e.g.HintInsertResult:Ok(Some(neighbors))— fast path (unchanged).Ok(None)with reason —MissingOrWrongSide,Unlinked,NeedWalkTowardHead { hint_id },NeedWalkTowardTail { start_id }.walk_insert_bid_from/walk_insert_ask_from— same comparator loop as today's head walk but starting at a cursor id and followingprevornextonly; incrementstepsper load; stop on position found or cap.find_insert_*:steps < max_stepsat directional failure — document choice; prefer no double walk to avoid doubling gas on attack. Safer default: single strategy per invocation.Acceptance criteria
hint_afterstill inserts in O(1) (≤ 3 order loads) — #256 behavior preserved.max_adjust_stepswhere today's head walk reverts.UpdateLimitOrderPriceand batch/ladder placement benefit without wire changes.docs/limit-orders.mdupdated for directional fallback semantics.Test plan (functional paths)
prevwalk from hint finds slot; succeeds under cap where head walk failsnextwalk from hint/hint.next finds slotprevwalk to correct levelnextwalkmax_adjust_stepstight with near-miss hintmax_adjust_steps = 1with far-miss hintLimitInsertStepsExceeded(unchanged error)Test plan (attack / abuse / hack vectors)
max_adjust_steps; no wrong-level insertprev/next; comparators reject; cap prevents infinite loopLimitInsertStepsExceeded; no partial insert / corrupted linksVerification criteria
cd smartcontracts && cargo test -p cl8y-dex-pair hint— existing #256 tests green + new directional cases.cd smartcontracts && cargo test -p cl8y-dex-tests limit_order— integration tests green.mentioned in issue #256
mentioned in commit
b347a7bbf9Implementation summary (merged to
main—b347a7b)Implemented directional insert-hint fallback (GitLab #265) in
orderbook.rs:try_insert_after_hint_*now returnsHintInsertOutcome: O(1) ready, head-walk (missing/wrong-side/unlinked), walk toward head (prev), or walk toward tail (next).walk_insert_*_toward_head/walk_insert_*_from— bounded walks from the hint neighborhood using the samebid_before/ask_beforecomparators; sharedstepscounter towardmax_adjust_steps.find_insert_*— single strategy per invocation (no double head walk after directional exhaustion); stale anchors still use head walk.Wire/API: unchanged (
hint_after_order_idonly).Docs: invariant L14 and L5 updated in
docs/contracts-security-audit.md;docs/limit-orders.md,docs/integrators.md; agent playbooksskills/AGENTS_FRONTEND_LIMIT_ORDER_PLACEMENT_GAS.md,skills/AGENTS_LIMIT_ORDER_BATCH_LADDER.md.Tests added/updated:
limit_batch_chained_near_miss_hint_directional_walk_succeeds; adjusted partial-batch skip test for #265 behaviorVerification checklist
cd smartcontracts && cargo test -p cl8y-dex-pair hint— 12 tests greencd smartcontracts && cargo test -p cl8y-dex-tests limit_order— 64 tests greenhint_afterstill O(1) (≤ 3 loads) —insert_bid_with_valid_hint_after_is_o1max_adjust_stepswhere pre-change head walk reverts —insert_bid_deep_book_near_miss_hint_beats_head_walk_capinsert_bid_stale_hint_falls_back_to_head_walk,insert_bid_wrong_side_hint_falls_backlimit_batch_chained_near_miss_hint_directional_walk_succeedsmax_adjust_steps = 1with far-miss still →LimitInsertStepsExceededFollow-ups
Requesting verification from the QA agent team when convenient.
mentioned in merge request !733
Verified #265 on
d6701c4(directional insert-hint fallback). Contract-only logic; no gas baseline required.preserved), insert_bid_deep_book_near_miss_hint_beats_head_walk_cap (headline — near-miss succeeds under
Low max_adjust_steps where head walk reverts), insert_bid/ask_near_miss_hint_toward_head/tail_succeeds_under_cap
(directional), insert_bid_stale_hint_falls_back_to_head_walk + insert_bid_wrong_side_hint_falls_back
(anchor unusable → head walk unchanged), insert_bid_bad_hint_with_max_steps_one_errors
(far-miss → LimitInsertStepsExceeded), relink_limit_order_price_near_miss_hint_succeeds (UpdateLimitOrderPrice benefits).
shared steps budget, single strategy per insert (no double head walk). Wire/API unchanged.
Good to close from my side once !733 merges. @PlasticDigits
mentioned in issue #263
mentioned in issue #309