Skip to content

feat(onchain-analytics): check merge-key duplicates after every ingestion run - #79

Open
thalescb wants to merge 1 commit into
masterfrom
feat/onchain-range-dup-check
Open

thalescb wants to merge 1 commit into
masterfrom
feat/onchain-range-dup-check

Conversation

@thalescb

Copy link
Copy Markdown
Collaborator

Adds a merge-key duplicate check that runs after every daily ingestion, backfill and repair, scoped to the keys that run wrote.

This settles how often the duplicate check runs. Every ingestion checks its own range, and the full-history scan (verifyMergeKeyUniqueness) is only needed by hand after a migration or the first full-history load.

What changes

Before After
After a daily run, backfill or repair No duplicate check The keys the run wrote are counted over a window wider than the MERGE window. A repeated key, or a check that cannot run, fails the run (non-zero exit and the existing Slack failure alert).
Long backfill n/a One statement per written month, so each stays under the 10 GiB per-query ceiling

The comment on twinWindowFor in window.ts explains why the window reaches past the MERGE window and how far. No schema change: it uses existing columns on the base tables and does not need the all-history views.

Cost

Estimated, to be confirmed with a dry run once RawLogs exists. The project's estimate for RawLogs is 719.4M rows for the full history of all four chains. Without Fuse, now out of scope, that is 584M rows, and that is a ceiling. Spread over about six years (~8M rows a month), at ~100 bytes read per row:

  • Daily run: ~5 GB across RawLogs and Transactions (~10 GB if recent months are twice the average), $0.03 to $0.06 a run.
  • Backfill or repair: ~7 GB per month written.
  • Manual full-history scan: ~88 GB, which needs MAX_BYTES_BILLED_PER_JOB raised for that one run.

Transactions is assumed to hold at most half as many rows as RawLogs.

Two schema options would cut this further, and both are cheapest before RawLogs is created: storing tx_hash as 32 bytes instead of a hex string (~36% less read on every query), and an 8-byte merge-key fingerprint column (full-history scan of RawLogs from ~58 GB to ~9 GB). Neither is included here.

Validation

  • npm run verify:local in pipeline-v5: lint, typecheck, build check, 555 unit and 21 known-failure tests pass.
  • test/unit/range-duplicate-check.test.ts seeds an April copy of a key the run writes in June. It fails the run for daily, backfill and repair. The tests go red when the check is unwired, when the window is narrowed to the MERGE window, and when the month split is removed.
  • Nothing has been run against BigQuery. Nothing runs in production until daily ingestion is commissioned.

Start review at verifyWrittenRangeUniqueness and the run-scoped branch of duplicateReport in src/bq.ts, then twinWindowFor and monthSlices in src/window.ts. Most of the line count is the test file.

Refs #40.

…tion run

After a daily run, backfill or repair, count every copy of the keys the run wrote over a window wider than the MERGE window, one statement per written month. A repeated key, or a check that cannot run, fails the run. The full-history scan stays a manual step after a migration or the first full load.
@thalescb thalescb mentioned this pull request Oct 28, 2026
6 of 9 tasks
@thalescb
thalescb requested a review from sirpy October 28, 2026 21:01

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant