Repository navigation
feat: merge v2.3.3 - #9
Merged
Merged
Conversation
prepare-continuation-config set BASE_REVISION: devlop. collect-params.sh
computes the changed-file set with git diff --name-only "origin/${BASE_REVISION}...HEAD"
and, on failure, silently falls back to git diff HEAD~1 HEAD. Because
origin/devlop does not exist, the diff against the merge base never ran and
change detection only saw the *last commit* of a multi-commit PR — so a PR
that changed rust/ or contracts in an earlier commit but ended on a docs-only
commit could be misclassified and skip its required tests.
Reproduced: origin/devlop does not resolve (triggering the HEAD~1 fallback);
origin/develop resolves. No unit test added: collect-params.sh is not
unit-tested and test-decision-tree.sh stubs the parameter JSON rather than
exercising the diff, so there is no natural harness for this one-line config
value; the fix is verified by ref resolution above.
The op-e2e/config init() unconditionally ran a full op-deployer genesis pipeline for all 4 alloc types across 9 hardfork modes (36 pipelines) at test-binary startup, costing minutes of CPU before any test ran. The op-e2e-fuzz job runs three concurrent `go test -fuzz ./opgeth` processes; each paid this full cost, oversubscribing CPU on the CI box. Under load the combined startup exceeded the 15m no-output timeout, killing the job with zero output from all three targets (including the pure-Go FuzzFastLzCgo, which shares the binary and was blocked behind the same init). Generate each alloc type lazily and once, so a binary only pays for the alloc types its tests request. The opgeth fuzz binary uses only DefaultAllocType, cutting its work from 4 alloc types to 1, and the two FastLz targets need none, so they now start and stream output in seconds. Refs ethereum-optimism/optimism#21191
…andoff bootstrap (#21220)
* test(devstack): un-skip #21164 light-sequencer interop tests via VN-handoff bootstrap
A follow-mode ELSync light sequencer cannot bootstrap a chain from genesis: as
the sole block producer it has no peer payload to initial-EL-sync from, so it
deadlocks in willStartEL (#21164). This left two interop tests skipped. Bootstrap
them instead by sequencing on the supernode VN first, then handing off to the
light sequencers, and un-skip:
- TestLightSequencerSupernodeDerivesSafeChain
- TestSupernodeLightSequencerInteropInvalidMessageReplacement (op-reth only)
Preset / runtime
- WithSupernodeVNSequencerForBootstrap: the supernode VN sequences and the light
follow-mode ELSync sequencers start stopped (l2CLNodeStartConfig.SequencerStopped
-> driver.Config.SequencerStopped). The VN produces + gossips so the light seqs
leave willStartEL via initial EL-sync.
- BootstrapLightSequencersViaVNHandoff helper: peers light<->VN, waits for the
light seqs to EL-sync out of willStartEL, then stops sequencing on the VN and
starts it on the light CLs.
- Batcher follows the VN during bootstrap, not the (stopped, EL-syncing) light
seqs. Batching the light seqs leaves a gap at the handoff boundary that wedges
L1 derivation ("dropping future span batch" forever) so the safe head never
advances and interop verification stalls. The VN produces during bootstrap and
tracks the light seqs via gossip after handoff, keeping a gap-free batch stream.
- Expose the supernode VN's EL per chain as L2ASupernodeEL / L2BSupernodeEL (a
distinct node from L2ELA/L2ELB in light-sequencer mode; aliases them in
virtual-sequencer mode).
invalid-message scenario
- Settle on cross-safe BEFORE asserting the invalid tx is gone. The unsafe head
oscillates during recovery (#21119) and can reorg back onto an invalid-containing
fork after the replacement validates; reading the block by number off the unsafe
tip caught that transient. Once cross-safe advances past the block it is
irreversible, so the read is stable.
- Anchor the post-recovery new-tx check on the supernode VN's L1-derived safe
chain (the canonical source of truth): follow the tx by hash until it lands at or
below the supernode's safe head, then assert it is present on BOTH the light
sequencer's EL and the supernode VN's EL. This proves producer and verifier
converge on one canonical chain, instead of trusting the producer's oscillating
tip via a block-number comparison.
- MarkFlaky(#21125) for the residual reorg-recovery flake (a tx sent mid-storm can
be orphaned even though the chain recovers). MarkFlaky only downgrades failures
on the testingT it is called on, and DSL node assertions route through each
node's own testingT, so it is applied to every node exercised in recovery, not
just the test-body t.
* test(devstack): extract ResendUntilSafe DSL helper
Move the resend-with-inclusion-check loop out of the invalid-message
replacement test and into a reusable dsl.L2ELNode.ResendUntilSafe helper
that takes a tx-generator and waits for a broadcast to derive onto the
node's safe chain. Uses the tolerant blockRefByLabel getter inside the
retry so a transient safe-head lookup error retries instead of unwinding
the goroutine.
* test(devstack): make VN-handoff bootstrap a system method
Move BootstrapLightSequencersViaVNHandoff from a standalone presets
function to a method on *TwoL2SupernodeInterop, alongside the other
system methods in twol2.go, so tests read as
sys.BootstrapLightSequencersViaVNHandoff(). Update both call sites and
the WithSupernodeVNSequencerForBootstrap doc reference.
---------
Co-authored-by: wwared <[email protected]>
…#21227)
* ci(rust): branch-scoped sccache GCS compile cache for Rust builds
Back the Rust CI compile cache with the op-rust-sccache GCS bucket, with
write access restricted to the develop branch.
- use sccache preinstalled in ci-base-clang (bump the effective rust_base_image
pin in config.yml + the continuation defaults)
- GCP Workload Identity coords, reader service account, and bucket come from
the project-restricted sccache-gcs-optimism CircleCI context attached to the
rust-ci jobs
- read-only reader identity is the default for every ref; develop overrides to
the read/write writer identity via a native when/equal on pipeline.git.branch
- the write/read split is enforced by GCP Workload Identity on the signed
CircleCI OIDC vcs-ref claim, so a non-develop ref cannot gain write by editing
this config; the condition only selects the service account
- sccache error log + idle timeout for observability/robustness
- prints sccache --show-stats at job end
* ci(rust): make sccache setup fail-open and drop the gcloud dependency
The sccache setup ran gcp-cli/install + gcp-oidc-authenticate as unguarded
steps, so a gcloud install break or a job missing the sccache-gcs-optimism
context hard-failed the whole rust job. sccache is an accelerator, not a gate.
- build the Workload Identity ADC config directly (no gcloud) and let sccache
consume it via GOOGLE_APPLICATION_CREDENTIALS
- skip with a warning (never fail) when the context/coords are absent, sccache
is missing, or the server won't start
* ci(rust): attach sccache-gcs-optimism to all Rust workspace builds
The context was only on the rust-ci anchor jobs; the heavy workspace
compiles in the main + rust-e2e workflows (rust-workspace-binaries,
rust-workspace-release, op-rbuilder, rollup-boost) ran without it and so
fell through to the cache-less fail-open path. Attach the context to those
invocations too so every Rust build on ci-base-clang uses the shared cache.
* ci(rust): use sccache in the vendored builds (op-rbuilder, rollup-boost)
Review caught that rust-build-vendored ran a bare cargo build without
RUSTC_WRAPPER, so op-rbuilder and rollup-boost carried the sccache context
but never used the cache. Invoke rust-sccache-setup in the job and set
CARGO_INCREMENTAL=0 in the command (this job does not run rust-setup-env),
so a vendored rebuild on a binary-cache miss is sccache-accelerated.
* ci(rust): slim down the sccache start step
Drop the redundant guards (sccache is baked into ci-base-clang; bad/absent
coords just make --start-server fail). Keep the one invariant that matters:
set RUSTC_WRAPPER only when the server actually starts, so a cache/auth/GCS
hiccup yields an uncached build rather than failing every rustc call.
* ci(rust): fail loud if sccache cannot start; cover all routing jobs
Drop the fail-open fallback: set RUSTC_WRAPPER and let the job fail if
sccache --start-server fails, so a broken cache surfaces immediately instead
of silently building uncached. Because rust-sccache-setup now fails loud,
every job that routes through it must carry the sccache-gcs-optimism context
— add it to the kona-publish-prestate-artifacts invocations (the only routing
jobs that lacked it).
* ci(rust): skip sccache where it is not installed (machine-executor jobs)
The cannon jobs (kona-build-fpvm/host-offline/lint) run on a VM machine
executor, not the ci-base-clang image, so sccache is absent and the fail-loud
start hit 'command not found'. Skip when the binary is missing; still fail
loud when sccache is installed but the server won't start.
* ci(rust): dedupe rust-prepare/rust-setup-env into helpers.yml; drop vendored dup
Address review: rust-prepare and rust-setup-env were defined in both main.yml
and rust-ci.yml, with the sccache wiring living only in the rust-ci.yml copy
that happens to win the deep-merge — a footgun (consolidating toward the
main.yml copy would silently disable sccache). Move the single canonical copy
into helpers.yml (merged first), so there is exactly one of each and the
sccache step can't be shadowed. Also remove the byte-identical duplicate
rust-build-vendored definition.
* ci(rust): dedupe Rust cache command definitions
rust-ci.yml redefined rust-build, rust-prepare-and-restore-cache,
rust-restore-build-cache and rust-save-build-cache, duplicating the
canonical definitions in main.yml. Because merge-configs.sh merges
rust-ci.yml after main.yml (later wins), the rust-ci.yml copies silently
shadowed main.yml's, dropping two behaviours that only existed in the
main.yml version:
- the rust_files_changed fast path that skips cargo build on feature
branches when rust/ is unchanged (parameter was still passed but
ignored), and
- the --bin <binary> filter (BINARY was set but never appended to the
cargo invocation).
Remove the duplicates so the main.yml definitions are the single source
of truth. No behaviour change beyond restoring the two dropped paths;
merged config validates with circleci config validate.
* ci(rust): share the Rust dependency cache across all jobs
The crate-download cache (.cargo/registry, .cargo/git, .cargo/bin,
.rustup) was keyed on the per-job prefix, so each of the ~18 Rust CI
jobs maintained its own copy even though the downloaded crate set is
identical for a given Cargo.lock — independent of job, profile, and
features. On any cold cache every job downloaded the full dependency
set from crates.io in parallel and CircleCI stored a separate multi-GB
copy per job.
Key this cache on a single shared 'rust-deps' prefix (still per-workspace
via the Cargo.lock checksum) so the dependencies are fetched and stored
once and reused by every job. The per-job target/ cache is unchanged.
No fallback key is used on purpose: a Cargo.lock change fully refreshes
the dependency cache rather than accreting old crate versions on top of
the existing set, bounding cache size. Lock changes are infrequent.
* ci(rust): cache the Rust toolchain separately from dependencies
.rustup and the cargo-installed binaries (.cargo/bin) were stored in the
dependency cache keyed on Cargo.lock, so every dependency bump threw away
and re-downloaded the entire Rust toolchain — even though the toolchain
is pinned by mise.toml and rust/rust-toolchain.toml, not Cargo.lock.
Split them into a dedicated 'rust-toolchain' cache keyed on those pin
files. The toolchain is now refreshed only when the pins change, while
the dependency cache holds just the downloaded crate sources (registry +
git). Both remain shared across all jobs.
* ci(rust): re-attach sccache stats to the consolidated rust-save-build-cache
The sccache --show-stats step lived in the rust-ci.yml copy of
rust-save-build-cache, which was removed by the dedup. Re-add it to the
single canonical rust-save-build-cache in main.yml.
---------
Co-authored-by: Adrian Sutton <[email protected]>
The image-build smoke check runs '<image> <image_name> --version', which exercises only the image's primary binary. op-challenger is the one fat image that bundles helper binaries (op-program, cannon, kona-host) and execs them at runtime, so a broken bundled binary is invisible to that check. This gap let a runtime-loader mismatch ship: cannon is cgo/musl-linked and could not exec on a glibc-only base image, while 'op-challenger --version' kept passing. Add a step that execs each bundled binary on both arch runners and fails on exit 126/127 (not executable / missing loader) or a signal-termination exit (>=128, e.g. 139 SIGSEGV).
…0581)
* feat(op-node): serve superroot_atTimestamp for non-interop chains
Add a new `superroot` JSON-RPC namespace on op-node with method
`AtTimestamp(timestamp)`, mirroring op-supernode's wire contract
exactly so existing clients (op-challenger, op-dispute-mon) can
point `--supernode-rpc` at op-node URL on non-interop chains.
The handler reuses op-node primitives only — driver SyncStatus +
BlockRefWithStatus, l2EthClient OutputV0AtBlock, and the shared
safedb.L1AtSafeHead walkback — to construct a single-chain
SuperRootAtTimestampResponse byte-compatible with op-supernode's
output for the same chain.
Field semantics are documented in code:
- CurrentSafeTimestamp / CurrentLocalSafeTimestamp / CurrentFinalizedTimestamp
pulled directly from SyncStatus, matching op-supernode's per-field
aggregation collapsed to one chain.
- VerifiedRequiredL1 (and OptimisticAtTimestamp[chainID].RequiredL1
on the verified branch) come from safedb.L1AtSafeHead — this is
the value op-challenger compares against l1Head to gate
InvalidTransition, so it is correctness-critical, not perf.
- Optimistic-only branch (block beyond LocalSafeL2 but within UnsafeL2)
uses the L2 block's L1Origin as RequiredL1, mirroring op-supernode.
- Pre-genesis / beyond-UnsafeL2 / safeDB-not-found all degrade to
populated sync fields with Data nil — never zero-out the response
on transport errors (consumers check CurrentL1.Number first).
Per the issue's resolution by @ajsutton, no activation gate: the API
behaves the same pre- and post-Interop, since a single-chain super
root is well-defined at any timestamp.
Unit tests cover: pre-genesis, beyond-unsafe, optimistic-only,
verified happy path, safeDB-not-found fallback, driver/output
errors, and a runtime SuperRootProvider conformance check (mirror
of op-challenger's and op-dispute-mon's consumer interface).
The compatibility check uses a test-only adapter rather than adding
a SuperRootAtTimestamp method to the live struct — go-ethereum
auto-registers exported methods on RPC services, so a method on the
live struct would leak `superroot_superRootAtTimestamp` as a wire
method. The test-only adapter keeps the wire surface to exactly
`superroot_atTimestamp`.
Refs: ethereum-optimism/optimism#20552
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* fixup(op-node): match op-supernode fallback semantics exactly
Address security review on PR #20581. Three fallback branches now
mirror op-supernode chain_container behavior precisely so the new
op-node handler is byte-for-byte equivalent for the single-chain
case across all paths op-challenger and op-dispute-mon exercise:
1. blockNum > LocalSafeL2.Number — was returning an optimistic
entry with RequiredL1 = ref.L1Origin. op-supernode's
LocalSafeBlockAtTimestamp returns ethereum.NotFound here, so
both VerifiedAt and OptimisticAt fail and the chain is OMITTED
from OptimisticAtTimestamp. Now omits.
2. safeDB returns ErrL1AtSafeHeadNotFound (transient) — was
returning an optimistic entry with L1Origin. op-supernode's
safeDBAtL2 maps this to ethereum.NotFound, OptimisticAt fails,
chain is OMITTED. Now omits.
3. safeDB returns ErrL1AtSafeHeadUnavailable (permanent gap) — was
silently degrading to optimistic-only. op-supernode's safeDBAtL2
maps this to ErrHistoryUnavailable which bubbles up as an RPC
error (operator must intervene). Now returns the wrapped error.
The previous behavior could cause op-challenger's
SuperNodeTraceProvider at step > 0 to include a chain in
expectedState.PendingProgress that op-supernode would have
rejected via InvalidTransition (the consumer reads
OptimisticAtTimestamp[chainID] without checking Data == nil at
non-zero steps).
Tests rewritten to assert the new semantics:
- TestSuperrootAPI_BeyondLocalSafe_OmitsChain
- TestSuperrootAPI_SafeDBNotFound_OmitsChain
- TestSuperrootAPI_SafeDBUnavailable_ReturnsError
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* fixup(op-node): reject superroot_atTimestamp when SafeDB disabled
Optional-interface assertion at the top of superrootAPI.atTimestamp:
if the configured SafeDBReader is *safedb.DisabledDB (Enabled()==false),
return a clear error before doing any work. Without this gate, requests
within LocalSafeL2 surface ErrNotEnabled from the helper while requests
beyond LocalSafeL2 short-circuit successfully with Data=nil — an
operator who forgot --safedb.path on a non-interop chain serving
dispute infra would see inconsistent responses and op-challenger would
loop on empty data.
op-supernode does not need an equivalent check: chain_container hard-
codes vncfg.SafeDBPath at virtual-node construction, so SafeDB is
always enabled there. On op-node --safedb.path is optional, so this is
a new failure mode unique to the non-interop path.
Test uses the real safedb.Disabled singleton and sets no driver
expectations — if the handler ever calls SyncStatus before rejecting,
the testify mock fails the test, asserting both the error and the
"before any work" semantics.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* fixup(op-node): address review on superroot_atTimestamp
Address ajsutton review on PR #20581:
- Pre-genesis now returns an error from rollup.TargetBlockNumber instead
of silently succeeding with Data nil. Dispute infra never legitimately
queries before genesis; a clear error beats an ambiguous empty success.
- Drop the explicit safedb.Enabled() gate. safedb.Disabled.L1AtSafeHead
returns ErrNotEnabled, which now propagates as a real error rather
than being treated like transient SafeDB lag.
- Restructure to call BlockRefWithStatus at the top instead of a separate
SyncStatus + BlockRefWithStatus pair, so the LocalSafeL2 bound check is
consistent with the resolved ref (no race). A SyncStatus fallback runs
only when BlockRefWithStatus fails (block beyond unsafe head).
- Only ErrL1AtSafeHeadNotFound (transient) maps to Data nil. All other
errors (ErrL1AtSafeHeadUnavailable, ErrNotEnabled, network/IO) now
propagate to the RPC caller.
- Drop the superrootAPIQueryAdapter shim and the SuperRootProviderCompat
test. Tests call atTimestamp directly; wire compatibility is the real
contract with op-challenger / op-dispute-mon.
- Trim verbose comments throughout.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* fixup(op-node): classify BlockRef/Output errors by ethereum.NotFound
Match op-supernode parity: only ethereum.NotFound from BlockRefWithStatus
or OutputV0AtBlock omits the chain. All other errors (context deadlines,
EL transport failures, driver-loop errors) fail the RPC rather than
silently degrading to an empty response.
Also drop the trailing blank line at EOF in the test file.
* fixup(op-node): trim comments in superroot files
* test(op-node): cover the L2-genesis superroot special case
* fixup(op-node): tighten superroot_atTimestamp error/omit policy
* fixup(op-node): drop unused logger from superrootAPI
---------
Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
* feat(op-reth/proof): backfill initial implementation * perform backfill against proof store * improvements * progress logging * doc and test fixes * fmt fixes and removed blanket impl * improvements and fixes * added test * feat(op-reth/proofs): one-time trie-state snapshot * removed unnecessary changes * fix rustdoc * bugfixes * snapshot earliest -> anchor * split providers * doc updated * feat(op-reth/proofs): integrate snapshot into backfill * minor improvement * feat(op-reth/proofs): snapshot hashed-leaf tables for backfill * backfill not implemented for immemory and v1 store * clippy fixes * refactor trait * metric removed * move snapshot related CompletionEstimatable * move snapshot related CompletionEstimatable * review fixes
Move the EIP-4844 RootsOfUnity table out of op-program/client/l1 into a new op-service/kzg package, so op-challenger no longer imports op-program. op-service (rather than op-challenger) is the right home: op-program/client is the fault-proof program compiled for cannon, and its build context (see op-program/Dockerfile.vmcompat.dockerignore / Dockerfile.repro.dockerignore) allowlists op-service but not op-challenger. Since client/l1 itself uses RootsOfUnity, it must stay importable from the FPVM client; op-service is the neutral package both op-challenger and op-program may depend on. Prerequisite for deleting op-program from the monorepo (ethereum-optimism/optimism#20276).
…254) * chore(op-devstack): remove Cannon game type (op-program) support Remove the legacy Cannon game type (game type 0, served by op-program) from op-devstack as part of removing op-program from the monorepo (ethereum-optimism/optimism#20276). PermissionedCannon (game type 1) is kept but configured with a dummy absolute prestate (0x..dead) so the challenger never executes the legacy fault-proof program: permissioned games skip prestate validation and resolve without reaching step(). The Cannon VM oracle server is pointed at the cannon binary (unused) instead of op-program. op-devstack no longer references op-program/bin/*. The op-program Cannon wiring that op-e2e still depends on is moved into op-e2e itself. * review: op-e2e permissioned games use dummy prestate; drop dead Cannon helpers - Switch op-e2e's base Cannon VM config to the shared WithPermissionedCannonConfig (dummy 0x..dead prestate), so op-e2e's challenger no longer references the op-program prestate. Permissioned games resolve at the output-root level without reaching step(), so the dummy is sufficient; verified via TestPermissionedGameType and TestOutputCannonGame. - Delete dead WithCannon (op-e2e) and WithCannonGameType (op-devstack): op-e2e exercises only cannon-kona and permissioned games, never the legacy Cannon type. - Drop the now-broken op-program prestate os.Stat checks from op-e2e's challenger config validation (mirrors op-devstack). - Unexport FindMonorepoRoot; op-e2e uses op-service.FindMonorepoRoot. - Rename proofs/cannon_kona package from 'cannon' to 'cannon_kona' to match the dir. * review: unexport applyCannonVMConfig op-e2e now uses WithPermissionedCannonConfig, so the base VM-config helper is only used internally by op-devstack/shared/challenger. Make it unexported. * review: remove orphaned PrestateVariant Switching op-e2e to the dummy permissioned prestate removed the last caller of .PrestateVariant(). Remove the now-dead chain end to end: - PrestateVariant type + MTCannon/MTCannonNext/Interop/InteropNext constants (op-devstack/shared/challenger) - PrestateVariant() from the System interfaces (challenger + disputegame helpers) and its implementations (e2esys.System, SuperDisputeSystem) - now-unused imports (shared/challenger, op-e2e/config). * review: use DummyPermissionedPrestate constant and clarify VM config name
… (#21245) apt-install, install-zstd, and gcp-oidc-authenticate were each defined in both main.yml and rust-ci.yml. Under the continuation merge (helpers -> main -> rust-ci -> rust-e2e, later file wins) main.yml holds each command's position in the merged output while rust-ci.yml's body wins on value. Remove the rust-ci.yml duplicates and keep the canonical copies in main.yml. Align main.yml's gcp-oidc-authenticate body to the (comment-less) version that previously won, so the merged value is unchanged. Verified byte-identical: re-running merge-configs.sh and diffing the merged output against develop shows no difference.
- Bump op-reth to v2.3.1 in the Upgrade 19 (Karst) component table - Regenerate release pages: op-reth now leads with v2.3.1; buggy v2.2.5 and v2.3.0 (superseded by v2.3.1) dropped; picks up newer op-contracts, op-deployer and other component releases - Move op-reth and op-contracts under the Releases "Protocol" nav group and remove the "Execution" and "Contracts" sub-groups (docs.json + generate-releases.ts group metadata) Co-authored-by: soyboy vegan <[email protected]> Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
…2.4.3 (#21265) Removes the stale `@custom:audit none` comment now that SuperchainConfig has been audited. Patch version bump per semver policy (comment-only change). Co-authored-by: Claude Sonnet 4.6 (1M context) <[email protected]>
* op-devstack: sequence on op-reth for Karst+ in acceptance tests op-geth is deprecated as of the Karst fork and (with op-geth#802) refuses to build, seal, or import Karst blocks. Make the acceptance-test harness use op-reth — the official Karst EL client — for Karst-activated chains. - Route the two presets that hardcoded the op-geth EL through the env-aware dispatch (startSequencerEL / startL2ELForKey), so they honor DEVSTACK_L2EL_KIND instead of always running op-geth: the sync-tester sequencer and the follow-L2 followers. - Add a Karst-aware guard at the EL dispatch point: when a chain activates Karst at genesis, skip env-selected op-geth (the op-geth CI lane cannot cover Karst) and fail loudly when a mixed-runtime node spec explicitly pins op-geth (a test misconfiguration). Everything else sequences/verifies on op-reth. No change for <= Jovian chains. Closes #21182. Co-Authored-By: Claude Opus 4.8 <[email protected]> * op-devstack: centralize Karst op-geth guard in buildL2Genesis Address review feedback (joshklop): the per-dispatch guard missed op-geth EL start paths that bypass startL2ELForKey (e.g. startSupernodeELWithInteropURL, which constructs *OpGeth directly). Move the env-driven skip to buildL2Genesis — the single point every runtime builds genesis through — so it covers all runtimes and EL-start paths. - buildL2Genesis: skip when an L2 chain configures Karst (KarstTime != nil) and DEVSTACK_L2EL_KIND=op-geth. Using KarstTime != nil (not just IsKarst(genesis)) also covers chains that activate Karst at an offset, which op-geth cannot cross either. - Drop the now-redundant startL2ELForKey guard. - Keep the mixed-runtime per-node fail for an explicit op-geth spec on a Karst chain (a misconfiguration not covered by the env-driven genesis guard). Co-Authored-By: Claude Opus 4.8 <[email protected]> * op-devstack: drop redundant mixed-runtime op-geth Karst guard Address review (joshklop): no preset sets a per-node op-geth EL spec, and the env-driven op-geth lane is already covered by the buildL2Genesis guard, so the per-node guard was unreachable. Remove it; the switch's default case still rejects unsupported EL kinds. Co-Authored-By: Claude Opus 4.8 <[email protected]> --------- Co-authored-by: Claude Opus 4.8 <[email protected]>
…s (#20937) The --proofs-history.prune-interval flag was removed in op-reth v2.2.3 (commit 97356ff, PR #20450) when pruning moved into the engine task and now runs inline with each persistence batch. Drop the now-broken flag from the exex README and public docs, and rewrite the surrounding narrative so operators do not chase a knob that no longer exists. Co-authored-by: soyboy vegan <[email protected]> Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> Co-authored-by: geoknee <[email protected]>
…debug_dbGet (#21269) debug_executePayload (the L2PayloadWitness hint) and the L2BlockData optimistic-block re-execution are "high-level" hints that bulk-populate the preimage store. They were fetched once when received and discarded, so any error was terminal: the client fell back to per-node debug_dbGet, which op-reth does not implement, turning a transient failure into a permanent one. Instead of fetching high-level hints eagerly, retain the latest one and let the existing get_preimage retry loop service it: each attempt tries the high-level hint first (bulk-populating the store), then the fine-grained hints. A high-level hint is cleared once it succeeds (its response is deterministic) and kept while it fails, so a transient error is retried indefinitely without re-running an already-satisfied hint. debug_dbGet remains the fallback only when the node genuinely lacks debug_executePayload (JSON-RPC method-not-found). is_rpc_method_not_found and the debug_executePayload call are consolidated into backend::util, removing the duplication between the single-chain and interop handlers.
* fix(op-challenger): tear down VM process group on timeout The VM (cannon) spawns the oracle/preimage server as its own child, which inherits the VM's stdout/stderr pipes. exec.CommandContext only SIGKILLs the direct child on timeout, so the oracle server is orphaned and keeps the pipe write ends open. cmd.Wait then blocks forever and the VM timeout never actually terminates a wedged run. Run the VM in its own process group, kill the whole group on cancellation, and set a bounded WaitDelay as a backstop so RunCmd always returns once the context is cancelled. * test(op-challenger): cancel only after process tree spawns Arm the teardown after the grandchild records its pid rather than on a fixed 200ms timer, so the test exercises the deadlock instead of racing cancellation against process startup on an overloaded CI box.
…) (#21274) proc-macro-error2 is flagged unmaintained by RUSTSEC-2026-0173 (no vulnerability, no patched release exists). It is a build-time-only proc-macro dependency pulled in via alloy-sol-macro; the latest alloy-core (1.6.0) and its main branch still pin it because they use a private API, so no upgrade removes it. Add a scoped advisory ignore matching the existing unmaintained/transitive ignores in deny.toml.
Decouple op-e2e from op-program so it can be deleted from the monorepo (ethereum-optimism/optimism#20276). After this, neither op-e2e nor op-devstack reference op-program. - Move the engineapi package (the in-process L2 engine used by action tests) from op-program/client/l2/engineapi into op-e2e/actions/helpers/engineapi. - Stop deploying the legacy type-0 Cannon dispute game in the op-e2e deploy intent. It is no longer served by op-challenger, and it was the only reason op-e2e read op-program/bin/prestate-proof-mt64.json. The generic CannonKona (type 8) game still exercises the proof system.
…ned game (#21270) * chore(op-challenger): don't require --cannon-server for permissioned game The permissioned game type is played only by trusted actors and resolves at the output-root level without ever reaching step(), so it never runs op-program. Make the --cannon-server flag (and the runtime op-program server binary existence check) optional when only the permissioned game type is enabled. The legacy Cannon game type (0) still requires it, as does CannonKona (kona-host). Part of removing op-program from the monorepo (ethereum-optimism/optimism#20276). * test(op-challenger): cover cannon+permissioned both-enabled server requirement When both the cannon and permissioned game types are enabled, --cannon-server must still be required because the cannon game runs op-program. Add config and CLI tests guarding this both-enabled path, which was previously uncovered.
* docs(upgrade-19): draft kona-client prestate verification step Draft for review. Uses kona-client/v1.5.2 hashes + Tabs for standard vs custom-config chains; kona-client version and hashes will change when the final U19 release tags are cut. Custom-config build flow linked to #21000. Closes ethereum-optimism/solutions#681 Co-Authored-By: Claude Opus 4.7 <[email protected]> * docs(upgrade-19): use kona-client v1.6.0 prestate hashes Update the kona-client prestate verification step for superchain-registry chains to the v1.6.0 release tag and its absolute prestate hashes: cannon64-kona and cannon64-kona-interop. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs(upgrade-19): add embedded-config check + fix custom prestate on-chain verify - Add a pre-deployment embedded-config check (gunzip | strings | grep <chain>) for custom prestates, run once per chain — catches a silently-dropped chain that otherwise yields the standard hash. - Fix the on-chain verification: on v2.4+ contracts the prestate lives in the DisputeGameFactory gameArgs (clones-with-immutable-args), so absolutePrestate() on the bare implementation returns zero. Read gameArgs(<gameType>) or a created game instance instead. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.7 <[email protected]>
…000) * docs(chain-operators): add kona-client custom prestate tutorial New tutorial under chain-operators/tutorials/ covering the custom-configuration kona-client prestate workflow for chains not yet in the public superchain-registry. Mirrors the structure of the existing absolute-prestate.mdx tutorial (which covers op-program / game type 1) but documents the kona-registry KONA_CUSTOM_CONFIGS_DIR mechanism for game type 8 (CANNON_KONA). The tutorial is intentionally a narrow public-facing reference: - Schema details for chainList.json + configs.json link out to the kona-registry README on GitHub (public). - An Info callout makes clear that most chains are in the SR and should not follow this path. - Steps cover branching off a kona-node release tag, staging configs, wiring the rust/justfile recipe, building, verifying reproducibility, and the deploy + op-challenger configuration. This tutorial will be linked from the U19 notice's "For chains with custom chain configurations" subsection (separate branch). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * docs(chain-operators): refocus absolute-prestate tutorial on kona-client Following Upgrade 19's promotion of CANNON_KONA (game type 8) as the respected game type for permissionless fault proofs and the deprecation of op-program for new fault proofs, this tutorial is rewritten to cover the canonical kona-client flow. - Standard prestate sourced from superchain-registry's cannon64-kona entries in standard-prestates.toml. - Build/verify steps use `just reproducible-prestate-kona` from the monorepo root at the kona-node/v<VERSION> tag. - Preimage output path updated to rust/kona/prestate-artifacts-cannon/ (vs op-program/bin/ in the previous version). - op-challenger flags switched to the cannon-kona variants: OP_CHALLENGER_CANNON_KONA_PRESTATES_URL, OP_CHALLENGER_CANNON_KONA_ROLLUP_CONFIG, OP_CHALLENGER_CANNON_KONA_L2_GENESIS. - Custom-config section is a brief stub linking to the new /chain-operators/tutorials/kona-custom-prestate tutorial for the full unannounced-chain flow. - A short retention note at the bottom points chains still resolving in-flight CANNON games to the archived Upgrade 18 notice. URL slug preserved (no redirects needed). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * docs(chain-operators): archive op-program prestate tutorial Preserves the pre-Upgrade-19 op-program absolute prestate flow at chain-operators/tutorials/archive/op-program-prestate.mdx, with a prominent Warning callout at the top noting the page is archived and pointing readers at the active kona tutorials. This is what the active /chain-operators/tutorials/absolute-prestate "op-program (legacy)" section now links to, instead of the archived Upgrade 18 notice. Nav: adds an "Archive" group under Chain Operators → Tutorials, mirroring the notices/archive structure. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * docs(chain-operators): trim absolute-prestate tutorial to minimal reproducer Per review: the previous rewrite carried over a lot of conceptual prose, alternative-config callouts, and a full Docker run snippet that weren't strictly needed to reproduce a prestate. Cuts those. The remaining content is the minimum required to: 1. Get from `git clone` to a built kona-client prestate 2. Verify the hash against standard-prestates.toml 3. Wire op-challenger to fetch the resulting binary Links to the custom-config tutorial and the archived op-program tutorial remain in the top callout for readers who need those paths. 116 lines removed, 22 added; total 159 -> 65. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * docs(chain-operators): polish kona prestate tutorials - absolute-prestate.mdx: drop the op-program-archive link from the top callout (kept only the custom-config redirect — operators who care about op-program will land via the upgrade-19 notice or the legacy page's own Warning callout); trim op-challenger configure block to the two env vars that actually change for kona, since rollup-config / l2-genesis / game-factory-address are inherited from the existing challenger setup. - kona-custom-prestate.mdx: inline chainList.json + configs.json templates with placeholders so a reader can copy-paste a working starting point without going to the kona-registry README; note that out-of-the-box KONA_CUSTOM_CONFIGS_DIR support needs kona-node/v1.5.2+ (older tags require an extra justfile patch). - docs.json: move the Archive group out of Tutorials and to the same level as Tutorials/Guides/Reference under Chain Operators, so the archive doesn't visually interrupt the active tutorial list. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * docs(kona-prestate): fix prestate-in-gameArgs + add embedded-config check - Correct the registration step: on v2.4+ dispute-game contracts the absolute prestate is NOT a constructor immutable — it lives in DisputeGameFactory gameArgs (clones-with-immutable-args). You reuse the existing permissionless FaultDisputeGame impl with new gameArgs (no fresh deploy per prestate). Show the 124-byte packed gameArgs, the 3-arg setImplementation + setInitBond, and AnchorStateRegistry.setRespectedGameType(8). Note the pre-v2.4 behavior. - Add an "embedded-config" verification step: the build log must list the merged chains and `gunzip | strings | grep <chain>` must match once per chain in chainList.json — catches a silently-dropped chain that otherwise yields the standard prestate hash. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * Update op-program-prestate.mdx --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> Co-authored-by: Zak Ayesh <[email protected]>
…21195)
* feat(op-reth): multi-endpoint quorum validation for interop filter
Fan out interop_checkAccessList to multiple interop-filter endpoints
concurrently inside InteropFilterClient and combine by quorum agreement:
a definitive verdict (valid, or a known SuperchainDAError rejection) counts
toward quorum; transport errors and timeouts do not. The aggregator decides
once min_responses verdicts arrive and does not await slower endpoints.
Accept iff all collected verdicts are valid; all-invalid surfaces the real
reason; a mix logs and rejects (Disagreement); too few definitive verdicts
fail closed (QuorumNotReached). A failsafe reported by any endpoint is a hard
short-circuit rejection regardless of quorum.
query_failsafe ORs admin_getFailsafeEnabled across endpoints, short-circuiting
on the first true so a slow endpoint cannot delay the failsafe poll.
CLI: --rollup.interop-http is now repeatable and --rollup.interop-min-responses
sets the quorum (defaults to the endpoint count, i.e. unanimity / fail-closed).
Single-endpoint configs behave as before. Updates OpPoolBuilder and the
op-rbuilder callers for the new with_interop signature.
* feat(op-reth): detect interop failsafe by dedicated RPC code -320602
Switch failsafe detection in from_json_rpc from matching the error message
to the dedicated JSON-RPC error code -320602 the op-interop-filter server
emits, replacing the previously overloaded -32602. Detection is now by code
only, never by message text. The query_failsafe OR poll and the
check_access_list hard short-circuit on any-endpoint failsafe are unchanged.
This is a hard cutover: detection requires the filter to emit -320602, a
prerequisite server change that must deploy first.
* feat(op-reth): a received failsafe beats a met quorum, deterministically
When the valid+invalid quorum is reached, non-blocking-drain the endpoint
futures that are already ready before returning Ok, and reject if any is
FailsafeEnabled. This makes "a failsafe that has arrived rejects even when the
minimum valids are in hand" deterministic instead of arrival-order dependent.
Endpoints that have not responded are still never awaited (fast-accept is
preserved); dropping the futures cancels them.
Make failsafe_on_any_endpoint_hard_rejects deterministic by requiring all
endpoints to resolve before the decision, and add a test proving a slow
non-failsafe endpoint does not delay accept.
* fix(op-reth): classify filter verdicts — definitive rejections vs soft out-of-sync
Two related classification fixes for the multi-endpoint interop aggregator.
Definitive rejections: a fabricated access list entry is rejected by the filter
with a generic -32602 "failed to parse access entry" (not a SuperchainDAError
code). is_definitive_invalid only counted InvalidEntry, so this legitimate
rejection was mis-classified as a non-response — with a single endpoint (min=1)
the aggregator collected 0 definitive verdicts and returned QuorumNotReached
instead of the filter's real rejection, regressing
TestInteropFilter_IngressRejectsInvalid. Now any JSON-RPC error response from
the filter is a definitive verdict (new Rejected { code, message } variant,
preserving the real reason) except the JSON-RPC internal error -32603, which
stays a non-response.
Soft out-of-sync failures: codes meaning "this node does not have the data yet"
— FutureData (-321401) and Uninitialized (-320400) — are soft, non-response
failures (new DataUnavailable variant; neither definitive_invalid nor failsafe).
A single out-of-sync node is ignored as long as the quorum is met by other
nodes; if every node is out of sync the aggregator fails closed
(QuorumNotReached). FutureData is a SuperchainDAError variant, so the soft check
precedes the SuperchainDAError mapping.
Classification order in from_json_rpc: no error response → Other (transport);
-320602 → FailsafeEnabled; (-321401|-320400) → DataUnavailable; SuperchainDAError
→ InvalidEntry; -32603 → Other; else → Rejected.
Verified with the op-acceptance-tests interop/filter suite:
TestInteropFilter_IngressRejectsInvalid and TestInteropFilter_FailsafeLifecycle
both pass.
* fix(op-reth): address interop-filter multi-endpoint review feedback
- query_failsafe no longer clears the failsafe gate on partial replies:
clearing to false now requires every endpoint to reply false; partial
info leaves the cached state unchanged (a silent endpoint may itself be
in failsafe). Turning the gate on still short-circuits on the first true.
- A failsafe detected during a check flips the cached gate/gauge immediately
(reject_failsafe) so admission stops and the dashboard reflects it without
waiting for the next ~1s poll.
- Per-endpoint metrics labeled by endpoint index (EndpointMetrics): latency,
valid/invalid/unavailable, so "which endpoint is slow/down/dissenting?" is
answerable. Labeled by index, never the raw URL (creds).
- Rate-limited info log when a check fails closed on an unmet quorum, plus a
startup info log of the effective min_responses / endpoint count, so a
degraded-quorum interop halt is visible beyond the counter.
- Spell out in --rollup.interop-min-responses help that the unanimity default
means any single unreachable/out-of-sync endpoint blocks all interop
admission, and suggest a majority quorum to tolerate a degraded endpoint.
* fix(op-reth): correct intra-doc link to InteropFilterClient
The crate::InteropFilterClient path does not resolve (the type is
re-exported from the interop_filter module, not the crate root). Use the
in-scope bracketed name so rustdoc -D warnings passes.
* feat(op-chain-ops): add check-interop smoke-test CLI A small CLI under op-chain-ops/cmd/check-interop for smoke-testing interop cross-chain messaging against a running pair of L2 chains. Subcommands: - roundtrip: bridges ETH A->B and B->A via the SuperchainETHBridge predeploy, relaying each message itself through L2ToL2CrossDomainMessenger.relayMessage, and asserts the recipient is credited the exact amount on each destination chain. No contract deploys — it uses the predeploys that already exist. - failsafe: verifies the op-interop-filter failsafe lifecycle via the filter admin RPC — a bridge succeeds, its relay is rejected while failsafe is enabled, and succeeds again once disabled. Flags can be supplied via CLI, CHECK_INTEROP_* env vars, or a TOML config file (--config); CLI and env values override the file. Endpoints can be any reachable RPC URL (e.g. a devnet's direct ingress), so no port-forward is required. * feat(op-chain-ops): add --iterations to check-interop roundtrip The roundtrip command now repeats the A->B / B->A cycle N times (default 3) via a new --iterations flag (env CHECK_INTEROP_ITERATIONS, config key "iterations"). The flag is registered only on the roundtrip command. Each iteration runs both legs and stops on the first failure, wrapping the error with "iteration i/N" for context. * test(op-chain-ops): address check-interop review feedback - randomRecipient: surface rand.Read errors via panic instead of discarding with blank `_` (repo baseline disallows blank error returns; crypto/rand failure is not expected) - add TestInteropTxRejected table test covering all recognized interop rejection substrings, a wrapped-error case, and negative cases - config.example.toml: group keys under which subcommand uses them
…ders (#21287) Create op-core/params, the OP-Stack chain config layer, ported from op-geth. Additive only: no call sites are swapped yet. - OptimismConfig: verbatim JSON tags from op-geth (the value is serialised as rollup.Config.ChainOpConfig, so the wire format must stay identical). - ChainConfig: a standalone type carrying the OP hardfork schedule. It does NOT embed go-ethereum's params.ChainConfig, so it cannot promote go-ethereum's OP-unaware EIP-1559 methods (ElasticityMultiplier, BaseFeeChangeDenominator) and return L1 defaults — there is no silent-wrong-default footgun. Fork predicates use a single ActivationTime / SetActivationTime switch pair with IsForkActive- delegating Is<Fork> methods, matching rollup.Config (tracked in #21267). - GethChainConfig: converts to the equivalent go-ethereum params.ChainConfig for code that drives a go-ethereum EVM, genesis, or block processor; its output mirrors op-geth's LoadOPStackChainConfig. - LoadChainConfig / LoadChainConfigFromChainID: replace op-geth's LoadOPStackChainConfig. The by-chain-ID loader lives here, not in op-core/superchain, so op-core/params -> op-core/superchain stays one-way and the two packages never form an import cycle. The zero-caller op-core/superchain stub that delegated to op-geth is removed. A registry-wide differential test asserts GethChainConfig reproduces op-geth's LoadOPStackChainConfig byte-for-byte across every embedded chain. Update docs/ai/opgeth-decoupling.md (sections 5-7, summary, and a new section 14) to the standalone + GethChainConfig design and the genesis-tooling migration path. Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
… releases index (#21280) Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
Fixes ethereum-optimism/optimism-private#552. The OP fork chronology is Jovian < Karst < Lagoon(Interop), so Interop is the newest fork. Fix 1 (kona-genesis): RollupConfig::spec_id jumped from HOLOCENE straight to FJORD with no GRANITE branch, so Granite-era (post-Granite, pre-Holocene) blocks wrongly resolved to FJORD. This diverges from op-geth, which enforces the restricted bn256Pairing precompile (input limit 112687) at IsOptimismGranite, and from op-revm, which selects it only for GRANITE. Add the missing GRANITE branch between HOLOCENE and FJORD. Fix 2 (op-revm): into_eth_spec mapped the newer INTEROP to PRAGUE while the older KARST mapped to OSAKA, i.e. a downgrade of the eth base for a newer fork. op-geth decouples the eth base via independent OsakaTime/PragueTime, so a post-Interop block's eth base should be Osaka (matching Karst). Map INTEROP to OSAKA alongside KARST. Fix 3 (alloy-op-evm): spec_by_timestamp_after_bedrock checked Karst before Lagoon/Interop, returning KARST for post-Lagoon blocks. Reorder to check Lagoon/Interop first (newest-first), matching kona's correct ordering. Add conformance guards in op-revm and alloy-op-evm locking in the newest-first fork ordering and eth-base monotonicity (a newer OP fork must never map to an older eth base). Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
* chore: remove op-program from the monorepo op-program is no longer used: op-e2e/op-devstack were decoupled (ethereum-optimism/optimism#21254, #21257) and op-challenger no longer requires the op-program server binary for the permissioned game type, while the legacy Cannon game type (0) is no longer in use. Kona is the in-tree fault-proof program in production. - Delete the op-program/ directory. - Remove op-program build/test/prestate targets from justfile, Makefile, op-e2e/justfile, and the err113 lint exception from .golangci.yaml. - Remove op-program CircleCI jobs (sanitize-op-program, analyze-op-program-client, op-program-compat, publish-cannon-prestates, preimage-reproducibility), their workflow wiring, the op-program/v.* release-tag prestate publishing, and the now-dead preimage-reproducibility scheduled pipeline plumbing. - go mod tidy (no transitive dep changes). GitHub Actions image config (.github/images.json) is intentionally left untouched. Completes ethereum-optimism/optimism#20276. * chore: drop stale op-program reference from rust/justfile comment * chore: fix dangling cannon-prestates refs after op-program removal The op-program removal deleted the root justfile cannon-prestates recipe, but two callers still referenced it. Acceptance tests now consume the kona prestate (via CannonKona game types and rust/kona/prestate-artifacts-cannon), so point op-acceptance-tests build-deps at just build-kona-prestates, and drop the now-dead cannon-prestates deprecated shim from op-e2e/Makefile. * chore: restore cannon-prestates as a kona-only recipe and update docs - Re-add `just cannon-prestates` (and keep `just reproducible-prestate`) building only the kona prestates, so existing callers keep working after op-program removal. - Remove op-program references from docs: README/AGENTS component listings, op-node/op-preimage READMEs, the acceptance-tests prestate note, and rewrite the cannon and op-challenger README examples to use kona (kona-host / cannon-kona). - Delete the vm-compat-triage skill, which triaged the now-removed analyze-op-program-client CI job. * Fix comment Co-authored-by: Adrian Sutton <[email protected]> * chore: keep prestate reproducibility check, move it out of op-program The preimage-reproducibility CI job verifies the reproducibility of every released cannon prestate — both op-program (op-program/v* tags) and kona (kona-client/v* tags, including legacy) — against the superchain-registry standard prestates. It must be kept after op-program removal: it still covers kona, and historical op-program prestates are rebuilt from their own checked-out release tags (which retain op-program), so that coverage is preserved too. - Move the driving scripts out of the deleted op-program tree to ops/prestate-reproducibility/ (build-prestates.sh + the prestates verify Go package), fixing the import path and temp-dir locations. - Add a `verify-reproducibility` recipe to the root justfile. - Restore the preimage-reproducibility CircleCI job (now run from the repo root via `just verify-reproducibility`), the scheduled-preimage-reproducibility workflow, and its dispatch plumbing. - Point op-acceptance-tests build-deps back at the generic `just cannon-prestates`. * chore(op-e2e): remove obsolete engineapi conformance test suite TestEngineAPITests ran the engineapi/test RunEngineAPITests suite, which was a factory-parameterized conformance suite originally used to prove the op-program engine backend matched op-geth. With op-program removed there is only one backend left, so the parity motivation is gone and the suite only re-exercises op-geth behavior already covered elsewhere. Remove the test and the engineapi/test subpackage (its sole consumer). The main engineapi package stays — it is the in-process L2 engine used by the action-test framework. * chore(op-challenger): drop op-program from the op-challenger docker image (#21284) * chore(op-challenger): drop op-program from the op-challenger docker image The op-challenger image bundled the op-program binary as the legacy cannon server (OP_CHALLENGER_CANNON_SERVER). With op-program removed from the monorepo the COPY from the op-program-builder stage fails, breaking the image build. Drop the op-program COPY and the OP_CHALLENGER_CANNON_SERVER env. The image still ships cannon and kona-host (OP_CHALLENGER_CANNON_KONA_SERVER / OP_CHALLENGER_ASTERISC_KONA_SERVER), which is what production fault proofs use; the legacy cannon game type (0) is no longer in use and the permissioned game type never runs a fault-proof server. * chore: remove the op-program docker image (#21285) op-program has been removed from the monorepo, so the op-program docker image can no longer be built. Remove it everywhere it's defined: - .github/images.json: drop the op-program image entry, and the stale op-program/** path glob from the op-challenger image's trigger paths. - docker-bake.hcl: remove the op-program bake target and the now-unused OP_PROGRAM_VERSION variable. - ops/docker/op-stack-go/Dockerfile: remove the op-program-builder and op-program-target build stages. The op-challenger image already stopped referencing op-program in the previous stacked PR.
* op-alloy: reject zero elasticity in eip1559 params decoding Following up on #18625, also catch zero elasticities during EIP-1559 params decoding. Catching this at the op-alloy level makes decoding fail early, mirroring the Go validation in op-geth and op-reth#20858. `decode_holocene_extra_data` and `decode_jovian_extra_data` now reject a zero denominator (`ZeroDenominator`) and a zero elasticity (`ZeroElasticity`) in the block-header extraData, matching the Go `validateHoloceneExtraDataPart` rule that both values must be non-zero. Since the zero-denominator (and now zero-elasticity) case is caught early in op-alloy, the redundant `denominator == 0` checks and the now-unused `Eip1559ValidationError::ZeroDenominator` variant are removed from kona-executor. Closes #18951 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * op-reth: drop unreachable both-zero base-fee fallback With #18951, decode_holocene_extra_data / decode_jovian_extra_data reject a zero denominator or elasticity, making the both-zero fallback to chain-default base-fee params in decode_holocene_base_fee / compute_jovian_base_fee unreachable. Remove it and the now-unused chain_spec/timestamp parameters. Refs #18951 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * op-alloy: drop private intra-doc links in eip1559 docs The `validate_extra_data_eip_1559_params` references in the public decode_holocene_extra_data / decode_jovian_extra_data docs link to a private helper, which fails `rustdoc::private_intra_doc_links` under `-D warnings` (rust-docs CI). The docs already state the non-zero rule, so drop the references. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * op-alloy/op-reth: address review — consensus base-fee tests + nits - reth-optimism-consensus: 4 base-fee tests fed raw (0,0) eip1559 params and asserted the old translate-to-defaults result, which now returns None since a (0,0) header is invalid per Holocene. The holocene extra_data_not_set test now asserts None; the three Jovian min-base-fee tests encode the chain defaults (as a real header does) so they keep exercising the min-base-fee floor. - op-alloy: order validate_extra_data_eip_1559_params args as (elasticity, denominator) to match decode_eip_1559_params; reword the Jovian decoder doc to 'inherits the Holocene header rules'. Refs #18951 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * kona-engine: update attributes eip1559 tests for stricter decode The op-alloy change rejects a zero denominator/elasticity in header extraData, so two attributes tests that fed an all-zero (0, 0) block header and asserted the old translate-to-(0, 0) value mismatch now fail at decode instead. Both now assert UnknownExtraDataDecodingError(ZeroDenominator), matching the sibling test that does so for InvalidExtraDataLength. Drop the now-unused EIP1559Parameters import. Refs #18951 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
…(#21515) Adds a MixedL2ELOpRethPremium EL kind that boots op-reth-premium in place of op-reth. The premium binary uses reth_optimism_cli::Cli (the same CLI as op-reth, with the proofs subcommands) plus an additive --subblocks.* namespace, so it is a genuine CLI superset and reuses the existing buildMixedOpRethNode invocation unchanged — only the resolved binary differs (new OpRethWithBinary option / OpRethConfig.Binary). Wired into both EL dispatch sites (NewMixedSingleChainRuntime and the env-driven startL2ELForKey, so DEVSTACK_L2EL_KIND=op-reth-premium also works). op-reth-premium lives in a separate repo, so it is resolved via the existing rustbin env overrides (RUST_BINARY_PATH_OP_RETH_PREMIUM, or RUST_SRC_DIR_OP_RETH_PREMIUM + RUST_JIT_BUILD). Adds TestPremiumSequencerProducesDerivableBlocks: a baseline regression guard that boots a premium sequencer (subblocks producer, SDM off) with a stock op-reth verifier and asserts both unsafe heads advance — i.e. premium produces derivable blocks as a drop-in. It does NOT assert SDM / 0x7D behavior (premium does not produce PostExec blocks yet). The test skips unless the premium binary is provided, so it is inert in CI without a premium image and never fails there. Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
… state-root mismatch (#21495) * fix(op-reth): surface pruned block bodies as a typed error instead of state-root mismatch * ci fixes * op-rbuilder fixes * bump rollup-boost cargo * review fixes * revert op-rbuilder change * revert space changes
…pt-in TOCTOU) (#21502) * fix(sdm): harden post-exec payload handling Reject Verify blocks that claim refunds without the trailing post-exec tx, and snapshot PostExecMode once per payload build so EVM setup and 0x7D appending agree. * fix(op-reth): sync op-rbuilder and rollup-boost lockfiles The reth-codec opt-in change (#21483) added reth-optimism-primitives as a dependency of reth-optimism-post-exec-replay but only updated the main rust workspace lockfile. The op-rbuilder and rollup-boost workspaces depend on that crate via path, so their Cargo.lock files went stale and the Docker builds (which run `cargo chef cook --locked`) failed with "cannot update the lock file because --locked was passed". Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
The report cover page identifies it as a Cantina Managed review, not Spearbit. Rename the PDF and update the ledger row to match.
…/fees (#21508) * op-core: wire op-node onto op-core/eip1559 and txinclude onto op-core/fees Switch op-node's eip1559 consumers and op-service/txinclude's fee consumers off op-geth onto the op-core packages, completing the eip1559 + fees parts of #20271 (sub-issue #21500). The superchain part landed separately in #21487. eip1559: swap the import path in payload_util.go, engine_consolidate.go, system_config.go (+ engine_consolidate_test.go) to op-core/eip1559, and add the ValidateOptimismExtraData helper the initial extraction omitted (+ test). fees: in txbudget.go and cost_oracle.go, replace types.NewL1CostFuncFjord and tx.RollupCostData() with the op-core/fees equivalents. Simplify the op-core/fees L1-cost API to free functions (L1CostEcotone/L1CostFjord taking an L1FeeParams struct), consistent with the existing L1CostBedrock — dropping the closure factories, the L1CostFunc type, and op-geth's vestigial calldataGasUsed return and blockTime arg, none of which any monorepo consumer needs. Add a live differential test pinning L1CostFjord to op-geth's NewL1CostFuncFjord. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * op-core/eip1559: dedupe ValidateOptimismExtraData dispatch test Trim TestValidateOptimismExtraData to cover only fork dispatch — each per-fork validator's edge cases stay in its own test (TestValidateHoloceneExtraData), removing the overlap a reviewer flagged. Keep ValidateHoloceneExtraData / ValidateJovianExtraData public rather than folding them behind ValidateOptimismExtraData: with the whole monorepo in scope for the op-geth decoupling, op-chain-ops/check-jovian (an ethclient checker that stays in Go, not block-building) is a real direct consumer of ValidateJovianExtraData. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * op-sync-tester: swap eip1559 onto op-core/eip1559 op-sync-tester validates header extraData and PayloadAttributes 1559 params via the eip1559 helpers; point them at op-core/eip1559 (pure rename, the functions already match). Removing op-sync-tester's remaining op-geth coupling — notably the miner.BuildPayloadArgs.Id() PayloadID hash — is tracked in #21525. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs(ai): widen opgeth-decoupling scope to the whole monorepo Replace the "in scope / out of scope" subset with the three-fates framing (swap-to-op-core / migrate-execution-to-op-reth / delete), and surface two components the plan had missed: op-sync-tester (a CL-sync EL mock that does no execution — a swap target, with its OP-aware PayloadID hash tracked in #21525) and the op-chain-ops/cmd/check-* per-fork checker family. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs(ai): drop op-program/op-supervisor from opgeth-decoupling doc Both have been removed from the monorepo (op-program superseded by rust/kona, op-supervisor by op-supernode), so the "replaced, not decoupled" note, the §12 out-of-scope subsection, and the §14 execution-engine reference to them are stale. Per PR review. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Bumps Go module dependencies to clear Grype findings on current develop:
- golang.org/x/crypto v0.46.0 -> v0.53.0
- golang.org/x/net v0.48.0 -> v0.56.0
- golang.org/x/sys v0.40.0 -> v0.46.0
- golang.org/x/image v0.25.0 -> v0.43.0
- go.opentelemetry.io/otel{,/trace,/metric} v1.40.0 -> v1.44.0
Related golang.org/x modules updated by the solver: x/mod, x/sync, x/term,
x/text, x/tools, and x/telemetry.
Leaves quic-go/webtransport-go for a separate libp2p upgrade, and leaves the
btcd scanner finding untouched because the latest btcd module split breaks
existing btcutil import paths.
* cleanup(contracts): rename super permissioned game type * review comments
* fix(op-rbuilder): gate interop txs during failsafe * fix(op-rbuilder): remove interop feature gate
…ns) (#21441) * fix(derive): keep upgrade gas on a NUT-bundle fork's activation block only Karst introduced "upgrade gas": extra gas added to a NUT-bundle fork's activation block gas limit so the network-upgrade transactions fit. It is meant to apply only to the activation block, but it stuck to every later block — the SystemConfig gas limit is reconstructed from the parent header (op-node PayloadToSystemConfig / kona to_system_config), so the inflated activation-block limit was read back as the steady-state limit indefinitely. op-node and kona shared the bug, so they agreed but were both wrong. Subtract the upgrade gas again at the block right after the activation block, for every NUT-bundle fork from Karst onward (forks.From(forks.Karst) in Go, OpHardfork::Karst.forks_from() in Rust), so future forks are covered automatically. A new rollup-config bool KeepKarstUpgradeGas / keep_karst_upgrade_gas (default false) lets chains that already activated Karst with the leak baked into their history opt out of the Karst subtraction only, so their history still validates; the operator clears it later with setGasLimit. The strip runs during system-config reconstruction, before UpdateSystemConfigWithL1Receipts / update_with_receipts, so a setGasLimit in the post-activation block's L1 origin still takes precedence. Also syncs the superchain-registry submodule to the companion change (ethereum-optimism/superchain-registry#1259), which enables keep_karst_upgrade_gas per-chain for the affected sepolia and mainnet chains, and regenerates the Go + Rust embeddings via `just sync-superchain`. Migrates the op-node derive test `ptr` helper to the shared op-service/ptr.New. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * derive: address upgrade-gas PR review feedback Addresses review comments on #21441. op-node: - Simplify upgradeGasToStrip to a one-fork-per-block early return. - Reword the strip doc/inline comments ("Starting with Karst", "subtract it back here"). - Tests: activate Jovian at genesis, fix an assertion message, parameterize TestUpgradeGasToStrip over forks.From(Karst), and drive the setGasLimit-precedence case through PreparePayloadAttributes instead of duplicating the strip/update ordering. - Print keep_karst_upgrade_gas at startup when set, and add the --override.keep-karst-upgrade-gas flag. kona: - Extract a public upgrade_gas(fork) getter with a VARIANTS guard test (OpHardfork is #[non_exhaustive], so a missing fork can't fail compilation). - Early-return simplification mirroring op-node; reword the strip comment. - HardForkConfig::Display prints keep_karst_upgrade_gas when set; move its comment between Karst and Lagoon. - Add the --keep-karst-upgrade-gas-override flag to kona-node and kona-cli. - Action test: prove the post-activation block too. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * kona test: prove post-activation block in NUT-bundle action test Run the fault-proof program over the post-activation block too, so kona-client verifies the gas-limit revert directly rather than relying only on op-node's assertion. Addresses review feedback on #21441. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * superchain: re-pin registry to superchain-registry#1259 merge commit Bump the superchain-registry submodule to d84b53b (the #1259 merge into SR main, adding keep_karst_upgrade_gas) and regenerate the Go + Rust embeddings via `just sync-superchain`. superchain-registry#1263 removed creator-chain-testnet and ethernity, so only lisk and the OP-stack chains carry the flag now. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * derive: address tuicr review feedback - payload_util_test: use op-service/ptr.New instead of a local minBaseFee const. - kona: extract a RollupConfig::is_fork_activation_block helper (mirrors op-node's IsActivationBlockForFork) and use it in upgrade_gas_to_strip. - kona: fix the Lagoon override env var (KONA[_NODE]_OVERRIDE_INTEROP -> KONA[_NODE]_OVERRIDE_LAGOON), a leftover from the Interop -> Lagoon rename. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * rust: refresh SP1 guest Cargo.lock kona-protocol depends on alloy-op-hardforks and kona-hardforks (the upgrade_gas logic); the SP1 guest workspace path-depends on kona-protocol, so its separate lockfile needs those entries. Regenerated via `just lock-sp1-guest`. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * fix(ci): make op-reth-compact-codec resilient to a superchain-registry bump The op-reth-compact-codec job builds op-reth on develop (to write compact vectors) and then on the PR branch (to read them). `git checkout` switches the tracked files between base and PR but leaves both the superchain-registry submodule working tree and the gitignored res/superchain-configs.tar at the other side's content. reth-optimism-chainspec's build.rs (superchain-configs is a hard, unconditional dep of the op-reth bin) regenerates/validates that tar against the committed .sha256, so on a PR that bumps the submodule it panics on a base-vs-PR mismatch. After each checkout, re-sync the submodule to the checked-out pin (`just update-superchain-registry-submodule`) and drop the stale gitignored tar so build.rs regenerates it from the now-current submodule. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * derive: address further PR review feedback - kona to_system_config / upgrade_gas_to_strip tests: activate all forks through Jovian at genesis via a forks_through_jovian_at_genesis() helper, matching the op-node test's fork schedule (geoknee). - kona NUT-bundle action test: prove the activation-block span before building the post-activation block (in addition to the post-activation span), and refresh the stale Lagoon early-return comment (drop the closed-#21114 reference and the outdated "op-node strips just Karst" note). - docs/ai/fault-proofs.md: call out that these tests cover op-node (which sequences and derives the chain) as well as kona-client (which proves it). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * genesis: add modular HardForkConfig fork accessors + activate_at_genesis Replaces the ad-hoc test helper with a proper API on HardForkConfig, mirroring op-node's Config.ActivateAtGenesis: OpHardfork-keyed fork_time / set_fork_time accessors and activate_at_genesis(fork), which iterates the fork sequence setting each to genesis up to and including the target. The kona to_system_config and upgrade_gas_to_strip tests use it (via a thin karst_at helper) so their fork schedule matches the op-node test. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * karst: add keep_karst_upgrade_gas action-test variant + deploy-config plumbing Adds TestKarstActivationKeepUpgradeGas to the NUT-bundle action test, covering the keep_karst_upgrade_gas opt-out (the other branch of testActivationBlockNUTBundle's revert assertion): the inflated activation-block gas limit must persist on later blocks, and kona-client must agree. The flag is set the same way as fork timestamps — via the deploy config: a new KeepKarstUpgradeGas field on UpgradeScheduleDeployConfig flows into rollup.Config through DeployConfig.RollupConfig(), and activateFork takes a keep parameter that sets it. This bakes the opt-out into the whole chain (sequencer, derivation, fault proof) from genesis, rather than mutating the live rollup config mid-test. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * e2eutils: propagate keep_karst_upgrade_gas into the action-test rollup config e2eutils.Setup builds rollup.Config by hand and wasn't copying the deploy config's KeepKarstUpgradeGas, so the kona fault-proof action test's keep variant (TestKarstActivationKeepUpgradeGas) saw the default and reverted the gas limit. Copy the field, alongside the fork-time fields it sits next to. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * karst: assert exact activation-block gas limit in the NUT-bundle action tests Check the activation block's gas limit is exactly preActivation + UpgradeGas(fork) rather than merely greater, in both the revert and keep variants. Verified locally: TestActivationBlockNUTBundle and TestKarstActivationKeepUpgradeGas both pass under a freshly built kona-host (revert + keep, fault proofs included). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
…stall (#21532) Follow-up to #21489. The ci-base-clang image now ships protobuf-compiler + libprotobuf-dev (the sp1-sdk prost/tonic build dep), so the per-job apt-get fallback install added in that PR is no longer needed. - Pin the rebuilt ci-base-clang digest (sha256:873a6709…, attested by the build-images workflow on develop; provenance verified by security.yml). This also realigns the c-rust_base_image fragment defaults, which had drifted to an older digest (758f67c7…) since the last manual bump (#21361) only updated config.yml + main.yml's rust_base_image. - Replace the protoc apt-get install in rust-prepare with a clang-style presence check that fails fast if protoc / the protobuf well-known type includes are missing from the image. Validated: merge-configs.sh, circleci config validate (orb stubbed), and test-decision-tree.sh (18/0). Co-authored-by: wwared <[email protected]>
* feat(op-node): remove deprecated Req/Resp CL P2P sync client Removes the client side of the deprecated Req/Resp CL P2P sync protocol from op-node, while keeping the serving side (ReqRespServer) intact. This is the first of two changes: serving payloads to peers that still request them lets nodes on older versions keep syncing against upgraded nodes during a rolling upgrade. The server is removed in a follow-up. - Delete the SyncClient (and all client-only helpers) from op-node/p2p/sync.go; the file now contains only ReqRespServer and the shared stream/protocol helpers it needs. - Strip client activation/wiring from NodeP2P: the req-resp serving side is still registered behind `p2p.sync.req-resp` (+ a data-source), but the client peer-tracking, RequestL2Range and AltSyncEnabled are gone. - Remove the driver AltSync interface, the altSync field/param, and OpNode.RequestL2Range / unixTimeStale. The unsafe-queue gap-check ticker is kept (renamed altSync* -> unsafeGap* locals) and now always drives the engine-queue gap-fill path. - Make `syncmode.req-resp` and `p2p.sync.onlyreqtostatic` hidden, deprecated no-op flags; delete `sync.Config.SyncModeReqResp` and simplify every branch that read it (sync_deriver, engine_controller) to the false path. Drop the cross-flag startup validation in service.go. `p2p.sync.req-resp` stays active and now gates only the serving side. - Remove the client payload-by-number metrics (ClientPayloadByNumberEvent, PayloadsQuarantineSize) and the quarantine collector; keep the server metric and the shared p2p req collectors. - Update devstack/op-e2e/op-acceptance-tests: drop the client-only UseReqResp(Sync) knobs (keeping EnableReqResp* which gates the server); delete the enabled-path depreqres suite and the e2e TestSystemP2PAltSync; keep a server-only TestMutexUnlocks in p2p/sync_test.go. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs(op-node): address review comments on req-resp client removal - Note that the req-resp sync server will be deprecated in a future release in favor of EL P2P sync, in the p2p.sync.req-resp flag usage. - Adapt the checkForGapInUnsafeQueue comment: it no longer retrieves payloads from peers over the network; it re-inserts the locally queued unsafe payload to drive the engine-queue gap-fill. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
…ot `earliest` (#21543)
Adds a Karst-activation acceptance test in op-acceptance-tests/tests/karst that activates Karst mid-chain and observes the gas limit across the pre-activation, activation, and post-activation blocks. It asserts the activation block carries the one-time NUT-bundle upgrade gas (gas limit > pre-activation) and that the post-activation block reverts to the steady-state limit, covering the fix in #21441. Two variants: - default: post-activation gas limit reverts to the pre-activation value. - keep_karst_upgrade_gas = true: post-activation gas limit keeps the inflated activation-block value. Each variant runs the kona-client fault proof (RunKonaNative) over a span agreeing on the pre-activation block and proving into the post-activation block, so the fault-proof program covers the behaviour too. Plumbs keep_karst_upgrade_gas through the deploy path so the second variant can opt out: a KeepKarstUpgradeGas DeployConfig field flows into rollup.Config via RollupConfig(), an intentbuilder L2 setter writes the deploy override, and a sysgo.WithKeepKarstUpgradeGas deployer option sets it on all L2s. Adds a small L2ELNode.GasLimitAtBlock DSL getter. Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
…694) (#21146) * docs(op-stack): reflect op-reth/kona defaults in protocol explainers Light conceptual-prose pass for the op-geth -> op-reth and op-program -> kona-client deprecations (partial #694): - fp-components: present kona-client as the default fault-proof program; op-program framed as predecessor with EOS at Karst - transaction-flow: state execution by "the execution client (op-reth by default)"; op-geth noted as supported-but-EOS - smart-contracts: MIPS-upgrade note covers kona-client (Cannon VM stays, client program changes) Out of scope here (op-geth-specific operational config or historical source links): architecture.mdx (GETH_* config -> #691), components.mdx, fees.mdx, sync-op-mainnet.mdx. Refs ethereum-optimism/solutions#694 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs(chain-operators): convert network-design-example to op-reth architecture.mdx (#694): replace op-geth as the default EL in prose and convert the GETH_* config blocks to op-reth. - txpool/netrestrict/gossip blocks -> op-reth CLI flags (--txpool.disable-transactions-backup/.nolocals/.lifetime, --netrestrict); op-reth has no GETH_*-style env vars for these (reth clap args define no env=; only globals like RETH_DATADIR exist) - archive: op-reth is archive by default (no gcmode); full -> --full - DB_ENGINE / STATE_SCHEME / snap syncmode have no op-reth equivalent (MDBX storage + staged sync) -> honest notes, snapshot-restore guidance - fix pre-existing broken /operators/* monitorism link Refs ethereum-optimism/solutions#694 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs(op-stack): point EVM/tx-encoding source links to op-reth stack #694 follow-up on the two remaining source-link pages: - components.mdx: drop the op-geth diff-viewer link and the geth-comparison Specifications line; point EVM "Source code" to op-reth (rust/op-reth) - fees.mdx: repoint the tx-RLP encoding links from op-geth's core/types/transaction.go to op-alloy's OpTxEnvelope (rust/op-alloy/.../transaction/envelope.rs); keep "standard Ethereum transaction RLP encoding" phrasing (accurate for user txs) Refs ethereum-optimism/solutions#694 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs(fault-proofs): frame cannon-kona as the path forward in challenger explainer challenger.mdx (#694): the op-challenger trace-executables note presented cannon/op-program host/kona-host as a flat list. Reframe so cannon-kona (kona-host) is the respected game type going forward and op-program host / the legacy cannon game type is marked end-of-support at Karst. Refs ethereum-optimism/solutions#694 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs: drop architecture.mdx from explainers PR Defer the network-design-example op-reth retarget to the dedicated PR #21296 (docs/network-design-op-reth) to avoid a merge conflict on this file; #21146 keeps its protocol-explainer scope. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs: address review on explainers migration - smart-contracts: revert Holocene MIPS bullet to op-program (point-in-time release note) - fees: restore pinned op-geth RLP encoding links (stable vs unpinned op-alloy/develop) - transaction-flow: end-of-support past tense + drop redundant double-link Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs: fix op-geth support tense contradiction in transaction-flow "is also supported but reached end-of-support" was self-contradictory; reword to past tense "was previously supported but reached". Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
…1528) * feat(kona): add kona-sp1 range-executor + SP1 execute action test Add an SP1 execute test harness so the kona-sp1 range guest can be exercised end-to-end by op-e2e action tests, mirroring the native fault-proof program harness. - New `kona-sp1-range-executor` binary: takes the native kona-host `single` boot inputs, generates the witness via the kona-host preimage server, runs the range guest in SP1 execute mode (no proving), reads the committed BootInfoStruct, and exits 0 (valid) / 1 (invalid claim) / 2 (infra), matching the native fault-proof exit-code convention. - Go wiring: rustbin.RunKonaSP1Range (shared oracle-server exec path), RunRangeExecutor + ProgramRunner refactor in the proofs helpers, RunSP1RangeProgram env method, and TestSP1RangeSimpleEmptyChain. - just recipes (build-range-executor, action-tests-sp1) + README section. - Add ETHDAWitnessGenerator::new()/Default and use it from the host. The test skips unless KONA_SP1_RANGE_EXECUTOR_PATH is set and is not yet wired into a CI job (needs the Dockerized SP1 ELF build in CI). It covers the honest-claim path only; the host-side witness generator rejects invalid claims before the guest runs, so invalid-claim coverage is a follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * fix zepter lint * cargo fmt * review comments --------- Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
* feat: add FeeVault withdrawal route setter Allow proxy admin owners to update the fee recipient and withdrawal network atomically. * fix: bump FeeVault NUT deployment gas limits Increase FeeVault implementation deployment headroom so generated upgrade bundles satisfy CI gas profile checks. * doc(ctb): add context on natspec comment * fix: bump L2ContractsManager semver for inlined FeeVault gas limits The FeeVault deployGasLimit bumps in Predeploys.sol are inlined at compile time into L2ContractsManager, changing its initCodeHash. The semver-diff check requires a version bump whenever semver-lock.json changes. * chore: regenerate current-upgrade-bundle.json for L2CM version bump L2ContractsManager 1.10.0 changes its compiled bytecode, which the upgrade bundle embeds. Regenerated via `just generate-nut-bundle`. * debug: dump callTracer for reverted activation-block txs Surfaces the revert frame for TestActivationBlockNUTBundle failures so karst-jovian tx 31 can be diagnosed in CI logs. * fix(contracts): update semver-lock * fix(deployment): bump gas limit left out during merge conflict * test(feevault): remove debug code * fix(feevault): use prefork state in tests which start pre-fork, and activate at runtime * fix(feevault): preserve storage during overlay --------- Co-authored-by: 0xCoati <[email protected]>
…(#21211) Document SDM: block-scoped warming rebates, the protocol/operator gates, the admin_setSdmPostExecOptIn and admin_sdmStatus RPCs, and verification. Register the page in the Features nav. Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
…21566) op-node's superchain-registry decoder dropped keep_karst_upgrade_gas: the Go HardforkConfig struct had no field for it (BurntSushi/toml silently ignores unknown keys) and applyHardforks never copied it. So an op-node started with --network=op-sepolia (or op-mainnet) loaded the flag as false even though the registry sets keep_karst_upgrade_gas = true, and would subtract the Karst upgrade gas at the post-activation block and diverge from canonical history. Operators had to pass --override.keep-karst-upgrade-gas by hand. PR #21441 wired the flag into kona (its HardForkConfig reads it from the embedded registry) and added the op-node rollup.Config field plus the CLI override, but never extended the Go SCR-loading path. This closes that gap: - Add KeepKarstUpgradeGas to superchain.HardforkConfig so the TOML key is decoded. - Copy it in applyHardforks alongside the fork-time fields. Tested first: asserting KeepKarstUpgradeGas == true for the SCR-loaded sepolia and mainnet configs in TestGetRollupConfig fails on the baseline (expected true, actual false) and passes after the fix. The reflection-based TestApplyHardforks is updated to handle the new non-pointer bool field. Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Extract the kona-sp1 range execution logic behind a shared Rust API so tests can exercise the core without running the SP1 ELF. Keep the guest entrypoint as the SP1 IO wrapper and add a range-executor native-core mode for faster action-test coverage while preserving the full SP1 execute smoke path.
BlobStore leaned on two implicit invariants: kzg_rs's batch verifier (which skips length checks at 0/1 blob) and an undocumented host packing order. Move both checks local to blob_provider.rs: * assert_eq! on the three BlobData lengths at top of From<BlobData>. * By-hash lookup (linear scan + swap_remove) in get_and_validate_blobs, panicking on miss instead of silently dropping the request. * Drop the now-dead .rev() in the constructor. In the SP1 guest both new panics surface as "invalid proof". Behavior note: if a host returned the correct set of blobs in wrong order, baseline returned an empty Vec; by-hash lookup now succeeds. Strictly more correct. Three unit tests fail on baseline cf2ce09 and pass after the fix. Closes #21490.
* op-devstack: add controlled lifecycle support * review comment * fix op-up
…on, prestate TBD (#21544) * docs: U19 notice draft — SCR fix, component versions, deposit gas, prestate TBD - remove OP Sepolia genesis.json workaround (SCR loading fixed in op-reth v2.3.2) - refresh component table (op-node v1.19.1, op-reth v2.3.2, kona-node TBD, rollup-boost v0.7.16, op-rbuilder v0.4.9) + Engine API upgrade-order note - EIP-7825: clarify outer L1 gas budget for deposits (_gasLimit + ~150k) - kona-client prestate tag + hashes set to [TBD] pending finalization - op-proposer step: warn it fails immediately if game type not updated Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs: U19 notice — add affected-chains section for Karst gas limit bug Lists the Sepolia chains that activated Karst with the buggy release and have an elevated block gas limit; clarifies mainnet needs no setGasLimit() action after activation. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs: U19 notice — setGasLimit required for ALL chains, add procedure keep_karst_upgrade_gas = true is set in the Superchain Registry for both Sepolia AND mainnet (verified against SR main: mainnet/op.toml and sepolia/op.toml), enshrining the elevated block gas limit after Karst. All chain operators must call SystemConfig.setGasLimit() after activation. - correct the prior (wrong) claim that mainnet needs no action - rename section to "Gas limit: action required for all chains" - add setGasLimit() procedure (read / set from owner / verify) Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs: U19 notice — drop per-chain gas-limit list, keep timing note The enumerated Sepolia chain list added no action over "all chains" and risked going stale; collapse to a one-line timing note (Sepolia live now, mainnet later). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs: U19 notice — remove deposit outer-L1-gas budget note Drop the EIP-7825 deposit L1 gas-budget paragraph per review. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs: U19 notice — drop OP Mainnet/OP Sepolia from SCR examples list Keep the example list illustrative; the explicit OP entries aren't needed. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs: U19 notice — address review (revert prestate TBD, name affected chains) - Revert prestate section to as-is: keep_karst_upgrade_gas preserves consensus, so no new prestate is required (restore kona-client/v1.6.0-rc.2 tag + hashes, drop the TBD Info note). Per @geoknee review. - Gas-limit section: name the affected chains (canonical SR #1259 list) and use the has-flag / no-flag / already-activated conditional instead of "all chains". Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs: U19 notice — address joshklop review - remove kona-node row (no kona-node release tied to Karst; clears last TBD) - op-reth: note v2.3.1 is now deprecated - upgrade-order: "break the sequencer" -> "cause downtime" - gas-limit: note some not-yet-activated mainnet chains also set the flag Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
… under Karst (#21574) * fix(op-reth): set tx_gas_limit_cap for Osaka so eth_estimateGas works under Karst EIP-7825 (Osaka) caps a single transaction's gas at 2^24, and the OP Stack inherits this cap from Karst onward (KARST/INTEROP -> OSAKA eth base). The OP EVM-env builder never populated `cfg_env.tx_gas_limit_cap`, so reth's `estimate.rs` fell back to the block gas limit (e.g. 30-60M) as the trial upper bound for `eth_estimateGas`. The Osaka EVM then rejected that trial with "intrinsic gas too high", breaking any contract-call estimate that omitted an explicit `gas <= 2^24`. This is the OP-side dual of reth PR #25612. Set the cap in `evm_env_for_op` (the chokepoint for the block, next-block, and payload env constructors), mirroring alloy-evm's `for_eth_block`. This is forward-compatible: once reth is bumped past #25612 the field-set becomes harmless belt-and-suspenders. Add a chronology-driven unit guard in alloy-op-evm asserting the cap is set exactly for Osaka+ forks, plus an op-reth integration test that drives a real `eth_estimateGas` RPC end-to-end on a Karst-active chain. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * fix: satisfy clippy::if_then_some_else_none in tx_gas_limit_cap guard test Use `.then_some(...)` instead of an if/else returning Some/None. CI runs clippy with `--all-targets`, which lints `#[cfg(test)]` code; the local `-p alloy-op-evm` run did not. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * refactor * fix(op-reth): add backticks to satisfy clippy::doc_markdown The estimate_gas_7825.rs module doc referenced eth_estimateGas without backticks, which clippy::doc_markdown rejects under -D warnings. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * Add TODO --------- Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]> Co-authored-by: geoknee <[email protected]>
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.
No description provided.