Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d154997
refactor(block): derive pre-block setup gates from the activated-spec…
RealiCZ Jul 31, 2026
c3614ef
refactor(system): state the Rex5 registry test chains as a rung
RealiCZ Jul 31, 2026
696cc36
refactor(hardfork): make `without` crate-private
RealiCZ Jul 31, 2026
a460fc1
refactor(hardfork): single-source spec gating with floor-projected pr…
RealiCZ Jul 31, 2026
0f92b95
test(hardfork): cover a skipped middle rung in validate_schedule
RealiCZ Jul 31, 2026
e253968
refactor(spec): declare MegaSpecId::ALL as the single spec enumeration
RealiCZ Aug 1, 2026
fa92648
perf(hardfork): early-exit the activated-spec floor scan
RealiCZ Aug 1, 2026
d74f533
test(rex5): pin the pre-REX5 30M pre-block system call budget
RealiCZ Aug 1, 2026
f3b0e3c
fix(hardfork): reject orphan patch forks and align timestamp types
RealiCZ Aug 1, 2026
568d51c
docs(spec): state hardfork schedule rules normatively
RealiCZ Aug 1, 2026
a510e5c
test(spec): make the ALL ladder checker itself testable
RealiCZ Aug 1, 2026
ce6ea8f
prototype: B design — 1:1 fork/spec with alias specs and behavior pro…
RealiCZ Aug 4, 2026
3e895d2
prototype: cleanup
RealiCZ Aug 4, 2026
f2d0980
merge origin/main (REX7 seal/open, compute-gas harness, Rex6 timestam…
RealiCZ Aug 4, 2026
f5ceaeb
docs: align vocabulary with alias specs and dual projections
RealiCZ Aug 4, 2026
04f1a31
refactor(spec): derive is_alias from the behavior projection
RealiCZ Aug 4, 2026
670590e
docs: cover alias specs across glossary, spec pages, and mega-evme
RealiCZ Aug 4, 2026
172d89e
fix(state-test): add fixture name mappings for the alias specs
RealiCZ Aug 4, 2026
26f1e09
docs(spec): show the alias rungs in the spec progression
RealiCZ Aug 4, 2026
4c580eb
refactor(evm): dispatch alias specs by direct arm grouping, reconcile…
RealiCZ Aug 4, 2026
a711a5b
fix(evm): pass the behavior spec to the dyn precompiles builder
RealiCZ Aug 4, 2026
2db133f
test: pin the alias specs in the cross-spec compute-gas snapshot
RealiCZ Aug 4, 2026
b420d60
refactor(hardfork): rename introduces_spec to introduces_behavior
RealiCZ Aug 4, 2026
bfc6420
docs: complete alias-spec coverage across rosters, ranges, and CLI va…
RealiCZ Aug 4, 2026
2609c26
docs(spec): record that alias specs get no dedicated upgrade page
RealiCZ Aug 4, 2026
2c56c2d
test: pin ladder positions and hardfork declaration order
RealiCZ Aug 4, 2026
f7bee86
refactor(evme): gate predeploy bytecode selection via reaches
RealiCZ Aug 4, 2026
40ed2c1
test(spec): pin behavior() flatness with a const assertion
RealiCZ Aug 11, 2026
158fe7a
test(hardfork): promote the ladder-climb check to a const assertion
RealiCZ Aug 11, 2026
2a62198
refactor(hardfork): delete max_activated_spec_id in favor of spec_id
RealiCZ Aug 11, 2026
abe9124
refactor(block): derive pre-block setup from the executing spec
RealiCZ Aug 11, 2026
baed076
test(block): reconcile BlockLimits alias grouping with behavior()
RealiCZ Aug 11, 2026
cb43284
test(spec): merge the name and position golden tables
RealiCZ Aug 11, 2026
cbc12c6
fix(state-test): derive the --bench-spec roster from MegaSpecId::ALL
RealiCZ Aug 11, 2026
291db6b
docs(mutants): state the behavior-axis alias omission in the spec roster
RealiCZ Aug 11, 2026
2720baf
test(block): pin the load-time and pre-block params rules together
RealiCZ Aug 11, 2026
45f2a40
docs(block): add the invariant map for the spec ladder and fork schedule
RealiCZ Aug 11, 2026
574bd50
bench(block): pair each block benchmark with its spec-coherent schedule
RealiCZ Aug 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Git submodules are required — clone with `--recursive` or run `git submodule u

### Spec System (`MegaSpecId`)

Progression: `EQUIVALENCE` → `MINI_REX` → `REX` → `REX1` → `REX2` → `REX3` → `REX4` → `REX5` → `REX6` → `REX7`
Progression: `EQUIVALENCE` → `MINI_REX` → `MINI_REX_1` → `MINI_REX_2` → `REX` → `REX1` → `REX2` → `REX3` → `REX4` → `REX5` → `REX6` → `REX7` (`MINI_REX_1`/`MINI_REX_2` are alias rungs executing `EQUIVALENCE` and `MINI_REX` behavior respectively)

- **Spec** defines EVM behavior (what the EVM does).
Defined in `crates/mega-evm/src/evm/spec.rs`.
Expand All @@ -66,10 +66,10 @@ Progression: `EQUIVALENCE` → `MINI_REX` → `REX` → `REX1` → `REX2` → `R
- Frozen and activated are separate properties.
`REX6` is frozen but has no activation timestamp on mainnet or testnet, so both chains still execute `REX5`.
Freezing forbids further semantic change; scheduling is a later, separate decision.
- Specifications of each spec can be found in the upgrade pages under `docs/spec/upgrades/`.
- Specifications of each behavior-introducing spec can be found in the upgrade pages under `docs/spec/upgrades/`; alias rungs have no page of their own and are recorded in the upgrade overview and `docs/spec/hardfork-spec.md`.
- **Hardfork** (`MegaHardfork`) defines network upgrade events (when specs activate).
Multiple hardforks can map to one spec.
`MiniRex1` and `MiniRex2` are hardforks that reuse `EQUIVALENCE` and `MINI_REX` respectively.
Every hardfork schedules a spec rung of its own — the fork→spec mapping is 1:1.
`MiniRex1` and `MiniRex2` schedule the alias specs `MINI_REX_1` and `MINI_REX_2`, whose `behavior()` projects to `EQUIVALENCE` and `MINI_REX` respectively.
Comment thread
RealiCZ marked this conversation as resolved.
Defined in `crates/mega-evm/src/block/hardfork.rs`.
- All specs use `OpSpecId::ISTHMUS` as the Optimism base layer.
But this is subject to change in the future.
Expand All @@ -81,6 +81,10 @@ Progression: `EQUIVALENCE` → `MINI_REX` → `REX` → `REX1` → `REX2` → `R
- **`block/`** — Block execution: executor, factory, hardfork-to-spec mapping, limit enforcement, and the canonical per-chain hardfork schedules.
This module defines how a block in MegaETH block should be executed.
`block/chain.rs` is the single source of truth for the mainnet/testnet chain IDs and activation-timestamp schedules (`hardfork_schedule(chain_id)`, `MAINNET_CHAIN_ID`, `TESTNET_CHAIN_ID`, `mainnet_hardforks()`, `testnet_hardforks()`); look there to find or change when a fork activates on a given chain.
Its unknown-chain fallback pins a named spec rather than following the latest one, so introducing a spec does not move chains that run from genesis; advancing that pin is a deliberate edit made when a spec is sealed.
Forks map 1:1 onto an ascending spec ladder, so the resolved `spec_id` is monotone; rollbacks are alias specs (`MINI_REX_1`, `MINI_REX_2`) whose `behavior()` projects to an earlier spec.
One value, two projections that must not be confused: `is_enabled` compares behavior and gates EVM semantics (rolls back in alias windows); `reaches` compares ladder position and gates one-way chain setup such as predeploys and pre-block rules (never rolls back).
The `is_<fork>_active_at_timestamp` predicates are position projections for behavior-introducing forks and raw event queries for alias forks, and `MegaHardforks::validate_schedule` is the load-time check that a published schedule climbs the ladder without gaps.
- **`limit/`** — Resource limit tracking: compute gas, data size, KV updates, state growth (each in its own module).
MegaETH introduces additional resource metering mechanism and this module implements their logic as utility structs to be used by mega-evm.
- **`access/`** — Block env access tracking and volatile data detection for parallel execution.
Expand All @@ -99,7 +103,7 @@ Progression: `EQUIVALENCE` → `MINI_REX` → `REX` → `REX1` → `REX2` → `R

#### Backward Compatibility of Specs

The spec system (`MegaSpecId`) forms a linear progression where each newer spec includes all previous behaviors.
The spec system (`MegaSpecId`) forms a linear progression where each newer behavior-introducing spec includes all previous behaviors; the alias rungs are the exception, re-executing an earlier spec's behavior instead.
The codebase **MUST** maintain backward-compatibility: EVM semantics must never change for existing (stable) specs.
The only exception is the latest spec if explicitly marked as **unstable**.
Consequently:
Expand Down Expand Up @@ -315,6 +319,7 @@ When the agent is requested to implement a new feature or bug fix, it should con
- **Override `HardforkParams::validate()` for every new params type.**
The default implementation accepts any value silently.
Override it with field-level invariant checks (e.g., non-zero addresses) so that `with_params()` panics loudly at chain-config load time rather than allowing the error to surface at the first block where the fork activates.
Also register the fork-requires-params rule in `MegaHardforks::validate_schedule` so a schedule that activates the fork without its params fails validation, not the fork's first block.
- **Pre-block helpers must return state, not commit directly.**
Any helper participating in `pre_execution_changes` (system contract deploys, pre-block system calls, etc.) MUST return `Option<EvmState>` and never call `db.commit(...)` directly.
Full convention: `crates/mega-evm/src/system/AGENTS.md` → `PRE-BLOCK STATE CHANGE CONTRACT`.
Expand Down
2 changes: 1 addition & 1 deletion ARCH.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This document provides detailed technical specifications and implementation deta
The implementation exposes multiple EVM versions (`MegaSpecId`). String names and hardfork-to-spec
mapping live in `crates/mega-evm/src/evm/spec.rs` and `crates/mega-evm/src/block/hardfork.rs`.

Available specs: `EQUIVALENCE`, `MINI_REX`, `REX`, `REX1`, `REX2`, `REX3`, `REX4`, `REX5`, `REX6`, `REX7`.
Available specs: `EQUIVALENCE`, `MINI_REX`, `MINI_REX_1`, `MINI_REX_2`, `REX`, `REX1`, `REX2`, `REX3`, `REX4`, `REX5`, `REX6`, `REX7` (`MINI_REX_1` and `MINI_REX_2` are alias rungs executing `EQUIVALENCE` and `MINI_REX` behavior respectively).

This page details only the first few; the authoritative per-spec behavior is the specification under
`docs/spec/`, whose upgrade pages cover every spec.
Expand Down
2 changes: 1 addition & 1 deletion bin/mega-evme/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ These options are available across all commands.

| Option | Default | Description |
| ---------------------- | ------- | ----------------------------------------- |
| `--spec <SPEC>` | Rex7 | Spec: `Equivalence`, `MiniRex`, `Rex`, `Rex1`, `Rex2`, `Rex3`, `Rex4`, `Rex5`, `Rex6`, `Rex7` |
| `--spec <SPEC>` | Rex7 | Spec: `Equivalence`, `MiniRex`, `MiniRex1`, `MiniRex2`, `Rex`, `Rex1`, `Rex2`, `Rex3`, `Rex4`, `Rex5`, `Rex6`, `Rex7` (`MiniRex1`/`MiniRex2` are aliases executing `Equivalence`/`MiniRex` behavior) |
| `--chain-id <ID>` | 6342 | Chain ID |

### Block Environment
Expand Down
5 changes: 3 additions & 2 deletions bin/mega-evme/src/common/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ use super::{EvmeError, Result};
#[derive(Args, Debug, Clone)]
#[command(next_help_heading = "Chain Options")]
pub struct ChainArgs {
/// Name of spec to use, possible values: `MiniRex`, `Equivalence`, `Rex`, `Rex1`, `Rex2`,
/// `Rex3`, `Rex4`, `Rex5`, `Rex6`, `Rex7`
/// Name of spec to use, possible values: `Equivalence`, `MiniRex`, `MiniRex1`, `MiniRex2`,
/// `Rex`, `Rex1`, `Rex2`, `Rex3`, `Rex4`, `Rex5`, `Rex6`, `Rex7` (`MiniRex1`/`MiniRex2`
/// are alias specs executing `Equivalence`/`MiniRex` behavior)
#[arg(long = "spec", default_value = "Rex7")]
pub spec: String,

Expand Down
4 changes: 2 additions & 2 deletions bin/mega-evme/src/common/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,8 +566,8 @@ where
// Rex5+: SequencerRegistry (v1.0.0 pre-Rex6, v2.0.0 from Rex6). Only the bytecode
// is installed here — a local run has no chain-config sequencer/admin to seed (the
// registry's storage is otherwise read from forked state).
if spec >= MegaSpecId::REX5 {
let code = if spec >= MegaSpecId::REX6 {
if spec.reaches(MegaSpecId::REX5) {
let code = if spec.reaches(MegaSpecId::REX6) {
SEQUENCER_REGISTRY_CODE_REX6
} else {
SEQUENCER_REGISTRY_CODE
Expand Down
5 changes: 3 additions & 2 deletions bin/mega-t8n/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ pub(crate) struct Cmd {
#[arg(long = "input.txs", default_value = "stdin")]
pub input_txs: String,

/// Name of hardfork to use, possible values: `Equivalence`, `MiniRex`, `Rex`, `Rex1`, `Rex2`,
/// `Rex3`, `Rex4`, `Rex5`, `Rex6`, `Rex7`
/// Name of hardfork to use, possible values: `Equivalence`, `MiniRex`, `MiniRex1`,
/// `MiniRex2`, `Rex`, `Rex1`, `Rex2`, `Rex3`, `Rex4`, `Rex5`, `Rex6`, `Rex7`
/// (`MiniRex1`/`MiniRex2` are alias specs executing `Equivalence`/`MiniRex` behavior)
#[arg(long = "state.fork", default_value = "MiniRex")]
pub fork: String,

Expand Down
6 changes: 3 additions & 3 deletions crates/mega-evm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ A specialized Ethereum Virtual Machine (EVM) implementation tailored for MegaETH

This codebase distinguishes between two related concepts:

- **Spec (`MegaSpecId`)**: Defines EVM behavior - what the EVM does. Values: `EQUIVALENCE`, `MINI_REX`, `REX`, `REX1`, `REX2`, `REX3`, `REX4`, `REX5`, `REX6`, `REX7`
- **Spec (`MegaSpecId`)**: Defines EVM behavior - what the EVM does. Values: `EQUIVALENCE`, `MINI_REX`, `MINI_REX_1`, `MINI_REX_2`, `REX`, `REX1`, `REX2`, `REX3`, `REX4`, `REX5`, `REX6`, `REX7`
- **Hardfork (`MegaHardfork`)**: Defines network upgrade events - when specs are activated. Values: `MiniRex`, `MiniRex1`, `MiniRex2`, `Rex`, `Rex1`, `Rex2`, `Rex3`, `Rex4`, `Rex5`, `Rex6`, `Rex7`

Multiple hardforks can map to the same spec.
For example, both `MiniRex` and `MiniRex2` hardforks use the `MINI_REX` spec.
The mapping between hardforks and specs is one-to-one: every hardfork schedules a spec rung of its own.
Rollbacks are expressed by alias specs whose behavior projects to an earlier spec: `MiniRex1` schedules `MINI_REX_1` (behavior: `EQUIVALENCE`) and `MiniRex2` schedules `MINI_REX_2` (behavior: `MINI_REX`).

## Key Features

Expand Down
79 changes: 53 additions & 26 deletions crates/mega-evm/benches/block_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ use std::convert::Infallible;

use alloy_consensus::{Signed, TxLegacy};
use alloy_evm::{block::BlockExecutor, EvmEnv, EvmFactory};
use alloy_hardforks::ForkCondition;
use alloy_op_evm::block::receipt_builder::OpAlloyReceiptBuilder;
use alloy_primitives::{address, Address, Bytes, Signature, TxKind, B256, U256};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use mega_evm::{
test_utils::{BytecodeBuilder, MemoryDatabase},
BlockLimits, MegaBlockExecutionCtx, MegaBlockExecutor, MegaEvmFactory, MegaHardfork,
MegaHardforkConfig, MegaSpecId, MegaTxEnvelope, SequencerRegistryConfig, TestExternalEnvs,
ACCESS_CONTROL_ADDRESS, ACCESS_CONTROL_CODE, HIGH_PRECISION_TIMESTAMP_ORACLE_ADDRESS,
BlockLimits, MegaBlockExecutionCtx, MegaBlockExecutor, MegaEvmFactory, MegaHardforkConfig,
MegaSpecId, MegaTxEnvelope, SequencerRegistryConfig, TestExternalEnvs, ACCESS_CONTROL_ADDRESS,
ACCESS_CONTROL_CODE, HIGH_PRECISION_TIMESTAMP_ORACLE_ADDRESS,
HIGH_PRECISION_TIMESTAMP_ORACLE_CODE, KEYLESS_DEPLOY_ADDRESS, KEYLESS_DEPLOY_CODE,
LIMIT_CONTROL_ADDRESS, LIMIT_CONTROL_CODE, MEGA_SYSTEM_ADDRESS, ORACLE_CONTRACT_ADDRESS,
ORACLE_CONTRACT_CODE_REX5, SEQUENCER_REGISTRY_ADDRESS, SEQUENCER_REGISTRY_CODE,
Expand Down Expand Up @@ -74,20 +73,20 @@ fn create_deploy_tx(
alloy_consensus::transaction::Recovered::new_unchecked(tx, CALLER)
}

/// Hardfork config activating all hardforks from genesis.
fn all_hardforks_config() -> MegaHardforkConfig {
MegaHardforkConfig::default()
.with(MegaHardfork::MiniRex, ForkCondition::Timestamp(0))
.with(MegaHardfork::Rex, ForkCondition::Timestamp(0))
.with(MegaHardfork::Rex1, ForkCondition::Timestamp(0))
.with(MegaHardfork::Rex2, ForkCondition::Timestamp(0))
.with(MegaHardfork::Rex3, ForkCondition::Timestamp(0))
.with(MegaHardfork::Rex4, ForkCondition::Timestamp(0))
.with(MegaHardfork::Rex5, ForkCondition::Timestamp(0))
.with_params(SequencerRegistryConfig {
/// Hardfork schedule coherent with `spec`: everything through the spec's rung is active from
/// genesis, with the params Rex5+ pre-block setup needs. Each benchmark row therefore measures
/// one complete per-spec world — pre-block setup included — matching the executor's rule that
/// setup follows the executing spec. (A REX6+ row would additionally need
/// `SequencerRegistryRex6Config` attached here.)
fn hardforks_for(spec: MegaSpecId) -> MegaHardforkConfig {
let mut config = MegaHardforkConfig::default().with_all_activated_through(spec);
if spec.reaches(MegaSpecId::REX5) {
config = config.with_params(SequencerRegistryConfig {
rex5_initial_sequencer: MEGA_SYSTEM_ADDRESS,
rex5_initial_admin: MEGA_SYSTEM_ADDRESS,
})
});
}
config
}

/// Create block EVM environment.
Expand Down Expand Up @@ -190,7 +189,7 @@ fn bench_block_empty_txs(c: &mut Criterion) {
let mut executor = MegaBlockExecutor::new(
evm,
block_ctx,
all_hardforks_config(),
hardforks_for(spec),
OpAlloyReceiptBuilder::default(),
);
executor
Expand Down Expand Up @@ -243,7 +242,7 @@ fn bench_block_mixed_txs(c: &mut Criterion) {
let mut executor = MegaBlockExecutor::new(
evm,
block_ctx,
all_hardforks_config(),
hardforks_for(spec),
OpAlloyReceiptBuilder::default(),
);
executor
Expand Down Expand Up @@ -294,7 +293,7 @@ fn bench_block_deploy(c: &mut Criterion) {
let mut executor = MegaBlockExecutor::new(
evm,
block_ctx,
all_hardforks_config(),
hardforks_for(spec),
OpAlloyReceiptBuilder::default(),
);
executor
Expand All @@ -316,10 +315,11 @@ fn bench_block_deploy(c: &mut Criterion) {

/// Benchmark spec comparison for block execution.
///
/// NOTE: All specs run with `all_hardforks_config()`, so even `EQUIVALENCE` and `MINI_REX`
/// deploy Rex4 system contracts during `pre_execution_changes`. This is intentional —
/// the benchmark isolates EVM execution behavior differences across specs, not system
/// contract deployment overhead.
/// NOTE: Each spec runs against its own coherent world (`hardforks_for(spec)`), pre-block
/// setup included: `EQUIVALENCE` deploys nothing while `REX5` bootstraps its predeploys and
/// registry inside every iteration. Rows therefore compare whole-block costs per spec, not
/// isolated EVM execution deltas — for the latter, the cross-spec compute-gas snapshot
/// (`tests/compute_gas/`) is the tool.
fn bench_block_spec_comparison(c: &mut Criterion) {
let mut group = c.benchmark_group("block_executor_spec_comparison");
group.sample_size(10);
Expand Down Expand Up @@ -353,7 +353,7 @@ fn bench_block_spec_comparison(c: &mut Criterion) {
let mut executor = MegaBlockExecutor::new(
evm,
block_ctx,
all_hardforks_config(),
hardforks_for(spec),
OpAlloyReceiptBuilder::default(),
);
executor
Expand Down Expand Up @@ -407,7 +407,7 @@ fn bench_rex5_pre_block(c: &mut Criterion) {
let mut executor = MegaBlockExecutor::new(
evm,
block_ctx,
all_hardforks_config(),
hardforks_for(spec),
OpAlloyReceiptBuilder::default(),
);
executor.apply_pre_execution_changes().expect("pre-execution changes should succeed");
Expand Down Expand Up @@ -435,7 +435,7 @@ fn bench_rex5_pre_block(c: &mut Criterion) {
let mut executor = MegaBlockExecutor::new(
evm,
block_ctx,
all_hardforks_config(),
hardforks_for(spec),
OpAlloyReceiptBuilder::default(),
);
executor.apply_pre_execution_changes().expect("pre-execution changes should succeed");
Expand All @@ -446,12 +446,39 @@ fn bench_rex5_pre_block(c: &mut Criterion) {
group.finish();
}

/// Benchmark hardfork-config resolution on the real mainnet schedule.
///
/// The position-projected predicates (`is_rex_5_active_at_timestamp`) are what downstream node
/// components call once per block; `spec_id` is the executor's per-block resolution;
/// `validate_schedule` is a once-per-config-load cost. Resolution's descending early-exit scan
/// keeps the per-query cost at one or two activation lookups for chains near the top of the
/// ladder, which this benchmark pins.
fn bench_hardfork_resolution(c: &mut Criterion) {
use mega_evm::MegaHardforks;

let mut group = c.benchmark_group("hardfork_resolution");
let schedule = mega_evm::mainnet_hardforks();
// A timestamp after the last scheduled fork: every real query happens here.
let ts = 1_800_000_000u64;

group.bench_function("is_rex_5_active_at_timestamp", |b| {
b.iter(|| black_box(schedule.is_rex_5_active_at_timestamp(black_box(ts))))
});
group.bench_function("spec_id", |b| b.iter(|| black_box(schedule.spec_id(black_box(ts)))));
group.bench_function("validate_schedule", |b| {
b.iter(|| black_box(schedule.validate_schedule()))
});

group.finish();
}

criterion_group!(
benches,
bench_block_empty_txs,
bench_block_mixed_txs,
bench_block_deploy,
bench_block_spec_comparison,
bench_rex5_pre_block,
bench_hardfork_resolution,
);
criterion_main!(benches);
2 changes: 1 addition & 1 deletion crates/mega-evm/src/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Core MegaEVM crate implementation layer that composes execution, block processin
## KEY PATTERNS
- `no_std` discipline is active for this crate.
- Use `#[cfg(not(feature = "std"))] use alloc as std;` when std collections are required.
- Spec progression is additive.
- Spec progression is additive for behavior-introducing specs; alias rungs (`MINI_REX_1`, `MINI_REX_2`) re-execute an earlier behavior instead.
- Keep behavior gates explicit via `spec.is_enabled(...)` at call sites.
- Per-frame trackers must stay stack-aligned with EVM frame lifecycle hooks.
- Intercepted synthetic frame results must keep tracker alignment via empty-frame pushes.
Expand Down
Loading
Loading