Skip to content

Conversation

@SDartayet
Copy link
Contributor

@SDartayet SDartayet commented Nov 7, 2025

Motivation

Improve the maintainability of our code with regards to future forks.

Description

Currently we have a lot of match statements spread throughout various functions to get the current fork, blobschedule, etc; and separate functions for checking the activation of each fork. This creates serious maintainability issues down the line. This PR centralized the match statements in two functions: one to get the activation timestamp/block for a fork, and one to get the blob schedule for a fork, and rewrites the rest of the functions accordingly. All the funcitons to check fork activation were also aggregated into a single is_fork_activated function that takes the fork as a parameter and checks its activation. The implementation of get_blob_schedule_for_time also fetches the most recent active blob schedule if the current fork specifies none, which is part of tackling #4849.

Additionally, some code related to pre-Merge logic was removed (checks for EIP 155 and EIP 2028)

Closes #4720

@github-actions github-actions bot added the L1 Ethereum client label Nov 7, 2025
@github-actions
Copy link

github-actions bot commented Nov 7, 2025

Lines of code report

Total lines added: 8
Total lines removed: 94
Total lines changed: 102

Detailed view
+--------------------------------------------------------------+-------+------+
| File                                                         | Lines | Diff |
+--------------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/blockchain.rs                       | 1314  | +1   |
+--------------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/constants.rs                        | 13    | -1   |
+--------------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/mempool.rs                          | 707   | -26  |
+--------------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/payload.rs                          | 672   | -4   |
+--------------------------------------------------------------+-------+------+
| ethrex/crates/common/types/block.rs                          | 882   | +4   |
+--------------------------------------------------------------+-------+------+
| ethrex/crates/common/types/genesis.rs                        | 896   | -56  |
+--------------------------------------------------------------+-------+------+
| ethrex/crates/l2/sequencer/block_producer/payload_builder.rs | 270   | -7   |
+--------------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/engine/blobs.rs                 | 139   | +2   |
+--------------------------------------------------------------+-------+------+
| ethrex/tooling/ef_tests/state/deserialize.rs                 | 417   | +1   |
+--------------------------------------------------------------+-------+------+

@github-actions
Copy link

github-actions bot commented Nov 7, 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 2.984 ± 0.072 2.941 3.175 1.00 ± 0.03
main_levm_BubbleSort 3.237 ± 0.016 3.219 3.268 1.09 ± 0.01
pr_revm_BubbleSort 2.974 ± 0.036 2.945 3.070 1.00
pr_levm_BubbleSort 3.272 ± 0.053 3.238 3.418 1.10 ± 0.02

Benchmark Results: ERC20Approval

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Approval 966.7 ± 15.1 956.9 1001.0 1.00
main_levm_ERC20Approval 1162.8 ± 6.5 1149.5 1171.3 1.20 ± 0.02
pr_revm_ERC20Approval 970.3 ± 10.6 962.0 987.1 1.00 ± 0.02
pr_levm_ERC20Approval 1163.7 ± 11.4 1153.8 1184.5 1.20 ± 0.02

Benchmark Results: ERC20Mint

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Mint 131.5 ± 1.6 129.8 134.0 1.00 ± 0.01
main_levm_ERC20Mint 170.0 ± 1.6 168.2 173.1 1.29 ± 0.02
pr_revm_ERC20Mint 131.5 ± 0.9 130.4 132.9 1.00
pr_levm_ERC20Mint 171.8 ± 1.7 170.3 175.9 1.31 ± 0.02

Benchmark Results: ERC20Transfer

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Transfer 228.9 ± 1.4 227.4 231.6 1.00 ± 0.01
main_levm_ERC20Transfer 289.9 ± 2.5 287.2 295.1 1.27 ± 0.01
pr_revm_ERC20Transfer 227.8 ± 1.3 226.5 230.5 1.00
pr_levm_ERC20Transfer 290.9 ± 7.7 286.6 312.5 1.28 ± 0.03

Benchmark Results: Factorial

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Factorial 223.3 ± 0.9 221.1 224.3 1.00
main_levm_Factorial 275.4 ± 23.0 265.9 340.9 1.23 ± 0.10
pr_revm_Factorial 225.0 ± 1.5 222.6 226.8 1.01 ± 0.01
pr_levm_Factorial 271.0 ± 2.0 269.1 275.8 1.21 ± 0.01

Benchmark Results: FactorialRecursive

Command Mean [s] Min [s] Max [s] Relative
main_revm_FactorialRecursive 1.598 ± 0.053 1.492 1.661 1.00
main_levm_FactorialRecursive 8.463 ± 0.088 8.239 8.551 5.30 ± 0.18
pr_revm_FactorialRecursive 1.629 ± 0.027 1.582 1.654 1.02 ± 0.04
pr_levm_FactorialRecursive 8.662 ± 0.055 8.532 8.725 5.42 ± 0.18

Benchmark Results: Fibonacci

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Fibonacci 205.1 ± 3.8 200.4 215.3 1.01 ± 0.02
main_levm_Fibonacci 263.6 ± 7.3 253.1 278.9 1.29 ± 0.04
pr_revm_Fibonacci 203.6 ± 1.4 200.9 205.9 1.00
pr_levm_Fibonacci 269.0 ± 2.5 265.3 274.3 1.32 ± 0.02

Benchmark Results: FibonacciRecursive

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_FibonacciRecursive 837.9 ± 7.2 824.4 846.3 1.09 ± 0.01
main_levm_FibonacciRecursive 773.5 ± 11.9 761.3 799.0 1.00 ± 0.02
pr_revm_FibonacciRecursive 836.1 ± 9.2 816.5 846.7 1.08 ± 0.01
pr_levm_FibonacciRecursive 771.3 ± 3.7 766.1 779.9 1.00

Benchmark Results: ManyHashes

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ManyHashes 8.2 ± 0.1 8.1 8.3 1.00
main_levm_ManyHashes 9.8 ± 0.2 9.6 10.3 1.19 ± 0.03
pr_revm_ManyHashes 8.3 ± 0.0 8.2 8.4 1.01 ± 0.01
pr_levm_ManyHashes 9.7 ± 0.1 9.6 9.9 1.18 ± 0.02

Benchmark Results: MstoreBench

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_MstoreBench 263.0 ± 2.8 261.1 270.4 1.08 ± 0.03
main_levm_MstoreBench 244.0 ± 7.0 239.0 262.0 1.00
pr_revm_MstoreBench 261.2 ± 0.8 259.6 262.2 1.07 ± 0.03
pr_levm_MstoreBench 245.6 ± 15.8 236.7 286.9 1.01 ± 0.07

Benchmark Results: Push

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Push 294.6 ± 2.0 291.8 297.5 1.01 ± 0.01
main_levm_Push 310.3 ± 2.3 308.5 315.2 1.06 ± 0.01
pr_revm_Push 292.4 ± 1.0 290.8 294.8 1.00
pr_levm_Push 323.5 ± 1.1 322.1 326.0 1.11 ± 0.01

Benchmark Results: SstoreBench_no_opt

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_SstoreBench_no_opt 165.8 ± 3.7 161.6 170.5 1.86 ± 0.06
main_levm_SstoreBench_no_opt 89.6 ± 2.1 87.9 94.4 1.00 ± 0.03
pr_revm_SstoreBench_no_opt 167.5 ± 4.3 161.5 175.6 1.88 ± 0.06
pr_levm_SstoreBench_no_opt 89.2 ± 1.8 87.4 93.0 1.00

GrayGlacier = 14,
Paris = 15,
Shanghai = 16,
Homestead = 0,
Copy link
Collaborator

Choose a reason for hiding this comment

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

why is this change of names?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed the enum so the forks would be the ones mentioned in labels for the activation block numbers and timestamps. This was necessary ƒor the match statements in fork_activation_time_or_block and is_fork_activated to work properly. While I could have made it a separate enum, I think it makes more sense for the fork enums to reflect the forks as laid out in the chain config files (and in practice only the chain config struct methods and the tests use the fork enum, so it shouldn't create broader problems)

GrayGlacier = 13,
Paris = 14,
Shanghai = 15,
#[default]
Copy link
Collaborator

Choose a reason for hiding this comment

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

we probably shouldn't have defaults

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to do this but it breaks other structs that have fork as a field and implement default, like parts of the LEVM runner or EVMConfig. Unless we want to remove those defaults too it might be better to leave this as is (so fork defaults aren't spread out throughout the code)

Copy link
Collaborator

Choose a reason for hiding this comment

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

it kinda sucks, but if you have to keep it, at least choose the (soon to be) current one, Osaka


let blob_schedule = chain_config
.get_fork_blob_schedule(block_header.timestamp)
.get_current_blob_schedule(block_header.timestamp)
Copy link
Collaborator

Choose a reason for hiding this comment

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

current is deceiving if its calculated based on a timestamp

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure. Addressed here (alongside some fixes for other things that were failing)

@SDartayet SDartayet marked this pull request as ready for review November 10, 2025 17:58
@SDartayet SDartayet requested a review from a team as a code owner November 10, 2025 17:58
@SDartayet SDartayet requested a review from mpaulucci November 10, 2025 17:58
@ethrex-project-sync ethrex-project-sync bot moved this to In Review in ethrex_l1 Nov 10, 2025
// Gas cost for each storage key specified on access lists
pub const TX_ACCESS_LIST_STORAGE_KEY_GAS: u64 = 1900;

// Gas cost for each non zero byte on transaction data
Copy link
Collaborator

Choose a reason for hiding this comment

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

this change seems unrelated to the PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I also took the opportunity to remove code that was only relevant for pre-Merge forks. This change is related to that. I should have clarified that in the PR description; will add it now.

// TODO: maybe fetch hash too when filtering mempool so we don't have to compute it here (we can do this in the same refactor as adding timestamp)
let tx_hash = head_tx.tx.hash();

// Check whether the tx is replay-protected
Copy link
Collaborator

Choose a reason for hiding this comment

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

state tests don't use this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They aren't failing on the CI and they aren't failing locally either, so preseumably not.

@SDartayet SDartayet requested a review from mpaulucci November 10, 2025 18:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

L1 Ethereum client

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

Improve the way we obtain the next and last forks

3 participants