docs: verify #287 swap_events per-tx swap_index dedup (doc drift) #780

Merged
PlasticDigits merged 1 commit from cursor/gitlab-issue-verification-e1f4 into main 2026-06-05 10:00:28 +00:00
PlasticDigits commented 2026-06-05 09:47:01 +00:00 (Migrated from gitlab.com)

Summary

Verification QA for GitLab #287 — swap_events ON CONFLICT collapsing two same-pair swaps in one tx.

Implementation status: Already shipped on main via MR !752 (swap_index column, unique key (tx_hash, pair_id, swap_index), parser ordinals, fill linkage via #316). This MR only fixes stale docs/guardrails that still described the old (tx_hash, pair_id) dedup key.

Doc updates:

  • docs/indexer-invariants.md — swap dedup invariant row
  • docs/runbooks/indexer-reorg-replay-dedup.md — replay dedup facts
  • skills/AGENTS_INDEXER_INGESTION_HARDENING.md — do-not-regress note
  • indexer/scripts/seed-charts-integration.sql — seed ON CONFLICT clause
  • gaps/GAP_1780200149.md — replay idempotency note

Verification checklist

Acceptance criterion Result How verified
A tx with two real swaps on the same pair stores two rows PASS Unit: cargo test parse_swaps_assigns_per_pair_swap_index --lib → ok. Integration: cargo test --test limit_fill_swap_linkage -j 1 -- --test-threads=1 inserts swap_index 0 and 1 → distinct ids. DB: SELECT COUNT(*) FROM swap_events WHERE tx_hash='TX316_MULTI_SWAP_SAME_PAIR' → 2 rows (swap_index 0, 1).
Genuine duplicate-delivery of the same swap is still deduped PASS Schema: unique index idx_swap_events_tx_hash_pair_id_swap_index. Manual SQL on dex_indexer_test: second INSERT … ON CONFLICT (tx_hash, pair_id, swap_index) DO NOTHING for same key returned 0 rows; COUNT(*) → 1. Code: insert_swap + trade_exists(pool, tx_hash, pair_id, swap_index) in parser.
Limit fill → swap linkage (comment thread #316) PASS cargo test parse_limit_order_fills_assigns_swap_index_per_pair_swap --lib → ok. limit_fill_swap_linkage resolves fills by swap_index, not MIN(id).

Issue

Leave #287 open until this doc MR merges (implementation already on main).


Note

Low Risk
Markdown and SQL fixture changes only; no indexer parser, migration, or API code in this diff.

Overview
Doc drift fix for GitLab #287 — runtime already uses per-tx swap_index and unique (tx_hash, pair_id, swap_index); this MR only updates text and seeds that still said (tx_hash, pair_id).

Swap dedup narrative is updated in docs/indexer-invariants.md, docs/runbooks/indexer-reorg-replay-dedup.md, and skills/AGENTS_INDEXER_INGESTION_HARDENING.md to document the 0-based per-pair ordinal, that multiple same-pair swaps in one tx are distinct rows, and that replay still dedupes identical delivery. The gap note in gaps/GAP_1780200149.md matches the same replay idempotency key.

Charts integration seed (indexer/scripts/seed-charts-integration.sql) inserts swap_index 0 and uses ON CONFLICT (tx_hash, pair_id, swap_index) DO NOTHING so re-seeds stay valid against the widened unique index.

Reviewed by Cursor Bugbot for commit d3f0a6c33e. Bugbot is set up for automated code reviews on this repo. Configure here.

## Summary Verification QA for [GitLab #287](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/287) — `swap_events` ON CONFLICT collapsing two same-pair swaps in one tx. **Implementation status:** Already shipped on `main` via MR !752 (`swap_index` column, unique key `(tx_hash, pair_id, swap_index)`, parser ordinals, fill linkage via #316). This MR only fixes **stale docs/guardrails** that still described the old `(tx_hash, pair_id)` dedup key. **Doc updates:** - `docs/indexer-invariants.md` — swap dedup invariant row - `docs/runbooks/indexer-reorg-replay-dedup.md` — replay dedup facts - `skills/AGENTS_INDEXER_INGESTION_HARDENING.md` — do-not-regress note - `indexer/scripts/seed-charts-integration.sql` — seed `ON CONFLICT` clause - `gaps/GAP_1780200149.md` — replay idempotency note ## Verification checklist | Acceptance criterion | Result | How verified | |----------------------|--------|--------------| | A tx with two real swaps on the same pair stores two rows | **PASS** | Unit: `cargo test parse_swaps_assigns_per_pair_swap_index --lib` → ok. Integration: `cargo test --test limit_fill_swap_linkage -j 1 -- --test-threads=1` inserts `swap_index` 0 and 1 → distinct ids. DB: `SELECT COUNT(*) FROM swap_events WHERE tx_hash='TX316_MULTI_SWAP_SAME_PAIR'` → **2** rows (`swap_index` 0, 1). | | Genuine duplicate-delivery of the same swap is still deduped | **PASS** | Schema: unique index `idx_swap_events_tx_hash_pair_id_swap_index`. Manual SQL on `dex_indexer_test`: second `INSERT … ON CONFLICT (tx_hash, pair_id, swap_index) DO NOTHING` for same key returned 0 rows; `COUNT(*)` → **1**. Code: `insert_swap` + `trade_exists(pool, tx_hash, pair_id, swap_index)` in parser. | | Limit fill → swap linkage (comment thread #316) | **PASS** | `cargo test parse_limit_order_fills_assigns_swap_index_per_pair_swap --lib` → ok. `limit_fill_swap_linkage` resolves fills by `swap_index`, not `MIN(id)`. | ## Issue Leave [#287](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/287) open until this doc MR merges (implementation already on `main`). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Markdown and SQL fixture changes only; no indexer parser, migration, or API code in this diff. > > **Overview** > **Doc drift fix for GitLab #287** — runtime already uses per-tx **`swap_index`** and unique `(tx_hash, pair_id, swap_index)`; this MR only updates text and seeds that still said `(tx_hash, pair_id)`. > > **Swap dedup narrative** is updated in `docs/indexer-invariants.md`, `docs/runbooks/indexer-reorg-replay-dedup.md`, and `skills/AGENTS_INDEXER_INGESTION_HARDENING.md` to document the 0-based per-pair ordinal, that multiple same-pair swaps in one tx are distinct rows, and that replay still dedupes identical delivery. The gap note in `gaps/GAP_1780200149.md` matches the same replay idempotency key. > > **Charts integration seed** (`indexer/scripts/seed-charts-integration.sql`) inserts **`swap_index` 0** and uses `ON CONFLICT (tx_hash, pair_id, swap_index) DO NOTHING` so re-seeds stay valid against the widened unique index. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit d3f0a6c33e21b765408685698b5a8b6ed0fbeaca. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
ghost1 commented 2026-06-05 09:47:08 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
ghost1 commented 2026-06-05 09:47:13 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-05 09:47:22 +00:00 (Migrated from gitlab.com)

mentioned in issue #287

mentioned in issue #287
PlasticDigits commented 2026-06-05 09:51:53 +00:00 (Migrated from gitlab.com)

Security review

Commit reviewed: d3f0a6c

Scope: 5 files — documentation/runbook/gap/skill text updates aligning swap_events dedup narrative with (tx_hash, pair_id, swap_index); indexer/scripts/seed-charts-integration.sql fixture adds swap_index column and widens ON CONFLICT to match the existing schema (already on main via !752 / #287).

Method: Full MR diff reviewed. No prior security-review threads on this MR. Each changed path traced for attacker-controlled input → sink (injection, authz, SSRF, XSS, secret leakage, unsafe deserialization). Unchanged runtime code (indexer parser, API, migrations) referenced only for context.

Outcome: FINDINGS: 0 medium+

Inline threads: none (no findings to anchor)

Notes

  • Docs-only delta: docs/indexer-invariants.md, docs/runbooks/indexer-reorg-replay-dedup.md, gaps/GAP_1780200149.md, skills/AGENTS_INDEXER_INGESTION_HARDENING.md — static markdown; no executable surface.
  • SQL seed fixture: seed-charts-integration.sql is run only in CI/local charts integration (scripts/test-charts-integration.sh, .github/workflows/test.yml) against dev/test Postgres. Inserts use hardcoded literals (swap_index = 0, fixed tx_hash); ON CONFLICT target change is schema-alignment, not user input. No injection path or production exposure.
  • No new dependencies, secrets, auth boundaries, or network calls introduced by this diff.

Security review: no medium+ findings on this diff.

## Security review **Commit reviewed:** [`d3f0a6c`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/commit/d3f0a6c33e21b765408685698b5a8b6ed0fbeaca) **Scope:** 5 files — documentation/runbook/gap/skill text updates aligning `swap_events` dedup narrative with `(tx_hash, pair_id, swap_index)`; `indexer/scripts/seed-charts-integration.sql` fixture adds `swap_index` column and widens `ON CONFLICT` to match the existing schema (already on `main` via !752 / #287). **Method:** Full MR diff reviewed. No prior security-review threads on this MR. Each changed path traced for attacker-controlled input → sink (injection, authz, SSRF, XSS, secret leakage, unsafe deserialization). Unchanged runtime code (indexer parser, API, migrations) referenced only for context. **Outcome:** `FINDINGS: 0` medium+ **Inline threads:** none (no findings to anchor) ### Notes - **Docs-only delta:** `docs/indexer-invariants.md`, `docs/runbooks/indexer-reorg-replay-dedup.md`, `gaps/GAP_1780200149.md`, `skills/AGENTS_INDEXER_INGESTION_HARDENING.md` — static markdown; no executable surface. - **SQL seed fixture:** `seed-charts-integration.sql` is run only in CI/local charts integration (`scripts/test-charts-integration.sh`, `.github/workflows/test.yml`) against dev/test Postgres. Inserts use hardcoded literals (`swap_index = 0`, fixed `tx_hash`); `ON CONFLICT` target change is schema-alignment, not user input. No injection path or production exposure. - **No new dependencies, secrets, auth boundaries, or network calls** introduced by this diff. Security review: no medium+ findings on this diff.
PlasticDigits commented 2026-06-05 10:00:28 +00:00 (Migrated from gitlab.com)

mentioned in commit 1c4ad9212d

mentioned in commit 1c4ad9212d5a99662730d2be7832e33924ef01b3
PlasticDigits (Migrated from gitlab.com) merged commit 1c4ad9212d into main 2026-06-05 10:00:28 +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!780
No description provided.