Skip to content

op-supernode: Interop Message Validation#19051

Merged
axelKingsley merged 15 commits intodevelopfrom
supernode/messageValidation
Feb 5, 2026
Merged

op-supernode: Interop Message Validation#19051
axelKingsley merged 15 commits intodevelopfrom
supernode/messageValidation

Conversation

@axelKingsley
Copy link
Contributor

@axelKingsley axelKingsley commented Feb 2, 2026

What

Implements the actual Message Validation task of Interop. Does Not yet have any handling for the invalid blocks it discovers.
Invalid messages in blocks cause a chain halt, which is demonstrated by an acceptance test.

How

1. Acceptance Test (op-acceptance-tests)

  • New: TestSupernodeInteropInvalidMessageHalt - An end-to-end test that sends a valid initiating message, then an invalid executing message (with bogus LogIndex=9999), and verifies that interop validity halts at the invalid block while safe/unsafe heads continue advancing on the Virtual Nodes.

2. LogsDB Infrastructure (logdb.go)

  • New: Per-chain logs.DB instances managed by the interop activity for persisting L2 logs.
  • LogsDB interface abstracting the database operations
  • loadLogs - fetches receipts from each chain and stores logs at each timestamp
  • processBlockLogs - extracts logs from receipts, identifies executing messages, and seals blocks
  • verifyPreviousTimestampSealed - ensures sequential timestamp processing with chain continuity checks

3. Verification Logic (algo.go)

  • New: Core algorithm for validating cross-chain messages.
    verifyInteropMessages - for each chain, opens the block from logsDB and validates all executing messages
  • verifyExecutingMessage - checks that the referenced initiating message exists in the source chain's logsDB and that timestamp ordering is correct (initiating < executing)

4. Chain Container / Engine Controller

  • New: FetchReceipts(ctx, blockID) method added to:
    • ChainContainer interface
    • EngineController interface
    • l2Provider interface
    • This provides the interop activity access to transaction receipts needed for log extraction.

5. Result Types (types.go)

  • Result struct InvalidHeads map is populated with any blocks which are not valid during validation.

@wiz-inc-a178a98b5d
Copy link

wiz-inc-a178a98b5d bot commented Feb 2, 2026

Wiz Scan Summary

Scanner Findings
Vulnerability Finding Vulnerabilities -
Data Finding Sensitive Data -
Secret Finding Secrets -
IaC Misconfiguration IaC Misconfigurations -
SAST Finding SAST Findings 1 Medium
Software Management Finding Software Management Findings -
Total 1 Medium

View scan details in Wiz

To detect these findings earlier in the dev lifecycle, try using Wiz Code VS Code Extension.

@codecov
Copy link

codecov bot commented Feb 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.0%. Comparing base (348988d) to head (151ae07).
⚠️ Report is 15 commits behind head on develop.

Additional details and impacted files
@@            Coverage Diff             @@
##           develop   #19051     +/-   ##
==========================================
- Coverage     76.3%    76.0%   -0.4%     
==========================================
  Files          188      188             
  Lines        10943    10943             
==========================================
- Hits          8359     8326     -33     
- Misses        2438     2473     +35     
+ Partials       146      144      -2     
Flag Coverage Δ
cannon-go-tests-64 66.4% <ø> (-0.9%) ⬇️
contracts-bedrock-tests 81.7% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@axelKingsley axelKingsley changed the title Supernode/message validation op-supernode: Interop Message Validation Feb 2, 2026
This TDD test verifies the Interop Activity's behavior when an invalid
executing message is included in a chain:
- Validity should NEVER advance to include the invalid block's timestamp
- Safety and unsafety for both chains should continue to advance

The test sends a valid initiating message on chain A, then sends an invalid
executing message on chain B (with an impossible log index), and observes
that the Supernode correctly halts validity advancement while allowing
safety heads to progress.
This prepares the interop activity for implementing the actual interop
algorithm by:

1. Moving stubbed algorithm functions to algo.go:
   - loadLogs: loads and persists logs up to a timestamp
   - verifyInteropMessages: validates executing messages
   - invalidateBlock: handles invalid blocks

2. Adding per-chain logs.DB for log persistence:
   - Uses op-supervisor's logs.DB directly (no wrapper)
   - openLogsDB helper creates DB per chain in data directory
   - Full persistence support (data survives restart)

3. Extending ChainContainer interface with FetchReceipts:
   - Added to ChainContainer, EngineController, and l2Provider interfaces
   - Enables interop activity to fetch receipts for log processing

4. Initializing logsDBs in Interop activity:
   - Creates one logs.DB per chain on startup
   - Properly closes all logsDBs on Stop()

5. Unit tests for log persistence:
   - Tests for open/close, seal block, persistence
   - Tests for multiple chain isolation
This commit reorganizes the interop activity code and adds comprehensive tests:

1. File reorganization:
   - Renamed algo.go to logdb.go for log persistence code
   - Created new algo.go with just verifyInteropMessages
   - Moved invalidateBlock back to interop.go

2. Added LogsDB interface:
   - Defines interface around logs.DB for better testability
   - Enables mock implementations in unit tests

3. Added chain continuity check:
   - verifyPreviousTimestampSealed now returns previous block hash
   - loadLogs verifies block parent matches logsDB hash
   - Added ErrParentHashMismatch error

4. Expanded unit test coverage for logdb:
   - Tests for verifyPreviousTimestampSealed (activation/non-activation)
   - Tests for processBlockLogs (empty, with logs, errors)
   - Tests for loadLogs parent hash mismatch

5. Improved interop_test.go assertions:
   - Verify logsDBs population in constructor tests
   - Verify verifyFn receives correct args
   - Verify timestamps before activation return true
   - Verify Result.IsEmpty for various scenarios
   - Verify data retrieval after handleResult
   - Full cycle tests verify logsDB and L2Heads
This commit implements the core verification logic for the interop activity,
completing the TDD cycle for the InvalidMessageHalt acceptance test.

Key changes:
- Implement verifyInteropMessages to validate executing messages at each timestamp
- Verify initiating messages exist in source chain's logsDB via Contains query
- Verify timestamp ordering: initiating timestamp < executing timestamp
- Fix verifyPreviousTimestampSealed to accept any sealed block timestamp < ts
  (not just ts-1), handling block times > 1 second
- Add comprehensive unit tests for verification logic

The acceptance test now passes, demonstrating that:
- Valid cross-chain messages are verified successfully
- Invalid executing messages (wrong LogIndex) halt validity advancement
- Safe/unsafe heads continue to advance independently
Refactor tests for better organization and reduced redundancy:

- Create logdb_test.go for logsDB infrastructure tests
  - TestLogsDB_Persistence (data persistence, multi-chain isolation)
  - TestVerifyPreviousTimestampSealed (7 table-driven cases)
  - TestProcessBlockLogs (5 subtests)
  - TestLoadLogs_ParentHashMismatch

- Rewrite algo_test.go for verification algorithm only
  - TestVerifyInteropMessages_ValidBlocks (3 subtests)
  - TestVerifyInteropMessages_InvalidBlocks (5 subtests)
  - TestVerifyInteropMessages_Errors

- Consolidate interop_test.go for lifecycle/coordination
  - Merge related tests into table-driven patterns
  - Remove trivial getter/empty-case tests

Test count: 62 functions → 19 functions (~55 cases via subtests)
Removed 8 trivial tests that added no value.
@axelKingsley axelKingsley force-pushed the supernode/messageValidation branch from 55ec7d1 to 4ae5b66 Compare February 4, 2026 19:32
@axelKingsley axelKingsley marked this pull request as ready for review February 4, 2026 19:33
@axelKingsley axelKingsley requested a review from a team as a code owner February 4, 2026 19:33
@axelKingsley axelKingsley requested a review from jelias2 February 4, 2026 19:33
@axelKingsley axelKingsley force-pushed the supernode/messageValidation branch 4 times, most recently from a7bc995 to 0ab024e Compare February 4, 2026 20:43
@axelKingsley axelKingsley force-pushed the supernode/messageValidation branch from fb2860d to 309ed88 Compare February 5, 2026 00:35
For activation-after-genesis, the logsDB cannot handle non-sequential block
sealing (starting from block N instead of genesis). At activation timestamp:
- Skip loading logs (logsDB requires sequential blocks from genesis)
- Skip verification (can't verify cross-chain messages referencing pre-activation data)
- Trust blocks at activation time

Also allow empty logsDB at activation+blockTime (the first real timestamp).
@axelKingsley axelKingsley force-pushed the supernode/messageValidation branch from 4a9b39b to 0e10164 Compare February 5, 2026 17:49
@axelKingsley axelKingsley added this pull request to the merge queue Feb 5, 2026
Merged via the queue into develop with commit 50d789e Feb 5, 2026
79 checks passed
@axelKingsley axelKingsley deleted the supernode/messageValidation branch February 5, 2026 18:44
@geoknee geoknee added the A-op-supernode Area: op-supernode label Feb 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-op-supernode Area: op-supernode

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants