storage: add event ordering sanity check in Events.BatchStore#8469
storage: add event ordering sanity check in Events.BatchStore#8469prateushsharma wants to merge 1 commit intoonflow:masterfrom
Conversation
Before writing events to storage, validate that the flattened event slice is correctly ordered and internally consistent. Invariants enforced: - TransactionIndex must be monotonically non-decreasing - TransactionIndex is allowed to skip (transactions with no events are absent from the slice) - Within a transaction, EventIndex must be contiguous starting at 0 - The first event of each new transaction must have EventIndex == 0 Adds validateEventOrder([]flow.Event) error which runs in O(n) time with no allocations. Called inside BatchStore before the cache is updated or the batch is committed. Also fixes existing test fixtures in TestEventStoreRetrieve and TestEventStoreAndRemove where EventIndex was incorrectly set to match TransactionIndex instead of being zero-based within each transaction. Closes onflow#8454
📝 WalkthroughWalkthroughThis pull request introduces runtime validation in the event Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
One thing I want to flag proactively — the issue mentions we should scan historical execution data across past sporks to verify this invariant wasn't already violated before enforcing it as a hard error. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
storage/store/events_test.go (1)
425-487: Tighten invalid-case assertions to verify error provenance.
require.Erroris broad here; userequire.ErrorContains(..., "invalid event ordering")so failures are specifically tied to the new ordering guard.Proposed assertion pattern
- require.Error(t, err) + require.ErrorContains(t, err, "invalid event ordering")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@storage/store/events_test.go` around lines 425 - 487, The tests in events_test.go use generic require.Error assertions which don't verify the error comes from the ordering guard; update the four invalid-case subtests (the ones invoking s.BatchStore) to assert the error message contains the ordering sentinel (e.g., use require.ErrorContains(err, "invalid event ordering") or similar) instead of require.Error so the failure indicates the new ordering validation in BatchStore; locate the assertions around the BatchStore calls in the subtests titled "invalid: first event has EventIndex != 0", "invalid: non-contiguous EventIndex within same transaction", "invalid: new transaction starts with EventIndex != 0", and "invalid: decreasing TransactionIndex" and replace require.Error checks with require.ErrorContains referencing the ordering error text.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@storage/store/events.go`:
- Line 77: Replace the regular error construction with an irrecoverable
exception for invariant violations: in validateEventOrder(), change each
fmt.Errorf(...) call (the four validation-failure returns inside
validateEventOrder) to use irrecoverable.NewExceptionf(...) so these checks
raise irrecoverable exceptions, and likewise replace the wrapper return in
BatchStore() that currently uses fmt.Errorf(...) with
irrecoverable.NewExceptionf(...); keep the same formatted message and wrapped
error argument but use irrecoverable.NewExceptionf to signal an exceptional,
non-recoverable validation failure.
---
Nitpick comments:
In `@storage/store/events_test.go`:
- Around line 425-487: The tests in events_test.go use generic require.Error
assertions which don't verify the error comes from the ordering guard; update
the four invalid-case subtests (the ones invoking s.BatchStore) to assert the
error message contains the ordering sentinel (e.g., use
require.ErrorContains(err, "invalid event ordering") or similar) instead of
require.Error so the failure indicates the new ordering validation in
BatchStore; locate the assertions around the BatchStore calls in the subtests
titled "invalid: first event has EventIndex != 0", "invalid: non-contiguous
EventIndex within same transaction", "invalid: new transaction starts with
EventIndex != 0", and "invalid: decreasing TransactionIndex" and replace
require.Error checks with require.ErrorContains referencing the ordering error
text.
Before writing events to storage, validate that the flattened event slice is correctly ordered and internally consistent.
Invariants enforced:
Adds validateEventOrder([]flow.Event) error which runs in O(n) time with no allocations. Called inside BatchStore before the cache is updated or the batch is committed.
Also fixes existing test fixtures in TestEventStoreRetrieve and TestEventStoreAndRemove where EventIndex was incorrectly set to match TransactionIndex instead of being zero-based within each transaction.
Closes #8454
Summary by CodeRabbit