fix(kona): load DependencySet from embedded registry, oracle as fallback#20377
Merged
fix(kona): load DependencySet from embedded registry, oracle as fallback#20377
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #20377 +/- ##
===========================================
- Coverage 76.3% 0.5% -75.9%
===========================================
Files 186 486 +300
Lines 10694 62756 +52062
===========================================
- Hits 8170 323 -7847
- Misses 2380 62433 +60053
+ Partials 144 0 -144
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
digorithm
reviewed
Apr 28, 2026
digorithm
reviewed
Apr 28, 2026
digorithm
reviewed
Apr 28, 2026
digorithm
reviewed
Apr 28, 2026
Move DependencySet, ChainDependency, MESSAGE_EXPIRY_WINDOW from kona-interop into kona-genesis to break the circular dep that would block kona-registry from embedding interop dependency sets. kona-interop re-exports the types so its public API is unchanged. Add a typed [interop] field to ChainConfig (Option<InteropConfig>, with serde(skip_serializing_if = "Option::is_none") so existing JSON round-trips do not gain "interop": null lines) and an aggregate_clusters helper that the registry build script will use to derive per-cluster depsets from the superchain-registry TOMLs. Also add an Arbitrary derive on the moved types so ChainConfig's existing Arbitrary derive keeps compiling once the field lands. Wire-format compatibility against op-supervisor's StaticConfigDependencySet is locked in by a fixture round-trip test and the rehearsal-0-bn-0.toml fixture exercises the [interop.dependencies] block end-to-end. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…nterop blocks Introduce kona_registry::DEPENDENCY_SETS, a HashMap<u64, DependencySet> keyed by L2 chain id, populated at compile time from etc/depsets.json. The build script resets the file to [] on every build, derives per-cluster DependencySets from each chain TOML's [interop.dependencies] block under KONA_BIND, and merges any KONA_CUSTOM_CONFIGS_DIR/depsets.json on top with cross-cluster collision detection. validate_depsets catches dangling chain id references at build time. Disjoint clusters (e.g. mainnet, sepolia, rehearsal-0-bn) stay disjoint: each cluster's chains map to that cluster's DependencySet, never a union. Also adds embedded_depsets_empty_by_default and extends custom_chain_is_loaded_when_enabled to assert cluster identity for the test fixture. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…le fallback BootInfo::load now consults kona_registry::DEPENDENCY_SETS before the preimage oracle, matching the existing embedded-first pattern for rollup_configs and l1_config. The on-chain PreimageOracle cannot supply DEPENDENCY_SET_KEY data, so the previous oracle-only path could not complete a real fault proof once interop is active. The lookup is extracted into load_dependency_set so it is unit-testable. When the proof's chain ids span two embedded clusters, the helper returns BootstrapError::CrossDependencySetProof rather than silently unioning them (which would let cross-cluster messages validate). Partial coverage and empty embedded maps fall back to the oracle, preserving existing host/test flows. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tightens load_dependency_set: if any chain id in the proof has an embedded DependencySet, all chain ids must have one. Previously, partial coverage fell back to the oracle for the missing chains, which would let an attacker insert non-cluster chains via oracle data while we trusted the rest from the embedded registry. Adds BootstrapError::PartialDependencySetCoverage and replaces the old fallback path with a hard error. Oracle fallback now only applies when no chain id is in any embedded depset. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Trust the build pipeline (aggregate_clusters / superchain-registry / custom-config validation) for embedded depset consistency. The boot helper now does a single HashMap lookup against chain_ids[0]; if the first chain id is in any embedded cluster, the build script's lazy_static loop guarantees we get the correct cluster. If not, fall back to the preimage oracle for dev/test flows. Drops the cross-cluster and partial-coverage checks (and their BootstrapError variants and tests). Cross-cluster and partial proofs still fail downstream when interop message validation rejects messages whose source chain isn't in the chosen depset's dependencies — same outcome, later detection, far cheaper inside cannon (no Vec allocations, single hashmap lookup, ~25 lines vs ~120). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The kona-interop depset.rs module became a single-line `pub use` of kona-genesis types after the type-cycle break. Inline the re-export into lib.rs and remove the file — there's no local definition to anchor a separate module the way SUPER_ROOT_VERSION anchors constants.rs. Public API (`kona_interop::DependencySet`, `kona_interop::ChainDependency`) is unchanged; only the internal `kona_interop::depset::*` submodule path goes away, and no in-tree consumer used that path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds an explicit HasChain-equivalent check to check_single_dependency on both ends of every cross-chain edge, mirroring op-supervisor's LinkChecker.CanExecute semantics. The pre-existing comment claiming this was "enforced implicitly by the graph constructor and the provider" was aspirational — nothing in the resolve path consulted the dependency set for membership, so a proof spanning chains from two disjoint embedded clusters would silently validate cross-cluster messages. MessageGraph now carries `&'a DependencySet` and surfaces a new MessageGraphError::ChainNotInDependencySet variant when either end of an edge is missing. proof-interop's consolidation driver passes the boot-info depset through. Test module gains a OnceLock-backed default_dep_set() helper so existing assertions are unchanged, plus two dedicated tests covering the executing-chain and initiating-chain rejection paths. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The fixture and test were framed as a cross-language wire-format check against op-supervisor. That framing isn't right: kona's depset format is its own, and op-supervisor (and op-supernode) may diverge. Rename the fixture and test to reflect what's actually being tested — that a DependencySet can be JSON round-tripped through kona's serde derives. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
debug_assert_eq! was silent in release builds, so a bug in aggregate_clusters or merge_custom_depsets that produced overlapping clusters with differing contents would have been masked in production binaries — last-insert-wins, no panic. Tighten to assert_eq! since the check runs once at lazy_static init. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
aggregate_clusters always emits None for override_message_expiry_window because no chain TOML field is read for it. Document this and the schema-extension contract. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ests The graph test module builds DependencySets directly via BTreeMap, which trips clippy::zero_sized_map_values since ChainDependency is empty. Match the allow already on DependencySet itself, and apply rustfmt.
768aed5 to
08dd2b2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BootInfo::load(kona-proof-interop) loaded the dependency set only from the preimage oracle, which the real on-chainPreimageOraclecannot supply (local(8)), so a fault-proof program couldn't complete once interop is active. This adds the embedded-first / oracle-fallback pattern already used forrollup_configsandl1_config:kona_registry::DEPENDENCY_SETSis now aHashMap<u64, DependencySet>keyed by L2 chain id and populated at compile time frometc/depsets.json. The build script aggregates oneDependencySetper cluster from the superchain-registry's[interop.dependencies]blocks (validating cluster consistency and rejecting dangling members) and merges any custom depsets fromKONA_CUSTOM_CONFIGS_DIR/depsets.jsonwith cross-cluster collision detection.BootInfo::loaddoes a single embedded lookup against the proof's first chain id and falls back to the oracle when the binary has no embedded depset for that chain. Cross-cluster and partial-coverage proofs aren't checked at boot — they fail downstream when interop message validation rejects messages whose source chain isn't in the chosen depset'sdependenciesmap.To break the
kona-interop ↔ kona-registrydependency cycle,DependencySet/ChainDependency/MESSAGE_EXPIRY_WINDOWmove tokona-genesis(re-exported bykona-interopfor API compatibility).ChainConfiggains an optional[interop]field withserde(skip_serializing_if = "Option::is_none")so existing JSON round-trips are unchanged. Wire compatibility with op-supervisor'sStaticConfigDependencySetis locked in by a fixture round-trip test.