Skip to content

feat(l1, l2): make some store getters async #2430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Apr 15, 2025
Merged

feat(l1, l2): make some store getters async #2430

merged 20 commits into from
Apr 15, 2025

Conversation

iovoid
Copy link
Contributor

@iovoid iovoid commented Apr 9, 2025

Motivation

Like with #2336 the goal is to avoid blocking the current task.

Description

Makes store getters not related to tries (and thus the EVM) async, and propagates the changes to users of store. They are made async by using spawn_blocking

Many instances of functional code (and_then, map) had to be replaced due to bad async support.

Closes #2424

@iovoid iovoid requested a review from a team as a code owner April 9, 2025 15:53
Copy link

github-actions bot commented Apr 9, 2025

Lines of code report

Total lines added: 394
Total lines removed: 3
Total lines changed: 397

Detailed view
+--------------------------------------------------------+-------+------+
| File                                                   | Lines | Diff |
+--------------------------------------------------------+-------+------+
| ethrex/cmd/ef_tests/blockchain/test_runner.rs          | 147   | +2   |
+--------------------------------------------------------+-------+------+
| ethrex/cmd/ethrex/ethrex.rs                            | 82    | +1   |
+--------------------------------------------------------+-------+------+
| ethrex/cmd/ethrex/initializers.rs                      | 340   | +2   |
+--------------------------------------------------------+-------+------+
| ethrex/cmd/ethrex/l2.rs                                | 250   | +1   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/blockchain.rs                 | 510   | +3   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/fork_choice.rs                | 142   | +1   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/mempool.rs                    | 571   | -3   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/smoke_test.rs                 | 235   | +6   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/l2/sequencer/l1_committer.rs             | 405   | +5   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/l2/sequencer/l1_watcher.rs               | 247   | +1   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/l2/sequencer/prover_server.rs            | 472   | +4   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/rlpx/connection.rs        | 535   | +2   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/rlpx/eth/transactions.rs  | 309   | +3   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/sync.rs                   | 568   | +1   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/sync/trie_rebuild.rs      | 244   | +2   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/sync_manager.rs           | 129   | +2   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/engine/fork_choice.rs     | 390   | +14  |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/engine/payload.rs         | 683   | +2   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/eth/account.rs            | 233   | +12  |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/eth/block.rs              | 356   | +4   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/eth/fee_market.rs         | 234   | +2   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/eth/filter.rs             | 605   | +3   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/eth/logs.rs               | 177   | +4   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/eth/transaction.rs        | 602   | +17  |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/l2/transaction.rs         | 216   | +5   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/types/block_identifier.rs | 140   | +8   |
+--------------------------------------------------------+-------+------+
| ethrex/crates/storage/api.rs                           | 251   | +20  |
+--------------------------------------------------------+-------+------+
| ethrex/crates/storage/store.rs                         | 1248  | +29  |
+--------------------------------------------------------+-------+------+
| ethrex/crates/storage/store_db/in_memory.rs            | 609   | +37  |
+--------------------------------------------------------+-------+------+
| ethrex/crates/storage/store_db/libmdbx.rs              | 1366  | +87  |
+--------------------------------------------------------+-------+------+
| ethrex/crates/storage/store_db/redb.rs                 | 1218  | +114 |
+--------------------------------------------------------+-------+------+

Copy link
Collaborator

@mpaulucci mpaulucci left a comment

Choose a reason for hiding this comment

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

LGTM

@@ -297,7 +306,7 @@ async fn handle_forkchoice(
let forkchoice_response = match forkchoice_error {
InvalidForkChoice::NewHeadAlreadyCanonical => {
ForkChoiceResponse::from(PayloadStatus::valid_with_hash(
latest_canonical_block_hash(&context.storage).unwrap(),
latest_canonical_block_hash(&context.storage).await.unwrap(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this function returns a result, let's leverage this PR to remove this unwrap

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

Comment on lines +412 to +415
let mut bodies = Vec::new();
for hash in self.hashes.iter() {
bodies.push(context.storage.get_block_body_by_hash(*hash).await?)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

It might make sense to do a single request to the DB for the bulk.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Implemented

Comment on lines 451 to 453
for block_num in self.start..=last {
bodies.push(context.storage.get_block_body(block_num).await?)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Implemented!

});
let latest_block_num = storage.get_latest_block_number().await?;
// Box needed to keep the future Sync
// https://github.com/rust-lang/rust/issues/128095
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's not very clear to me why we need to use box. There is no mention to it in that github issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It doesn't have to be Box (anything that can keep the variable Sync works). The issue explains why we need to keep the variable  Sync even though it's dropped before the next await

@@ -573,7 +616,10 @@ impl StoreEngine for Store {
self.write_batch::<Receipts>(key_values).await
}

fn get_receipts_for_block(&self, block_hash: &BlockHash) -> Result<Vec<Receipt>, StoreError> {
async fn get_receipts_for_block(
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 async if it doesn't go through the async api?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@@ -837,7 +890,10 @@ impl StoreEngine for Store {
.map_err(|e| StoreError::Custom(format!("task panicked: {e}")))?
}

fn read_account_snapshot(&self, start: H256) -> Result<Vec<(H256, AccountState)>, StoreError> {
async fn read_account_snapshot(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here, how is this async?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@@ -624,7 +630,7 @@ impl StoreEngine for RedBStore {
.await
}

fn get_finalized_block_number(&self) -> Result<Option<BlockNumber>, StoreError> {
async fn get_finalized_block_number(&self) -> Result<Option<BlockNumber>, StoreError> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is await missing here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It wasn't missing but the function was sync. Made it async.

@@ -642,7 +648,7 @@ impl StoreEngine for RedBStore {
.await
}

fn get_safe_block_number(&self) -> Result<Option<BlockNumber>, StoreError> {
async fn get_safe_block_number(&self) -> Result<Option<BlockNumber>, StoreError> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is await missing here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It wasn't missing but the function was sync. Made it async.

Copy link

Benchmark Block Execution Results Comparison Against Main

Command Mean [s] Min [s] Max [s] Relative
base 182.445 ± 0.932 180.999 184.686 1.00
head 183.186 ± 1.597 180.792 185.537 1.00 ± 0.01

Copy link
Collaborator

@Arkenan Arkenan left a comment

Choose a reason for hiding this comment

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

LGTM

@iovoid iovoid added this pull request to the merge queue Apr 15, 2025
Merged via the queue into main with commit 5b5c66c Apr 15, 2025
31 checks passed
@iovoid iovoid deleted the store/async-getters branch April 15, 2025 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make all store getter functions async
5 participants