Indexer: enforce LCD-heavy route rate limits in production #363
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#363
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?
Parent
Gap analysis follow-up from GitLab #361 — register item H7 (LCD amplification on heavy routes).
Current codebase
rate_limit_lcd_heavy_rps(indexer/src/api/mod.rs:380-411).limit-book(deep/shallow/head/insert-hints),route/solve,route/solve/best,cg/orderbook,cmc/orderbook/{market_pair}.indexer/src/config.rs); envRATE_LIMIT_LCD_HEAVY_RPS. Setting0disables the extra layer (seeindexer/tests/security.rs).rate_limit_rpsstill applies separately.Why needed
These endpoints fan out multiple LCD
smartqueries per request. A single client (or integrator) can amplify load on the indexer and upstream LCD. Rate limiting is implemented but optional when set to 0 — production deployments need enforced defaults and operator guidance.Constraints / guardrails
/metricsscope (rejected in #361 parent triage).Relevant files
indexer/src/api/mod.rsindexer/src/config.rsindexer/tests/security.rsindexer/.env.example(if present) /docs/operator config docsscripts/qa/start-qa.sh(QA indexer env)Recommended direction
RATE_LIMIT_LCD_HEAVY_RPS=0inRunMode::Production(or warn + clamp to minimum), while keeping0for local/integration tests.limit-bookdepth params if abuse persists.start-qa/ deploy env template with a sane non-zero value.Acceptance criteria
Test plan
cd indexer && cargo test --test securitymake test-indexer-integrationcurlagainst/api/v1/route/solve/beston QA indexer; expect 429 after thresholdAttack / abuse test plan
route/solve/bestwith deep hop list → 429, no LCD stampede.Verification criteria
RATE_LIMIT_LCD_HEAVY_RPSin documented env template.make test-indexer-integrationgreen; security tests cover limiter enabled path.mentioned in issue #361
mentioned in commit
f29d2de543mentioned in merge request !873
Verified !873 at the source + test layer (this is my #355 rate-limiter territory).
The underlying lcd-heavy limiter mechanism was already proven live on this stack (#355 — true RPS restored after the per_second period fix). Note: I did not run the cargo security test here (indexer rebuild, disk at 93%); the clamp logic + the dedicated test are sound, and it'll exercise on the clean-host/CI run once the rust-1.83 CI break (#370) is fixed. Good from my side at the source layer.
mentioned in commit
823daf68eementioned in commit
3a757c7714mentioned in merge request !882
mentioned in commit
9de66003d1mentioned in commit
4d33747d7fmentioned in merge request !874
mentioned in commit
d72c80f2c8mentioned in merge request !883
mentioned in commit
2f9c79676amentioned in commit
ee7828f038Verification — GitLab #363 (LCD-heavy route rate limits in production)
Verified on
main@2f9c796(includes merged !873). No repo changes required.Acceptance criteria
indexer/src/config.rs:RUN_MODE=prodclampsRATE_LIMIT_LCD_HEAVY_RPS=0→ 10 withtracing::warn!; same for globalRATE_LIMIT_RPS→ 60. Unit:cargo test --lib config::tests::prod_forces_nonzero_rate_limits_when_zero. Startup log inmain.rsprints effective RPS.docs/operator-secrets.md(profiles, 429 shape, route cross-link),skills/AGENTS_INDEXER_API_LCD_SECURITY.md,docs/indexer-invariants.md,indexer/.env.example,docs/route-solver.md.cargo test --test security prod_lcd_heavy -j 1 -- --test-threads=1(2 tests); fullcargo test --test security→ 25/25.RATE_LIMIT_LCD_HEAVY_RPS=10,RATE_LIMIT_RPS=0from deploy template): 15 retail-pacedroute/solve/bestcurls @ 500 ms → all 200.http://127.0.0.1:5173/swapand/trade/EMBER-CORAL→ 200.Test plan / attack matrix
cd indexer && cargo test --test security -j 1 -- --test-threads=1→ 25 passedmake test-indexer-integrationfails onapi::db_orderbook_sim::tests::zero_reserve_mirror_returns_no_output(#369); not #363 scoperoute/solve/bestretry-after,x-ratelimit-limit: 20,x-ratelimit-remaining: 0/cg/orderbook?...→ 429scripts/deploy-dex-local.shwritesRATE_LIMIT_LCD_HEAVY_RPS=10; confirmed inindexer/.envaftermake setup-cloud-localterraNotes
RATE_LIMIT_RPS=0for Playwright/UI bursts; LCD-heavy stays at 10 unless both knobs are0in dev-only mode.RUN_MODE=prod/productiononly.Follow-ups
limit-bookif abuse persists.zero_reserve_mirror_returns_no_output(#369) somake test-indexer-integrationis green onmain.mentioned in merge request !891
mentioned in issue #379
mentioned in issue #424
mentioned in issue #597
mentioned in issue #694
mentioned in issue #717