Conversation
* op-reth: add chain_id to ExecutingDescriptor in supervisor_checkAccessList The ExecutingDescriptor sent to supervisor_checkAccessList was missing the chainID field, causing the interop filter to see chain ID 0 and reject all cross-chain relay transactions with "executing chain 0: unknown chain". The Go-side ExecutingDescriptor expects chainID but op-reth's local copy of the struct omitted it. This adds chain_id to the struct, threads it through from ChainSpec, and includes it in the serialized RPC payload. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(op-reth): fix rustfmt formatting in supervisor client Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(op-reth): use explicit chainID rename to match spec and kona The camelCase rename_all serialized chain_id as "chainId" (lowercase d), but the Go supervisor and kona both expect "chainID" (uppercase D). Use an explicit serde rename to match the spec. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: opsuperchain <opsuperchain@slop.bot> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…imism#19777) * ci(rust): downsize 7 Rust CI jobs from xlarge to medium Reduce resource_class from xlarge (40 cr/min) to medium (10 cr/min) for Docker-based Rust CI jobs that complete in under 5 minutes and are unlikely to be CPU/memory bound: - rust-ci-clippy - rust-ci-check-no-std - rust-ci-docs - rust-ci-udeps - rust-ci-cargo-hack-build (wasm targets) - op-reth-compact-codec - rust-docs-build Machine-executor jobs (kona-cargo-lint, kona-build-fpvm, kona-host-client-offline) are excluded as they require Docker-in-Docker and privileged access. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ci(rust): revert rust-ci-docs to xlarge (OOM on medium) The rust-docs job was killed with SIGKILL (OOM) on medium — the reth_op crate doc build with all features needs more memory than medium provides. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add ConditionalDeployer to implementations names array and add implementations count check * fix: isUpgradeable comment in l2cm utils
…lls (ethereum-optimism#19745) * feat(op-devstack): use EIP-7702 SetCode for OPCM migration delegatecalls Replace the DelegateCallProxy deploy-transfer-execute-restore pattern in migrateSuperRoots and addGameTypeForRuntime with EIP-7702 SetCode. The L1PAO EOA temporarily adopts DelegateCallProxy code via SetCode, then calls executeDelegateCall on itself. Since the EOA is already the owner of all ProxyAdmins, no ownership transfers are needed. This reduces the transaction count from ~5+5N to 2 per invocation (one deploy + one SetCode tx), eliminating a large class of ownership transfer/restoration complexity. The new delegateCallWithSetCode helper uses txplan for nonce management, gas pricing, signing, and retry — the same infrastructure that dsl.EOA.PlanAuth uses without requiring a dsl.EOA. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove extra blank line caught by goimports Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(acceptance): await validated timestamp before querying optimistic data AwaitValidatedTimestamp was called with endTimestamp but SuperRootAtTimestamp was queried at endTimestamp+1. When the supernode hasn't validated that timestamp yet, OptimisticAtTimestamp is empty and latestRequiredL1 returns a zero-valued BlockID, causing kona-host to receive --l1-head 0x00..00 and fail. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: conditional deployer to be predeploy * fix: downgrade invariant * fix: wording
Migrate Kona, op-reth, and op-alloy documentation from the standalone Vocs site (rust/docs/) into the unified Mintlify docs (docs/public-docs/). - Convert 140 MDX files: remove Vocs imports, add Mintlify frontmatter, convert Callout components to Warning/Note/Info/Tip - Add 'Rust' navigation tab to docs.json with full sidebar structure - Create Mintlify-native landing page with CardGroup components - Add dedicated docs-ci.yml CircleCI continuation config that runs mintlify validate on docs/public-docs/ changes - Delete standalone rust/docs/ Vocs site
…ism#19773) * op-supernode: Workaround op-reth FCU edge case * op-acceptance-tests: unskip op-reth interop reorg tests that now pass Remove SkipUnlessOpGeth from 5 tests that now pass with op-reth after the FCU rewind fix. Update the skip reason on TestSupernodeInteropInvalidMessageReplacement which still fails due to missing interop tx eviction. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * op-supernode: replace sleep with FCU retry-verify loop in RewindToTimestamp Replace the fixed 50ms sleep between back-to-back FCU calls with a proper retry loop that verifies each FCU took effect by checking the heads match. If the head hasn't converged (e.g. due to reth#23205 race), sleep 500ms and retry the FCU, up to 20 attempts (total of 10s). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: wwared <541936+wwared@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…m#19665) * fix(test): fix and fuzz mint moreThanAvailableBalance test The test was missing vm.prank(address(superchainETHBridge)), causing it to revert with Unauthorized instead of testing the intended insufficient balance scenario. Also converted to fuzz test for broader coverage. * test(contracts): add version format validation for ETHLiquidity Add ETHLiquidity_Version_Test with SemverComp.parse() to validate the version string follows proper semver format. --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ethereum-optimism#19557) * refactor(test): fix test naming conventions in LegacyMintableERC20 tests Rename test_constructor_works to test_constructor_succeeds and test_supportsInterface_works to test_supportsInterface_supportedInterfaces_succeeds to follow the naming convention [method]_[functionName]_[scenario]_[outcome]. * test(contracts): convert tests to fuzz and add coverage for supportsInterface - Convert mint/burn tests to fuzz tests with event emission checks - Add fuzz test for unsupported interface IDs (false branch) - Declare Mint/Burn events in TestInit for expectEmit assertions - Fuzz access control tests across arbitrary caller addresses --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ism#19794) PRs are squash-merged so only one commit appears in history.
* chore: check for l2cm code in l2proxy admin upgrade * fix: comment * fix: add check for v4 initializing slot aswell * fix: improve expected intent string comment * fix: prank issue * fix: tests * fix: nits * fix: tests
…ism#19668) * feat(l1block): add system customization feature flags * feat(l1block): unify custom gas token under system customizations * feat(contracts): move enableFeature() call into setL1Block * chore: semver lock * fix(contracts): reset isFeatureEnabled(CUSTOM_GAS_TOKEN) * refactor(l1block): align feature flag interface with SystemConfig Use bytes32 keys with Features library constants, public mapping auto-getter, FeatureSet event, and setFeature function name. * feat(l2cm): populate isInterop from L1Block feature flag Read INTEROP feature from L1Block into FullConfig instead of querying L1Block inline in _apply. * feat(l2cm): revert if interop dev feature and system feature disagree Move interop flag resolution into _loadFullConfig and revert with L2ContractsManager_FeatureFlagMismatch if the dev feature and L1Block system feature are out of sync. * feat(l2cm): dev feature gates system customization, not vice versa The dev feature is a prerequisite for the system customization to be enabled. Revert only when sys=true and dev=false (misconfiguration). * fix(contracts): Address contracts checks failures * Enable custom gas token feature in L1Block test * Use legacy isCustomGasToken() and use try/catch on isInterop * Apply suggestion from @0xOneTony Co-authored-by: 0xOneTony <112496816+0xOneTony@users.noreply.github.com> * Add custom gas token check in L2ContractsManager * feat(contracts): Update authorization on setFeature and setCustomGasToken * feat(contracts): move docs to better place * fix(contract): interfaces for L1Block proxy admin inheritance * fix: semver bumps * fix: increase gaslimit for L1block deployment * fix: address PR review feedback - Remove redundant isCustomGasToken() check in setCustomGasToken() - Fix typo: consenus -> consensus in L2ContractsManager - Use setCustomGasToken() instead of setFeature() in L2Genesis for consistency * fix: downgrade L1BlockCGT semver and add @dev comment Semver back to +custom-gas-token.1 after removing the redundant check. Document authorization behavior on setCustomGasToken(). * fix: remove unused import and regenerate NUT bundle L1Block_FeatureAlreadyEnabled import was unused after removing the redundant check in setCustomGasToken(). * fix(l2cm): fix typo in _loadFullConfig comment s/def/dev/ in feature flags comment. * chore(l2cm): add TODO to remove CGT migration step after Karst * feat(l2cm): remove setCustomGasToken() There is now only one right way to set a feature which is to call setFeature(). * feat(l1block): restrict CUSTOM_GAS_TOKEN feature to genesis only Prevents setFeature(CUSTOM_GAS_TOKEN) from being called after block 1, ensuring the feature can only be set during genesis. * fix(l1block): update interfaces, tests, and snapshots for setCustomGasToken removal setCustomGasToken() was removed from L1BlockCGT but references in interfaces, L2CM, and tests were not updated. Regenerated snapshots. * fix(contracts): address review feedback on versions and NUT comment Downgrade L1Block to 1.9.0 and L2CM to 1.2.0 per reviewer request. Add comment explaining how INTEROP feature is enabled via NUT. * fix(l1block): remove genesis-only guard for CUSTOM_GAS_TOKEN feature The block.number check is incompatible with L2ContractsManager which needs to call setFeature(CUSTOM_GAS_TOKEN) post-genesis for migration. Access control via _assertSetFeatureAuthorized is sufficient. * fix(contracts): remove unused imports, bump semver, regen snapshots Removes unused Features import from L1Block and IL1BlockCGT import from L2ContractsManager after genesis guard removal. * fix(l1block): match natspec tag to version string * fix(contracts): revert semver bumps, regen snapshots These contracts already had their versions bumped in earlier commits on this branch. The semver-diff check compares against the target branch, not the previous commit. * Update snapshots * fix(l2cm): bump L2ContractsManager semver to 1.3.0 Bytecode changed due to removed IL1BlockCGT import. Regen snapshots. --------- Co-authored-by: 0xOneTony <112496816+0xOneTony@users.noreply.github.com>
* feat: add weekly l2 fork tests * fix: remove okx-xlayer from l2 fork ci matrix Co-authored-by: Maurelian <john@oplabs.co> --------- Co-authored-by: Maurelian <john@oplabs.co>
…19808) Adds a section pointing to subdirectory CLAUDE.md files so AI agents know they exist but only read them when working in that area, avoiding unnecessary context bloat. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…hereum-optimism#19765) * fix(kona): use configurable message expiry window in MessageGraph MessageGraph::check_single_dependency() was using the hardcoded MESSAGE_EXPIRY_WINDOW constant (7 days) instead of the configurable value from the DependencySet. This prevented acceptance tests that configure custom expiry windows from working correctly with Kona's fault proof program. Changes: - Add message_expiry_window parameter to MessageGraph::derive() - Load DependencySet from preimage oracle key 8 in BootInfo - Thread expiry window from BootInfo through SuperchainConsolidator - Add tests for custom expiry window behavior Closes ethereum-optimism#19636 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style: apply rustfmt to graph.rs and boot.rs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style: fix nightly rustfmt formatting in graph.rs Apply nightly-specific binop_separator and import grouping rules. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add `DependencySet`` serving to `kona-host` interop The `kona-host` interop binary didn't handle local key 8 (`DEPENDENCY_SET_KEY`), so `BootInfo::load()` would hang forever waiting for the preimage oracle to return the `DependencySet`. Changes: - Add --dependency-set-path CLI arg to InteropHost - Add read_dependency_set() method to InteropHost - Handle DEPENDENCY_SET_KEY in InteropLocalInputs::get() - Add kona-interop dependency to kona-host Cargo.toml * fix: rustfmt and update Cargo.lock for kona-host Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(kona): return default DependencySet when no path is configured When --dependency-set-path is not provided, InteropLocalInputs now returns a default DependencySet instead of None. This prevents BootInfo::load() from hanging forever waiting for the preimage oracle to return data for DEPENDENCY_SET_KEY. The default DependencySet has no override, so get_message_expiry_window() returns MESSAGE_EXPIRY_WINDOW (7 days), preserving existing behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style: fix clippy or_fun_call and nightly fmt in local_kv.rs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…thereum-optimism#19801) Add error codes 8429 (virtual modifiers) and 2424 (natspec memory-safe-assembly) to ignored_error_codes, and migrate deny_warnings to deny syntax.
…des (ethereum-optimism#18699) Hardcode ShutdownOnRemove=false in raft config instead of using an opt-in flag. When the leader removes itself from the cluster (e.g., during automated failover), raft's default ShutdownOnRemove=true shuts down the raft instance while the process stays alive. This creates a zombie node: RPC responds but raft is dead, replication fails permanently, and the node cannot rejoin without a container restart. With ShutdownOnRemove=false, the node transitions to follower state and can be cleanly re-added to the cluster. There is no valid use case for the zombie behavior, so this is hardcoded rather than configurable.
…ism#19822) In merge queues CIRCLE_BRANCH is gh-readonly-queue/<base>/pr-<n>-<sha>, causing semver-diff-check to diff against itself instead of the base branch.
…imism#19815) Add a `main-skip` workflow that runs when only docs/public-docs/ files are changed. It reports no-op passing status for all 11 required GitHub checks, preventing docs-only PRs from being stuck in "Waiting for status to be reported" indefinitely. Previous PRs correctly gated the main workflow behind c-non_docs_changes, but when the entire workflow is skipped, GitHub branch protection never receives the required status checks. This follows the same pattern used by rust-ci-gate-short and rust-e2e-gate-skip. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ManagerUtils (ethereum-optimism#19797) * refactor(contracts): separate v4/v5 init slot clearing in L2ContractsManagerUtils The v4 and v5 initialization clearing paths were interleaved, making the code hard to follow and causing a redundant SSTORE when _slot == v5Slot. Separate them into distinct blocks and add a validation that v5 offset must be 0. * fix(contracts): add InvalidV5Offset error to IL2ContractsManager interface * update bundle * fix(contracts): bump L2ContractsManager version to 1.3.1 Semver check requires a version bump when semver-lock hashes change. * fix(contracts): update natspec @Custom:semver to match 1.3.1 Semgrep requires the natspec comment to match the version string. * chore(contracts): update current nut bundle * test(l2cm): fuzz slot value and offset in utils tests Address review comments — fuzz inputs instead of hardcoding to improve coverage of the mask logic. * fix(ct): handle merge queue branch in get-target-branch.sh In merge queues, CIRCLE_BRANCH is gh-readonly-queue/<base>/pr-<n>-<sha> which was being used as TARGET_BRANCH instead of extracting the base branch. * Revert "fix(ct): handle merge queue branch in get-target-branch.sh" This reverts commit 034a36b.
…optimism#19824) SafeDB.Close() sets the closed flag and closes the underlying pebble DB, but read/write methods did not check the closed flag after acquiring their lock. During supernode shutdown, the interop activity goroutine can still be mid-iteration when the chain container stops its VirtualNode (closing the inner op-node's SafeDB). A subsequent SafeHeadAtL1 call from the interop goroutine then hits pebble's closed DB and panics. Add closed checks to SafeHeadAtL1, SafeHeadUpdated, and SafeHeadReset so they return ErrClosed instead of panicking on the closed pebble DB. Fixes ethereum-optimism#19821
…loys (ethereum-optimism#19798) * fix(l2cm): revert instead of silently skipping non-upgradeable predeploys Silent no-ops hide misuse. Callers should explicitly guard conditional predeploys. * chore: bundle and snapshots * chore(contracts): L2CM semver bump
…fig (ethereum-optimism#19810) * chore(kona): remove dead interop_message_expiry_window from RollupConfig The message expiry window is now sourced exclusively from DependencySet (7-day default via MESSAGE_EXPIRY_WINDOW), as wired in ethereum-optimism#19765. The RollupConfig.interop_message_expiry_window field (1-hour default) was never read by any production code, has no Go equivalent, and disagreed with the ecosystem's 7-day default by 168x. Removes: - DEFAULT_INTEROP_MESSAGE_EXPIRY_WINDOW constant - default_interop_message_expiry_window() serde helper - interop_message_expiry_window field from RollupConfig - All references in test configs and ChainConfig conversion Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(kona): remove interop_message_expiry_window from executor test fixtures The executor test fixtures contained the removed field in their serialized RollupConfig JSON. Since RollupConfig uses deny_unknown_fields, deserialization fails on the unknown field. Strip it from all 8 fixture tar.gz files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ram (ethereum-optimism#19803) * feat(kona-host): add directory-based kv store compatible with op-program Add DirectoryKeyValueStore that writes preimages in op-program's DataFormatDirectory layout (<dir>/<4hex>/<rest>.txt with hex-encoded values) and writes a kvformat marker file for op-challenger autodetection. This enables op-challenger to read preimages written by kona-host, which previously used RocksDB (incompatible with the Go preimage loader). The RocksDB implementation is preserved as an option via the new --data-format CLI flag (default: directory). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(kona-host): add Serialize derive to DataFormat, fix formatting - DataFormat needs Serialize since the config structs derive it - Fix import ordering (alphabetical) - Fix rustfmt formatting in directory.rs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(kona-host): write kvformat marker for RocksDB format Write "rocksdb" to the kvformat marker file when using the RocksDB DiskKeyValueStore, consistent with DirectoryKeyValueStore writing "directory". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(kona-host): make kv module public, fix import ordering - Make `kv` module pub so `DataFormat` is nameable (clippy error) - Fix nightly rustfmt import ordering in directory.rs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(kona-host): auto-detect kv format from existing data directory When opening an existing data directory, read the `kvformat` marker file to determine the storage format instead of always using the CLI flag. Falls back to `--data-format` (default: directory) when no marker exists. This matches op-program's detection behavior and ensures compatibility with op-challenger. Also updates comments to reference op-challenger instead of op-program where the compatibility is with op-challenger. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(kona-host): use tempfile for test isolation, deduplicate kv store creation Tests were using the system temp directory directly, causing test interference and potential race conditions across proptest cases and parallel test runs. Switch all tests to tempfile::TempDir for unique, auto-cleaned directories. Also extract common kv store creation logic from single/cfg.rs and interop/cfg.rs into a shared create_key_value_store helper in the kv module. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(kona-host): apply nightly rustfmt formatting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(kona-host): satisfy clippy option_if_let_else lint Use map_or instead of match on Result in detect_data_format. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(kona-host): address PR review feedback - DirectoryKeyValueStore::new() takes &Path instead of PathBuf - create_key_value_store() takes Option<&Path> instead of Option<&PathBuf> - get() warns on corrupt preimage files instead of silently returning None - set() writes atomically via temp file + rename to prevent partial writes - kv module visibility narrowed to pub(crate); items re-exported from lib.rs - Fixed detect_data_format doc comment (it reads the marker, doesn't write it) - Stricter key_path_layout test assertion - tempfile moved to regular dependency (used in production set()) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(kona-host): apply nightly rustfmt formatting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…head capture (ethereum-optimism#19805) * fix(op-acceptance): fix flaky VariedBlockTimes by restructuring batcher choreography The test captured L1 heads by querying the supernode's RequiredL1 values via l1BlockWithLocalSafeBlocks, which races with continued sequencer block production shifting those values. Instead, read the L1 head directly from the L1 client at each stage of the batcher choreography — the invariants (which chain's data is on L1) are maintained by which batchers are running, not by timing windows. Also removes the t.Skip() from all four VariedBlockTimes test variants. Fixes ethereum-optimism#19804 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(op-acceptance): apply race-free batcher choreography to all super fault proof tests Apply the same pattern used for RunVariedBlockTimesTest to RunSuperFaultProofTest and RunSingleChainSuperFaultProofSmokeTest. Replace l1BlockWithLocalSafeBlocks polling with direct L1 head reads from the L1 client, using batcher start/stop state as the synchronization mechanism. Remove the now-unused l1BlockWithLocalSafeBlocks helper and the "math" import it required. Fixes ethereum-optimism#19804 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(op-acceptance): stop batchers after capturing L1 heads to prevent cleanup failure The t.Cleanup(Batcher.Start) calls registered in Stage 1 fail with "batcher is already running" if the batchers are still running at test teardown. Stop them after capturing l1HeadCurrent so the cleanup can restart them cleanly. Fixes ethereum-optimism#19804 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(op-acceptance): allow deployer options in supernode proofs presets and remove batcher cleanup Add optionKindDeployer to supernodeProofsPresetSupportedOptionKinds so WithL2BlockTimes (which wraps WithDeployerOptions) works with NewSimpleInteropSupernodeProofs and NewSimpleInteropIsthmusSuper. The underlying runtime already processes deployer options via cfg.DeployerOptions. Also remove t.Cleanup(Batcher.Start) and corresponding Batcher.Stop() calls — tests don't share devnets so there's no need to restore batcher state at teardown. Fixes ethereum-optimism#19804 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(op-acceptance): fix interop fault proof tests by using LocalSafe heads The interop VariedBlockTimes tests were failing for two reasons: 1. EL safe label waits deadlocked: EL safe only advances after interop validation, which requires ALL chains to have batch data. When only one chain's batcher is running, EL safe never advances. Switch to waiting on CL LocalSafe which advances independently per-chain. 2. endTimestamp computed from cross-safe heads: nextTimestampAfterSafeHeads used SafeL2 (cross-safe) which lags far behind LocalSafe in interop mode. This caused endTimestamp to target blocks whose batch data was already on L1, breaking the l1HeadBefore/l1HeadAfterFirst invariants. Now uses LocalSafeL2 when available. Also stops both batchers simultaneously to prevent one from submitting data past the safe heads while waiting for the other to stall. Wires BatcherOptions through to the two-L2 supernode runtime and adds WithBatcherStopped() preset option. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: remove unused WithBatcherStopped option Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: re-add optionKindBatcher to supernode proofs preset The BatcherOptions wiring is now supported via multichain_supernode_runtime.go, so the preset should accept batcher options. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…sm#19814) * feat(op-reth): Add custom OpPool type that filters interop txs on reorg * feat: Add a reorg window to the filter for robustness * chore: Minor clean-up and refactor - Remove redundant tests - Clean up comments - Remove enabled flag and simplify ReorgState inside OpPool - Simplify impl blocks and tighter trait bounds on OpPool - Set REORG_WINDOW to 30 for now * chore: Address review comments --------- Co-authored-by: wwared <541936+wwared@users.noreply.github.com>
…ts (ethereum-optimism#19825) Change optimisticBlockAtTimestamp to query the supernode's super_atTimestamp API instead of calling OutputAtBlock directly on the rollup client. OutputAtBlock returns whatever block is currently canonical at a given number. After an invalid block is replaced during cross-safe validation, this returns the replacement block's output root rather than the original optimistic block's output root. The super_atTimestamp API's optimistic_at_timestamp field is the intended source for optimistic output roots. Currently, the supernode's OptimisticOutputAtTimestamp implementation also calls OutputAtBlock internally, so both paths return the same (wrong) value after replacement. This means the three TestInteropFaultProofs_InvalidBlock sub-tests that depend on getting the true optimistic output root still fail: - SecondChainOptimisticBlock-fpp - Consolidate-ExpectInvalidPendingBlock-fpp - Consolidate-ExpectInvalidPendingBlock-challenger Once the supernode is fixed to preserve the original optimistic output root, these tests should pass without further changes. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…optimism#19955) * test: add ZKDisputeGame unit and integration test coverage * test: add opcm full flow integration test * chore: upgrade bundle * fix: remove unneeded exclusions.toml entry * fix: cover under/oversized calldata in ZK dispute invalidCalldataSize test * fix: assert anchor hasn't advanced before claiming credits in ZK integration test * chore: pre pr
* chore(rust): bump op stack to revm 38 * fix(rust): restore local op-revm karst path
* fix: correct inverted comment in resolve() invariant check * fix: cache IDisputeGame(address(this)) in closeGame() * fix: document uint32.max sentinel in getParentGameStatus() * fix: rename proxy to parent in initialize() * fix: document bond burn invariant when parent is invalid and game is unchallenged * fix: document that parent blacklisting does not propagate to descendants * fix: move ZK_ARGS_LENGTH constant to top of LibGameArgs with other constants * fix: bump ZKDisputeGame version to 1.1.0 * fix: remove governance mention in comment when parent gets invalidated * chore: update semver-lock.json for zkgame due to changed comment
…ler (ethereum-optimism#20255) Steady.Run's polling goroutine samples the unsafe head every blockTime to drive AIMD backpressure. The prior code only tolerated context errors and fatally asserted on every other error via t.Require().NoError. Under load (e.g. TestRelayWithInvalidMessagesSteady, where the EL is being spammed with ~1000 invalid executing messages per block time), the proxy in front of op-reth intermittently hits TCP dial-backlog saturation and returns "dial tcp ...: i/o timeout". That is neither context.Canceled nor context.DeadlineExceeded, so it bypassed the errors.Is guard and tripped the Require. The sampler's job is to observe gas usage for backpressure, not to assert EL liveness. This matches every other error path in this package (logOnError in Burst/Constant, the warn-and-continue path in the invalid message spammer), which treats transient EL errors as non-fatal. On error we now log a warning and skip this tick, leaving AIMD state unchanged so the current RPS is preserved until the next successful sample. Closes ethereum-optimism#20254
…L1AtSafeHead (ethereum-optimism#20292) L1AtSafeHead previously surfaced raw safedb.ErrNotFound from both its initial latest-lookup and its walkback probe, which chain_container did not match against ErrL1AtSafeHeadNotFound. Interop's Start loop logged "failed to progress and record interop" / "error determining l1 block number at which l2 block became safe" / "L1AtSafeHead: walkback lookup failed, stopping" every errorBackoffPeriod, drowning logs on nodes that bootstrapped via CL/snap sync (their SafeDB starts above genesisL1, so walkback probes below the earliest entry always miss). Fix it by splitting the failure mode into two sentinels with clearly different semantics, so callers can react correctly: - virtual_node.ErrL1AtSafeHeadNotFound (transient): * target is ahead of the latest recorded L2 -- chain will catch up * SafeDB is empty at startup -- first advance will populate it chain_container maps this to ethereum.NotFound; interop backs off quietly, same as before. - virtual_node.ErrL1AtSafeHeadUnavailable (permanent): * walkback crossed below the earliest SafeDB entry (CL/snap-sync bootstrap gap: the L2 safe-head advance we want happened before this node started writing records) * walkback reached the genesis bound without L2 ever dropping below target (SafeDB near genesis is not considered stable) chain_container maps this to a new ErrHistoryUnavailable -- kept distinct from ethereum.NotFound so it cannot masquerade as lag. Interop's Start loop recognizes it, logs once at Error with operator-actionable remediation hints (reseed data dir, advance interop.activation-timestamp past the gap, or rederive from L1), and returns -- halting the activity instead of spinning on errorBackoffPeriod forever. Tests cover every branch: - virtual_node_test.go: walkback-past-earliest and genesis-bound both return Unavailable (and are asserted distinct from NotFound); empty-DB-on-latest-lookup and target-beyond-latest still return NotFound; mock SafeDBReader now returns safedb.ErrNotFound to mirror the real DB. - chain_container_test.go: Unavailable -> ErrHistoryUnavailable, and explicitly NOT ethereum.NotFound; NotFound -> ethereum.NotFound remains. - interop_test.go: Start halts within 5s (well under errorBackoffPeriod) with an error wrapping cc.ErrHistoryUnavailable when a chain reports permanent history loss. Made-with: Cursor
…upgrade (ethereum-optimism#20248) * test(op-acceptance-tests): install super-root games via opcm.upgrade Adds a single-chain interop preset that exercises the standard OPCMv2.upgrade entrypoint for installing super-root dispute games, as an alternative to the opcmMigrator.migrate path (which is really about switching multiple chains onto a shared DisputeGameFactory — not relevant to single-chain tests). The new runtime deploys the chain with the SUPER_ROOT_GAMES_MIGRATION dev feature on (so the upgrade accepts the overrides.cfg.startingAnchorRoot override), waits for the supernode to produce a real super root, then calls opcm.upgrade with disputeGameConfigs enabling SUPER_CANNON / SUPER_PERMISSIONED_CANNON / SUPER_CANNON_KONA and ExtraInstructions overriding the starting anchor root and respected game type. * refactor(op-devstack): route single-chain interop presets through opcm.upgrade Makes NewSingleChainInteropSupernodeProofs / NewSingleChainInteropIsthmusSuper install super-root dispute games via OPCMv2.upgrade (with SUPER_ROOT_GAMES_MIGRATION enabled at deploy) instead of opcmMigrator.migrate. migrate stays in use for multi-chain runtimes where it actually does its job — moving multiple chains onto a shared DisputeGameFactory. Consolidates the upgrade runtime/helper into multichain_proofs.go next to the existing attachSupernodeSuperProofs, drops the now-redundant NewSingleChainInteropSupernodeProofsViaUpgrade preset, and points the new TestSuperRootGamesInstalledViaOPCMUpgrade acceptance test at the canonical single-chain preset so existing single-chain interop tests pick the change up without any callsite changes. * docs(op-devstack): tighten comments on super-root upgrade helpers Fix the NewSingleChainSupernodeProofsRuntimeWithConfig comment (the chain is deployed with SuperPermissionedCannon at genesis and upgraded to the permissionless super games, not "switched to super-root dispute games"), and shorten the other super-root-upgrade comments. * refactor(op-devstack): dedupe OPCM upgrade plumbing Extract two helpers shared by addGameTypesForRuntime, upgradeToSuperRoots, and migrateSuperRoots: - resolveL1ProxyAdminOwner — returns the L1 proxy-admin owner address + key - executeOPCMUpgrade — runs UpgradeOPChain.s.sol through a forked script host and submits the resulting calldata on L1 as a SetCode delegatecall Drop the shared-DGF discovery/write-back loop from upgradeToSuperRoots: unlike opcmMigrator.migrate (which redirects chains onto a newly-created shared DGF), opcm.upgrade re-initialises the same DisputeGameFactory proxy, so L2Deployment.disputeGameFactoryProxy is already correct and there's nothing to rediscover. The caller was ignoring the return value anyway; change signature to return nothing. Also trims the buildSuperRootUpgradeGameConfigs zero-init boilerplate. Net: -69 lines across the three files. All four single-chain interop tests still pass locally. * refactor(op-devstack): move OPCM upgrade helpers to opcm_upgrade.go Relocate resolveL1ProxyAdminOwner and executeOPCMUpgrade out of add_game_type.go into their own file so callers beyond addGameTypesForRuntime don't have to pull unrelated add-game-type concerns transitively. * docs(op-devstack): restore OPCMv2 game config ordering comment Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(rust): bump op stack to revm 38 * fix(rust): restore local op-revm karst path --------- Co-authored-by: Gustavo Figueiredo <me@figtracer.com>
…thereum-optimism#20296) The SupervisorClient default request timeout was 100ms, which is too tight for the localhost HTTP round trip to op-interop-filter / op-supervisor under CI load (GC pauses, CPU contention, noisy-neighbour runners). When the timeout fires, op-reth returns InteropTxValidatorError::Timeout(0) — the trailing 0 comes from Duration::as_secs() on 100ms — surfacing the error "inbox entry validation timed out, timeout: 0 secs" at the ingress path. This caused intermittent failures in TestInteropFilter_IngressRejectsInvalid (ethereum-optimism#20291): the test submits a tx with a fabricated access list expecting the filter's "failed to parse access entry" rejection, but on load the 100ms timeout fires first. Raise the default to 2s. The timeout is a protective ceiling against a truly hung upstream, not a latency SLA — the supervisor normally answers in microseconds and 2s is still well below the test-level 10s context budget, so a stuck upstream is still caught. Refs ethereum-optimism#20291 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ptimism#20156) Add an integration test that spins up two op-reth nodes, lets them complete the devp2p handshake, and asserts the negotiated eth subprotocol version is exactly 69. The test is intentionally written to fail when upstream reth bumps the negotiated version (e.g. to eth/70). That failure is the signal: it forces a conscious review of the new version's behavior before we ship it, rather than silently inheriting a protocol change on the next reth bump. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* U19 notice page draft * Update U19 notice page with Fusaka on L2, Glamsterdam Defense, and latest scope - Add Fusaka on L2 section (EIP-7825 gas limit, deposit tx exemption) - Add Glamsterdam Defense section (BN256 pairing input size limitation) - Confirm hard fork status and uncomment hard fork callout - Add op-node, op-reth, op-geth to component table - Add node operator hard fork preparation steps - Add OPCMv2 as explicit feature bullet - Expand breaking changes and app developer sections - Add new TODOs for pending details * Document Upgrade 19 features and requirements Upgrade 19 introduces the L2 Contract Manager, promotes CANNON_KONA, activates Fusaka EIPs, and implements the Glamsterdam Defense. Node operators must upgrade before the activation timestamp. * Update upgrade-19.mdx * Update upgrade-19.mdx * Update upgrade-19.mdx * Apply suggestions from code review Co-authored-by: Maurelian <john@oplabs.co> * Update upgrade-19.mdx * Update upgrade-19.mdx * Apply suggestion from @sbvegan Co-authored-by: soyboy <85043086+sbvegan@users.noreply.github.com> * Apply suggestion from @sbvegan * Update upgrade-19.mdx * Revert "Update upgrade-19.mdx" This reverts commit effef2e. * Update upgrade-19.mdx --------- Co-authored-by: Maurelian <john@oplabs.co> Co-authored-by: soyboy <85043086+sbvegan@users.noreply.github.com>
…ethereum-optimism#19888) Gates the NUT bundle upgrade transactions behind IsL2CM toggle so it can be disabled during development without modifying fork activation.
* feat: add EIP-8037 / TIP-1016 state gas support (bluealloy/revm#3406) * feat: implement EIP-8037 state gas (reservoir model) Add state gas accounting with reservoir model across interpreter, handler, context, and precompile crates. Includes comprehensive EIP-8037 test suite with 35+ test vectors covering SSTORE, CALL, CREATE, SELFDESTRUCT, reservoir refill, and gas opcode behavior. * rm statetest jsons * Rename spent to regular_gas_spent in ResultGas and simplify reservoir refill - Rename ResultGas::spent to regular_gas_spent to distinguish from state gas after EIP-8037 - Add total_gas_spent() method and deprecate old spent()/set_spent()/with_spent() accessors - Simplify reservoir refill logic: replace handler_reservoir_refill() with inline max() - Remove unnecessary reservoir manipulation in precompile path - Update op-revm handler to use simplified reservoir refill - Update Cargo.lock dependencies * Simplify EIP-8037 state gas: remove redundant fields from ResultGas and update test data * Move EIP-7702 state gas refund split into pre_execution Consolidate the EIP-8037 auth list refund splitting logic from run_without_catch_error into apply_eip7702_auth_list, avoiding duplication between handler and inspector. pre_execution now takes init_and_floor_gas as a mutable reference and returns only the regular refund portion. * Add PrecompileFailure type for state gas propagation on error Introduce PrecompileFailure wrapper that carries both the error and an optional GasTracker, allowing precompiles that charge state gas (EIP-8037) to propagate gas info back to the caller on failure for proper reservoir refill. * Convert precompile errors to PrecompileFailure via .into() Update all precompile Err returns to use .into() for converting PrecompileError to PrecompileFailure, enabling state gas tracking on precompile failures. * Fix EIP-8037 state gas accounting regression Commit 14bd5a61 introduced a regression in gas accounting by incorrectly erasing both remaining and reservoir gas from total_gas_spent. The reservoir should not be erased since it's tracked separately via state_gas_spent. This fix reverts the erase_cost line from erase_cost(remaining + reservoir) to erase_cost(remaining), which correctly accounts for: - Regular gas: deducted from remaining calculation - State gas: tracked separately in state_gas_spent field Results: - State test failures reduced from 20 to 4 (pre-regression count) - All 408 workspace tests now pass - Updated EIP-8037 test data and assertions to match correct values * Move state gas deduction into first_frame_input Refactor to improve code organization by moving the state gas deduction logic from the execution method into the first_frame_input method, where frame initialization concerns are naturally grouped together. This keeps frame setup logic cohesive and simplifies the execution method to focus on the execution loop rather than frame setup details. No functional change - same gas accounting and execution behavior. * Fix EIP-8037 gas accounting: floor gas, reservoir, inspector, validation Four fixes for EIP-8037 state gas interactions: 1. post_execution: Fix EIP-7623 floor gas check to account for EIP-8037 reservoir. Per EIP-8037, gas_used = tx.gas - gas_left - reservoir. The floor check now subtracts reservoir when computing gas used. 2. handler: Simplify reservoir handling in last_frame_result to always use the frame's final reservoir value directly. It already reflects child frame restorations via handle_reservoir_remaining_gas. 3. handler: Add EIP-8037 floor gas validation when gas_limit exceeds TX_MAX_GAS_LIMIT. The maximum gas_used is capped at TX_MAX_GAS_LIMIT since excess goes to reservoir, so floor_gas must not exceed that cap. 4. inspector: Remove double deduction of initial_state_gas in inspect_execution. The first_frame_input method already handles the deduction; the explicit deduction in the inspector was redundant. * Fix EIP-8037 reservoir accounting: tx_gas_used, child revert refunds, and EIP-7702 - tx_gas_used now subtracts unused reservoir gas (tx.gas - gas_left - state_gas_left) - Child revert/halt returns all state gas to parent reservoir (matching Python spec) - EIP-7702 state gas refund goes to reservoir instead of reducing initial_state_gas - Refund cap uses gas_used excluding reservoir - Precompile provider preserves reservoir across gas tracker replacement - Updated EIP-8037 test expectations and test data * Fix CREATE/CREATE2 static call check ordering for EIP-8037 state gas recovery Move require_non_staticcall! after gas charging in the CREATE/CREATE2 instruction handler. In the execution-specs, the static check is inside generic_create() after all gas (including state gas) has been charged. The previous ordering prevented state gas from being recorded on the frame, so on child error the parent could not recover it via handle_reservoir_remaining_gas. * Simplify last_frame_result: remove initial_reservoir parameter and fix reservoir handling - Remove unused `initial_reservoir` parameter from `last_frame_result` across all handlers - Fix precompile provider to save reservoir before overwriting gas tracker - Add deprecated `gas_used()` method on ExecutionResult pointing to `tx_gas_used()` * Revert CREATE/CREATE2 static call check to before gas charging Static call check doesn't need to be after gas charging - CREATE in a static context is always an error regardless of gas accounting. * Fix reservoir handling: restore state gas on revert/halt On revert/halt, state changes are rolled back so state gas should be refunded back to the reservoir. Only on success should the frame's final reservoir be used as-is. * Fix EIP-8037 state_gas_spent accounting for EIP-7702 auth list Two bugs in state_gas_spent reporting: 1. build_result_gas added full initial_state_gas without subtracting eip7702_reservoir_refund, overcounting state gas for existing authority accounts. This caused block_state_gas_used to be too high and block_regular_gas_used to be too low. 2. On revert/halt, last_frame_result set state_gas_spent before restoring it to the reservoir, leaving a stale execution value. Now correctly zeroed since state changes are rolled back. * Improve precompile reservoir handling and apply formatting fixes Refactor precompile provider to properly handle reservoir refill logic for both success and error/halt cases, ensuring state gas accounting is correct when precompiles don't track reservoir. Also apply rustfmt formatting across multiple files. * Fix precompile_provider compilation errors against current precompile API PrecompileOutput has gas_used (not gas: GasTracker) and PrecompileError is a flat enum (no .error/.gas subfields). Use record_regular_cost() to avoid deprecation warning. * Simplify precompile interface: remove gas_limit from PrecompileOutput, flatten PrecompileError Remove gas_limit field from PrecompileOutput (only gas_used needed) and eliminate the PrecompileError wrapper layer so errors are returned directly as the enum variant without .into() conversion. * Fix EIP-8037 reservoir refill tests and complete precompile interface cleanup Update 4 EIP-8037 tests to match current reservoir refill behavior: on revert/halt at the top level, state_gas_spent is zeroed and state gas is restored to the reservoir (state changes rolled back). Regenerate testdata. Also complete the PrecompileOutput/PrecompileError simplification from the previous commit: remove reverted field, flatten error matching in tests. * temporary remove all ee-tests * Fix state gas accounting: include reservoir in total_gas_spent and prevent underflow - Remove saturating_sub of reservoir from total_gas_spent in build_result_gas - Use saturating_sub in block_regular_gas_used to prevent underflow * Apply formatting fixes and use saturating arithmetic for state gas spent * Revert "temporary remove all ee-tests" This reverts commit 03986fcd15d861b32ce2e56186ffd9ebdbfa3871. * Fix total_gas_spent to exclude reservoir and use saturating arithmetic Compute total_gas_spent as limit - remaining - reservoir in build_result_gas to correctly exclude unused state gas. Use saturating_sub in Gas::spent/total_gas_spent to prevent underflow. Add std feature to ee-tests revm dependency. * Use build_result_gas helper in system call gas handling Replace manual ResultGas construction with the shared build_result_gas function for consistency with the main execution path. * bump rust to 1.91 * Remove redundant gas_limit from Gas, delegate to GasTracker Gas had its own `limit` field duplicating `GasTracker::gas_limit`. Remove it and delegate `Gas::limit()` to `self.tracker.limit()`. Also fixes `Gas::new_spent` which previously set tracker gas_limit to 0 instead of the actual limit. * refactor(precompile): restructure PrecompileOutput for state gas and reservoir support (bluealloy/revm#3541) * refactor(precompile): split PrecompileOutput and PrecompileError for state gas support Rename PrecompileOutput to PrecompileOutputEth (simple gas_used + bytes) for individual precompile functions. Introduce new PrecompileOutput with halt, gas_used, state_gas_used, reservoir, and bytes fields for provider-level results. Split PrecompileError: non-fatal errors become PrecompileHaltReason (expressed via PrecompileOutput::halt), while PrecompileError now only holds fatal errors (Fatal/FatalAny) that abort EVM execution. New type aliases: - PrecompileEthResult = Result<PrecompileOutputEth, PrecompileHaltReason> - PrecompileResult = Result<PrecompileOutput, PrecompileError> * refactor(precompile): replace Option<PrecompileHalt> with PrecompileStatus enum Introduce PrecompileStatus enum (Success, Revert, Halt) to replace the Option<PrecompileHalt> field in PrecompileOutput. Add PrecompileEthFn type alias for legacy precompile function signatures, with Precompile::execute() now returning PrecompileOutput via a From<PrecompileEthResult> conversion. Add helper methods: is_success, is_revert, halt_reason, into_halt_reason. * refactor(handler): extract precompile_output_to_interpreter_result helper Add a standalone function that converts PrecompileOutput into InterpreterResult, and use it in EthPrecompiles::run. Fmt and clippy fixes. * refactor(precompile): thread reservoir through PrecompileOutput and revert execute signature - Add `reservoir` parameter to PrecompileOutput::new, halt, revert constructors - Add `from_eth_result` constructor that takes reservoir - Revert Precompile::execute to return PrecompileEthResult - Move PrecompileOutput conversion to call site in EthPrecompiles - Remove unused into_halt_reason and From<PrecompileEthResult> impl * refactor(precompile): change Precompile fn_ from PrecompileEthFn to PrecompileFn (bluealloy/revm#3546) Change the Precompile struct's fn_ field from PrecompileEthFn (fn(&[u8], u64) -> PrecompileEthResult) to PrecompileFn (fn(&[u8], u64, u64) -> PrecompileOutput) so precompiles receive reservoir directly and return PrecompileOutput. Add call_eth_precompile helper to wrap existing PrecompileEthFn implementations into the new PrecompileFn signature. Each precompile module gets a thin wrapper using this helper. * refactor(precompile): add eth_precompile_fn! macro to eliminate wrapper boilerplate Replace 17 hand-written PrecompileEthFn-to-PrecompileFn wrapper functions with the new eth_precompile_fn! macro that generates them uniformly. * refactor(op-revm): use eth_precompile_fn! macro for precompile wrappers Replace 8 hand-written wrapper functions in op-revm with the eth_precompile_fn! macro. * style: apply cargo fmt * Rename Eth precompile structs * fix(op-revm): add missing reservoir argument to execute calls in tests * refactor(precompile): move reservoir into PrecompileOutput and add PrecompileStatus helpers PrecompileOutput now carries reservoir and state_gas_used, so precompile_output_to_interpreter_result no longer needs a separate reservoir parameter. Added convenience methods on PrecompileStatus and fixed unused import warning. * fix: update bench and test code for new Precompile API Update eip2537 benchmarks to use Precompile::execute() instead of removed precompile() method, and fix manual div_ceil clippy warning. * docs: fix ResultGas doc comments to match current API Remove references to removed getters (limit, spent, intrinsic_gas, remaining) and update table and derived values to reflect the actual methods (total_gas_spent, tx_gas_used, block_regular_gas_used, etc.). * docs: fix broken doc links and typos in ResultGas - Fix unresolved links to non-existent `regular_gas_spent` and `with_regular_gas_spent` methods in deprecation notes - Fix typos: "substract" → "subtract", "enought" → "enough" - Fix stale comments referencing `regular_gas_spent` field * feat: track state_gas_spent and reservoir in GasInspector * fix: validate max(intrinsic_gas, floor_gas) against TX_MAX_GAS_LIMIT cap * chore: add must_use annotations to gas recording methods and minor cleanups * refactor: update custom_precompile_journal example to use PrecompileOutput API Use `PrecompileOutput::from_eth_result` and `precompile_output_to_interpreter_result` instead of manually constructing InterpreterResult, aligning with the new gas handling. * refactor: make Precompile::execute return Result<PrecompileOutput, PrecompileError> Distinguish fatal/unrecoverable precompile errors from non-fatal halts by returning a Result. PrecompileFn signature updated accordingly, and all call sites now propagate or unwrap the error. * chore: bump MSRV to 1.91 in CI * fix: exclude EIP-8037 reservoir gas from op-revm fee settlement The core revm handler already excludes reservoir gas when calculating beneficiary rewards and caller reimbursement, but op-revm's fee settlement did not account for it. Once Osaka/EIP-8037 is enabled, transactions with leftover reservoir gas would over-credit BASE_FEE_RECIPIENT and OPERATOR_FEE_RECIPIENT, and under-refund operator fees to the caller. - reward_beneficiary: use effective_used (gas.used() - reservoir) for base_fee_amount and operator_fee_cost calculations - operator_fee_refund: include gas.reservoir() when computing gas_used so the refund correctly covers unused reservoir gas - handler validation: use initial_regular_gas (excluding state gas) when checking floor_gas against TX_MAX_GAS_LIMIT cap * refactor: move EIP-8037 gas cap validation into validate_initial_tx_gas (bluealloy/revm#3552) Extract `initial_regular_gas()` helper on InitialAndFloorGas and move the EIP-8037 TX_MAX_GAS_LIMIT validation from the handler into `validate_initial_tx_gas`, consolidating validation logic. Also clean up formatting across precompile and op-revm crates. * chore: release (bluealloy/revm#3472) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * chore: v106 release prep (bluealloy/revm#3554) * docs: add v106 migration guide entry * chore: v106 release prep — version bumps and changelogs * add revm version * fix(op-revm): update validate_against_state_and_deduct_caller signature Adds the new `&mut InitialAndFloorGas` parameter introduced in ethereum-optimism#3577 to the OpHandler trait impl, and passes `&mut Default::default()` at all test call sites. * chore: v107 release prep * chore(op-revm): fmt --------- Co-authored-by: rakita <rakita@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: rakita <dragan0rakita@gmail.com>
…um-optimism#20337) The rust-doctest job intermittently OOMs (rustc killed by SIGKILL) while compiling reth-optimism-node with --all-features on the xlarge (16 GB) executor. Bumps to 2xlarge (32 GB), matching the fix applied to the sibling rust-ci-cargo-tests job in ethereum-optimism#20100 for the same root cause. Also aligns CI with rust/justfile's test-docs recipe: - CI now invokes 'just test-docs' instead of duplicating the cargo command inline, so local and CI behavior stay in sync. - The justfile recipe picks up --all-features to match what CI covers. Tracking: ethereum-optimism#19935
) Wire EthConfigHandler into OpAddOns so the eth_config method (EIP-7910) is served on the eth namespace. Extend the generic bounds on the NodeAddOns and RethRpcAddOns impls to satisfy EthConfigHandler::new: ChainSpec must also implement Hardforks (OpHardforks only implies EthereumHardforks), and the primitives' header must implement HeaderMut so per-fork configs can be built by cloning and retiming the latest header. Implement HeaderMut for the custom-node example's CustomHeader so the example keeps compiling. Add an integration test in crates/node/tests/it/rpc.rs that launches an OpNode against BASE_MAINNET and calls eth_config via the jsonrpsee HTTP client, verifying the endpoint is wired up. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ereum-optimism#20343) The SingleChainMultiNode preset's initial sync check runs the same 30-attempt (60s) CrossSafe match for every verifier sync mode. In ELSync mode that is too tight: the verifier must finish P2P EL sync and emit its first forkchoice update before derivation can start advancing safe, and under CI load that chain of events routinely exceeds 60s, causing TestELSyncSafeRetractedByOffset and TestTruncateDatabaseOnELResync to flake at setup. Expose the resolved sync mode on OpNode and give ELSync verifiers a 4x CrossSafe budget. LocalUnsafe and CLSync budgets are unchanged.
…thereum-optimism#20326) * supernode: rewrite interop log backfill around backfillEndTimestamp Replace the mutable runtimeActivationTimestamp with a pure backfillEndTimestamp. runLogBackfill now returns (minCrossSafeTime, error) instead of advancing activation in place; the caller assigns the result to i.backfillEndTimestamp and firstVerifiableTimestamp() derives end+1 (or activationTimestamp when backfill did not run). Backfill itself runs per chain in parallel over a uniform timestamp window [max(act, minCrossSafeTime-depth), minCrossSafeTime] so all chains seal to the same endpoint — chains whose local tip is ahead of min cross-safe catch up via the main loop instead of eagerly during backfill. Adds tests covering the short-circuits (depth<=0, no chains, activation-in-future) and updates devstack assertions plus logdb's empty-DB guard to use firstVerifiableTimestamp. Made-with: Cursor * supernode: clamp backfill start to chain genesis and short-circuit activation-in-future Promote simpleChainContainer.BlockNumberToTimestamp to the ChainContainer interface (keeping the pre-genesis guard) so backfill can ask each chain for its genesis time. runLogBackfill now clamps the per-chain start up to genesis when genesis is ahead of the computed startTime, avoiding requests for pre-genesis block numbers. Also move the activation > minCrossSafeTime short-circuit out of the goroutine and up to function scope: when hit, runLogBackfill now returns (0, nil), matching the "backfill did not run" convention used by the other short-circuits. This keeps backfillEndTimestamp honest — it's only non-zero when a sealing window was actually attempted. Reject syncStatus with SafeL2.Number == 0 so we don't interpret an unpopulated sync status as a zero-timestamp cross-safe. Relaxes the field comment on backfillEndTimestamp to describe the handoff-boundary semantics rather than overclaiming "last sealed timestamp". Adds TestLogBackfill_ClampsStartToGenesis to pin the clamp behavior; flips TestLogBackfill_ActivationInFuture to assert the new (0, nil) short-circuit contract; stubs BlockNumberToTimestamp on the existing ChainContainer mocks. Made-with: Cursor * Use localSafe for sync status monitoring
* chore(contracts-bedrock): fix contract typos * chore(contracts-bedrock): clean up contract comments * chore(contracts-bedrock): update contract version checks
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.