feat(pair): bound CleanLimitBook traversal with max_steps + resume cursor (#274) #753

Merged
Brouie merged 1 commit from qa/274-clean-traversal-cap into main 2026-06-05 03:21:03 +00:00
Brouie commented 2026-06-05 02:16:59 +00:00 (Migrated from gitlab.com)

Follow-up on #274, your "start index + max steps" direction.

clean_limit_book capped parks (max_orders) but not traversal — the walk visited every node until it parked max_orders or hit the end, so a book of healthy or zero-remaining orders could be walked unboundedly (the gas DoS).

Fix:

  • New MAX_CLEAN_SCAN_STEPS=500 in dex-common/limit_clean.rs (mirrors the matcher's MAX_SCAN_STEPS, same ~19k-gas/iter sizing) + clamp_max_clean_scan_steps.
  • clean_limit_book takes max_steps, counts EVERY visited node (zero-remaining skip, healthy fall-through, parked), and breaks at the cap. CleanLimitBookResult gains scan_capped + resume_cursor — the first UNVISITED oid (the gotcha: NOT the last processed, or re-passing the same start_hint loops on the same prefix). Both emitted as execute attrs.
  • New optional max_steps on the CleanLimitBook ExecuteMsg (#[serde(default)]; absent or 0 -> the full cap, backward-compatible). A stale resume_cursor degrades safely via resolve_start -> head.
  • start_hint is the "start index"; the park cap stays independent.

Keeper loop: re-submit with start_hint = resume_cursor until scan_capped/cap_hit clear (no resume_cursor).

Tests (contract suite 419/0): clean_limit_book_traversal_bounded_when_nothing_parked (the DoS — 0 parks, still bounded), ..._scan_cap_resume_reaches_tail, ..._zero_max_steps_means_full_cap, ..._park_cap_independent_of_scan_cap. Live gas re-confirm rides the next deploy. No closing keyword.

Follow-up on #274, your "start index + max steps" direction. `clean_limit_book` capped *parks* (max_orders) but not *traversal* — the walk visited every node until it parked `max_orders` or hit the end, so a book of healthy or zero-remaining orders could be walked unboundedly (the gas DoS). Fix: - New `MAX_CLEAN_SCAN_STEPS=500` in dex-common/limit_clean.rs (mirrors the matcher's `MAX_SCAN_STEPS`, same ~19k-gas/iter sizing) + `clamp_max_clean_scan_steps`. - `clean_limit_book` takes `max_steps`, counts EVERY visited node (zero-remaining skip, healthy fall-through, parked), and breaks at the cap. `CleanLimitBookResult` gains `scan_capped` + `resume_cursor` — the first UNVISITED oid (the gotcha: NOT the last processed, or re-passing the same start_hint loops on the same prefix). Both emitted as execute attrs. - New optional `max_steps` on the `CleanLimitBook` ExecuteMsg (`#[serde(default)]`; absent or `0` -> the full cap, backward-compatible). A stale resume_cursor degrades safely via resolve_start -> head. - `start_hint` is the "start index"; the park cap stays independent. Keeper loop: re-submit with `start_hint = resume_cursor` until `scan_capped`/`cap_hit` clear (no `resume_cursor`). Tests (contract suite 419/0): `clean_limit_book_traversal_bounded_when_nothing_parked` (the DoS — 0 parks, still bounded), `..._scan_cap_resume_reaches_tail`, `..._zero_max_steps_means_full_cap`, `..._park_cap_independent_of_scan_cap`. Live gas re-confirm rides the next deploy. No closing keyword.
Brouie commented 2026-06-05 02:17:15 +00:00 (Migrated from gitlab.com)

mentioned in issue #274

mentioned in issue #274
Brouie commented 2026-06-05 02:19:54 +00:00 (Migrated from gitlab.com)

mentioned in issue #289

mentioned in issue #289
PlasticDigits commented 2026-06-05 03:21:03 +00:00 (Migrated from gitlab.com)

mentioned in commit 974cabb659

mentioned in commit 974cabb659d85dedbb1b4a32a62e4d76f2b35eb0
PlasticDigits (Migrated from gitlab.com) merged commit 974cabb659 into main 2026-06-05 03:21:03 +00:00
Sign in to join this conversation.
No reviewers
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!753
No description provided.