Skip to content

feat: REX6 preparation — merge back the internal REX6 line (spec + REX5 refinements)#348

Open
RealiCZ wants to merge 39 commits into
mainfrom
cz/feat/rex6-preview
Open

feat: REX6 preparation — merge back the internal REX6 line (spec + REX5 refinements)#348
RealiCZ wants to merge 39 commits into
mainfrom
cz/feat/rex6-preview

Conversation

@RealiCZ

@RealiCZ RealiCZ commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Merges the internal REX6 preparation line back into public main, preserving the individual commits on the branch for review (final merge will be squashed as usual).
  • Introduces the REX6 spec (unstable, not scheduled on any network): unified per-opcode gas-metering order, consolidated EIP-7702 authorization accounting with dynamic SALT gas for net-new authorities, CREATE-frame accounting, KeylessDeploy sandbox hardening, post-execution fee-reward accounting, system-originated tx metering exemption, extended beneficiary detention / volatile-access coverage, forwarded-gas return on compute-limit halts, and value self-transfer account-info dedup.
  • Lands the REX5-line audit refinements that had not yet reached public in identical form (GuardianAudits remediation rounds; behavior-preserving for live specs).
  • Reconciles with main's recent perf work — REX≤5 semantics follow main, REX6 comes from the internal line: the two-arm wrap_op_compute_gas! hot-path split, the SLOAD fold, and the cached net_usage tracker are all preserved; internal's direct tracker writes were converted to the cache-aware helpers (plus a new add_parent_discardable), and the REX6 Exempt short-circuit is folded into the compute fast path.
  • Hardfork schedules stay on block/chain.rs: mainnet/testnet do not schedule Rex6; the unknown-chain fallback activates REX6 at genesis.

This PR is deliberately scoped to the faithful migration only. Review-driven fixes and remaining REX6 hardening are handled in a dedicated follow-up PR so this one stays a clean, byte-faithful internal→public merge (the branch tip resets to the migration merge commit; the fix commits live on the follow-up branch).

Verification

  • Full workspace test suite (~1300 tests), clippy / fmt / cargo-sort / no_std / Prettier, bench smoke runs, and the Rex5 mainnet replay self-validating fixtures all pass locally.
  • Completeness audited mechanically against both parents: all test names and all added source lines from each side survive the merge (the handful of intentional replacements are documented in the merge commit message).

Notes

  • REX6 is the current unstable spec; scheduling it on a real network is out of scope here.

RealiCZ added 29 commits May 12, 2026 15:05
Reconciles the internal REX6 preparation line with public main. Resolution
principles: REX<=5 semantics follow main (live behavior), REX6 behavior comes
from the internal line, and main's perf/infra work is preserved:

- wrap_op_compute_gas keeps main's two-arm split (plain + @frame); the
  surviving frame-creating compute_gas_ext wrappers use the @frame arm, and
  the REX6 storage-affecting handlers record through the shared
  record_storage_compute_gas! primitive.
- storage_gas_ext::selfdestruct keeps main's static-frame fast path and
  all-dims trailing latch; the REX6 existing-beneficiary accounting arm is
  grafted in.
- FrameLimitTracker keeps main's cached net_usage; internal's direct tracker
  writes are converted to the cache-aware helpers, with a new cache-aware
  add_parent_discardable for the REX6 parent-lane CREATE charge.
- record_compute_gas keeps main's compute-only fast path with the REX6
  Exempt sticky short-circuit folded in ahead of the latch protocol.
- The shared EIP-7702 authorization scanner keeps internal's REX5/REX6 split
  with main's BTreeMap simulated-nonce table.
- Hardfork schedules come from main's block/chain.rs registry; unknown-chain
  fallback now activates REX6 (unstable) at genesis.
- Docs: main's sealed Rex5 pages and versioned-artifact bytecode format as
  the base, internal REX6 unstable blocks on top.
- Benches: main's Workload/register_all framework with a rex6 row added to
  the shared SPEC_IDS table.
@RealiCZ
RealiCZ requested a review from Troublor as a code owner July 21, 2026 07:37
@RealiCZ RealiCZ added spec:unstable Changes to the unstable spec (currently REX5) spec:stable Touches stable spec code — must not change behavior labels Jul 21, 2026
@codspeed-hq

codspeed-hq Bot commented Jul 21, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 366 untouched benchmarks
🆕 30 new benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
🆕 rex6/empty_account_50 N/A 265.1 µs N/A
🆕 rex6/existing_account_50 N/A 261.8 µs N/A
🆕 rex6/create_10 N/A 213.5 µs N/A
🆕 rex6/create2_10 N/A 290.9 µs N/A
🆕 rex6/compute_only_500 N/A 336.3 µs N/A
🆕 rex6/volatile_then_compute_500 N/A 337.7 µs N/A
🆕 rex6/log0_256b N/A 119.6 µs N/A
🆕 rex6/log0_32b N/A 114.8 µs N/A
🆕 rex6/log2_32b N/A 148.7 µs N/A
🆕 rex6/log4_256b N/A 178.7 µs N/A
🆕 rex6/log4_32b N/A 173.5 µs N/A
🆕 rex6 N/A 160.3 µs N/A
🆕 rex6/oracle_sload_50 N/A 132.3 µs N/A
🆕 rex6/regular_sload_50 N/A 132.2 µs N/A
🆕 rex6/sload_100 N/A 176.2 µs N/A
🆕 rex6/sstore_100 N/A 285.4 µs N/A
🆕 rex6/sstore_sload_100 N/A 329.6 µs N/A
🆕 rex6/baseline_add N/A 121.9 µs N/A
🆕 rex6/coinbase N/A 84.1 µs N/A
🆕 rex6/number N/A 83.6 µs N/A
... ... ... ... ...

ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.


Comparing cz/feat/rex6-preview (996c16a) with main (3b550bd)

Open in CodSpeed

@RealiCZ RealiCZ removed the dependencies Pull requests that update a dependency file label Jul 21, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

Scope: 57 files, mostly REX6 additions gated on MegaSpecId::REX6 (unstable) plus REX5 refinements the PR body documents as behavior-preserving. Checked the stable-spec backward-compat contract as the first-order concern (per REVIEW.md): I did not find a path where an existing stable spec (EQUIVALENCE..REX5) changes semantics because of this merge. Test coverage is dense (12 new tests/rex6/* modules totaling ~5.6k lines) and CodSpeed shows no regressions on the shared hot path.

Pre-mortem track (parallel independent review)

Ran a pre-mortem sub-agent to look for likely failure modes and verified each candidate against the code. All candidates resolve to either (a) intentional, tested design tradeoffs already documented in-tree, or (b) follow-ups the PR body's Notes section already lists. Cross-referenced for the record:

  • Fee-reward merge_persistent_usage bypasses check_limit()evm/execution.rs:935-940 calls merge_persistent_usage on all four trackers, and each impl (limit/{data_size,kv_update,state_growth}.rs::merge_persistent_usage) only calls add_tx_persistent(amount) with no follow-up latch. This matches the "post-execution fee-reward accounting vs limit latching" follow-up called out in the PR body's Notes. Block-level accounting still absorbs the writes via BlockLimiter::post_execution_update, so no live-spec effect; REX6-only.
  • REX6 EIP-7702 Ok(0) on pre-frame limit exceedevm/execution.rs:598-621 drops the existing-authority refund on skip, explicitly documented in the inline comment and pinned by test_rex6_authority_state_growth_overflow_forgoes_refund. All-or-nothing is the intended semantic.
  • create_rex6 static-frame halt reorder — documented as change #11 in docs/spec/upgrades/rex6.md (only the trace-visible halt reason changes; committed gas/state are identical).
  • best_effort_resolve_eip7702_delegate_address swallows DB errorsevm/host.rs:263-274, 350-359. By design; the doc comment spells out why (a precheck/side-mark must not turn a legitimate StackUnderflow into a spurious DB error).
  • MegaSpecId::default()REX6 + CLI --spec default → Rex6evm/spec.rs:51, bin/mega-evme/src/common/env.rs:30. Mainnet/testnet schedules don't include REX6 (per block/chain.rs and the PR body); doc-impact already surfaced separately, so this stays an unstable-only default flip.

No inline comments — pre-mortem verified against the code and own-track review found nothing beyond the items already documented or acknowledged.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown

🧬 Mutation testing — ✅ PASS

Diff mutation score: 100.0% (17/17 viable mutants killed)

  • caught: 17
  • survived (real gaps): 0
  • timed out (inconclusive): 0
  • suppressed (equivalent/dead-code): 0
  • unviable: 0 · timeout total: 0

No new test gaps introduced by this change. 🎉

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e7da79d965

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/mega-evm/src/evm/execution.rs
Comment thread crates/mega-evm/src/evm/execution.rs
Comment thread crates/mega-evm/src/evm/execution.rs
Comment thread crates/mega-evm/src/evm/execution.rs
RealiCZ added 2 commits July 21, 2026 15:58
Skip fee-recipient snapshots for deposit-style transactions (op-revm credits
no recipient for them), read fee-recipient balance/emptiness without hydrating
bytecode, and skip the EIP-7702 authority scan when a pre-frame limit is
already latched — so stateless witnesses only need accounts the transaction
actually touches. Each path is pinned by an error-injecting regression test.
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown

🧬 Mutation testing — ❌ FAIL

Diff mutation score: 100.0% (59/59 viable mutants killed)

  • caught: 59
  • survived (real gaps): 0
  • timed out (inconclusive): 47
  • suppressed (equivalent/dead-code): 0
  • unviable: 100 · timeout total: 47

Timed-out mutants (inconclusive)

Each mutation below never finished within the timeout, so it was not proven caught. Make it terminate (a faster test), kill it, or — if it is a genuine non-terminating/equivalent case — add a justified entry to mutants/suppressions.toml.

  • crates/mega-evm/src/evm/execution.rs:235:41: replace && with || in MegaHandler<EVM, ERROR, FRAME>::scan_applied_eip7702_authorizations
  • crates/mega-evm/src/evm/execution.rs:235:16: delete ! in MegaHandler<EVM, ERROR, FRAME>::scan_applied_eip7702_authorizations
  • crates/mega-evm/src/evm/execution.rs:235:58: replace != with == in MegaHandler<EVM, ERROR, FRAME>::scan_applied_eip7702_authorizations
  • crates/mega-evm/src/evm/execution.rs:238:38: replace == with != in MegaHandler<EVM, ERROR, FRAME>::scan_applied_eip7702_authorizations
  • crates/mega-evm/src/evm/execution.rs:255:45: replace && with || in MegaHandler<EVM, ERROR, FRAME>::scan_applied_eip7702_authorizations
  • crates/mega-evm/src/evm/execution.rs:255:24: delete ! in MegaHandler<EVM, ERROR, FRAME>::scan_applied_eip7702_authorizations
  • crates/mega-evm/src/evm/execution.rs:255:48: delete ! in MegaHandler<EVM, ERROR, FRAME>::scan_applied_eip7702_authorizations
  • crates/mega-evm/src/evm/execution.rs:263:71: replace && with || in MegaHandler<EVM, ERROR, FRAME>::scan_applied_eip7702_authorizations
  • crates/mega-evm/src/evm/execution.rs:263:42: delete ! in MegaHandler<EVM, ERROR, FRAME>::scan_applied_eip7702_authorizations
  • crates/mega-evm/src/evm/execution.rs:270:46: replace && with || in MegaHandler<EVM, ERROR, FRAME>::scan_applied_eip7702_authorizations
  • crates/mega-evm/src/evm/execution.rs:263:84: replace == with != in MegaHandler<EVM, ERROR, FRAME>::scan_applied_eip7702_authorizations
  • crates/mega-evm/src/evm/execution.rs:348:65: replace == with != in MegaHandler<EVM, ERROR, FRAME>::snapshot_fee_recipients
  • crates/mega-evm/src/evm/execution.rs:394:31: replace == with != in MegaHandler<EVM, ERROR, FRAME>::record_rex6_eip7702_authority_accounting
  • crates/mega-evm/src/evm/execution.rs:598:37: replace == with != in <impl Handler for MegaHandler<EVM, ERROR, FRAME>>::pre_execution
  • crates/mega-evm/src/evm/execution.rs:685:51: replace && with || in <impl Handler for MegaHandler<EVM, ERROR, FRAME>>::validate
  • crates/mega-evm/src/evm/execution.rs:685:73: replace == with != in <impl Handler for MegaHandler<EVM, ERROR, FRAME>>::validate
  • crates/mega-evm/src/evm/execution.rs:800:51: replace += with -= in <impl Handler for MegaHandler<EVM, ERROR, FRAME>>::validate
  • crates/mega-evm/src/evm/execution.rs:800:51: replace += with *= in <impl Handler for MegaHandler<EVM, ERROR, FRAME>>::validate
  • crates/mega-evm/src/evm/execution.rs:915:12: delete ! in <impl Handler for MegaHandler<EVM, ERROR, FRAME>>::reward_beneficiary
  • crates/mega-evm/src/evm/execution.rs:930:24: replace == with != in <impl Handler for MegaHandler<EVM, ERROR, FRAME>>::reward_beneficiary
  • … and 27 more (see timeout.txt in the run artifacts).

Tip: run /improve-mutation-score to triage and fix these.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧭 Re-review update

  • Summary: Incremental scope since prior review at e7da79d9 covers changes to crates/mega-evm/src/evm/execution.rs and crates/mega-evm/src/evm/host.rs, paired tests in crates/mega-evm/tests/rex6/eip7702_authority_accounting.rs and crates/mega-evm/tests/rex6/fee_reward_accounting.rs, and CLI-spec doc syncs. All changes are witness-friendly follow-ups to the Codex feedback (threads already resolved).
  • The three fixes look correct and are each pinned by an error-injecting regression test:
    • Deposit-tx guard in reward_beneficiary (execution.rs:928) mirrors op-revm's deposit early-return; symmetric with the sandbox-tx path.
    • New inspect_account_balance_and_emptiness helper (host.rs:518) is a non-hydrating sibling of inspect_account_code_hash; skips code_by_hash in both branches while still marking the account cold in the vacant branch.
    • REX6 authority-scan skip in validate() (execution.rs:690) uses additional_limit.limit_exceeded() — the same condition pre_execution at execution.rs:617 gates the auth-list apply on, so validate-time scan and pre-execution apply now agree on the doomed-tx path.
  • Pre-mortem: independent sub-agent produced 5 candidates; verifier confirmed 0. PM-001/PM-005 (unstable-spec defaults + unknown-chain fallback) match documented intent (mainnet/testnet schedules pin REX≤5). PM-002 refuted from repo evidence at evm/instructions.rs:769-770 (parent_original_gas_left = gas.remaining() + forwarded_gas) — revm has deducted forwarded gas before the abort erase, so the refund is correct. PM-004 refuted: push_create_frame returns parent_needs_update=false at top level, so record_parent_discardable is never entered for a top-level CREATE; the sender account-info write is already covered at before_tx_start.
  • Inline comments: 0. Body-only items: 0 blocking.
  • Still open from earlier reviews: none. All prior Codex/CodeQL threads are resolved.

Pre-mortem (unverified):

  • crates/mega-evm/src/limit/frame_limit.rs:197-198,208-209pop_frame revert branches use plain -= on cached_total_used and cached_total_refund. The invariant (child.discardable_usage ≤ cached_total_used, child.refund ≤ cached_total_refund) is enforced only by construction and a #[cfg(debug_assertions)] assert_eq! in net_usage() — not by the pop path itself. No failing input under current callers; worth confirming whether promoting these four to saturating_sub (or a release-mode debug-assert) is desired hardening against future edits, given add_parent_discardable newly writes to the parent slot.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8bf474b97a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/mega-evm/src/limit/frame_limit.rs
Comment thread crates/mega-evm/src/evm/instructions.rs
Comment thread crates/mega-evm/src/limit/state_growth.rs
RealiCZ added 3 commits July 21, 2026 16:41
Kill the surviving diff-scoped spec-gate mutants: exact-boundary tests for
the REX5 delegate-resolution hydration gate, the MiniRex/REX contract-creation
formula switch, and both directions of the REX-family unscaled-gas debug
asserts (available at REX exactly; should-panic pre-REX).

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧭 Re-review update

  • Scope since prior review at 8bf474b9: a single commit 1a0f8548 — 14 lines in crates/mega-evm/src/limit/frame_limit.rs. This is exactly the hardening the previous re-review's Pre-mortem (unverified) item requested: pinning the pop-frame cache invariant with debug_assert! on both child.discardable_usage <= cached_total_used and child.refund <= cached_total_refund, applied symmetrically to the parent-branch and tx_entry-branch revert paths.
  • The debug-only assertion is the right severity tier here: the hot path stays branch-free in release, tests with debug_assertions trip at the exact pop where a future direct-write mutation bypasses the cache-aware helpers, and the comment explains why "by construction every add to any entry also added to the cache" makes the invariant hold today. The subsequent -= remains a straight subtraction so release-mode underflow would still panic (in debug) — no saturating_sub cover-up.
  • Pre-mortem: sub-agent produced 6 candidates. All resolve without a new inline comment:
    • MegaSpecId::default() == REX6 and unknown-chain fallback activating REX6 at genesis — both are the documented intentional posture per PR body and AGENTS.md ("REX6 is the current unstable spec"); mainnet/testnet schedules do not include REX6.
    • MegaContext::system_address staying at MEGA_SYSTEM_ADDRESS on the CLI run/tx path — explicitly acknowledged as accepted design tradeoff in the create_evm_context docstring at bin/mega-evme/src/common/env.rs:189-192 ("these paths do not go through the block executor and do not resolve from SequencerRegistry"). Block execution correctly resolves via resolve_system_address at crates/mega-evm/src/block/executor.rs:627.
    • FrameLimitTracker cache invariant is now backed by the pop-frame debug_assert!s added in 1a0f8548; making the fields private would be a larger refactor and is not warranted here.
    • mark_exempt() also disables gas detention — documented in system/tx.rs:117-121; whitelist is currently only ORACLE_CONTRACT_ADDRESS.
    • REX6 EIP-7702 Ok(0) on pre-frame limit-exceeded (no existing-authority refund) — already covered by prior review; the all-or-nothing semantic is intentional and pinned by test_rex6_authority_state_growth_overflow_forgoes_refund.
  • Inline comments: 0. Body-only items: 0 blocking.
  • Still open from earlier reviews: three Codex-authored P1/P2 threads on limit/frame_limit.rs:362, evm/instructions.rs:1094, and limit/state_growth.rs:287. These are the REX6-only follow-ups the PR body's Notes section explicitly carries forward (CREATE pre-frame accounting lifecycle, source-side SELFDESTRUCT marking under volatile access, CREATE-target preload before revm depth/balance checks). Not authored by this workflow, so left as-is.

Pre-mortem: no verifiable high-impact failure path found.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review update

  • Scope since prior review at 85883cb: one commit 1119f39 - three doc-comment lines in crates/mega-evm/src/external/gas.rs (backticks around MiniRex in test docstrings). No functional change.
  • All 9 prior review threads are resolved. Nothing to reconcile.
  • Pre-mortem: sub-agent produced 5 candidates, none tied to the incremental commit and none newly actionable. PM-001 (REX6 reward_beneficiary writes bypassing per-tx limit re-check) is already listed in the PR body Notes as a tracked REX6-only follow-up. PM-002 through PM-005 are all self-labeled hypothesis with no decisive evidence at HEAD.
  • No new inline findings.
  • Still open from earlier reviews: three Codex-authored P1/P2 threads on limit/frame_limit.rs, evm/instructions.rs, and limit/state_growth.rs are the REX6-only follow-ups the PR body itself carries forward.

Pre-mortem: no verifiable high-impact failure path found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1119f399a3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/mega-evm/src/evm/execution.rs
Comment thread crates/mega-evm/src/limit/data_size.rs
Comment thread crates/mega-evm/src/system/tx.rs
Comment thread crates/mega-evm/src/evm/execution.rs
The review-driven fixes and remaining follow-up work move to a dedicated PR so
this PR stays a clean, byte-faithful internal->public migration. All fix
commits are preserved on the follow-up branch.
RealiCZ added 4 commits July 21, 2026 17:56
Kill the surviving diff-scoped spec-gate mutants: exact-boundary tests for
the REX5 delegate-resolution hydration gate, the MiniRex/REX contract-creation
formula switch, and both directions of the REX-family unscaled-gas debug
asserts (available at REX exactly; should-panic pre-REX).
@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Documentation Impact

This PR already adds extensive REX6 documentation, but a few gaps and one artifact remain relative to docs/spec/AGENTS.md conventions and the code changes.

Spec Documentation

Doc page Reason
docs/spec/upgrades/rex6.md Doesn't follow the required upgrade-page structure from docs/spec/AGENTS.md: the Summary section should be 2-4 paragraphs, but instead contains a 13-item list followed by 9 full narrative subsections that duplicate what belongs under What Changed. Meanwhile What Changed only provides Previous behavior / New behavior pairs for 7 of the 13 summarized changes -- missing pairs for: CREATE-frame resource accounting, KeylessDeploy sandbox hardening, post-execution fee-reward accounting, the beneficiary-detention/volatile-access coverage extensions (source-side SELFDESTRUCT, EIP-7702-delegated CALL, existing-beneficiary accounting, Oracle sendHint gating), the per-log data-size base + forwarded-gas-return corrections, value self-transfer dedup, the EIP-7702 auth-list pre-frame-limit skip, the CREATE2 oversized-initcode/static-frame halts, and the KeylessDeploy occupancy-check journal read.
docs/spec/system-contracts/keyless-deploy.md Missing coverage for the REX6 occupancy-check-reads-through-the-journal change (inspect_account_code_hash in evm/host.rs, used in sandbox/execution.rs) -- this affects whether the deploy address is captured in the transaction's returned state. The other two REX6 KeylessDeploy changes (gas rescue on compute-gas halt, self-destructing-constructor classification) are correctly documented, but this third one is absent.
docs/spec/evm/gas-forwarding.md The storage gas stipend paragraph and its 5-item bullet list under Storage Gas Stipend Interaction is duplicated verbatim (appears twice in a row). This looks like a copy-paste artifact introduced by this PR's diff rather than a pre-existing issue.

These can be addressed in this PR or a fast follow-up.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧭 Re-review update

  • Scope since prior review at 1119f399: one commit 304fa1arevert: reset PR to the faithful migration merge (f736086). Net effect at HEAD: reverts the six commits added on top of the migration merge (deposit-tx guard in reward_beneficiary, non-hydrating _balance_and_emptiness sibling, EIP-7702 auth-scan skip on latched limit, pop-frame cache debug_assert!s, spec-gate boundary tests, doc-comment fixes). PR body Notes states this is intentional — those fixes move to a dedicated follow-up PR so this PR ships a byte-faithful internal→public migration.
  • Re-review posture: the tip is now the merge commit itself. Live-spec (EQUIVALENCE..REX5) semantics still trace to main; REX6 is unstable and unscheduled on mainnet/testnet per crates/mega-evm/src/block/chain.rs. No new blocking finding surfaced against the migration merge that is not already captured below.
  • Pre-mortem: sub-agent produced 5 candidates; verifier judged 0 as new confirmed findings. PM-001 (MegaSpecId::default() == REX6) and PM-002 (reward_beneficiary merge_persistent_usage bypasses check_limit()) are both already acknowledged in earlier reviews and in the PR body Notes. PM-004 (best_effort_resolve_eip7702_delegate_address swallows DB errors) is documented as intentional in its doc comment. PM-005 is a low-confidence hypothesis. PM-003 promoted to the Pre-mortem (unverified) section below.
  • Inline comments: 0. Body-only items: 0 new; existing follow-ups tracked in the open Codex threads listed below.

Still open from earlier reviews (all Codex-authored, on paths whose fixes were reverted by 304fa1a or never landed on this PR; the PR body explicitly carries these to the follow-up PR):

  • P1 evm/execution.rs:800 — REX6 EIP-7702 authority-scan loop uses unchecked initial_gas += authority_storage_gas after new_account_storage_gas may saturate to u64 MAX; can wrap past the gas_limit / affordability check and admit an unfunded auth list.
  • P2 evm/execution.rs:824 — Deposit-caller emptiness read uses inspect_account(caller, false), which can hydrate code_by_hash on the occupied branch and fail stateless/witness replay for a deposit whose caller is a lazy contract account.
  • P2 limit/data_size.rs:295 — REX6 CREATE parent-lane record_parent_discardable(ACCOUNT_INFO_WRITE_SIZE) after push_create_frame still marks charged_parent_update, so pop_frame_unwind_parent(false) resets parent.target_updated on child revert even though the creator nonce bump survives. A subsequent CREATE / value-CALL at the same parent frame re-charges the creator write. limit/kv_update.rs has the same shape.
  • P2 system/tx.rs:134is_system_originated matches a deposit-typed tx purely on source_hash == MEGA_SYSTEM_TRANSACTION_SOURCE_HASH, so an executor input (t8n / replay) that hands in a deposit-typed tx from a non-system caller can trigger LimitCheck::Exempt in on_new_tx without traversing before_run caller/whitelist gate.

Pre-mortem (unverified):

  • crates/mega-evm/src/limit/limit.rs (mark_exempt) + crates/mega-evm/src/evm/context.rs:594-609 (on_new_tx ordering) — on_new_tx calls additional_limit.before_tx_start(&self.inner.tx) (which can latch LimitCheck::ExceedsLimit) before mark_exempt() unconditionally stamps LimitCheck::Exempt. No caller today can hit this because the exempt path is entered only for txs the is_system_originated gate accepts; but there is no defense-in-depth (no debug_assert! that the state was WithinLimit, no early-return reordering), so a future refactor of is_system_originated (see the open system/tx.rs:134 Codex thread) or of mark_exempt callers could silently unlock the metering bypass. Worth confirming whether a debug_assert! inside mark_exempt, or reordering on_new_tx to skip before_tx_start entirely for system txs, is desired hardening.

Pre-mortem: no verifiable high-impact failure path found.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review update: no incremental commits since prior review at 996c16a; all 13 prior review threads are resolved. Pre-mortem produced 5 candidates: PM-001 was refuted upon verification (push_create_frame returns false when the frame stack is empty, so record_parent_discardable is never invoked for a top-level CREATE; the tx-caller creator write is already recorded in DataSizeTracker::before_tx_start via add_tx_persistent). PM-002, PM-003, PM-004, PM-005 are all already covered by prior reviews or PR body Notes. No new inline findings. Pre-mortem: no verifiable high-impact failure path found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api:breaking Crate interface change — downstream users must update comp:core Changes to the `mega-evm` core crate comp:doc Changes in the documentation comp:mega-evme Changes to the `mega-evme` tool comp:misc Changes to the miscellaneous part of this repo rust Pull requests that update rust code spec:new Introduces a new MegaSpecId variant spec:stable Touches stable spec code — must not change behavior spec:unstable Changes to the unstable spec (currently REX5)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants