Skip to content

Add L1SLOAD and L1STATICCALL on real-time - #175

Closed
jmadibekov wants to merge 30 commits into
taikoxyz:mainfrom
NethermindEth:jmadibekov/l1precompiles-realtime
Closed

jmadibekov wants to merge 30 commits into
taikoxyz:mainfrom
NethermindEth:jmadibekov/l1precompiles-realtime

Conversation

@jmadibekov

Copy link
Copy Markdown

Real-time-rebased version of the L1SLOAD + L1STATICCALL precompiles. Stacked semantically on PR #12 (real-time proving support).

Relationship to existing PRs

  • #11 — original L1SLOAD precompile, on Shasta. Untouched.
  • #13 — original L1STATICCALL precompile, on Shasta. Untouched.

This new PR rebases the same work onto main (post PR #12) so the precompiles can run alongside real-time proving. The 18 commits from PR #11 + PR #13 cherry-picked cleanly with zero conflicts (the precompile code is hardfork-agnostic).

What changed vs. PR #11 + PR #13

One additional commit: rename CURRENT_L1_ORIGIN_BLOCK_ID → CURRENT_L1_MAX_ANCHOR_BLOCK_ID plus all callers, error messages, and test names. Same underlying value — Shasta's originBlockNumber and RealTime's maxAnchorBlockNumber play the same structural role (the on-chain-verified L1 block that anchors the precompile's [N − 256, N] lookback window). The rename makes the variable name accurate under both forks.

Files

  • 19 commits total. 23 files net (+2,243 / -156).
  • Precompile additions:
    • crates/evm/src/precompiles/l1sload.rs (812 LoC)
    • crates/evm/src/precompiles/l1staticcall.rs (1,286 LoC)
    • crates/evm/src/precompiles/mod.rs (20 LoC) — wires taiko_precompiles_map() into the EVM factory
  • All other files are mechanical merges around PR feat(rpc): introduce find_last_block_number_by_batch_id #12's RealTime hardfork additions.

Tests

cargo test -p alethia-reth-evm --lib precompiles::
# test result: ok. 60 passed; 0 failed

cargo build --workspace clean. cargo clippy -p alethia-reth-evm zero errors.

Cross references

Gohnnyman and others added 30 commits February 18, 2026 12:12
* feat: Move Node Builder types to alethia-reth-node

* feat: custom treasury address added for evm factory

* feat: rpc feature for TaikoNextBlockEnvAttributes, local-payload-builder for LocalPayloadAttributesBuilder<TaikoChainSpec>

* feat: update reth dependencies for alethia-reth-rpc

* update reth dependencies for alethia-reth-primitives

* update reth dependencies for alethia-reth-payload

* update reth dependencies for alethia-reth-node

* update reth dependencies for alethia-reth-evm

* update reth dependencies for alethia-reth-db

* update reth dependencies for alethia-reth-consensus

* update reth dependencies for alethia-reth-cli

* update reth dependencies for alethia-reth-chainspec

* update reth dependencies for alethia-reth-block

* update reth dependencies

* feat: merge from main

---------

Co-authored-by: abiba <b>
* feat: add real time proving support

* Delete PROVING_MIGRATION.md

* Delete PROTOCOL_MIGRATION_REAL_TIME_FORK.md

* Delete ALETHIA_RETH_MIGRATION.md

* style: run cargo +nightly fmt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Ahmad Bitar <33181301+smartprogrammer93@users.noreply.github.com>
Co-authored-by: smartprogrammer93 <smartprogrammer@windowslive.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds the L1SLOAD precompile at address 0x10001 for reading L1 storage
from L2. The precompile takes 84-byte input (address + storage key +
block number) and returns the cached storage value.

The precompile is a dummy cache: Raiko populates it with verified
values before block re-execution during proving. The cache keys
include block number to support lookback up to 256 blocks from
the anchor block.

Changes:
- crates/evm/src/precompiles/l1sload.rs: Cache, API, precompile logic
- crates/evm/src/precompiles/mod.rs: taiko_precompiles_map() helper
- crates/evm/src/factory.rs: Use taiko_precompiles_map in EVM factory
- 11 unit tests covering all paths
- PR #1: Convert eprintln! to trace! in L1SLOAD precompile hot path to
  avoid flooding stderr in production. Keep [jmadibekov] tags for debugging.
- PR #3: Update comment byte ranges from inclusive [0:19] to Rust slice
  syntax [0..20], [20..52], [52..84] matching the actual code.
Promote trace! to info! and add [jmadibekov] tags for:
- Precompile entry, input parsing, range checks
- Cache hit/miss, RPC fallback, anchor/l1origin context
- Consolidate ~12 per-call info logs in l1sload_run() into 2-3 targeted logs
- Cache hits downgraded to trace level; RPC fallback remains at info
- Trim verbose doc comments that restate obvious code
- Keep all functional logic and tests intact

E2E verified: all L1SLOAD scenarios pass on devnet.
- Remove unused L1SLOAD const bundle (address inlined in mod.rs)
- Inline clear_anchor_block_id/clear_l1_origin_block_id into clear_l1_storage
- Make 4 constants private (not used outside crate)
- Unify duplicated output construction in cache-hit/RPC-fallback branches
- Downgrade RPC fallback log from info to debug
- Remove redundant clear calls in tests
The lookback range is now measured from L1 origin instead of anchor,
matching surge-raiko's simplified trust model. L1 origin is the single
reference point for both upper and lower bounds.
A1: set_l1_staticcall_value silently drops return data larger than
    MAX_RETURN_DATA_SIZE with an error-level log; rationale documented
    on the setter doc-comment. Test pins the boundary behavior.
A2: Drop the underscore prefix on `anchor_block_id` in both precompile
    modules now that the variable is fully used (the prefix used to
    signal "unused but kept for clarity" — no longer accurate).
A3: Document that `total_gas` deliberately does NOT clamp to gas_limit;
    revm's caller-side OOG check is the correct surface. New regression
    test `test_l1staticcall_l1_gas_alone_oog_when_exceeding_limit`
    locks the contract in.
The Shasta proposal field 'originBlockNumber' was renamed to 'maxAnchorBlockNumber'
in the RealTime fork. Both serve the same role — the on-chain-verified L1 block
that anchors the precompile's [N − 256, N] lookback window. The static, accessor
functions, and error messages all carried the Shasta-era 'l1_origin' name; rename
them to be accurate under both forks.

No functional change — the value passed by raiko is still the same:
- Shasta: Proposal.originBlockNumber
- RealTime: RealTimeProposal.maxAnchorBlockNumber
@jmadibekov

Copy link
Copy Markdown
Author

Wrong target repo — recreating against NethermindEth/alethia-reth.

@jmadibekov jmadibekov closed this May 7, 2026
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.

4 participants