Skip to content

fix: bound receipt enrichment updates to repaired blocks - #289

Draft
kuyziss wants to merge 1 commit into
mainfrom
agent/bound-receipt-enrichment
Draft

fix: bound receipt enrichment updates to repaired blocks#289
kuyziss wants to merge 1 commit into
mainfrom
agent/bound-receipt-enrichment

Conversation

@kuyziss

@kuyziss kuyziss commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • track the exact block numbers whose receipts were successfully fetched
  • enrich transactions only for those blocks instead of the full min..max span
  • constrain both sides of the PostgreSQL join and include block_timestamp, matching the partition key

Issue

In production, the Moderato receipt backfill repeatedly times out while running:

UPDATE txs
SET gas_used = r.gas_used, fee_payer = r.fee_payer
FROM receipts r
WHERE txs.block_num = r.block_num
  AND txs.idx = r.tx_idx
  AND txs.block_num >= $1
  AND txs.block_num <= $2
  AND txs.gas_used IS NULL;

The repair worker can select sparse missing blocks. Collapsing those blocks into a single lowest/highest range makes PostgreSQL examine every transaction and receipt between them, potentially across a large portion of the chain. Both tables are partitioned by block_timestamp, but the join omitted that key. Production showed sustained PostgreSQL temporary-file throughput up to roughly 140 MB/s, approximately 1 GB temporary files, and the statement being cancelled by the 60-second timeout before the worker retried it.

The currently deployed production image also predates #277, which added the durable bounded receipt-repair queue and stopped treating legitimate empty blocks as missing receipts. Rolling out a build containing both changes addresses selection/retry behavior and keeps genuine repair enrichment bounded.

Fix

The enrichment query now receives the deduplicated exact block list, limited by the existing 100-block receipt-repair batch. It applies block_num = ANY($1) to both tables and joins on block_timestamp in addition to block number and transaction index. This allows PostgreSQL to use the per-partition indexes and prevents sparse repair work from becoming a broad range scan.

No database migration or new production index is required.

Impact

Receipt repair remains functionally identical, but transaction enrichment is proportional to the blocks actually repaired. This should eliminate the recurring statement timeouts and high temporary-file I/O caused by the broad range join.

Validation

  • cargo fmt --check
  • cargo test --lib (409 passed)
  • cargo clippy --lib -- -D warnings

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