Skip to content

perf: write friendly ExecutionResult#1674

Merged
gakonst merged 45 commits intomainfrom
onbjerg/executor-perf
Mar 16, 2023
Merged

perf: write friendly ExecutionResult#1674
gakonst merged 45 commits intomainfrom
onbjerg/executor-perf

Conversation

@onbjerg
Copy link
Copy Markdown
Collaborator

@onbjerg onbjerg commented Mar 8, 2023

Restructures ExecutionResult to be easier to write to the database in a more performant way.

  • Uses cursors (faster than just using a transaction)
  • Uses duptable cursors where appropriate
  • Uses duptable specific features (NODUPDATA, APPENDDUP, NEXTDUP)
  • Inserts data sorted where possible
  • Keeps a cache of the latest up to date storage and account values, reducing the number of writes to the plain state tables

Still need to:

  • Update tests
  • Clean up the code
  • Validate that it is working as intended for a longer block range
  • Reduce the number of clones (there are quite a few currently where it might not make sense)
  • Fix the state clear EIP check

Some other things that might make sense to add:

  • Helpers to access per-tx and per-block changes etc., currently it is all merged into flatter structures instead of the deeply nested ones we had before

@onbjerg onbjerg added C-perf A change motivated by improving speed, memory usage or disk footprint A-execution-reth Related to the Execution and EVM labels Mar 8, 2023
@onbjerg onbjerg force-pushed the onbjerg/executor-perf branch from f5eb97c to 3a32d63 Compare March 9, 2023 18:38
@onbjerg onbjerg force-pushed the onbjerg/executor-perf branch from edcd237 to 74368c3 Compare March 10, 2023 00:56
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Mar 10, 2023

Codecov Report

Merging #1674 (3905934) into main (670db0b) will increase coverage by 0.20%.
The diff coverage is 88.84%.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

@@            Coverage Diff             @@
##             main    #1674      +/-   ##
==========================================
+ Coverage   73.48%   73.69%   +0.20%     
==========================================
  Files         405      405              
  Lines       49810    50035     +225     
==========================================
+ Hits        36604    36872     +268     
+ Misses      13206    13163      -43     
Flag Coverage Δ
integration-tests 19.87% <0.00%> (-0.07%) ⬇️
unit-tests 67.99% <88.84%> (+0.22%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...ates/executor/src/blockchain_tree/block_indices.rs 88.05% <ø> (ø)
crates/executor/src/blockchain_tree/config.rs 58.06% <ø> (ø)
crates/executor/src/blockchain_tree/externals.rs 85.71% <0.00%> (-14.29%) ⬇️
crates/executor/src/lib.rs 100.00% <ø> (ø)
crates/storage/provider/src/lib.rs 100.00% <ø> (ø)
crates/executor/src/substate.rs 16.32% <11.76%> (-9.52%) ⬇️
crates/executor/src/blockchain_tree/chain.rs 85.18% <82.22%> (+1.45%) ⬆️
crates/storage/provider/src/post_state.rs 89.66% <89.66%> (ø)
crates/storage/provider/src/transaction.rs 88.42% <90.00%> (-0.39%) ⬇️
crates/executor/src/blockchain_tree/mod.rs 90.75% <91.17%> (+0.06%) ⬆️
... and 3 more

... and 7 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@onbjerg onbjerg changed the title wip(perf): write friendly ExecutionResult perf: write friendly ExecutionResult Mar 10, 2023
@onbjerg onbjerg marked this pull request as ready for review March 10, 2023 03:05
@onbjerg onbjerg force-pushed the onbjerg/executor-perf branch from c5e0ae7 to 8944225 Compare March 16, 2023 17:39
Copy link
Copy Markdown
Member

@gakonst gakonst left a comment

Choose a reason for hiding this comment

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

LGTM. I love how this PR keys changesets by transition ID and lets us sort/split etc. more effectively than before.

I also like how we are clearly separating "insert block and all indexes" which are our append operations from "apply state changes" which is the more expensive part

}

// Write storage changes
let mut storages_cursor = tx.cursor_dup_write::<tables::PlainStorageState>()?;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: move this down

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

We can't, it is used in Change::StorageWiped to check if there is any storage to wipe at all

if let Some((_, entry)) = storages_cursor.seek_exact(address)? {
storage_changeset_cursor.append_dup(storage_id, entry)?;

while let Some(entry) = storages_cursor.next_dup_val()? {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Excellent - cc @joshieDo on usage of the dup apis which you also made use of in the hashing/merkle stages and seem to be impactful

Comment on lines +612 to +614
let account_a = Account { balance: U256::from(1), nonce: 1, bytecode_hash: None };
let account_b = Account { balance: U256::from(2), nonce: 2, bytecode_hash: None };
let account_b_changed = Account { balance: U256::from(3), nonce: 3, bytecode_hash: None };
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit we'll want to add some builder pattern funcs to the Account struct to make making these nicer, i.e. Account::default().set_balance(3 /* impl Into<U256>, may not be possible due to ruint perhaps? */).nonce(3);

}
block_exec_res.finish_transition();
next_transition_id += 1;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we log an error! if this was None?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Don't think it is even possible that it is none as all transactions will always result in at least one change, but I am unsure. I just kept it in this structure to make it work for now, I will refactor it later (it was way too much to mentally keep track of in its current state)

Comment on lines +1530 to +1532
exec_res1.clone().write_to_db(tx.deref_mut(), 0).unwrap();
tx.insert_block(block1.clone()).unwrap();
tx.insert_hashes(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Main reaction here is that we used to call the function insert_block and now it only inserts the historical block indices, so we'll want to rename it into something more descriptive I think. And we may want to have a function around which does all 3 operations?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

We would never use the one that does all 3 in any part of main reth, maybe only in tests - but then again, what would you be testing in that case?

@gakonst gakonst merged commit 7f5ac99 into main Mar 16, 2023
@gakonst gakonst deleted the onbjerg/executor-perf branch March 16, 2023 23:43
onbjerg added a commit that referenced this pull request Mar 17, 2023
onbjerg added a commit that referenced this pull request Mar 17, 2023
entry.insert(code.clone());
}
}
if !code.is_empty() && !db.contracts.contains_key(&account.info.code_hash) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It is more efficent to have Entry, this is like double hashing code_hash as it needs two accesses to db.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-execution-reth Related to the Execution and EVM C-perf A change motivated by improving speed, memory usage or disk footprint

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants