Skip to content

Osaka hard fork#99

Merged
mrLSD merged 2 commits intomasterfrom
osaka-hard-fork
Jan 17, 2026
Merged

Osaka hard fork#99
mrLSD merged 2 commits intomasterfrom
osaka-hard-fork

Conversation

@mrLSD
Copy link
Copy Markdown
Member

@mrLSD mrLSD commented Jan 15, 2026

Summary by CodeRabbit

  • New Features

    • Added Osaka hard fork support, including CLZ (Count Leading Zeros) opcode, updated gas handling, runtime flags, and Osaka-specific precompile set.
  • Chores

    • Bumped workspace version to 3.0.0.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 15, 2026

Walkthrough

Add EIP-7939 CLZ (count leading zeros) support for the Osaka hard fork: new opcode, execution implementation and tests, gas metering conditional on runtime flag, runtime Config flag and Osaka preset, precompile set and test dependency adjustments, and workspace version bump.

Changes

Cohort / File(s) Summary
Version Update
Cargo.toml
Bump workspace package version from "2.2.0" to "3.0.0"
Opcode Definition
evm/src/core/opcode.rs
Add CLZ opcode constant 0x1e and include "CLZ" in Display mapping (EIP-7939, Osaka)
Execution Logic
evm/src/core/eval/bitwise.rs, evm/src/core/eval/mod.rs
Implement pub fn clz(op1: U256) -> U256 with tests; add CLZ dispatch entry using op1_u256_fn!
Gas Metering
evm/src/gasometer/mod.rs, evm-tests/src/types/spec.rs
Make CLZ gas cost conditional on config.has_clz; add Osaka support in gasometer config lookup
Runtime Configuration
evm/src/runtime/mod.rs
Add pub has_clz: bool to Config and has_clz to DerivedConfigInputs; add Config::osaka() / derived inputs enabling CLZ
Precompiles & Tests
evm-tests/src/precompiles.rs, evm-tests/Cargo.toml
Add Precompiles::new_osaka() and adjust precompile composition (Osaka-specific ModExp); replace/adjust aurora-engine precompiles dependency provenance

Sequence Diagram

sequenceDiagram
    participant Runtime as Runtime Config
    participant Engine as EVM Engine
    participant Dispatch as Opcode Dispatch
    participant Gas as Gas Metering
    participant Exec as Bitwise Executor

    Runtime->>Runtime: Initialize (has_clz = true for Osaka)
    Engine->>Dispatch: Encounter opcode 0x1e (CLZ)
    Dispatch->>Gas: Query dynamic opcode cost for CLZ
    Gas->>Runtime: Check config.has_clz
    alt has_clz enabled
        Gas->>Dispatch: Return GasCost::Low
        Dispatch->>Exec: Call clz(op1)
        Exec->>Exec: Compute leading_zeros(U256)
        Exec->>Engine: Push result to stack
    else has_clz disabled
        Gas->>Dispatch: Return GasCost::Invalid
        Dispatch->>Engine: Reject/invalid opcode
    end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested Reviewers

  • aleksuss

Poem

🐰 A hop, a nibble, a CLZ so bright,

I count the zeros from left to right,
Osaka wakes this new opcode tune,
Gas and config hum beneath the moon,
Hooray — leading bits revealed by night!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title "Osaka hard fork" directly and clearly describes the main objective of the changeset, which is to add support for the Osaka hard fork across multiple components.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

🧹 Recent nitpick comments
evm-tests/src/precompiles.rs (1)

136-172: Consider extending new_prague() to reduce duplication.

The new_osaka() implementation duplicates all precompiles from new_prague(), differing only in the ModExp type parameter (Osaka vs Berlin). You could reduce maintenance burden by extending new_prague() and replacing the ModExp entry:

♻️ Suggested refactor
 pub fn new_osaka() -> Self {
-    let mut map = BTreeMap::new();
-    map.insert(
-        ECRecover::ADDRESS.raw(),
-        Box::new(ECRecover) as Box<dyn Precompile>,
-    );
-    map.insert(SHA256::ADDRESS.raw(), Box::new(SHA256));
-    map.insert(RIPEMD160::ADDRESS.raw(), Box::new(RIPEMD160));
-    map.insert(Identity::ADDRESS.raw(), Box::new(Identity));
-    map.insert(
-        ModExp::<Osaka, AuroraModExp>::ADDRESS.raw(),
-        Box::new(ModExp::<Osaka, AuroraModExp>::new()),
-    );
-    map.insert(
-        Bn256Add::<Istanbul>::ADDRESS.raw(),
-        Box::new(Bn256Add::<Istanbul>::new()),
-    );
-    map.insert(
-        Bn256Mul::<Istanbul>::ADDRESS.raw(),
-        Box::new(Bn256Mul::<Istanbul>::new()),
-    );
-    map.insert(
-        Bn256Pair::<Istanbul>::ADDRESS.raw(),
-        Box::new(Bn256Pair::<Istanbul>::new()),
-    );
-    map.insert(Blake2F::ADDRESS.raw(), Box::new(Blake2F));
-
-    map.insert(Kzg::ADDRESS, Box::new(Kzg));
-    map.insert(BlsG1Add::ADDRESS.raw(), Box::new(BlsG1Add));
-    map.insert(BlsG1Msm::ADDRESS.raw(), Box::new(BlsG1Msm));
-    map.insert(BlsG2Add::ADDRESS.raw(), Box::new(BlsG2Add));
-    map.insert(BlsG2Msm::ADDRESS.raw(), Box::new(BlsG2Msm));
-    map.insert(BlsPairingCheck::ADDRESS.raw(), Box::new(BlsPairingCheck));
-    map.insert(BlsMapFpToG1::ADDRESS.raw(), Box::new(BlsMapFpToG1));
-    map.insert(BlsMapFp2ToG2::ADDRESS.raw(), Box::new(BlsMapFp2ToG2));
-    Self(map)
+    let mut map = Self::new_prague().0;
+    // Replace ModExp with Osaka-specific gas costs
+    map.insert(
+        ModExp::<Osaka, AuroraModExp>::ADDRESS.raw(),
+        Box::new(ModExp::<Osaka, AuroraModExp>::new()),
+    );
+    Self(map)
 }

This assumes ModExp::<Osaka, _>::ADDRESS equals ModExp::<Berlin, _>::ADDRESS (same precompile address 0x05). If they differ, the current explicit approach is correct.


📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0290fb6 and c8cb4ad.

📒 Files selected for processing (2)
  • evm-tests/Cargo.toml
  • evm-tests/src/precompiles.rs
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: mrLSD
Repo: aurora-is-near/aurora-evm PR: 95
File: evm-tests/src/precompiles.rs:45-86
Timestamp: 2025-12-19T01:09:14.674Z
Learning: In the aurora-evm codebase (evm-tests), there are no test cases for pre-Istanbul Ethereum forks (Frontier, Homestead, Tangerine, SpuriousDragon, Byzantium, Constantinople, Petersburg). Therefore, it is acceptable for the precompile set composition in evm-tests/src/precompiles.rs to route all these forks to new_istanbul() even though this technically applies Istanbul-era gas costs to earlier forks, as there are no tests that would be affected by this implementation choice.
📚 Learning: 2025-12-19T00:45:15.604Z
Learnt from: mrLSD
Repo: aurora-is-near/aurora-evm PR: 95
File: evm-tests/src/types/transaction.rs:195-238
Timestamp: 2025-12-19T00:45:15.604Z
Learning: In the aurora-evm-jsontests crate (evm-tests), explicit panics with `expect()` or `unwrap()` are preferred over error handling for test debugging purposes, as they provide exact failure locations and stack traces that are more useful during test development and debugging.

Applied to files:

  • evm-tests/Cargo.toml
📚 Learning: 2025-12-19T01:14:58.120Z
Learnt from: mrLSD
Repo: aurora-is-near/aurora-evm PR: 95
File: evm-tests/src/state_dump.rs:84-92
Timestamp: 2025-12-19T01:14:58.120Z
Learning: In evm-tests/src/state_dump.rs (aurora-evm crate), the dump_to_file method correctly generates filenames using format!("state_test_{spec:?}_{now}.json"). The Spec enum Debug format produces clean variant names (e.g., "Shanghai", "Cancun") that are filesystem-safe and do not contain problematic characters like colons. This is Aurora EVM, not REVM.

Applied to files:

  • evm-tests/Cargo.toml
  • evm-tests/src/precompiles.rs
📚 Learning: 2025-12-19T00:47:31.731Z
Learnt from: mrLSD
Repo: aurora-is-near/aurora-evm PR: 95
File: evm-tests/src/types/eip_7702.rs:84-91
Timestamp: 2025-12-19T00:47:31.731Z
Learning: In the aurora-evm codebase (evm-tests), the version of `primitive-types` being used has `U256::to_big_endian()` return a `[u8; 32]` array value, not require a mutable slice parameter. The pattern `result[..32].copy_from_slice(&r.to_big_endian())` is correct and compiles successfully.

Applied to files:

  • evm-tests/Cargo.toml
📚 Learning: 2025-12-19T01:09:14.674Z
Learnt from: mrLSD
Repo: aurora-is-near/aurora-evm PR: 95
File: evm-tests/src/precompiles.rs:45-86
Timestamp: 2025-12-19T01:09:14.674Z
Learning: In the aurora-evm codebase (evm-tests), there are no test cases for pre-Istanbul Ethereum forks (Frontier, Homestead, Tangerine, SpuriousDragon, Byzantium, Constantinople, Petersburg). Therefore, it is acceptable for the precompile set composition in evm-tests/src/precompiles.rs to route all these forks to new_istanbul() even though this technically applies Istanbul-era gas costs to earlier forks, as there are no tests that would be affected by this implementation choice.

Applied to files:

  • evm-tests/Cargo.toml
  • evm-tests/src/precompiles.rs
📚 Learning: 2025-12-19T00:45:08.192Z
Learnt from: mrLSD
Repo: aurora-is-near/aurora-evm PR: 95
File: evm-tests/src/types/transaction.rs:195-238
Timestamp: 2025-12-19T00:45:08.192Z
Learning: In test code within the evm-tests crate (evm-tests/src/...), prefer using unwrap() or expect() to trigger immediate panics with precise location when a test condition fails. This aids debugging by showing the exact failure point and stack trace. Use this approach only in test code; production/error-handling paths should still use proper error handling rather than unwrapping.

Applied to files:

  • evm-tests/src/precompiles.rs
📚 Learning: 2025-12-19T00:59:18.510Z
Learnt from: mrLSD
Repo: aurora-is-near/aurora-evm PR: 95
File: evm-tests/src/types/ecrecover.rs:6-26
Timestamp: 2025-12-19T00:59:18.510Z
Learning: In evm-tests/src/types/ecrecover.rs (aurora-evm-jsontests crate), panicking on invalid input (such as insufficient signature length) is preferable to adding input validation checks and returning errors, as explicit panics provide clearer failure locations and stack traces that are more useful for test debugging purposes.

Applied to files:

  • evm-tests/src/precompiles.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: ethereum-tests-32-bit
  • GitHub Check: unit-tests-32-bit
  • GitHub Check: ethereum-tests
🔇 Additional comments (3)
evm-tests/src/precompiles.rs (2)

5-5: LGTM!

Import path correctly updated to use the consolidated aurora_engine_precompiles::modexp module.


55-56: LGTM!

Clean separation of Prague and Osaka spec handling, routing each to their respective precompile constructors.

evm-tests/Cargo.toml (1)

18-18: Package version confirmed. Aurora-engine-precompiles version 2.1.0 is published and correctly includes both the Osaka type and modexp module. The code successfully imports and uses them (e.g., use aurora_engine_precompiles::modexp::AuroraModExp; and ModExp::<Osaka, AuroraModExp>::new()).

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@mrLSD mrLSD merged commit f5ed625 into master Jan 17, 2026
7 checks passed
@mrLSD mrLSD deleted the osaka-hard-fork branch January 17, 2026 00:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants