feat(indexer): reorg halt alerting and recovery preview (#362) #883
No reviewers
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!883
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "verify/issue-362-reorg-recovery-alerting"
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
reorg_alertmodule: structuredINDEXER_REORG_HALTstderr JSON + tracing targetindexer_reorg_halt, optionalREORG_ALERT_WEBHOOK_URLPOST on halt.indexer-reorg-recover.shdry-run with per-table row-impact counts; addmake indexer-reorg-recover HEIGHT=H [APPLY=1].last_indexed_block_hash(empty string) as post-recovery skip for reorg guard.Verification checklist
reorg_alert.rsemitsINDEXER_REORG_HALTJSON +target=indexer_reorg_halt; optional webhook viaREORG_ALERT_WEBHOOK_URL./scripts/indexer-reorg-recover.sh --height 100andmake indexer-reorg-recover HEIGHT=100swap_replay_is_idempotent_on_conflictintegration testdocs/runbooks/indexer-reorg-replay-dedup.mdsections updatedcd indexer && cargo test --libmake setup-indexer-postgres && make test-indexer-integrationindexer_ingestion_hardening8/8--applyAPPLY=1for make targetreorg_recovery_rewind_allows_catch_upintegration testFollow-ups
REORG_ALERT_WEBHOOK_URLin production orchestration / PagerDuty.block_height >= Hbehind a second--purge-derivedflag (out of scope for #362).changed the description
changed the description
Stale Security Review comment
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.
Reviewed by Cursor Bugbot for commit
8a92d56452. Configure here.MAKE APPLY zero still applies
Medium Severity
The
indexer-reorg-recovertarget passes--applywheneverAPPLYis any non-empty value because$(if $(APPLY),--apply,)treats0orfalseas set. A dry-run likeAPPLY=0mutatesindexer_stateinstead of previewing SQL.Reviewed by Cursor Bugbot for commit
8a92d56452. Configure here.changed this line in version 2 of the diff
added 1 commit
ae66cddd- fix: only pass --apply when APPLY=1 in indexer-reorg-recoverCompare with previous version
Security review — MR !883
Commit reviewed:
8a92d56452d1a75a36685fe839407905e4d6348cScope:
reorg_alerthalt signaling + optionalREORG_ALERT_WEBHOOK_URLwebhook;verify_checkpoint_unchangedempty-hash post-recovery skip;indexer-reorg-recover.shrow-impact preview /make indexer-reorg-recover; docs/tests.Outcome:
FINDINGS: 0medium+Inline threads: none (no medium+ issues on this diff)
Summary
Reviewed attacker-controlled input paths for the new/changed code:
REORG_ALERT_WEBHOOK_URL/post_webhookLCD_URLS/DATABASE_URL; 5s timeout; JSON body is indexer-generated (height, public block hashes, staticrecovery_cmd)verify_checkpoint_unchangedempty-hash skipindexer_state; skip is intentional post-rewind window documented in runbookindexer-reorg-recover.shSQL--heightonly^[0-9]+$,>= 1; table names hardcodedserde_jsonserialization; hashes are public chain dataRecovery remains CLI/operator-only (no new API rewind). Swap replay idempotency unchanged (
ON CONFLICT DO NOTHING).Note: Bugbot's
APPLY=0Makefile footgun is an operator ergonomics issue (localmakewith DB access), not a remote authz or injection finding — out of scope for this security pass.Security review: no medium+ findings on this diff.
changed the description
resolved all threads
added 32 commits
main52f5f10e- Merge origin/main into verify/issue-362-reorg-recovery-alertingCompare with previous version
Resolved merge conflicts with
main.Code: Unified
reorg_alert.rs— keptReorgHaltDetailsAPI +INDEXER_REORG_HALTstderr JSON from this branch, merged with main's webhook delivery and--cleanup-derivedrecovery path.poller.rsusesReorgHaltDetails::new; Makefile passesAPPLY=1/CLEANUP=1only when explicitly set.Script:
indexer-reorg-recover.shcombines main's row-impact preview + derived cleanup with compose-awarepostgres-psql.sh.Docs: Merged rate-limit secrets (#363) with reorg alerting docs (#362); runbook/incident template/invariants updated consistently.
Sanity:
cargo test --lib reorg_alert,cargo test --test reorg_alert_webhook,scripts/test-indexer-reorg-recover.sh— all pass.changed the description
Security review — MR !883
Commit reviewed:
52f5f10efe22a00f7e571932b7739df67a824e06Scope: Post-merge-conflict re-review of
reorg_alerthalt signaling (INDEXER_REORG_HALTstderr JSON, optionalREORG_ALERT_WEBHOOK_URLwebhook),verify_checkpoint_unchangedempty-hash post-recovery skip,indexer-reorg-recover.shcompose-aware psql + row-impact preview,make indexer-reorg-recover(APPLY=1/CLEANUP=1gating), integration tests, docs.Outcome:
FINDINGS: 0medium+Inline threads: none (no medium+ issues on this diff)
Summary
Re-traced attacker-controlled input paths on the updated diff (includes merge with
main):REORG_ALERT_WEBHOOK_URL/post_webhookLCD_URLS/DATABASE_URL; 10s timeout; JSON body is indexer-generated (height, public block hashes, staticrecovery_cmd)verify_checkpoint_unchangedempty-hash skipindexer_state; skip is intentional post-rewind window documented in runbookindexer-reorg-recover.shSQL--heightonly^[0-9]+$,>= 1; table names hardcoded;PREVis arithmeticserde_jsonserialization; hashes are public chain datamake indexer-reorg-recoverAPPLY=1/CLEANUP=1exact-match gating (fixes priorAPPLY=0footgun)Recovery remains CLI/operator-only (no new API rewind). Swap replay idempotency unchanged (
ON CONFLICT DO NOTHING).Prior review on
8a92d564still applies; merge-resolution changes (Makefile gating, compose psql helpers, stderr JSON/target rename) do not introduce new exploitable paths.Security review: no medium+ findings on this diff.
added 11 commits
mainee7828f0- Merge origin/main into verify/issue-362-reorg-recovery-alertingCompare with previous version
Resolved merge conflicts with
origin/main.Conflict:
docs/operator-secrets.md— kept the MR'sREORG_ALERT_WEBHOOK_URLenv row and adopted main's #363 rate-limit wording forRATE_LIMIT_RPS.Merge commit:
ee7828f. MR is mergeable again; not merged per conflict-fix workflow.changed the description
Security review — MR !883
Commit reviewed:
ee7828f0388ad031bd4e11dac3670500d7f85da4Scope:
reorg_alerthalt signaling (INDEXER_REORG_HALTstderr JSON, tracing targetindexer_reorg_halt, optionalREORG_ALERT_WEBHOOK_URLwebhook);verify_checkpoint_unchangedempty-hash post-recovery skip;indexer-reorg-recover.shcompose-aware psql helpers + row-impact preview;make indexer-reorg-recover(HEIGHTrequired,APPLY=1/CLEANUP=1exact-match gating); integration tests; docs.Outcome:
FINDINGS: 0medium+Inline threads: none (no medium+ issues on this diff)
Summary
Re-traced attacker-controlled input paths on the current diff (vs
origin/main):REORG_ALERT_WEBHOOK_URL/post_webhookLCD_URLS/DATABASE_URL; 10s timeout; JSON body is indexer-generated (height, public block hashes, staticrecovery_command)verify_checkpoint_unchangedempty-hash skipindexer_state; skip is intentional post-rewind window documented in runbookindexer-reorg-recover.shSQL--heightonly^[0-9]+$,>= 1; table names hardcoded;PREVis arithmeticserde_jsonserialization; hashes are public chain datamake indexer-reorg-recoverAPPLY=1/CLEANUP=1exact-match gating (fixes priorAPPLY=0footgun)Recovery remains CLI/operator-only (no new API rewind). Swap replay idempotency unchanged (
ON CONFLICT DO NOTHING).Prior reviews on
8a92d564and52f5f10still apply; latest merge commit adds no new exploitable surfaces beyond the scoped diff above.Security review: no medium+ findings on this diff.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issues.
Reviewed by Cursor Bugbot for commit
ee7828f038. Configure here.Upstream errors become not-found
Medium Severity
run_concurrent_candidate_evaluationsnow logs and skipsOk(Err(...))fromevaluate_candidateinstead of aborting. When every evaluated path returns a gateway error (e.g. LCD/router 502),evalsstays empty andsolve_global_best_executionresponds with 404no viable routerather than propagating 502.Reviewed by Cursor Bugbot for commit
ee7828f038. Configure here.Missing mirror skips LCD fallback
High Severity
The new zero-reserve short-circuit in
query_hybrid_sim_unifiedtreats any mirror withreserve_0 == 0orreserve_1 == 0as zero hop output.preload_mirrors_for_pairsuses the same zero reserves forMirrorFreshness::MissingReservesplaceholders when no snapshot row exists, so those hops now returnOk(0)instead of reaching the existing LCD fallback path.Reviewed by Cursor Bugbot for commit
ee7828f038. Configure here.added 1 commit
2ac33b06- fix(indexer): restore LCD fallback and gateway errors on route solveCompare with previous version
changed the description
mentioned in commit
0cf04e530e