Skip to content

Sec-107: Enforce inbound OPP envelope chaining - #499

Merged
heifner merged 1 commit into
masterfrom
fix/sec-107-enforce-inbound-chain
Jul 9, 2026
Merged

heifner merged 1 commit into
masterfrom
fix/sec-107-enforce-inbound-chain

Conversation

@heifner

@heifner heifner commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Completes SEC-107 by flipping the depot's inbound envelope-chain verification from staged to enforced, now that both outposts self-chain per stream (wire-ethereum #128/#132 and wire-solana #364, all merged).

sysio.msgch::apply_consensus records each accepted envelope's canonical epoch digest as the per-outpost chain tip and verifies continuity, but it previously:

  • STAGED an empty previous_envelope_hash (accepted + logged) because not every outpost chained yet, and
  • carried an INTERIM SVM-only cross-stream fallback that accepted the Solana outpost's pre-SEC-114 link to the depot's own last outbound emit.

Both are removed. Once a tip is recorded for an outpost, previous_envelope_hash must be exactly the 32-byte tip; an empty (non-genesis), wrong-length, all-zero, or non-matching value is a chain break and the envelope is dropped before dispatch, consensus record, or cleanup (delivery rows stay for audit/dispute), per the never-throw convention. to_checksum256_exact already rejects any non-32-byte field, so wrong-length and all-zero values are breaks too, matching the outposts' canonical-form enforcement. An empty prev is valid only at genesis (no tip yet), and an outpost's first accepted envelope still bootstraps.

Validation

  • sysio_msgch_chain_tests (7), sysio_dispatch_tests (39), sysio_dispute_tests (19) pass under sys-vm. The chain suite's staged-empty-accept case flips to a rejection and the SVM cross-stream-accept case flips to a rejection (both now drop, tip unmoved).
  • flow-swap-from-wire passes 15/15 against the enforced depot with the merged ETH and Solana outposts; zero DROP envelope chain break. SOL->WIRE and ETH->WIRE both verified chaining per stream (genesis-empty, then keccak256 of the prior emit).

ABI unchanged; no reference-data regen (msgch is not in the deep-mind/snapshot reference chains).

Follow-ups

  • SEC-118 (per-digest consensus counting on both outposts) remains open.
  • SEC-106 finalizeEpoch gating (ETH legacy path) remains open.

apply_consensus verified the per-outpost envelope chain but STAGED the empty-previous-hash case (accepted + logged, because not every outpost chained yet) and carried an INTERIM SVM cross-stream fallback that bridged the pre-SEC-114 Solana outpost. Both outposts now self-chain per stream -- EVM via OPP.prevEpochHash, SVM via previous_outbound_epoch_hash (wire-solana #364) -- so once a chain tip is recorded for an outpost, an empty or non-continuing previous_envelope_hash is a chain break: the envelope is dropped before dispatch, consensus record, or cleanup, exactly as a non-matching hash already was. An empty prev-hash remains valid only at genesis (before any tip), and an outpost's first accepted envelope still bootstraps. to_checksum256_exact already rejects any non-32-byte field, so wrong-length and all-zero values are breaks too, matching the outposts' canonical-form enforcement.

Both the staged empty-accept branch and the SVM cross-stream fallback are removed, collapsing the check to a single "must equal the recorded tip." Recompiles sysio.msgch.wasm; ABI unchanged.
@heifner
heifner requested a review from huangminghuang July 9, 2026 19:09
@heifner
heifner merged commit 8771433 into master Jul 9, 2026
11 checks passed
@heifner
heifner deleted the fix/sec-107-enforce-inbound-chain branch July 9, 2026 19:40
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.

2 participants