Skip to content

Conversation

@Oppen
Copy link
Contributor

@Oppen Oppen commented Nov 20, 2025

Implements the Code::from_bytecode_unchecked function to create the
code object from a trusted or bogus hash.

The trusted case is used for snap sync, where the downloader task
already checks the hash is correct, so it can pass it down.

The bogus hash case is for init code, where the hash is never used
(there is no account pointing to it, no entries in the DB addressed by
it and no opcode can access the current code's hash, only the hash for
an account associated to an address).

Gas Benchmarks

Main

http://ethrex-performance-1:4000/reports/37

Title ↑ ↓	Max (MGas/s) ↑ ↓	p50 (MGas/s) ↑ ↓	p95 (MGas/s) ↑ ↓	p99 (MGas/s) ↑ ↓	Min (MGas/s) ↑ ↓	N	Description	Start Time	End Time	Duration (ms) ↑ ↓	FCU time (ms) ↑ ↓	NP time (ms) ↑ ↓
tests_benchmark_test_worst_bytecode.py__test_worst_initcode_jumpdest_analysis[fork_Prague-benchmark-blockchain_test_engine_x-00]-gas-value	303.92	303.92	303.92	303.92	303.92	1	Description not found on metadata file	2025-11-26 19:50:09.584877+00	2025-11-26 19:50:09.963341+00	378.46	0.42	329.04
tests_benchmark_test_worst_bytecode.py__test_worst_initcode_jumpdest_analysis[fork_Prague-benchmark-blockchain_test_engine_x-5b]-gas-value	269.02	269.02	269.02	269.02	269.02	1	Description not found on metadata file	2025-11-26 19:50:10.913177+00	2025-11-26 19:50:11.334488+00	421.31	0.38	371.72
tests_benchmark_test_worst_bytecode.py__test_worst_initcode_jumpdest_analysis[fork_Prague-benchmark-blockchain_test_engine_x-605b5b]-gas-value	259.06	259.06	259.06	259.06	259.06	1	Description not found on metadata file	2025-11-26 19:50:12.312645+00	2025-11-26 19:50:12.748253+00	435.61	0.70	386.01
tests_benchmark_test_worst_bytecode.py__test_worst_initcode_jumpdest_analysis[fork_Prague-benchmark-blockchain_test_engine_x-605b]-gas-value	241.64	241.64	241.64	241.64	241.64	1	Description not found on metadata file	2025-11-26 19:50:13.776154+00	2025-11-26 19:50:14.239418+00	463.27	0.46	413.83
tests_benchmark_test_worst_bytecode.py__test_worst_initcode_jumpdest_analysis[fork_Prague-benchmark-blockchain_test_engine_x-615b5b5b]-gas-value	275.57	275.57	275.57	275.57	275.57	1	Description not found on metadata file	2025-11-26 19:50:15.103287+00	2025-11-26 19:50:15.515709+00	412.42	0.93	362.89
tests_benchmark_test_worst_bytecode.py__test_worst_initcode_jumpdest_analysis[fork_Prague-benchmark-blockchain_test_engine_x-615b5b]-gas-value	270.55	270.55	270.55	270.55	270.55	1	Description not found on metadata file	2025-11-26 19:50:16.437637+00	2025-11-26 19:50:16.856361+00	418.73	0.25	369.62
tests_benchmark_test_worst_compute.py__test_worst_jumpdests[fork_Prague-benchmark-blockchain_test_engine_x]-gas-value	606.13	606.13	606.13	606.13	606.13	1	Description not found on metadata file	2025-11-26 19:50:17.356636+00	2025-11-26 19:50:17.570259+00	213.62	0.60	164.98

PR

http://ethrex-performance-1:4000/reports/38

Title ↑ ↓	Max (MGas/s) ↑ ↓	p50 (MGas/s) ↑ ↓	p95 (MGas/s) ↑ ↓	p99 (MGas/s) ↑ ↓	Min (MGas/s) ↑ ↓	N	Description	Start Time	End Time	Duration (ms) ↑ ↓	FCU time (ms) ↑ ↓	NP time (ms) ↑ ↓
tests_benchmark_test_worst_bytecode.py__test_worst_initcode_jumpdest_analysis[fork_Prague-benchmark-blockchain_test_engine_x-00]-gas-value	1236.92	1236.92	1236.92	1236.92	1236.92	1	Description not found on metadata file	2025-11-26 19:51:42.832825+00	2025-11-26 19:51:42.964958+00	132.13	0.51	80.85
tests_benchmark_test_worst_bytecode.py__test_worst_initcode_jumpdest_analysis[fork_Prague-benchmark-blockchain_test_engine_x-5b]-gas-value	830.69	830.69	830.69	830.69	830.69	1	Description not found on metadata file	2025-11-26 19:51:43.704262+00	2025-11-26 19:51:43.874268+00	170.01	0.56	120.38
tests_benchmark_test_worst_bytecode.py__test_worst_initcode_jumpdest_analysis[fork_Prague-benchmark-blockchain_test_engine_x-605b5b]-gas-value	730.90	730.90	730.90	730.90	730.90	1	Description not found on metadata file	2025-11-26 19:51:44.592064+00	2025-11-26 19:51:44.778229+00	186.16	0.67	136.82
tests_benchmark_test_worst_bytecode.py__test_worst_initcode_jumpdest_analysis[fork_Prague-benchmark-blockchain_test_engine_x-605b]-gas-value	612.77	612.77	612.77	612.77	612.77	1	Description not found on metadata file	2025-11-26 19:51:45.533035+00	2025-11-26 19:51:45.745781+00	212.75	0.57	163.19
tests_benchmark_test_worst_bytecode.py__test_worst_initcode_jumpdest_analysis[fork_Prague-benchmark-blockchain_test_engine_x-615b5b5b]-gas-value	892.41	892.41	892.41	892.41	892.41	1	Description not found on metadata file	2025-11-26 19:51:46.352303+00	2025-11-26 19:51:46.513977+00	161.68	0.67	112.06
tests_benchmark_test_worst_bytecode.py__test_worst_initcode_jumpdest_analysis[fork_Prague-benchmark-blockchain_test_engine_x-615b5b]-gas-value	836.63	836.63	836.63	836.63	836.63	1	Description not found on metadata file	2025-11-26 19:51:47.189529+00	2025-11-26 19:51:47.357864+00	168.33	0.26	119.53
tests_benchmark_test_worst_compute.py__test_worst_jumpdests[fork_Prague-benchmark-blockchain_test_engine_x]-gas-value	528.09	528.09	528.09	528.09	528.09	1	Description not found on metadata file	2025-11-26 19:51:48.173264+00	2025-11-26 19:51:48.411232+00	237.97	0.35	189.36

Copilot AI review requested due to automatic review settings November 20, 2025 20:12
@Oppen Oppen requested a review from a team as a code owner November 20, 2025 20:12
@github-actions github-actions bot added L1 Ethereum client L2 Rollup client performance Block execution throughput and performance in general labels Nov 20, 2025
@github-actions
Copy link

github-actions bot commented Nov 20, 2025

Lines of code report

Total lines added: 17
Total lines removed: 0
Total lines changed: 17

Detailed view
+-------------------------------------------------+-------+------+
| File                                            | Lines | Diff |
+-------------------------------------------------+-------+------+
| ethrex/crates/common/types/account.rs           | 237   | +9   |
+-------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/sync.rs            | 1384  | +4   |
+-------------------------------------------------+-------+------+
| ethrex/crates/vm/levm/runner/src/input.rs       | 119   | +1   |
+-------------------------------------------------+-------+------+
| ethrex/crates/vm/levm/src/hooks/default_hook.rs | 352   | +3   |
+-------------------------------------------------+-------+------+

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces a performance optimization to avoid unnecessary code hashing by adding a new Code::from_bytecode_unchecked function that accepts a pre-computed or placeholder hash. The optimization targets two scenarios: snap sync (where hashes are pre-validated) and init code execution (where hashes are never accessed).

Key changes:

  • Added from_bytecode_unchecked method to accept bytecode with a trusted or bogus hash
  • Refactored account creation code to avoid double-hashing by reusing computed hashes
  • Updated VM execution paths for init code to use zero hash placeholders

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
crates/common/types/account.rs Implements from_bytecode_unchecked and refactors GenesisAccount conversion to avoid double-hashing
crates/vm/levm/src/opcode_handlers/system.rs Uses from_bytecode_unchecked with zero hash for CREATE opcode init code
crates/vm/levm/src/hooks/default_hook.rs Uses from_bytecode_unchecked with zero hash for create transaction init code
crates/vm/levm/runner/src/input.rs Refactors to reuse computed hash instead of hashing twice
crates/networking/p2p/sync.rs Attempts to use from_bytecode_unchecked for snap sync with pre-validated hashes (contains bug)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link

github-actions bot commented Nov 20, 2025

Benchmark Results Comparison

No significant difference was registered for any benchmark run.

Detailed Results

Benchmark Results: BubbleSort

Command Mean [s] Min [s] Max [s] Relative
main_revm_BubbleSort 3.001 ± 0.015 2.973 3.020 1.01 ± 0.01
main_levm_BubbleSort 3.130 ± 0.026 3.107 3.188 1.06 ± 0.01
pr_revm_BubbleSort 2.965 ± 0.029 2.938 3.010 1.00
pr_levm_BubbleSort 3.103 ± 0.017 3.080 3.125 1.05 ± 0.01

Benchmark Results: ERC20Approval

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Approval 988.7 ± 10.5 976.0 1011.6 1.02 ± 0.01
main_levm_ERC20Approval 1094.3 ± 6.6 1087.6 1110.9 1.13 ± 0.01
pr_revm_ERC20Approval 968.6 ± 2.1 965.2 972.2 1.00
pr_levm_ERC20Approval 1089.0 ± 12.7 1075.0 1123.3 1.12 ± 0.01

Benchmark Results: ERC20Mint

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Mint 137.4 ± 1.6 134.1 139.4 1.04 ± 0.01
main_levm_ERC20Mint 164.0 ± 1.1 162.9 166.1 1.24 ± 0.01
pr_revm_ERC20Mint 132.0 ± 0.9 130.8 133.2 1.00
pr_levm_ERC20Mint 161.1 ± 0.6 160.2 162.4 1.22 ± 0.01

Benchmark Results: ERC20Transfer

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Transfer 235.8 ± 5.2 230.6 244.2 1.03 ± 0.03
main_levm_ERC20Transfer 279.2 ± 5.1 275.4 292.4 1.22 ± 0.03
pr_revm_ERC20Transfer 229.7 ± 3.5 225.8 234.3 1.00
pr_levm_ERC20Transfer 277.7 ± 2.9 275.2 284.3 1.21 ± 0.02

Benchmark Results: Factorial

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Factorial 226.5 ± 1.1 224.6 227.9 1.01 ± 0.01
main_levm_Factorial 267.2 ± 2.1 265.3 272.0 1.19 ± 0.01
pr_revm_Factorial 225.1 ± 1.2 223.4 227.3 1.00
pr_levm_Factorial 265.5 ± 2.3 263.0 271.1 1.18 ± 0.01

Benchmark Results: FactorialRecursive

Command Mean [s] Min [s] Max [s] Relative
main_revm_FactorialRecursive 1.669 ± 0.019 1.643 1.707 1.02 ± 0.04
main_levm_FactorialRecursive 8.238 ± 0.062 8.171 8.329 5.03 ± 0.18
pr_revm_FactorialRecursive 1.637 ± 0.058 1.500 1.696 1.00
pr_levm_FactorialRecursive 8.251 ± 0.039 8.196 8.331 5.04 ± 0.18

Benchmark Results: Fibonacci

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Fibonacci 206.2 ± 0.5 205.4 207.0 1.00
main_levm_Fibonacci 265.2 ± 1.2 263.7 267.8 1.29 ± 0.01
pr_revm_Fibonacci 206.5 ± 2.2 204.5 211.8 1.00 ± 0.01
pr_levm_Fibonacci 259.4 ± 4.7 252.1 264.8 1.26 ± 0.02

Benchmark Results: FibonacciRecursive

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_FibonacciRecursive 871.5 ± 10.6 856.3 893.9 1.18 ± 0.04
main_levm_FibonacciRecursive 735.8 ± 22.3 723.9 798.4 1.00
pr_revm_FibonacciRecursive 869.9 ± 8.6 858.2 882.5 1.18 ± 0.04
pr_levm_FibonacciRecursive 736.8 ± 11.1 727.5 766.5 1.00 ± 0.03

Benchmark Results: ManyHashes

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ManyHashes 8.2 ± 0.1 8.2 8.3 1.01 ± 0.01
main_levm_ManyHashes 9.0 ± 0.2 8.9 9.5 1.11 ± 0.02
pr_revm_ManyHashes 8.2 ± 0.1 8.1 8.3 1.00
pr_levm_ManyHashes 8.9 ± 0.1 8.8 9.0 1.09 ± 0.01

Benchmark Results: MstoreBench

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_MstoreBench 264.3 ± 5.5 260.0 276.7 1.09 ± 0.02
main_levm_MstoreBench 243.8 ± 9.3 238.7 270.1 1.01 ± 0.04
pr_revm_MstoreBench 264.0 ± 5.1 260.5 274.9 1.09 ± 0.02
pr_levm_MstoreBench 241.9 ± 1.8 240.1 245.4 1.00

Benchmark Results: Push

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Push 293.9 ± 1.8 292.1 297.8 1.01 ± 0.01
main_levm_Push 306.3 ± 1.7 302.2 308.7 1.05 ± 0.01
pr_revm_Push 291.3 ± 0.7 290.2 292.4 1.00
pr_levm_Push 306.4 ± 1.6 303.6 309.4 1.05 ± 0.01

Benchmark Results: SstoreBench_no_opt

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_SstoreBench_no_opt 165.9 ± 2.8 160.8 168.9 1.85 ± 0.05
main_levm_SstoreBench_no_opt 91.1 ± 4.2 87.5 101.4 1.02 ± 0.05
pr_revm_SstoreBench_no_opt 166.8 ± 3.4 160.4 172.0 1.86 ± 0.05
pr_levm_SstoreBench_no_opt 89.6 ± 1.8 87.5 91.9 1.00

Implements the `Code::from_bytecode_unchecked` function to create the
code object from a trusted or bogus hash.

The trusted case is used for snap sync, where the downloader task
already checks the hash is correct, so it can pass it down.

The bogus hash case is for init code, where the hash is never used
(there is no account pointing to it, no entries in the DB addressed by
it and no opcode can access the current code's hash, only the hash for
an account associated to an address).
@Oppen Oppen force-pushed the perf/unhashed_code branch from b5e9cfa to 10be50c Compare November 26, 2025 19:11
@github-actions
Copy link

github-actions bot commented Nov 26, 2025

Benchmark Block Execution Results Comparison Against Main

Command Mean [s] Min [s] Max [s] Relative
base 60.538 ± 0.249 60.247 60.973 1.00
head 60.782 ± 0.337 60.177 61.131 1.00 ± 0.01

Copy link
Contributor

@JereSalo JereSalo left a comment

Choose a reason for hiding this comment

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

Very interesting change. At first I thought that something could go wrong with this but after thinking a while it seems that it's a great optimization to make. N1

The comments added are good, if you want we can add an extra comment on the attribute bytecode of CallFrame in call_frame.rs saying that in case of initcode bytecode.hash is a "dummy" because it's never read. I believe newcomers would appreciate that.

@Oppen
Copy link
Contributor Author

Oppen commented Nov 26, 2025

Very interesting change. At first I thought that something could go wrong with this but after thinking a while it seems that it's a great optimization to make. N1

The comments added are good, if you want we can add an extra comment on the attribute bytecode of CallFrame in call_frame.rs saying that in case of initcode bytecode.hash is a "dummy" because it's never read. I believe newcomers would appreciate that.

Great idea. Adding the comment.

@github-project-automation github-project-automation bot moved this to In Review in ethrex_l1 Nov 26, 2025
@JereSalo
Copy link
Contributor

@Oppen changelog has conflicts but I think it would be good to merge afterwards. wdyt?

@MegaRedHand MegaRedHand changed the title perf(l1,l2): avoid unnnecessary code hashing perf(l1,l2): avoid unnecessary code hashing Dec 2, 2025
@MegaRedHand MegaRedHand enabled auto-merge December 2, 2025 14:32
@MegaRedHand MegaRedHand added this pull request to the merge queue Dec 2, 2025
Merged via the queue into main with commit 1e75cb0 Dec 2, 2025
55 checks passed
@MegaRedHand MegaRedHand deleted the perf/unhashed_code branch December 2, 2025 15:45
@github-project-automation github-project-automation bot moved this from In Review to Done in ethrex_l1 Dec 2, 2025
@github-project-automation github-project-automation bot moved this from Todo to Done in ethrex_performance Dec 2, 2025
@github-project-automation github-project-automation bot moved this to Done in ethrex_l2 Dec 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

L1 Ethereum client L2 Rollup client performance Block execution throughput and performance in general

Projects

Status: Done
Status: Done
Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants