test(indexer): verify CG/CMC orderbook lcd-heavy rate limit (#278) #765

Merged
PlasticDigits merged 1 commit from cursor/verify-issue-278-docs-test-1678 into main 2026-06-05 04:15:12 +00:00
PlasticDigits commented 2026-06-05 04:05:15 +00:00 (Migrated from gitlab.com)

Summary

Independent verification of GitLab #278 (CG/CMC orderbook endpoints under lcd_heavy_router). The route move is already on main (MR !996 / qa/278-cgcmc-orderbook-lcd-heavy). This MR adds regression coverage and doc cross-links from QA verification.

Changes

  • indexer/tests/security.rs: cg_cmc_orderbook_lcd_heavy_rate_limit_returns_429 — proves /cg/orderbook and /cmc/orderbook/* return 429 under the LCD-heavy governor when global RATE_LIMIT_RPS=0.
  • docs/indexer-invariants.md: list CG/CMC orderbook mirrors in rate-limit / LCD amplification rows; link #278.
  • skills/AGENTS_INDEXER_API_LCD_SECURITY.md: document CG/CMC orderbook on the LCD-heavy route list.

Verification checklist (acceptance → evidence)

Item Result How
AC1 /cg/orderbook and /cmc/orderbook/* use same per-IP LCD-heavy limit as native book PASS Code: indexer/src/api/mod.rs routes on lcd_heavy_router + apply_rate_limit_layer(..., rate_limit_lcd_heavy_rps). Test: cargo test --test security cg_cmc_orderbook_lcd_heavy_rate_limit_returns_429. Live: 25× hammer on /cg/orderbook?ticker_id=EMBER_CORAL → 20× 200 then 429; /cmc/orderbook/EMBER_CORAL shares drained heavy bucket (all 429 after CG burst); /api/v1/overview stayed 200 (general limiter not gating).
AC2 No LCD-fanout route on general limiter only (orderbook surface) PASS (scoped) Orderbook mirrors on heavy router. CG/CMC tickers/summary N+1 fanout tracked separately in #288 (60s cache).
Native book heavy throttle (regression) PASS cargo test --test security lcd_heavy_route_rate_limit_returns_429
Test plan: hammer /cg/orderbook past heavy RPS PASS Live burst above + integration test
Test plan: hammer /cmc/orderbook/{pair} PASS Live burst above + integration test

Commands run

cargo test --test security lcd_heavy_route_rate_limit_returns_429 cg_cmc_orderbook_lcd_heavy_rate_limit_returns_429 -j 1 -- --test-threads=1
# Live (indexer on :3001, RATE_LIMIT_LCD_HEAVY_RPS=10, LocalTerra LCD)
# 25× GET /cg/orderbook → 20×200 then 429; overview 25×200

Follow-ups

  • Consider asserting x-ratelimit-limit on heavy 429 responses in tests if governor header semantics stabilize (live run showed 120 from layered governors).
## Summary Independent verification of GitLab #278 (CG/CMC orderbook endpoints under `lcd_heavy_router`). The route move is already on `main` (MR !996 / `qa/278-cgcmc-orderbook-lcd-heavy`). This MR adds regression coverage and doc cross-links from QA verification. ## Changes - `indexer/tests/security.rs`: `cg_cmc_orderbook_lcd_heavy_rate_limit_returns_429` — proves `/cg/orderbook` and `/cmc/orderbook/*` return **429** under the LCD-heavy governor when global `RATE_LIMIT_RPS=0`. - `docs/indexer-invariants.md`: list CG/CMC orderbook mirrors in rate-limit / LCD amplification rows; link **#278**. - `skills/AGENTS_INDEXER_API_LCD_SECURITY.md`: document CG/CMC orderbook on the LCD-heavy route list. ## Verification checklist (acceptance → evidence) | Item | Result | How | |------|--------|-----| | **AC1** `/cg/orderbook` and `/cmc/orderbook/*` use same per-IP LCD-heavy limit as native book | **PASS** | Code: `indexer/src/api/mod.rs` routes on `lcd_heavy_router` + `apply_rate_limit_layer(..., rate_limit_lcd_heavy_rps)`. Test: `cargo test --test security cg_cmc_orderbook_lcd_heavy_rate_limit_returns_429`. Live: 25× hammer on `/cg/orderbook?ticker_id=EMBER_CORAL` → 20× **200** then **429**; `/cmc/orderbook/EMBER_CORAL` shares drained heavy bucket (all **429** after CG burst); `/api/v1/overview` stayed **200** (general limiter not gating). | | **AC2** No LCD-fanout route on general limiter only (orderbook surface) | **PASS** (scoped) | Orderbook mirrors on heavy router. CG/CMC **tickers/summary** N+1 fanout tracked separately in **#288** (60s cache). | | Native book heavy throttle (regression) | **PASS** | `cargo test --test security lcd_heavy_route_rate_limit_returns_429` | | Test plan: hammer `/cg/orderbook` past heavy RPS | **PASS** | Live burst above + integration test | | Test plan: hammer `/cmc/orderbook/{pair}` | **PASS** | Live burst above + integration test | ## Commands run ```bash cargo test --test security lcd_heavy_route_rate_limit_returns_429 cg_cmc_orderbook_lcd_heavy_rate_limit_returns_429 -j 1 -- --test-threads=1 # Live (indexer on :3001, RATE_LIMIT_LCD_HEAVY_RPS=10, LocalTerra LCD) # 25× GET /cg/orderbook → 20×200 then 429; overview 25×200 ``` ## Follow-ups - Consider asserting `x-ratelimit-limit` on heavy 429 responses in tests if governor header semantics stabilize (live run showed `120` from layered governors).
PlasticDigits commented 2026-06-05 04:06:24 +00:00 (Migrated from gitlab.com)

Security review (automated)

Commit reviewed: 9e47f4daf74f9cba057c9517056db3f3deb20e63
Scope: 3 files — indexer/tests/security.rs (new integration test), docs/indexer-invariants.md, skills/AGENTS_INDEXER_API_LCD_SECURITY.md

Outcome: FINDINGS: 0 medium+

Security review: no medium+ findings on this diff.

Summary

This MR adds regression coverage and documentation cross-links for GitLab #278 (CG/CMC orderbook routes on lcd_heavy_router). The route move and apply_rate_limit_layer(..., rate_limit_lcd_heavy_rps) wiring are already on main; this change does not modify production indexer code.

Reviewed paths

Area Assessment
cg_cmc_orderbook_lcd_heavy_rate_limit_returns_429 Test-only; uses existing lcd_mock, seeded DB, and TestServer patterns identical to lcd_heavy_route_rate_limit_returns_429. No secrets, no attacker-controlled sinks, no new HTTP surface.
Doc / skill updates Descriptive only; no credentials or exploitable configuration.

Attack-surface check (diff-limited)

  • Injection / SSRF / authz: N/A — no new handlers or input parsing in this MR.
  • DoS / LCD amplification: Addressed by prior #278 production change; this MR only asserts 429 behavior under RATE_LIMIT_LCD_HEAVY_RPS with global limit disabled.
  • Secret leakage: None in added content.

Inline threads

None (no findings to anchor).


Reviewer: Cursor security automation · branch cursor/verify-issue-278-docs-test-1678

## Security review (automated) **Commit reviewed:** `9e47f4daf74f9cba057c9517056db3f3deb20e63` **Scope:** 3 files — `indexer/tests/security.rs` (new integration test), `docs/indexer-invariants.md`, `skills/AGENTS_INDEXER_API_LCD_SECURITY.md` **Outcome:** `FINDINGS: 0` medium+ Security review: **no medium+ findings** on this diff. ### Summary This MR adds regression coverage and documentation cross-links for GitLab #278 (CG/CMC orderbook routes on `lcd_heavy_router`). The route move and `apply_rate_limit_layer(..., rate_limit_lcd_heavy_rps)` wiring are already on `main`; this change does not modify production indexer code. ### Reviewed paths | Area | Assessment | |------|------------| | `cg_cmc_orderbook_lcd_heavy_rate_limit_returns_429` | Test-only; uses existing `lcd_mock`, seeded DB, and `TestServer` patterns identical to `lcd_heavy_route_rate_limit_returns_429`. No secrets, no attacker-controlled sinks, no new HTTP surface. | | Doc / skill updates | Descriptive only; no credentials or exploitable configuration. | ### Attack-surface check (diff-limited) - **Injection / SSRF / authz:** N/A — no new handlers or input parsing in this MR. - **DoS / LCD amplification:** Addressed by prior #278 production change; this MR only asserts 429 behavior under `RATE_LIMIT_LCD_HEAVY_RPS` with global limit disabled. - **Secret leakage:** None in added content. ### Inline threads None (no findings to anchor). --- *Reviewer: Cursor security automation · branch `cursor/verify-issue-278-docs-test-1678`*
PlasticDigits (Migrated from gitlab.com) merged commit bd90d82902 into main 2026-06-05 04:15:12 +00:00
PlasticDigits commented 2026-06-05 04:15:13 +00:00 (Migrated from gitlab.com)

mentioned in commit bd90d82902

mentioned in commit bd90d82902ab4ff4b08cdad655731b1d8a5e52bd
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!765
No description provided.