Benchmark MAX_EXPIRED_PARKS_PER_SWAP vs max gas/tx size (GitLab #289) #309

Closed
opened 2026-06-05 04:08:26 +00:00 by PlasticDigits · 9 comments
PlasticDigits commented 2026-06-05 04:08:26 +00:00 (Migrated from gitlab.com)

Current codebase

MAX_EXPIRED_PARKS_PER_SWAP is 15, defined in smartcontracts/packages/dex-common/src/pair.rs and mirrored in:

  • smartcontracts/contracts/pair/src/orderbook.rs — parks expired limits during match_bids / match_asks
  • frontend-dapp/src/services/terraclassic/hybridBookWalkLimits.ts — offline gas budgeting
  • frontend-dapp/src/services/terraclassic/hybridSwapGas.ts — bookWalkScanOverheadGas
  • Tests: smartcontracts/tests/src/limit_order_tests.rs, pair unit tests in orderbook.rs

When cap is hit, additional expired head orders are skipped (expired_parks_capped=true). Value 15 was raised in #254 from an earlier lower cap but was not re-benchmarked against Terra Classic max tx gas / max tx size after subsequent orderbook features (dust flush #264, scan cap #254, adjust steps #265).

Follow-up: GitLab #289.

Why this is needed

Raising MAX_EXPIRED_PARKS_PER_SWAP improves maker UX (fewer stranded expired orders) but each park costs storage writes + events. Too high risks:

  • Tx exceeding block gas limit (HYBRID_SWAP_GAS_LIMIT / chain max)
  • Wasm tx size limit with many wasm events
  • Failed taker swaps near book heads heavy with expired orders

An evidence-based cap balances cleanup throughput vs reliability.

Constraints / guardrails

  • On-chain constant must match frontend hybridBookWalkLimits.ts after change.
  • Do not break invariant L5 (docs/contracts-security-audit.md).
  • Benchmark on optimized wasm (CosmWasm optimizer build), not debug.
  • Consider interaction with MAX_SCAN_STEPS (500) and MAX_MAKER_FILLS_HARD_CAP (100) — worst-case tx uses all budgets.
  • If cap changes, update docs/limit-orders.md, skills/AGENTS_TERRACLASSIC_GAS.md, and security audit table.
  • Migration: changing const requires contract redeploy — document for governance.

Relevant files

Area Path
Constant smartcontracts/packages/dex-common/src/pair.rs
Logic smartcontracts/contracts/pair/src/orderbook.rs
Gas docs skills/AGENTS_TERRACLASSIC_GAS.md, docs/limit-orders.md
Frontend gas frontend-dapp/src/services/terraclassic/hybridSwapGas.ts, hybridBookWalkLimits.ts
Tests smartcontracts/tests/src/limit_order_tests.rs
  1. Add benchmark test / script: synthetic book with N expired orders at head; execute hybrid swap with book_input > 0, measure gas used vs limit for N = 1..30.
  2. Record wasm event count and serialized tx size if executing via integration test App.
  3. Identify highest N such that gas < 15M (dApp ceiling) with headroom (~20%) and under chain max tx bytes.
  4. Set MAX_EXPIRED_PARKS_PER_SWAP to that N; update frontend mirror + docs.
  5. If 15 is already optimal, document benchmark artifacts in docs/limit-orders.md.

Acceptance criteria

  • Benchmark methodology documented (book setup, swap params, build profile).
  • Chosen cap justified with gas + event data table.
  • Frontend offline gas formula uses new constant.
  • Integration test proves swap succeeds at cap and fails gracefully above chain limit (if testable).
  • Docs/skills updated.

Test plan (all paths)

Path Expected
N expired = cap All parked in one swap
N expired = cap + 5 Cap attrs set; skipped > 0
Pool-only swap Parks = 0 overhead unchanged
Gas estimate hybridSwapGas.test.ts expectations updated

Attack / abuse / hack vectors

Vector Test
Griefing: flood expired orders to brick takers Cap + skip path; taker swap still succeeds within gas
Park loop gas exhaustion Benchmark worst case at max scan steps + max parks

Verification criteria

  • make test-contracts green with updated cap tests.
  • make test-frontend for gas helper tests.
  • Benchmark numbers committed (markdown table or test output comment).
## Current codebase `MAX_EXPIRED_PARKS_PER_SWAP` is **15**, defined in `smartcontracts/packages/dex-common/src/pair.rs` and mirrored in: - `smartcontracts/contracts/pair/src/orderbook.rs` — parks expired limits during `match_bids` / `match_asks` - `frontend-dapp/src/services/terraclassic/hybridBookWalkLimits.ts` — offline gas budgeting - `frontend-dapp/src/services/terraclassic/hybridSwapGas.ts` — `bookWalkScanOverheadGas` - Tests: `smartcontracts/tests/src/limit_order_tests.rs`, pair unit tests in `orderbook.rs` When cap is hit, additional expired head orders are **skipped** (`expired_parks_capped=true`). Value **15** was raised in #254 from an earlier lower cap but was **not** re-benchmarked against Terra Classic **max tx gas / max tx size** after subsequent orderbook features (dust flush #264, scan cap #254, adjust steps #265). Follow-up: GitLab **#289**. ## Why this is needed Raising `MAX_EXPIRED_PARKS_PER_SWAP` improves maker UX (fewer stranded expired orders) but each park costs storage writes + events. Too high risks: - Tx exceeding block gas limit (`HYBRID_SWAP_GAS_LIMIT` / chain max) - Wasm tx size limit with many wasm events - Failed taker swaps near book heads heavy with expired orders An evidence-based cap balances cleanup throughput vs reliability. ## Constraints / guardrails - On-chain constant must match frontend `hybridBookWalkLimits.ts` after change. - Do not break invariant **L5** (`docs/contracts-security-audit.md`). - Benchmark on **optimized** wasm (CosmWasm optimizer build), not debug. - Consider interaction with `MAX_SCAN_STEPS` (500) and `MAX_MAKER_FILLS_HARD_CAP` (100) — worst-case tx uses all budgets. - If cap changes, update `docs/limit-orders.md`, `skills/AGENTS_TERRACLASSIC_GAS.md`, and security audit table. - Migration: changing const requires contract redeploy — document for governance. ## Relevant files | Area | Path | |------|------| | Constant | `smartcontracts/packages/dex-common/src/pair.rs` | | Logic | `smartcontracts/contracts/pair/src/orderbook.rs` | | Gas docs | `skills/AGENTS_TERRACLASSIC_GAS.md`, `docs/limit-orders.md` | | Frontend gas | `frontend-dapp/src/services/terraclassic/hybridSwapGas.ts`, `hybridBookWalkLimits.ts` | | Tests | `smartcontracts/tests/src/limit_order_tests.rs` | ## Recommended direction 1. Add benchmark test / script: synthetic book with N expired orders at head; execute hybrid swap with `book_input > 0`, measure gas used vs limit for N = 1..30. 2. Record wasm event count and serialized tx size if executing via integration test `App`. 3. Identify highest N such that gas < **15M** (dApp ceiling) with headroom (~20%) and under chain max tx bytes. 4. Set `MAX_EXPIRED_PARKS_PER_SWAP` to that N; update frontend mirror + docs. 5. If 15 is already optimal, document benchmark artifacts in `docs/limit-orders.md`. ## Acceptance criteria - [ ] Benchmark methodology documented (book setup, swap params, build profile). - [ ] Chosen cap justified with gas + event data table. - [ ] Frontend offline gas formula uses new constant. - [ ] Integration test proves swap succeeds at cap and fails gracefully above chain limit (if testable). - [ ] Docs/skills updated. ## Test plan (all paths) | Path | Expected | |------|----------| | N expired = cap | All parked in one swap | | N expired = cap + 5 | Cap attrs set; skipped > 0 | | Pool-only swap | Parks = 0 overhead unchanged | | Gas estimate | `hybridSwapGas.test.ts` expectations updated | ## Attack / abuse / hack vectors | Vector | Test | |--------|------| | Griefing: flood expired orders to brick takers | Cap + skip path; taker swap still succeeds within gas | | Park loop gas exhaustion | Benchmark worst case at max scan steps + max parks | ## Verification criteria - `make test-contracts` green with updated cap tests. - `make test-frontend` for gas helper tests. - Benchmark numbers committed (markdown table or test output comment).
PlasticDigits commented 2026-06-05 04:08:27 +00:00 (Migrated from gitlab.com)

marked as related to #289

marked as related to #289
ghost1 commented 2026-06-05 10:38:02 +00:00 (Migrated from gitlab.com)

mentioned in commit 00e6467733

mentioned in commit 00e6467733db9258901b991f1a1c15198ddb7d22
PlasticDigits commented 2026-06-05 10:38:37 +00:00 (Migrated from gitlab.com)

mentioned in merge request !794

mentioned in merge request !794
PlasticDigits commented 2026-06-05 10:38:41 +00:00 (Migrated from gitlab.com)

Implementation complete — MR !794 opened.

Outcome: retain MAX_EXPIRED_PARKS_PER_SWAP = 15. LocalTerra optimized-wasm sweep (N=1..30) shows isolated worst case ~855k gas_used at the cap (≪ 12M headroom). ~29k gas/park on-chain; scan-step budget (500) remains binding on deep expired prefixes.

Benchmark table and methodology: docs/limit-orders.md#expired-park-benchmark-gitlab-309
Live repro: make verify-issue-309

Implementation complete — MR !794 opened. **Outcome:** retain `MAX_EXPIRED_PARKS_PER_SWAP = 15`. LocalTerra optimized-wasm sweep (N=1..30) shows isolated worst case ~855k `gas_used` at the cap (≪ 12M headroom). ~29k gas/park on-chain; scan-step budget (500) remains binding on deep expired prefixes. Benchmark table and methodology: `docs/limit-orders.md#expired-park-benchmark-gitlab-309` Live repro: `make verify-issue-309`
ghost1 commented 2026-06-05 10:45:41 +00:00 (Migrated from gitlab.com)

mentioned in commit 6463af2bb5

mentioned in commit 6463af2bb561e031a2693d2f5f38e9133c5cdd7e
PlasticDigits commented 2026-06-05 10:55:52 +00:00 (Migrated from gitlab.com)

mentioned in commit c0d8ad6c49

mentioned in commit c0d8ad6c498756ef6b685bb726b04ab86f42effe
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-05 10:55:53 +00:00
PlasticDigits commented 2026-06-05 11:03:25 +00:00 (Migrated from gitlab.com)

mentioned in merge request !795

mentioned in merge request !795
ghost1 commented 2026-06-08 13:55:04 +00:00 (Migrated from gitlab.com)

mentioned in merge request !841

mentioned in merge request !841
PlasticDigits commented 2026-06-13 07:56:27 +00:00 (Migrated from gitlab.com)

mentioned in issue #379

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