cherry pick upstream up to 318838e9841de8865ecd4a580e66d99d7fa98a78#49
cherry pick upstream up to 318838e9841de8865ecd4a580e66d99d7fa98a78#49ClaytonNorthey92 wants to merge 1286 commits into
Conversation
Per CircleCI's resource class analysis (issue ethereum-optimism#2366), this job runs at 19.5% avg CPU and 2.8% avg RAM on xlarge across 346 runs. Downsizing to medium brings effective utilization to ~78% CPU, which is still within bounds and yields meaningful credit savings. Refs: ethereum-optimism/core-team#2366
Per CircleCI's resource class analysis (issue ethereum-optimism#2366), this job runs at 24.6% avg CPU and 6.6% avg RAM on large across 371 runs. Downsizing to medium yields a modest credit saving while staying within bounds. This job persists workspaces consumed by downstream jobs (cannon, op-program). Watch for duration regressions on dependent jobs. Refs: ethereum-optimism/core-team#2366
…sm#20479) * feat(op-dispute-mon): add game type breakdown metric Add op_dispute_mon_games gauge with game_type label to track the distribution of monitored games by dispute game type (cannon, permissioned, super-cannon, etc.). Follows existing monitor pattern with a new GameTypeMonitor wired into the game monitor pipeline. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: linting --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* update interop explainer doc * Remove supervisor reference
…20439) * feat: make l2cm default path * Revert "feat: make l2cm default path" This reverts commit e652826. * fix: refactor default l2cm on dev feature library level * fix: tests * fix: hard enable L2CM in multi flag queries * test: update stale vm.assume for L2CM flag * chore: just pr * test: strip out L2CM flag from ALL_FEATURES flag * chore: adjust gas limits * test: ensure devFeatureBitmap stores bytes32(0) during tests * fix: hard enable L2CM in multi flag queries in devfeatures.go * refactor: update flag comparison * feat: make cannon-kona default path in devfeature bitmap (ethereum-optimism#20470) Mirrors the L2CM override for CannonKona: hardcodes the flag to true at the library level (Go and Solidity) so the bitmap acts as a circuit breaker rather than an opt-in toggle. * chore: regen bundle & just pr --------- Co-authored-by: IamFlux <175354924+0xiamflux@users.noreply.github.com> Co-authored-by: Maurelian <john@oplabs.co>
* chore: Disable redundant contracts test jobs * test(devfeatures): table-drive hardcoded-flag override tests Collapses the per-flag "always enabled regardless of bitmap" / "when combined with other flags" subtests into a single loop over the hardcoded-on flags (L2CM, CannonKona). Subtest names and assertions are unchanged. Touches the L2CM tests too — split into a separate PR if reviewers prefer to keep the L2CM-only changes minimal in ethereum-optimism#20439.
…thereum-optimism#20443) * feat(op-supernode): add SLI Prometheus metrics for interop quality gate Add six new metrics required for interop quality gate qualification: - supernode_interop_verification_duration_seconds (SLI-SN-4) - supernode_chain_rewind_depth_blocks (SLI-SN-5) - supernode_denylist_entries_total (SLI-SN-6) - supernode_log_backfill_progress + supernode_log_backfill_retries_total (SLI-SN-7) - supernode_activity_errors_total (SLI-SN-8) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(op-supernode): remove SLI comment annotations from metrics struct Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(op-supernode): remove dead metrics nil checks Constructors for ChainContainer and Interop already default nil metrics to NewSupernodeMetrics(), so the field is never nil after construction. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: measure full interop verification time inlcuding applying transitions to db * fix(op-supernode): keep denylist metrics idempotent * Revert "fix(op-supernode): keep denylist metrics idempotent" This reverts commit 2194182. * fix(op-supernode): make denylist metric a counter --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Karl Floersch <karl@oplabs.co>
ethereum-optimism#20482) * test(op-acceptance): drive AfterChainHead test setup via TestSequencer Replaces the running-sequencer-driven Stage 1+2 in RunSuperFaultProofTest and RunVariedBlockTimesTest with deterministic block production via TestSequencer.SequenceBlock, and adds the 6 AfterChainHead subtests (DisputeTimestampAfterChainHead*, DisputeBlockAfterChainHead*, AgreedBlockAfterChainHead*). Setup: freezeChains(chains) // stop real sequencers + batchers, WaitForStall endTimestamp := nextTimestampAfterSafeHeads(t, chains) advanceUnsafeToTimestamp(t, sys, chains, endTimestamp) capture l1HeadBefore advanceSafeToCurrentUnsafe(t, chains[0]); capture l1HeadAfterFirst advanceSafeToCurrentUnsafe(t, chains[1]); capture l1HeadCurrent AwaitValidatedTimestamp(endTimestamp) extendChainsExpectingBoundaryBlock(t, sys, chains, endTimestamp+1) build*Tests + buildAfterChainHeadTests freezeChains stops the running real sequencer and batchers and waits for LocalUnsafe + LocalSafe to stall on every chain. From there, only TestSequencer.SequenceBlock advances UnsafeL2 and only explicit Batcher.Start/Stop advances LocalSafe. Per-config branching in buildAfterChainHeadTests is keyed off block-time inference (blockExpectedAt) rather than runtime supernode probing. Trace indices: literal consolidateStep+1, consolidateStep+2, 2*sPT-1, 2*sPT, 4*sPT-1, 4*sPT+1. Drops MarkFlaky("ethereum-optimism#19828") from the two varied tests. The flake reason — endTimestamp aligning with a no-op transition for the slower chain — is impossible now: nextTimestampAfterSafeHeads walks the target until every chain produces a real block at it, and we drive each chain there deterministically via TestSequencer. Two AfterChainHead subtests have their challenger halves skipped (via SkipChallenger on transitionTest) pending op-supernode bug ethereum-optimism#20481 — VerifiedRequiredL1 uses MIN of per-chain L1s where it should use MAX, which makes the challenger and FPP disagree on the L1 head for those trace indices. The FPP halves still run. Also bumps GossipTimestampThreshold to 1 hour in the devstack p2p config. In devstack the chain timestamps are synthetic and can lag many minutes behind wallclock during long-running scenarios (e.g. waiting for fault dispute games to play out before producing more blocks), and the supernode's local gossip topic validator runs against wallclock — so the production-default 60s "payload too old" check rejects otherwise- valid TestSequencer-produced blocks. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(op-acceptance): correct boundary-alignment comment extendChainsExpectingBoundaryBlock does batch the boundary blocks (after l1HeadCurrent has been captured), so the comment claiming "without batching" was inaccurate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…um-optimism#20484) Resolves ethereum-optimism#20481. Superroot.atTimestamp tracked the MIN of per-chain VerifiedAt L1 blocks, which contradicts the field's semantics: VerifiedRequiredL1 should be "the minimum L1 block including the required data to fully verify all blocks at this timestamp" — that requires the MAX of per-chain required L1s. With MIN, when only one chain's data was on L1 at a given L1 head, the boundary super root falsely looked "fully verified" so the challenger's trace provider returned SuperRoot(boundary) instead of cascading to InvalidTransition, producing a real challenger / FPP disagreement at trace idx 2*stepsPerTimestamp - 1. Also unskips the two AfterChainHead subtests that worked around this bug (DisputeTimestampAfterChainHeadConsolidate-challenger, DisputeBlockAfterChainHead-FirstChain-challenger) and removes the SkipChallenger field on transitionTest (now unused). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…un-trace (ethereum-optimism#20512) The runner factory dispatched both CannonKonaGameType and SuperCannonKonaGameType through vm.NewKonaExecutor(). The single-chain KonaExecutor emits the kona host `single` subcommand, requires exactly one entry in cfg.L2s, reads inputs.L2Head / inputs.L2OutputRoot, and ignores inputs.AgreedPreState - none of which match the super-state inputs createGameInputsInterop produces. The result was a kona-host command with zero L2 head hashes that could never reach a successful output-root verification. Split the case so SuperCannonKonaGameType uses vm.NewKonaSuperExecutor() (matching the production challenger registration in op-challenger/game/fault/register.go), and add a runner-level test that asserts each game type maps to its expected executor and that the super-cannon-kona path produces the kona host `super` subcommand with --agreed-l2-pre-state, --claimed-l2-post-state, --l2-node-addresses, and --depset-cfg. Fixes ethereum-optimism#20506 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… writer deadlock (ethereum-optimism#20485) `init_from_state_dump` was being called while `provider_rw` (a RW MDBX transaction acquired earlier in the function for the optional without-OVM bedrock setup) was still alive. Since `init_from_state_dump` now takes a `DatabaseProviderFactory` and opens its own RW transaction internally, and MDBX permits only one writer at a time, the inner txn blocked forever waiting for the outer one — surfacing as "Process stalled, awaiting read-write transaction lock" right after "Initiating state dump". Commit `provider_rw` before invoking `init_from_state_dump` so the outer writer lock is released first. Fixes ethereum-optimism#20464 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-optimism#20514) Both advisories were published 2026-05-01 and affect hickory-proto <0.26.1, pulled in transitively via reth-network -> reth-dns-discovery. Ignore in deny.toml until an upstream bump lands. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ethereum-optimism#20487) FetchAndVerifyProofs queries the validator (op-reth) via eth_getProof, which reads through OpStateProviderFactory backed by the proofs ExEx store. The ExEx ingests ChainCommitted notifications asynchronously, so the EL head can advance to the target block before the store has indexed it, causing "no state found for block number N". WaitForBlockNumber syncs only the EL head, so the first proof query right after a deploy (e.g. block 2 in TestStorageProofUsingSimpleStorageContract) flakes. Mirror the fix from ethereum-optimism#19986 by polling debug_proofsSyncStatus on the validator before calling GetProof. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-optimism#20518) The EIP-2935 history lookup decoded the storage slot leaf as B256, which expects exactly 32 bytes of RLP payload. Ethereum stores storage values as RLP-encoded U256 with leading zero bytes stripped — so any block hash whose high byte is 0x00 (~1/256 of all hashes) encodes to fewer than 32 bytes and fails to decode with RlpError::UnexpectedLength. Decode as U256 and reconstruct the 32-byte hash, matching the pattern already used by TrieDB::storage in kona-executor. Update the test mock to mirror real-chain encoding and add a regression case for a hash with a leading zero byte.
* Move interop activation to migrator * Require ETHLockbox before OPCM migration * Enable per-chain ETHLockbox before migrate in test setUp * Let migrate enable ETH_LOCKBOX instead of requiring it preset Drop the EthLockboxNotEnabled precondition and idempotently flip the ETH_LOCKBOX feature inside migrate, mirroring how INTEROP is already handled. Fresh chains skip the per-chain lockbox sweep (gated on oldLockbox != 0), chains with an existing per-chain lockbox still migrate liquidity into the shared lockbox. Removes the only path to first-time activation that op-e2e, op-deployer, and the contracts unit tests previously had to synthesize, and matches the original 'move interop activation to migrator' intent.
…er (ethereum-optimism#20519) The kona action-test runner previously filtered tests by name (first only `Test_ProgramAction_*`, then post-ethereum-optimism#20446 anything except `Test_OPProgramAction_*`). That coupled "is this test op-program-only?" to a function-name convention, which silently excluded tests named differently. Replace the convention with an explicit runtime check: - `helpers.SkipIfKona(t)` skips when `KONA_HOST_PATH` is set (the same env var `IsKonaConfigured` already reads). Used today only by `TestOPProgram_PrecompileHint`. - Drop the `Test_ProgramAction_` decorative prefix from all 32 affected tests in `op-e2e/actions/proofs/`. Rename `Test_OPProgramAction_PrecompileHint` → `TestOPProgram_PrecompileHint`. - Strip the `skip_pattern` argument and `-skip` flag from `rust/kona/tests/justfile`; CI now runs every `Test*` and lets tests opt out at runtime. - Flip `defer matrix.Run(gt)` → trailing `matrix.Run(gt)` everywhere it appeared, matching the pattern already used in several files. - Remove the dead `go-tests-ci-kona-action` justfile target (and its Makefile shim entry); its `-run Test_ProgramAction` filter was never invoked from CI and would no longer match anything after the rename.
…thereum-optimism#20501) * op-challenger: route SuperPermissionedGameType through cannon-kona SuperPermissionedGameType uses the kona-interop super absolute prestate on-chain, so the challenger must fetch the kona prestate and run the kona VM/server, not the cannon (op-program) pair. Switch its registration, config validation, and CLI flag checks to the cannon-kona path. Closes ethereum-optimism#20500 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * op-challenger: enforce kona-host CLI flags for super-kona games CheckSuperCannonKonaFlags now requires --cannon-kona-server and --cannon-kona-prestate (or kona prestates URL), parallel to how CheckSuperCannonFlags already requires the cannon equivalents via CheckCannonBaseFlags. This makes SUPER_PERMISSIONED_CANNON enforce "require kona-host, not op-program" at CLI parse time, and closes the same latent gap for SUPER_CANNON_KONA. Tests in op-challenger/cmd/main_test.go are reorganized to match: SUPER_PERMISSIONED_CANNON moves out of the cannon-flavored arg tests and into a new TestCannonKonaRequiredArgs covering the kona super game types. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* tests: add InSync check for advancing heads Made-with: Cursor * test: re-sample both nodes in InSyncFn The previous InSyncFn snapshotted the reference head once at the start of the check and then waited up to N attempts for the base node to incorporate that exact block. In reorg-recovery tests the reference node can briefly hold an unsafe block that is later reorged out by the sequencer, which left InSyncFn permanently stuck against a stale target (see TestFollowL2_ReorgRecovery). Re-sample both nodes on every attempt and consider them in sync when: 1. the two head numbers differ by at most maxInSyncGap blocks 2. at the lower of the two heights, both nodes agree on the canonical block hash Both heads being live means a transient reorg on either side is forgiven on the next tick, while the gap+canonical check prevents declaring nodes in sync when one is far behind or on a different fork. * test: require slower node to catch up to initial high water mark in InSyncFn The 10-block tolerance in InSyncFn could falsely pass when a reorg has just happened: both nodes can sit a few blocks below the divergence point, agree on shared pre-reorg history, and look in-sync even though the slower node hasn't yet observed the reorg. Sample both heads once before the retry loop and remember the higher of the two as a catch-up target. The slower live head must reach that target before the gap and canonical-hash checks decide convergence, which forces both nodes to advance past where the faster node was when the check started. * test: tighten InSyncFn gap tolerance to 5 blocks 10 blocks (~20s of L2 progression at 2s block time) was generously permissive. 5 is enough to absorb sample-to-sample timing variance between the two nodes while keeping the in-sync window tight. * test: treat InSyncFn arguments as peers The two nodes passed to InSyncFn play symmetric roles, so name them node1/node2 and update the wrapper parameters to other. Fold the lower/higher/gap derivation into a single if-block. * test: clarify comments near InSync checks InSyncFn tolerates a small head gap rather than requiring exact equality, so wording like "identical chain", "match", and "Unsafe gap is closed" overstates the assertion. Replace with phrasing that matches what InSyncFn actually verifies: convergence on the same canonical chain. --------- Co-authored-by: axelKingsley <axel.kingsley@gmail.com>
* op-supernode: avoid engine rewind on L1 drift * op-supernode: address rewind review feedback
…ptimism#20448) Previously op-supernode unconditionally forced each virtual node's p2p.listen.tcp / p2p.listen.udp to 0 (dynamic). Users could not pin a P2P listen port, even though the supernode already exposes the op-node flags via vn.all.* and vn.<id>.*. withNamespacedP2P now only injects the 0 override when the user has not supplied a value via vn.all.<flag> or vn.<id>.<flag>. With no flags, behaviour is unchanged. withNoP2P still forces 0 since the ports are unused. The user is responsible for picking distinct ports when running multiple chains. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…scape hatches (ethereum-optimism#20531) The two methods existed only to expose the underlying *types.Header to a small set of callers. They forced every BlockInfo implementation to either hold a header or panic, blocking new implementations (e.g. payload-backed ones). - Add Extra() []byte to BlockInfo, removing the most common reason callers reached for HeaderRLP() (RLP roundtrip just to read header.Extra). - Add EthClient.HeaderBy{Hash,Number,Label} and HeaderAndTxsByHash. These are now the source of truth: headerCall fetches and verifies, the cache stores *types.Header, and InfoBy* / InfoAndTxsBy* wrap into BlockInfo on the way out. - Add a new apis.EthHeader interface embedded in apis.EthClient. - Extend prefetcher L1Source / L2Source / RetryingL1Source / RetryingL2Source / MockL2Source with the new methods. - Migrate the four production callers (dispute_game_factory, prefetcher L1 and L2 hint paths, internal CalcBlobFee) and simplify the two jovian acceptance tests (RLP roundtrip → info.Extra()). - Delete now-dead L1Source.InfoByHash and L2Source.InfoAndTxsByHash plus their wrappers, mocks, and tests; migrate reexec.go to HeaderAndTxsByHash. - Extract RPCHeader.Header(trustCache, mustBePostMerge) so the verification logic isn't duplicated between RPCHeader.Info and EthClient. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…imism#20363) * fix(opcm): disallow super cannon respected start Reject SUPER_CANNON as a migrator starting respected game type, move migration callers and CLI defaults to SUPER_CANNON_KONA, and re-enable post-migration validator checks for stale SUPER_CANNON implementations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(opcm): update interop migration test expectations * test(opcm): restore non-super registered game type in TestInteropMigration Pre-ethereum-optimism#20363, TestInteropMigration deliberately registered a non-super game type (Cannon=0) alongside a super starting respected type (SuperCannon=4). That asymmetry exercised the migrator's permissive disputeGameConfigs[].gameType handling — distinct from the strict respected-type check. The original migration to SuperCannonKona for both fields collapsed that coverage. Restore the asymmetric pattern (Cannon registered, SuperCannonKona respected) and add a comment documenting why the two types are intentionally different. * test(devstack): use SUPER_CANNON_KONA as respected type in upgrade-via path Aligns op-devstack/sysgo/superroot_via_upgrade.go with the post-retirement default and keeps the devstack V2-upgrade test compatible with the re-enabled SCDG-SHAPE check that asserts SUPER_CANNON is unregistered post-upgrade. * feat(opcm): retire SUPER_CANNON from OPContractsManagerV2 deploy/upgrade path Tightens OPContractsManagerV2._assertValidFullConfig by dropping SUPER_CANNON from validGameTypes (7 → 6 entries), and removes the corresponding branches in OPContractsManagerUtils.getGameImpl and makeGameArgs. This brings the V2 deploy/upgrade path in line with the migrator's post-retirement allow-list. Cascades: - Bumps OPContractsManagerV2 semver 7.1.17 → 7.1.18 (bytecode change). - Drops the SUPER_CANNON config slot from Deploy.s.sol, DeployOPChain.s.sol, PastUpgrades.sol, ForkL1Live.s.sol, SuperGameTestInit.sol, and all OPContractsManagerV2.t.sol / OPContractsManagerStandardValidator.t.sol / OPContractsManagerMigrationValidator.t.sol fixtures. - Drops embedded.GameTypeSuperCannon and the SUPER_CANNON arm from the fault-game-config switch in op-deployer/upgrade/embedded. - Drops the slot from op-deployer integration tests (apply_test ABI fixture re-encoded for 6 entries, eiOffset now 0x580) and op-devstack helpers (add_game_type.go, superroot_via_upgrade.go). - Renames the super-via-upgrade acceptance test to verify SUPER_CANNON_KONA as the post-upgrade respected type instead of SUPER_CANNON. Validator checks asserting SUPER_CANNON is unregistered (MIG-DGF-60, SCDG-SHAPE) remain in place — they are now load-bearing for both the migrator and V2 paths. The migrator path still permits permissive disputeGameConfigs registration of SUPER_CANNON; the validator catches that case. Existing on-chain SUPER_CANNON games remain serviceable through op-challenger and op-dispute-mon. * fix(opcm): narrow manage migrate validation to SUPER_CANNON ban Replaces the strict "--dispute-game-type must equal --starting-respected-game-type == 9 (SUPER_CANNON_KONA)" CLI checks with a focused "SUPER_CANNON (4) is rejected" ban on both flags. The on-chain validator already covers cross-config consistency, so the CLI just needs to enforce the retirement of SUPER_CANNON. - migrate.go: replace 2 strict checks with 2 SUPER_CANNON==4 bans - flags.go: drop manageMigrateDefaultGameType, restore DisputeGameTypeFlag default to standard.DisputeGameType (1), keep MigrateStartingRespectedGameTypeFlag default at 9 (SUPER_CANNON_KONA, since 4/SUPER_CANNON is now banned) - manage/migrate_test.go: replace mismatch+unsupported tests with a TestMigrateCLIRejectsSuperCannonBeforeRPC table-driven test - integration_test/cli/migrate_test.go: --dispute-game-type back to 0 (CANNON); --starting-respected-game-type stays at 9 (SUPER_CANNON_KONA replaces banned 4) - OPContractsManagerV2.t.sol: fix [6]→[5] disputeGameConfigs index for ZK_DISPUTE_GAME after the validGameTypes array shrunk from 7 to 6 entries * fix: drop SUPER_CANNON from migrator inputs and ABI fixture The OPCMv2 migrator loop in OPContractsManagerMigrator.sol calls _getGameImpl(gameType) for every entry in disputeGameConfigs regardless of the Enabled flag. After this PR removed SUPER_CANNON from OPContractsManagerUtils.getGameImpl/makeGameArgs, any disputeGameConfigs slice still containing a SUPER_CANNON entry reverts the entire migrate delegatecall with OPContractsManagerUtils_UnsupportedGameType. - op-chain-ops/interopgen/deploy.go: drop SUPER_CANNON from migration DisputeGameConfigs and remove the now-unused GameTypeSuperCannon constant. Fixes the runtime regression in op-e2e/interop tests (TestInteropDevRecipe, supersystem.NewSuperSystem, dsl/interop.go). - op-devstack/sysgo/superroot.go: drop SUPER_CANNON from migrateSuperRoots- WithProposal's DisputeGameConfigsV2 and remove the now-unused superCannonGameType = 4 constant. Fixes the runtime regression in op-acceptance-tests/tests/{interop/proofs,interop/super-via-upgrade, superfaultproofs}, op-devstack/example, and rust/kona/tests/supervisor Go shims. - op-deployer/pkg/deployer/manage/migrate_test.go: rewrite TestEncodedMigrateInputV2's fixture from GameType/StartingRespectedGameType 4 → 9 (SUPER_CANNON_KONA). The expected ABI hex bytes were updated for the new game-type values. * fix(opcm): clear stale SUPER_CANNON in upgrade and remove devstack proof refs OPContractsManagerV2.upgrade no longer has a config slot for SUPER_CANNON, so a chain that already has gameImpls(SUPER_CANNON) registered would survive the upgrade with a stale type-4 entry the StandardValidator now rejects (SCDG-SHAPE in super mode, SCDG-NOSHAPE in legacy mode). Clear gameImpls/initBonds for SUPER_CANNON unconditionally inside _apply, after the per-config loop. Bump OPCMv2 semver 7.1.18 -> 7.1.19; add a fork regression test that pre-registers type 4 and asserts both impl and bond are cleared post-upgrade. Devstack/sysgo/dsl proof paths still referenced retired type 4. Clean them up: - multichain_proofs.go: switch attachSupernodeSuperProofsViaUpgrade to SUPER_CANNON_KONA and drop WithSuperCannonGameType from startInteropChallenger. - add_game_type.go: comment was 7-config (incl. SUPER_CANNON); now 6-config. - dsl/bridge.go: drop SuperCannonGameType from UsesSuperRoots. - dsl/proofs/dispute_game_factory.go: drop SuperCannonGameType from SuperGameAtIndex's supported super-game list. - shared/challenger/challenger.go and op-e2e/e2eutils/challenger/helper.go: delete the now-unused WithSuperCannonGameType preset and its e2e wrapper. --------- Co-authored-by: wwared <541936+wwared@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…timism#20534) Drop the `deploy.sh` wrapper and its `just deploy` recipe. The script was a thin wrapper over a forge script invocation and is no longer used. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Remove c-non_docs_changes parameter from CI configs This parameter was used to skip CI for docs-only changes but is no longer needed. The rust_changes_detected parameter now handles the gating logic for rust-related workflows. * Add missing job dependencies to required-rust-ci The required-rust-ci job was only waiting on rust-tests, rust-clippy, and rust-docs. Add all other Rust CI jobs to ensure the gate job properly reflects the full CI status. * Remove c-non_docs_changes parameter from CI config This parameter was used to skip the main workflow for docs-only PRs, but is no longer needed. Also fixes indentation in semgrep workflow conditions. * Allow deprecated LGPL-3.0+ license identifier for gmp-mpfr-sys * Update gmp-mpfr-sys license identifier in deny.toml The crate now reports "LGPL-3.0" instead of the deprecated "LGPL-3.0+" identifier.
…mism#20923) * op-acceptance: test light CL sequencing with supernode * op-acceptance: assert light sequencer topology * test: wait for light sequencer tx inclusion * go lint
…imit to karsttest (ethereum-optimism#20678) Add `karsttest.CheckKarstBn256PairInputLimit`, wire it into `CheckAll`, add a `karst-bn256-pair` subcommand on `check-karst`, and add `TestKarstBn256PairingInputSizeReduction` to the Osaka-on-L2 suite. Mirrors the EIP-7823 / EIP-7951 structure. Go-side identifiers follow op-geth's `bn256` convention; the same curve also appears as bn128 (kona FPVM) and bn254 (op-revm, `Bn254PairLength`). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…thereum-optimism#21027) CheckAll now invokes every post-Karst check in sequence, including the block-size-disabled poll and the deposit-bypass check that previously existed only as dedicated subcommands. The `all` subcommand now requires the L1 flags (--l1, --l1-account, --portal) since the deposit check needs L1 access; the L2 interface gains apis.ReceiptFetcher for the deposit-receipt poll. The osaka_on_l2_test caller is updated for the 3-arg CheckEIP7934BlockSizeDisabled signature. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ethereum-optimism#21039) * docs(notices): add Upgrade 19 activation dates for Sepolia and Mainnet Replaces the placeholder ("Activation timestamps for each network will be communicated once finalized") with the finalized dates: Sepolia on Wed, Jun 17, 2026; Mainnet on Wed, Jul 8, 2026. Lists the chains in scope (OP, Soneium, Ink, Unichain). Format matches the Upgrade 16a notice. Component release versions and the cannon64-kona absolute prestate hash remain TBD in the same file, pending separate updates. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Update docs/public-docs/notices/upgrade-19.mdx Co-authored-by: soyboy <85043086+sbvegan@users.noreply.github.com> * Update docs/public-docs/notices/upgrade-19.mdx Co-authored-by: soyboy <85043086+sbvegan@users.noreply.github.com> * Update docs/public-docs/notices/upgrade-19.mdx Co-authored-by: soyboy <85043086+sbvegan@users.noreply.github.com> * docs(notices): adopt "Karst Hard Fork" naming in upgrade-19 notice Mirrors the upgrade-17 "Jovian Hard Fork" pattern: title and description explicitly name the Karst hard fork, body intro and Info block refer to "The Karst hard fork" rather than "Upgrade 19 protocol upgrade". Section headings and the Warning block retain "Upgrade 19" as the release label. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: soyboy <85043086+sbvegan@users.noreply.github.com>
* fix: ci semver not running properly * fix: l2cm version
…optimism#21004) * fix(op-node): stall consolidate on NotFound during EL sync When op-node receives a future unsafe payload via gossip during EL sync, the EL accepts it as a sync target and returns SYNCING. Derivation then tries to consolidate the next safe block against the unsafe chain, but the EL doesn't have pending_safe+1 yet, so PayloadByNumber returns NotFound. Previously this triggered a derivation pipeline reset. The reset's forkchoiceUpdated re-targets the EL away from its in-flight sync target, and the next gossiped payload moves it back — producing a thrash loop where EL sync never finishes and local safe never advances. When the engine reports IsEngineInitialELSyncing, treat NotFound at pending_safe+1 as a transient condition and emit EngineTemporaryErrorEvent instead of ResetEvent. The attributes stay queued and consolidation retries on the next pending-safe poke, by which point EL sync should have filled in the block. Outside EL sync, NotFound still triggers the existing reset. * fix: satisfy attributes.EngineController in sequencer test fake
…tability changes (ethereum-optimism#20948) * refactor(kona/service): move cancellation out of actors; replace start with step; split engine actor Selectively port the cancellation-token ownership changes from ethereum-optimism#19141 without adopting that PR's Builder / InboundData / init() trait pattern. NodeActor trait: - Replace `start(self, ctx) -> Result<(), Error>` with `step(&mut self) -> Result<(), Error>`. - Drop the StartData associated type and the CancellableContext trait. - The orchestrator macro (`spawn_and_wait!`) now owns the umbrella CancellationToken, the loop, and the select! against `cancelled()`; no actor sees a cancellation primitive. Actor migrations: - Derivation, DelegateDerivation, L1Watcher, Sequencer: drop the cancellation_token field + CancellableContext impl; move loop-local state onto self (tickers, payload-to-seal, last seal duration, etc). - Network: take a live NetworkHandler at construction; build/start the libp2p swarm in RollupNode::start so the constructor stays sync. The NetworkInboundData bundle is deleted in favor of injecting senders individually. - Rpc: become non-generic. Module assembly and the initial server launch move upstream; the actor holds config + modules + handle and relaunches up to RpcBuilder::restart_count on stop. A Drop impl calls ServerHandle::stop() so graceful cancellation shuts the jsonrpsee server cleanly. Engine actor restructure: - The fan-out EngineActor (which only routed EngineActorRequest variants into one of two sub-tasks) is deleted. - EngineProcessor is promoted to EngineActor; EngineRpcProcessor is promoted to EngineRpcActor. Both run as first-class peers under spawn_and_wait!. - EngineProcessingRequest takes over the freed name EngineActorRequest; the old fan-out EngineActorRequest enum and its RpcRequest variant are deleted (the rpc client sends EngineRpcRequest directly). - EngineRequestReceiver and EngineRpcRequestReceiver placeholder traits (testing-only scaffolding per their own doc comments) are deleted. - No more JoinHandle polling, is_finished() checks, or PhantomData generics in the engine actors. RollupNode::start: - Single CancellationToken owned by the macro; no actor receives it. - All cross-actor channels (mpsc + watch) created at the top of start() in one visually-grouped block. - Actor construction broken out into five build_* helpers (build_engine_actors, build_derivation_actor, build_l1_watcher, build_sequencer, build_rpc_actor) plus three private type aliases. - create_engine_actor helper deleted (inlined into build_engine_actors). External callers: - bin/node and examples/gossip: build the swarm handler upstream and spawn a step loop on a tokio task. Fixes a pre-existing bug in bin/node's net subcommand where the prior `network.start(()).await?` blocked forever, making subsequent interval-poll code unreachable. - Network/sequencer integration tests: TestNetworkBuilder::build is now async; TestNetwork holds the four inbound senders individually. - SequencerActor::new tests pass `block_time: 2` to avoid tokio::time::interval(0) panicking. Verification: cargo build -p kona-node-service: 0 errors cargo check --all-targets -p kona-node-service -p kona-node -p example-gossip: 0 errors cargo test --lib -p kona-node-service: 109 passed cargo test --test integration test_p2p_network_conn: passed cargo test --test integration test_sequencer_network_conn: passed * refactor(kona/service): make RpcActor generic over server launcher Introduces RpcServerLauncher + RpcServerHandle traits so the actor's relaunch and shutdown logic can be unit-tested with a controllable mock instead of a real jsonrpsee server. The production path is unchanged: a new JsonrpseeServerLauncher wraps RpcBuilder and produces a real ServerHandle. Adds six unit tests covering the restart budget, failed relaunches, and the Drop-stops-handle path. Also documents that RollupNode shutdown is unordered, and that L1WatcherActor's builder intentionally returns impl NodeActor because its block-stream type is unnameable. * refactor(kona/service): drop RollupNode::engine_config accessor The accessor's name shadowed the field of the same name, making self.engine_config() and &self.engine_config visually ambiguous at the only call site. Since the accessor only cloned the field, callers can clone inline. * docs(kona/service): clarify NetworkActor::new live-handler contract Constructing the actor with an unstarted handler causes step() to hang or fail on the first gossip poll. The constructor stays sync to keep NodeActor minimal, so the live-handler invariant lives in the caller — document that explicitly. * fix(kona/service): unbreak rust-docs intra-doc link in rpc/launcher The doc comment referenced crate::service::node::RollupNode, but service is a pub(crate) module so the path is not part of the documented graph. RollupNode is re-exported from the crate root; link there instead. * refactor(kona/service): inject delegate-derivation deps via traits DelegateDerivationActor used to take its two external dependencies — the sync-status fetch client and the L1 chain provider — by concrete type, so the actor's validation logic (sync-status fetch, L1 consistency check, conditional forwarding) could not be exercised without standing up real HTTP and RPC clients. That is why the actor has no unit tests today. Introduces a one-method DerivationDelegateProvider trait, generalizes the L1 provider to any kona_derive::ChainProvider, and threads the two generics through the actor and its enum wrapper in RollupNode. The production path is unchanged: DerivationDelegateClient implements the new trait and AlloyChainProvider already implements ChainProvider. No new tests in this commit — the DI seam alone unlocks future test work without committing to a specific test matrix here. * refactor(kona/engine): narrow EngineRpcActor to a read-only client trait EngineRpcActor previously held an Arc<EngineClient_>, giving it access to the full Engine API surface — including mutation methods like forkchoiceUpdated, newPayload, and getPayload that an RPC query actor must never call. Constrain the actor to a new EngineRpcClient trait exposing only the two methods EngineQueries::handle actually needs: l2_block_by_label and get_storage_hash (a narrowed projection of get_proof that returns just the storage hash field used to compute the L2-to-L1 message-passer storage root pre-Isthmus). A blanket impl of EngineRpcClient for every T: EngineClient keeps production wiring (OpEngineClient) unchanged; only the actor's static type bound has tightened. Tests can now implement the two-method trait directly instead of the entire EngineClient/OpEngineApi surface. Also rename the field engine_client -> engine_rpc_client to match the new narrowed responsibility. * refactor(kona/service): rename NetworkActor channel fields for consistency All receiver fields now share the _rx suffix: - signer -> unsafe_block_signer_rx - p2p_rpc -> p2p_rpc_rx - admin_rpc -> admin_query_rx publish_rx and unsafe_block_rx already followed the convention. Also rename the local select! binding signer -> unsafe_block_signer so it no longer collides with self.handler.signer, which represents a different concept (the local block-signing key, not an address). Call sites are positional so no caller updates required. * docs(kona/service): describe NetworkActor live-handler invariant abstractly Rewrite the constructor doc comment so it describes the precondition (the libp2p swarm must already be built and started) rather than naming the specific NetworkBuilder method chain. The trade-off rationale — sync constructor over an init() trait method — is retained. * test(kona/service): drop real-server tests from RpcActor test_launch_no_modules, test_launch_with_modules, and test_real_launcher_smoke all bound real localhost sockets via jsonrpsee. Unit tests should not spin up actual servers; the mock-driven RpcActor tests still cover the restart/stop logic, and the production JsonrpseeServerLauncher is exercised end-to-end by integration tests at the RollupNode level. With the only remaining users of the free `launch` function now inside launcher.rs itself, drop its pub(crate) visibility too. * PR feedback
…erations (ethereum-optimism#21015) * feat(op-supernode): re-insert canonical payload during engine rewind When rewinding the engine for DecisionRewind/DecisionInvalidate, the existing flow inserted a synthetic block and FCU'd to it, then FCU'd back to the original target block. The target block was no longer canonical between those two FCUs, which lets op-reth's pruner discard it and breaks the second FCU. Re-insert the canonical target payload via engine_newPayload immediately before the second FCU so the EL is guaranteed to still have the block. Also short-circuit RewindToTimestamp when the chain is not actually ahead of the target, and treat ethereum.NotFound from L2BlockRefByNumber in InvalidateBlock as "already rewound — nothing to do". * fixup: treat ethereum.NotFound from blockAtTimestamp as no-op rewind If the EL has not yet produced a block at the requested rewind target, L2BlockRefByNumber returns ethereum.NotFound — there is nothing to rewind. errors.Is(err, ethereum.NotFound) survives the RPC jump via eth.MaybeAsNotFoundErr, which the L2 client wraps every block-fetch response with. Simplifies the redundant `unsafe.Number < target.Number` branch since that case is now handled at step 0. * feat(op-supernode): WAL canonical payloads for rewind / invalidate operations The previous design left a window where the engine could not safely complete a rewind across a crash: after the synthetic FCU made the target block non-canonical, the EL (op-reth in particular) was free to prune it. On recovery, fetching the canonical block at the rewind height by number would return the synthetic block instead of the original target, and fetching by hash could return NotFound. This change makes the supernode WAL the authoritative source for the rewind target: - RewindPlan gains TargetPayloads (canonical envelope per chain at the rewind target). PendingTransition gains InvalidationParentPayloads (parent envelope per invalidated chain). - Build paths fetch each chain's canonical payload by hash at decision time — while the block is still canonical — and persist it in the WAL. Any fetch failure aborts the build; the decision is re-evaluated next round. - Apply paths use the WAL'd payloads exclusively. The engine controller no longer consults the live EL to discover the target. - engine.Rewind(ctx, target) replaces RewindToTimestamp. The synthetic block is derived from the supplied target, and the same target is re-inserted via engine_newPayload between the synthetic and target FCUs to guarantee EL durability across pruning. InvalidateBlock and RewindEngine now take the target envelope explicitly so the WAL contract reaches all the way down to the engine controller. Tests have been updated to register canonical payloads through a harness helper that mirrors verifiedDB commits onto the chain mocks. * fixup: tighten review feedback on rewind/invalidate - Rewind no-ops when unsafe is at or behind target (chain state may have moved since the WAL'd target was captured). - InvalidateBlock no longer treats NotFound as a no-op: a prior crashed attempt may have left a synthetic block at this height with no canonical entry visible by number, so we still drive the rewind. Only skip when the canonical block at the height exists and is not the invalidated hash. Drop the cross-check against parentPayload.ExecutionPayload.BlockHash — the WAL target is the authoritative destination. - Remove redundant nil-payload checks after PayloadByHash (the L2 client promotes nil-result to ethereum.NotFound) and trim verbose comments. * fix(op-supernode): wal reset rewind payloads * fix(op-supernode): satisfy bigint lint * fixup: drop redundant rewind payload validation EthClient's payloadCall already verifies the returned envelope matches the requested ID and is non-nil on success. * Apply suggestions from code review Co-authored-by: Karl Floersch <karl@oplabs.co> --------- Co-authored-by: Karl Floersch <karl@oplabs.co>
…ptimism#21023) * fix(op-supernode): retry RewindEngine on DeadlineExceeded The synthetic FCU in the rewind path can take minutes against a slow execution layer (op-reth in particular). When the engine's per-call RPC deadline fires, engine.Rewind returns context.DeadlineExceeded even though the caller's interop-transition ctx still has budget. Previously the retry loop in RewindEngine bailed immediately on DeadlineExceeded. Treat it as a transient error instead and rely on the existing ctx.Done() select to stop the loop when the caller's ctx is actually done. * fixup: clarify ctx framing — service ctx has no deadline
…reum-optimism#21036) * fix(op-chain-ops): look up kona prestate registry commit in monorepo The kona project was merged into ethereum-optimism/optimism, so kona-client/v* tags from v1.5.1 onward no longer exist in op-rs/kona. Read the superchain-registry commit from op-core/superchain/superchain-registry-commit.txt in the monorepo instead, and report the fpp-program diff URL against the monorepo too. * fix(op-chain-ops): serialize empty outdated-chains as [] not null slices.Collect over an empty map yielded a nil slice, breaking diff-check.zsh's sort_by. Use the same make([]T, 0) pattern as the other two report slices. * refactor(op-chain-ops): read kona SR commit from local git, not GitHub API The kona-client tags now live in this monorepo, so 'git show ref:path' is simpler than a GitHub Contents API call and avoids the unauthenticated 60/hr rate limit. Fetches the tag from origin lazily if it's not in the local clone yet.
Adds rust/UPDATING-RETH.md covering when and how to bump the reth git rev in the workspace: prefer upstream release tags, fall back to merge commits on main, avoid PR branch tips. Includes the practical "use cargo update reth-chainspec, not -p reth" gotcha and a list of common upstream-churn categories to expect. Links to it from docs/ai/rust-dev.md with agent-specific tips on the iterative compile-and-adapt workflow. Adds code comments at OpPayloadTypes::block_to_payload and From<OpBuiltPayload<N>> for OpExecData explaining why they're kept as parallel conversion paths (mirroring upstream EthPayloadTypes) rather than delegating to each other — the BAL travels differently in each and silent drops would corrupt payloads once OP gains BAL support.
…thereum-optimism#20620) * feat(op-interop-filter): add chain tip lag and ingestion lag metrics Add three new Prometheus gauges per chain to track how far the ingester is behind: chain_tip (RPC head), tip_lag_blocks (block delta), and ingestion_lag_seconds (wall-clock delta from latest ingested timestamp). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(op-interop-filter): add missing Metricer methods to test mock Add RecordChainTip, RecordTipLagBlocks, and RecordIngestionLagSeconds no-op methods to capturingMetrics to satisfy the updated Metricer interface. * fix(op-interop-filter): fix goimports formatting --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…#21052) * docs(node-operators/tutorials): default to op-reth op-geth reaches EOS on 2026-05-31 and will not support the L1 Glamsterdam hardfork. Rewrites the Docker and run-from-source tutorials so a migrator copy-pasting top-to-bottom ends up with an op-reth + op-node node, deletes the obsolete node-from-source page (subsumed by run-from-source), and preserves the legacy simple-optimism-node walkthrough at its own URL for operators still running that stack. Scope tracking: ethereum-optimism/solutions#689 (this PR) and ethereum-optimism/solutions#703 (follow-up for ops/management guides). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Update docs/public-docs/node-operators/tutorials/node-from-docker.mdx Co-authored-by: soyboy <85043086+sbvegan@users.noreply.github.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: soyboy <85043086+sbvegan@users.noreply.github.com>
…stic (ethereum-optimism#21058) * fix(contracts-bedrock): make semver lock artifact selection deterministic * chore(contracts-bedrock): tighten semver-lock artifact comment
…ism#21033) Set --syncmode.offset-el-safe to a nonzero default so safe and finalized heads no longer collapse onto the unsafe tip when EL sync completes (the correctness bug from ethereum-optimism#17631). 12h matches the OP Mainnet sequencing window: past the seq window, derivation can deterministically validate the retracted range, giving the minimum offset that restores safe/finalized correctness without demanding the multi-day derivation backlog a 168h default would impose. Also relax the validator: when --syncmode != execution-layer, log a warning and zero the offset instead of erroring, so the new default is non-breaking for CL-sync deployments.
| needs: [plan, build] | ||
| if: | | ||
| always() | ||
| && needs.plan.outputs.has_go_check_images == 'true' | ||
| && needs.build.result == 'success' | ||
| strategy: | ||
| fail-fast: true | ||
| matrix: | ||
| image_name: ${{ fromJson(needs.plan.outputs.go_check_images_json) }} | ||
| runner: | ||
| - ubuntu-24.04 | ||
| - ubuntu-24.04-arm | ||
| runs-on: ${{ matrix.runner }} | ||
| env: | ||
| IMAGE: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) && format('ttl.sh/{0}/{1}:{2}', github.sha, matrix.image_name, github.sha) || format('us-docker.pkg.dev/oplabs-tools-artifacts/images/{0}:{1}', matrix.image_name, github.sha) }} | ||
| steps: | ||
| - name: Run image | ||
| env: | ||
| IMAGE_NAME: ${{ matrix.image_name }} | ||
| run: docker run "$IMAGE" "$IMAGE_NAME" --version | ||
|
|
||
| check-cross-platform-rust: |
| needs: [plan, build] | ||
| if: | | ||
| always() | ||
| && needs.plan.outputs.has_rust_check_images == 'true' | ||
| && needs.build.result == 'success' | ||
| strategy: | ||
| fail-fast: true | ||
| matrix: | ||
| image_name: ${{ fromJson(needs.plan.outputs.rust_check_images_json) }} | ||
| runner: | ||
| - ubuntu-24.04 | ||
| - ubuntu-24.04-arm | ||
| runs-on: ${{ matrix.runner }} | ||
| env: | ||
| IMAGE: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) && format('ttl.sh/{0}/{1}:{2}', github.sha, matrix.image_name, github.sha) || format('us-docker.pkg.dev/oplabs-tools-artifacts/images/{0}:{1}', matrix.image_name, github.sha) }} | ||
| steps: | ||
| - name: Run image | ||
| run: docker run "$IMAGE" --version |
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
… behavior, and reorganize rust/op-revm After cherry-picking upstream commits, several integration issues required correction across the Go and Rust sides of the repo: Go fixes: - Move stray bluealloy/revm root-level files (Cargo.toml, CHANGELOG.md, src/) into rust/op-revm/ where they belong; add a LICENSE for that crate. - Restore missing packages and revert stale imports left over from the cherry-pick (op-service/bgpo, op-service/bigs, dial/rollup_sync, etc.). - Resolve remaining build errors introduced by the cherry-pick to 318838e: ChannelConfig call-site fixes in op-batcher, span_batch TX adjustments, withdrawal utility cleanup, op-chain-ops genesis additions, and removal of the interop proofs test that depends on upstream-only infra. - Restore SyncStatus.CurrentL1 as eth.BlockID in op-proposer source files. - Add the missing HemitrapConfig field to op-node/config. - Update go.mod/go.sum to pick up the corrected dependency versions. - Re-add the opgeth notifier goroutine (opgethNotifier, notifyOpgethKeystone, parseAndNotifyOpgeth) to EngineController, which was dropped during the cherry-pick. The notifier sends L2Keystone notifications to op-geth on every keystone-period block boundary. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4a53885 to
7e6af13
Compare
cherry picked up to commit
318838e9841de8865ecd4a580e66d99d7fa98a78from upstream optimismfix: cherry-pick fixups — resolve build errors, restore Hemi-specific behavior, and reorganize rust/op-revm
localnet test passing here https://github.com/hemilabs/heminetwork/actions/runs/28376711508/job/84068175238