Skip to content

Conversation

@hudsonhrh
Copy link

@hudsonhrh hudsonhrh commented Feb 7, 2026

Each iteration of the offchain trigger loop in handle_offchain_triggers creates a fresh BlockState with vid_seq reset to RESERVED_VIDS (100). When two or more offchain triggers (e.g. file/ipfs data sources) fire in the same block and write to the same entity table, they produce identical VIDs, causing a unique constraint violation.

This threads vid_seq from the onchain EntityCache through the offchain trigger loop so each trigger continues the sequence where the previous one left off. Also adds unit tests demonstrating both the collision and the fix.

There are tests for illustrative purposes showing the bug and the fix

Fixes #6335

When specVersion >= 1.3.0, VIDs are computed deterministically as
(block_number << 32) + vid_seq. Each offchain trigger in
handle_offchain_triggers creates a fresh EntityCache with vid_seq
reset to RESERVED_VIDS (100). When multiple file data source triggers
fire in the same block and write to the same entity table, they
produce identical VIDs, causing PostgreSQL primary key violations:

  "duplicate key value violates unique constraint task_metadata_pkey"

Fix: Pass the onchain EntityCache's final vid_seq into
handle_offchain_triggers and accumulate it across loop iterations,
so each offchain trigger continues the sequence from where the
previous one left off.
Two tests demonstrate the bug where multiple offchain triggers (e.g. file
data sources) in the same block each create a fresh EntityCache with
vid_seq reset to RESERVED_VIDS (100), producing duplicate VIDs that
violate the primary key constraint.

- offchain_trigger_vid_collision_without_fix: proves VIDs collide
- offchain_trigger_vid_no_collision_with_fix: proves threading vid_seq
  across triggers prevents collisions
@hudsonhrh hudsonhrh marked this pull request as ready for review February 7, 2026 21:07
@hudsonhrh hudsonhrh force-pushed the fix/vid-seq-offchain-collision branch from 20bba68 to f24825a Compare February 7, 2026 21:21
@hudsonhrh
Copy link
Author

@lutter fixed the styling issue with 8ab10ca
thanks for triggering the workflow run

@lutter
Copy link
Collaborator

lutter commented Feb 11, 2026

@lutter fixed the styling issue with 8ab10ca thanks for triggering the workflow run

No Problem. One thing I am not entirely sure about is that now everywhere an EntityCache is created, we need to remember to preserve the vid_seq. I would like to have something more automatic that is harder to screw up. Maybe we introduce an EntityCacheBuilder or some such and have as_modifications return that. The builder would then be responsible for preserving state from one cache to the next. But I haven't fully wrapped my head around how the cache and its data move through the code.

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.

Bug: Duplicate VID constraint violation when multiple offchain triggers fire in the same block

2 participants