fix(indexer): per-(tx,pair) swap ordinal so same-pair swaps aren't collapsed (#287) #752

Merged
Brouie merged 1 commit from qa/287-swap-per-tx-ordinal into main 2026-06-05 03:19:10 +00:00
Brouie commented 2026-06-05 01:47:48 +00:00 (Migrated from gitlab.com)

Follow-up on #287, your approved per-tx swap-ordinal direction.

The bug: insert_swap used ON CONFLICT (tx_hash, pair_id) DO NOTHING, so a tx emitting two swaps on the same pair (a route that revisits a pair, or batched swaps) kept only the first and silently dropped the rest.

Fix:

  • ParsedSwap gets a deterministic swap_index (0-based, per (tx, pair), from parser walk order).
  • New migration: ADD swap_index (backfilled row_number()-1 OVER (PARTITION BY tx_hash, pair_id ORDER BY id)), DROP the old (tx_hash, pair_id) unique index, CREATE the (tx_hash, pair_id, swap_index) one.
  • insert_swap binds swap_index + ON CONFLICT (tx_hash, pair_id, swap_index); trade_exists scopes to it. Each swap now stores its own row/id (your "unique id per swap").

Tests: parse_swaps_assigns_per_pair_swap_index (two same-pair swaps -> 0,1; different pair restarts at 0); full indexer suite green (the one red is the pre-existing api_hooks::hooks_list_returns_rows shared-test-DB parallelism flake, passes single-threaded, untouched here).

Honest scope note — the fill->swap linkage swap_id_for_tx_pair still resolves MIN(id), so for the rare multi-swap-same-pair tx the fills point at the first swap. That's a net improvement over today (the swaps themselves are no longer lost), but making the linkage ordinal-correct needs the parser to carry the swap ordinal onto each fill (no LCD msg_index to lean on) — flagging it as the focused follow-up rather than bolting a half-association in here.

Migration is additive + idempotent; it only takes effect when the new binary is deployed (the running indexer keeps its old conflict key until then). No closing keyword.

Follow-up on #287, your approved per-tx swap-ordinal direction. The bug: `insert_swap` used `ON CONFLICT (tx_hash, pair_id) DO NOTHING`, so a tx emitting two swaps on the same pair (a route that revisits a pair, or batched swaps) kept only the first and silently dropped the rest. Fix: - `ParsedSwap` gets a deterministic `swap_index` (0-based, per `(tx, pair)`, from parser walk order). - New migration: `ADD swap_index` (backfilled `row_number()-1 OVER (PARTITION BY tx_hash, pair_id ORDER BY id)`), `DROP` the old `(tx_hash, pair_id)` unique index, `CREATE` the `(tx_hash, pair_id, swap_index)` one. - `insert_swap` binds `swap_index` + `ON CONFLICT (tx_hash, pair_id, swap_index)`; `trade_exists` scopes to it. Each swap now stores its own row/id (your "unique id per swap"). Tests: `parse_swaps_assigns_per_pair_swap_index` (two same-pair swaps -> 0,1; different pair restarts at 0); full indexer suite green (the one red is the pre-existing `api_hooks::hooks_list_returns_rows` shared-test-DB parallelism flake, passes single-threaded, untouched here). Honest scope note — the fill->swap linkage `swap_id_for_tx_pair` still resolves `MIN(id)`, so for the rare multi-swap-same-pair tx the fills point at the first swap. That's a net improvement over today (the swaps themselves are no longer lost), but making the linkage ordinal-correct needs the parser to carry the swap ordinal onto each fill (no LCD msg_index to lean on) — flagging it as the focused follow-up rather than bolting a half-association in here. Migration is additive + idempotent; it only takes effect when the new binary is deployed (the running indexer keeps its old conflict key until then). No closing keyword.
Brouie commented 2026-06-05 01:47:59 +00:00 (Migrated from gitlab.com)

mentioned in issue #287

mentioned in issue #287
PlasticDigits commented 2026-06-05 03:19:10 +00:00 (Migrated from gitlab.com)

mentioned in commit 39a681f82f

mentioned in commit 39a681f82fa21a804c2609a64aa46ab452ecf8a4
PlasticDigits (Migrated from gitlab.com) merged commit 39a681f82f into main 2026-06-05 03:19:10 +00:00
PlasticDigits commented 2026-06-05 09:47:03 +00:00 (Migrated from gitlab.com)

mentioned in merge request !780

mentioned in merge request !780
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!752
No description provided.