Skip to content

Conversation

@MegaRedHand
Copy link
Collaborator

Motivation

We were seeing some missed slots in local networks with high throughput (900Mgas limit). The cause was a blocking call being passed to CancellationToken::run_until_cancelled.

Description

This PR changes the block building process to run on a blocking task with spawn_blocking, and also removes the async tag to some non-async methods from Store and Blockchain.

Closes #4992

@MegaRedHand MegaRedHand requested a review from a team as a code owner October 22, 2025 18:34
Copilot AI review requested due to automatic review settings October 22, 2025 18:34
@MegaRedHand MegaRedHand changed the title fix: stop block building preemptively fix(l1): stop block building preemptively Oct 22, 2025
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 removes unnecessary async/await patterns from the block building process to prevent blocking calls that were causing missed slots in high-throughput local networks. The key change is converting synchronous storage operations that were incorrectly marked as async back to synchronous functions, and wrapping the actual CPU-intensive block building in spawn_blocking to prevent blocking the async runtime.

Key Changes:

  • Removed async from Store::apply_account_updates_batch and related storage methods that perform synchronous operations
  • Modified Blockchain::build_payload and finalize_payload to be synchronous
  • Wrapped block building calls in spawn_blocking within the payload building loop to run on blocking thread pool

Reviewed Changes

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

Show a summary per file
File Description
crates/storage/store.rs Removed async from apply_account_updates_batch and apply_account_updates_from_trie_batch methods
crates/blockchain/payload.rs Converted build_payload and finalize_payload to sync, added spawn_blocking wrapper in build loop
crates/blockchain/blockchain.rs Removed await calls for apply_account_updates_batch
crates/l2/sequencer/block_producer.rs Removed await call for apply_account_updates_batch
crates/l2/sequencer/block_producer/payload_builder.rs Removed await call for finalize_payload
crates/blockchain/smoke_test.rs Removed await call for build_payload in test
tooling/ef_tests/state_v2/src/modules/result_check.rs Removed async from post_state_root function
cmd/ethrex/l2/command.rs Removed await call for apply_account_updates_from_trie_batch

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@github-actions github-actions bot added the L1 Ethereum client label Oct 22, 2025
@github-actions
Copy link

github-actions bot commented Oct 22, 2025

Lines of code report

Total lines added: 1
Total lines removed: 6
Total lines changed: 7

Detailed view
+--------------------------------------------------------------+-------+------+
| File                                                         | Lines | Diff |
+--------------------------------------------------------------+-------+------+
| ethrex/cmd/ethrex/l2/command.rs                              | 628   | -1   |
+--------------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/blockchain.rs                       | 956   | -2   |
+--------------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/payload.rs                          | 663   | +1   |
+--------------------------------------------------------------+-------+------+
| ethrex/crates/l2/sequencer/block_producer.rs                 | 258   | -1   |
+--------------------------------------------------------------+-------+------+
| ethrex/crates/l2/sequencer/l1_committer.rs                   | 985   | -1   |
+--------------------------------------------------------------+-------+------+
| ethrex/tooling/ef_tests/state_v2/src/modules/result_check.rs | 294   | -1   |
+--------------------------------------------------------------+-------+------+

@MegaRedHand MegaRedHand moved this to In Review in ethrex_l1 Oct 22, 2025
/// Applies account updates based on the block's latest storage state
/// and returns the new state root after the updates have been applied.
#[instrument(level = "trace", name = "Trie update", skip_all)]
pub async fn apply_account_updates_batch(
Copy link
Collaborator

@mpaulucci mpaulucci Oct 23, 2025

Choose a reason for hiding this comment

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

Im quite confused about this change (probably due to lack of knowledge). Intuitively I would expect ALL store functions to be async. And also not have to put spawn_blocking in places, which are code smell imo

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Just for the record, I also think that Store functions should be async. However, I prefer functions to be marked as async only when they are actually asynchronous. This one didn't call any async functions, so the keyword only misleads. What's more, I suspect the compiler actually removes the keyword internally, and I'm upset Clippy doesn't mark cases like this 😠

I agree that a spawn_blocking is a smell when intermingled with async code, but in this case, it's justified: building a block is mostly a synchronous task. To avoid using spawn_blocking, we'd need to rework the EVM itself to be async, or keep a dedicated threadpool for EVMs (essentially making our own spawn_blocking).

@MegaRedHand MegaRedHand added this pull request to the merge queue Oct 27, 2025
Merged via the queue into main with commit a83b959 Oct 27, 2025
40 of 41 checks passed
@MegaRedHand MegaRedHand deleted the stop-block-building-preemptively branch October 27, 2025 19:57
@github-project-automation github-project-automation bot moved this from In Review to Done in ethrex_l1 Oct 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

L1 Ethereum client

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

getPayload timeouts in localnet during periods of high traffic (500Mgas or more)

4 participants