fix(levm): install the specified EIP-8272 RECENT_ROOT_CODE instead of a native write - #7120
Conversation
Greptile SummaryThe PR replaces EIP-8272’s VM-native recent-root write with an installed 144-byte runtime contract, allowing ordinary EVM execution and EIP-8037 state-gas accounting.
Confidence Score: 4/5The PR appears safe to merge after the non-blocking EIP-8272 integration fixtures are updated to execute the newly installed runtime. The runtime’s derivations and generic EVM behavior match the removed native implementation, but two existing regression tests still construct an empty-code predeploy and will no longer validate or complete the intended write. Files Needing Attention: crates/vm/system_contracts.rs and test/tests/levm/eip8272_tests.rs
|
| Filename | Overview |
|---|---|
| crates/vm/system_contracts.rs | Adds the EIP-8272 runtime bytecode; its decoded hash and storage layouts match the read-side helpers, but existing integration fixtures do not install it. |
| crates/vm/backends/levm/mod.rs | Installs recent-root code and nonce on both L1 activation paths while preserving account balance and recording BAL changes. |
| crates/vm/levm/src/opcode_handlers/frame_tx.rs | Removes frame-specific native writes so frames rely on installed bytecode; stale empty-code test fixtures now silently execute default EOA behavior. |
| crates/vm/levm/src/opcode_handlers/system.rs | Removes CALL-family interception and delegates write behavior, gas, and rollback to ordinary EVM execution. |
| crates/vm/levm/src/vm.rs | Removes native and top-level recent-root handling while retaining generic execution and unrelated frame receipt cleanup. |
| docs/eip-8272.md | Documents the transition from native writes to bytecode execution and the resulting gas and call-path semantics. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[Hegota activation] --> B[Install RECENT_ROOT runtime]
C[Top-level tx / Frame / CALL] --> D[Ordinary EVM execution]
B --> D
D --> E[Validate calldata and value]
E --> F[Derive source ID and slot key]
F --> G[SSTORE through standard gas and journaling]
Prompt To Fix All With AI
### Issue 1
crates/vm/system_contracts.rs:164
**Update empty-code write fixtures**
The existing EIP-8272 write tests still seed `RECENT_ROOT_ADDRESS` with empty code, so after removal of the native frame interception they execute EOA default behavior and fail to populate the expected storage slot. Install `RECENT_ROOT_RUNTIME_BYTECODE` in those fixtures so the write and BAL regression cases exercise the new consensus path.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "fix(levm): install the specified EIP-827..." | Re-trigger Greptile
| /// | ||
| /// Provisional: `RECENT_ROOT_CODE` is TBD in the spec's constants table, so | ||
| /// this is the candidate proposed in ethereum/EIPs#12131. | ||
| pub const RECENT_ROOT_RUNTIME_BYTECODE: [u8; 144] = [ |
There was a problem hiding this comment.
Update empty-code write fixtures
The existing EIP-8272 write tests still seed RECENT_ROOT_ADDRESS with empty code, so after removal of the native frame interception they execute EOA default behavior and fail to populate the expected storage slot. Install RECENT_ROOT_RUNTIME_BYTECODE in those fixtures so the write and BAL regression cases exercise the new consensus path.
Knowledge Base Used: VM: LEVM Execution and the Database Glue
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/vm/system_contracts.rs
Line: 164
Comment:
**Update empty-code write fixtures**
The existing EIP-8272 write tests still seed `RECENT_ROOT_ADDRESS` with empty code, so after removal of the native frame interception they execute EOA default behavior and fail to populate the expected storage slot. Install `RECENT_ROOT_RUNTIME_BYTECODE` in those fixtures so the write and BAL regression cases exercise the new consensus path.
**Knowledge Base Used:** [VM: LEVM Execution and the Database Glue](https://app.greptile.com/lambdaclass/-/custom-context/knowledge-base/lambdaclass/ethrex/-/docs/vm-levm.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.cb7f72d to
5c1a9dc
Compare
… a native write The spec left RECENT_ROOT_CODE TBD, so the 64-byte salt-root write was handled as a VM-level special case on four paths. ethereum/EIPs#12131 specifies the bytecode, so the predeploy carries it and the write is ordinary EVM execution: the entry a caller commits and the gas it pays are both what the code does, and the four interception points go away. Without the code the write bypassed the EIP-8037 state-gas charge for the created slot, which forked the family devnet against a client that executes the predeploy.
5c1a9dc to
22cb7da
Compare
Stacked on #7086; review the last commit only.
Motivation
RECENT_ROOT_CODEwas TBD in EIP-8272, so the predeploy carried no bytecode and the 64-bytesalt ‖ rootwrite was a VM-level special case on four paths: the top-level entry, the CALL family, the frame default-code path, and a carve-out in the simple-transfer fast path. The write cost a flatRECENT_ROOT_WRITE_GAS.ethereum/EIPs#12131 specifies the bytecode, assembled verbatim from the spec's write operation. With it installed the write is ordinary EVM execution, so the entry a caller commits and the gas it pays for committing it are both what the code does, and none of the interception points are needed.
This also removes a consensus divergence. The native write bypassed the EIP-8037 state-gas charge for the created storage slot, so the same transaction cost 38 064 here and 127 196 on a client that executes the predeploy, and the two forked on the first block carrying a root write. An isolated contract doing one fresh
SSTOREcosts the same on both, so the general 8037 path already agrees — it was only the predeploy that did not.Description
RECENT_ROOT_RUNTIME_BYTECODE: the 144 bytes from EIPs#12131, with the derivation and the two prohibitions the spec says need no explicit check documented on the constant.install_recent_root_codenow installs code, matchinginstall_nonce_manager_code: idempotent on code equality, nonce converges tomax(existing, 1), balance preserved.run_top_level_recent_root_write,recent_root_native_write,execute_recent_root_frame, thegeneric_callinterception, the fast-path carve-out andRECENT_ROOT_WRITE_GAS.The read side is untouched: reference validity, the hash derivations and the mempool policy are unchanged, and a root written through the predeploy still validates its own reference because both sides derive keys from the same helpers.
How to test
cargo test -p ethrex-vm --libandcargo test -p ethrex-common recent_rootpass;cargo check --workspaceis clean.