Skip to content
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

feat(revm): Integrate State #3512

Merged
merged 70 commits into from
Sep 16, 2023
Merged

feat(revm): Integrate State #3512

merged 70 commits into from
Sep 16, 2023

Conversation

rakita
Copy link
Collaborator

@rakita rakita commented Jun 30, 2023

Integrate revm State inside reth and remove instances of CacheDB and PostState and replace all functionality that PostState had.

Handling account status inside revm helped us to be more certain that transitions and changesets are correctly created.

revm PR that explains inner workings of State can be seen here: bluealloy/revm#499

Additionally, bump revm to the newest version.

Rename the Executor to EVMProcessor and add take_output and take_stats to it, this allows us to get an aggregated output of the execution of multiple blocks and take_stats allows us to see how much time a particular operation took.

🤖 Generated by Copilot at d017931

This pull request improves the primitives crate by removing unnecessary code from the Bytecode struct, fixing its deserialization logic, and suppressing a clippy lint warning in the bits.rs module.

🤖 Generated by Copilot at d017931

We're cleaning up the Bytecode struct, me hearties
We're throwing out the methods we don't need
We're fixing up the logic for deserialization
And making sure it matches how we serialize

@rkrasiuk rkrasiuk added C-enhancement New feature or request A-execution Related to the Execution and EVM labels Jul 1, 2023
@rakita
Copy link
Collaborator Author

rakita commented Jul 31, 2023

Wanted to do full sync with revm state as It passes first 5M blocks, and set target to 17M. It is a lot slower so I left a few timestamps to figure out where the time goes. Commit 4c5453d

A number of executed blocks is hardcoded to 10k will do it for 50k and 200k just to compare numbers.

One log is here:

2023-07-31T11:30:03.786851Z  INFO sync::stages::execution:  Execution duration. block_fetch=843.055596ms execution=66.535648914s write_preperation=30ns write=7.120426345s
2023-07-31T11:30:03.786867Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=41.984116315s apply_state=1.571352567s apply_post_state=12.126806ms merge_transitions=19.569243135s receipt_root=3.29340676s sender_recovery=0ns

66s for execution where 7s is writing/commiting data to the database.

Out of 66s, 41s is spent in revm and 19s is spent on merging transitions. The great thing is that merging transitions can be done in parallel with evm execution.

Few more logs to see consistency of times:

2023-07-31T11:27:29.545177Z  INFO sync::stages::execution:  Execution duration. block_fetch=900.63897ms execution=71.851295701s write_preperation=80ns write=7.987286374s
2023-07-31T11:27:29.545192Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=43.785836398s apply_state=1.723983605s apply_post_state=12.574019ms merge_transitions=22.600253182s receipt_root=3.61530829s sender_recovery=0ns
2023-07-31T11:27:29.745477Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=9560132 checkpoint=27.0% eta=unknown
2023-07-31T11:27:38.697533Z  INFO reth::cli: Status connected_peers=15 stage=Execution checkpoint=27.0% eta=unknown
2023-07-31T11:28:08.697626Z  INFO reth::cli: Status connected_peers=17 stage=Execution checkpoint=27.0% eta=unknown
2023-07-31T11:28:38.697854Z  INFO reth::cli: Status connected_peers=20 stage=Execution checkpoint=27.0% eta=unknown
2023-07-31T11:28:48.034881Z  INFO sync::stages::execution:  Execution duration. block_fetch=872.937768ms execution=68.188019916s write_preperation=80ns write=7.620039193s
2023-07-31T11:28:48.034894Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=44.365019666s apply_state=1.692649636s apply_post_state=11.921763ms merge_transitions=18.432856789s receipt_root=3.57573591s sender_recovery=0ns
2023-07-31T11:28:48.229358Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=9570133 checkpoint=27.1% eta=1day 3h 39m 39s
2023-07-31T11:29:08.697950Z  INFO reth::cli: Status connected_peers=23 stage=Execution checkpoint=27.1% eta=1day 3h 39m 19s
2023-07-31T11:29:38.698213Z  INFO reth::cli: Status connected_peers=23 stage=Execution checkpoint=27.1% eta=1day 3h 38m 49s
2023-07-31T11:30:03.786851Z  INFO sync::stages::execution:  Execution duration. block_fetch=843.055596ms execution=66.535648914s write_preperation=30ns write=7.120426345s
2023-07-31T11:30:03.786867Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=41.984116315s apply_state=1.571352567s apply_post_state=12.126806ms merge_transitions=19.569243135s receipt_root=3.29340676s sender_recovery=0ns
2023-07-31T11:30:04.008630Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=9580134 checkpoint=27.2% eta=1day 4h 5m 55s
2023-07-31T11:30:08.697794Z  INFO reth::cli: Status connected_peers=24 stage=Execution checkpoint=27.2% eta=1day 4h 5m 50s
2023-07-31T11:30:38.698153Z  INFO reth::cli: Status connected_peers=26 stage=Execution checkpoint=27.2% eta=1day 4h 5m 20s
2023-07-31T11:31:08.697797Z  INFO reth::cli: Status connected_peers=28 stage=Execution checkpoint=27.2% eta=1day 4h 4m 50s
2023-07-31T11:31:09.279674Z  INFO sync::stages::execution:  Execution duration. block_fetch=760.686122ms execution=57.134441118s write_preperation=90ns write=6.557598172s
2023-07-31T11:31:09.279687Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=38.360898343s apply_state=1.430223015s apply_post_state=11.306469ms merge_transitions=14.204644175s receipt_root=3.029241669s sender_recovery=0ns
2023-07-31T11:31:09.452212Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=9590135 checkpoint=27.2% eta=1day 3h 26m 24s
2023-07-31T11:31:38.697949Z  INFO reth::cli: Status connected_peers=27 stage=Execution checkpoint=27.2% eta=1day 3h 25m 55s
2023-07-31T11:32:08.697480Z  INFO reth::cli: Status connected_peers=29 stage=Execution checkpoint=27.2% eta=1day 3h 25m 25s
2023-07-31T11:32:32.188544Z  INFO sync::stages::execution:  Execution duration. block_fetch=847.945614ms execution=72.745263198s write_preperation=29ns write=7.184017491s
2023-07-31T11:32:32.188559Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=48.804262669s apply_state=1.584685096s apply_post_state=12.076124ms merge_transitions=18.935814322s receipt_root=3.300727425s sender_recovery=0ns
2023-07-31T11:32:32.406646Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=9600136 checkpoint=27.3% eta=1day 6h 37m 13s
2023-07-31T11:32:38.697452Z  INFO reth::cli: Status connected_peers=29 stage=Execution checkpoint=27.3% eta=1day 6h 37m 7s
2023-07-31T11:33:08.697599Z  INFO reth::cli: Status connected_peers=28 stage=Execution checkpoint=27.3% eta=1day 6h 36m 37s
2023-07-31T11:33:38.697483Z  INFO reth::cli: Status connected_peers=31 stage=Execution checkpoint=27.3% eta=1day 6h 36m 7s
2023-07-31T11:33:47.496565Z  INFO sync::stages::execution:  Execution duration. block_fetch=811.459412ms execution=65.423867184s write_preperation=60ns write=6.857411038s
2023-07-31T11:33:47.496579Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=44.880761237s apply_state=1.52533269s apply_post_state=11.529883ms merge_transitions=15.66918938s receipt_root=3.229929276s sender_recovery=0ns
2023-07-31T11:33:47.668124Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=9610137 checkpoint=27.3% eta=1day 5h 53m 50s
2023-07-31T11:34:08.698408Z  INFO reth::cli: Status connected_peers=30 stage=Execution checkpoint=27.3% eta=1day 5h 53m 29s
2023-07-31T11:34:38.698107Z  INFO reth::cli: Status connected_peers=35 stage=Execution checkpoint=27.3% eta=1day 5h 52m 59s
2023-07-31T11:35:08.697465Z  INFO reth::cli: Status connected_peers=33 stage=Execution checkpoint=27.3% eta=1day 5h 52m 29s
2023-07-31T11:35:10.902900Z  INFO sync::stages::execution:  Execution duration. block_fetch=851.176173ms execution=73.415450973s write_preperation=70ns write=7.264793211s
2023-07-31T11:35:10.902914Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=48.110906646s apply_state=1.596086223s apply_post_state=12.032045ms merge_transitions=20.237039563s receipt_root=3.35176405s sender_recovery=0ns
2023-07-31T11:35:11.109110Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=9620138 checkpoint=27.4% eta=1day 6h 42m 38s
2023-07-31T11:35:38.697746Z  INFO reth::cli: Status connected_peers=33 stage=Execution checkpoint=27.4% eta=1day 6h 42m 10s
2023-07-31T11:36:08.697508Z  INFO reth::cli: Status connected_peers=33 stage=Execution checkpoint=27.4% eta=1day 6h 41m 40s
2023-07-31T11:36:25.616806Z  INFO sync::stages::execution:  Execution duration. block_fetch=769.962202ms execution=64.963965989s write_preperation=70ns write=6.865122998s
2023-07-31T11:36:25.616820Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=45.409398563s apply_state=1.460644963s apply_post_state=11.473832ms merge_transitions=14.932982433s receipt_root=3.049636304s sender_recovery=0ns
2023-07-31T11:36:25.775048Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=9630139 checkpoint=27.4% eta=1day 6h 59m 2s
2023-07-31T11:36:38.697785Z  INFO reth::cli: Status connected_peers=35 stage=Execution checkpoint=27.4% eta=1day 6h 58m 49s
2023-07-31T11:37:08.697543Z  INFO reth::cli: Status connected_peers=34 stage=Execution checkpoint=27.4% eta=1day 6h 58m 19s
2023-07-31T11:37:38.697688Z  INFO reth::cli: Status connected_peers=40 stage=Execution checkpoint=27.4% eta=1day 6h 57m 49s
2023-07-31T11:38:01.484472Z  INFO sync::stages::execution:  Execution duration. block_fetch=939.878996ms execution=84.996005084s write_preperation=80ns write=8.111352432s
2023-07-31T11:38:01.484489Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=56.26903896s apply_state=1.914950019s apply_post_state=12.286825ms merge_transitions=22.884263034s receipt_root=3.799012146s sender_recovery=0ns
2023-07-31T11:38:01.689282Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=9640140 checkpoint=27.5% eta=1day 7h 23m 34s
2023-07-31T11:38:08.698196Z  INFO reth::cli: Status connected_peers=39 stage=Execution checkpoint=27.5% eta=1day 7h 23m 27s
2023-07-31T11:38:38.697582Z  INFO reth::cli: Status connected_peers=40 stage=Execution checkpoint=27.5% eta=1day 7h 22m 57s
2023-07-31T11:39:08.698355Z  INFO reth::cli: Status connected_peers=40 stage=Execution checkpoint=27.5% eta=1day 7h 22m 27s

@rakita
Copy link
Collaborator Author

rakita commented Jul 31, 2023

for hardcoded 50k blocks commit:

One line:

2023-07-31T14:22:49.407467Z  INFO sync::stages::execution:  Execution duration. block_fetch=22.201081063s execution=1888.288018182s write_preperation=40ns write=41.954709198s
2023-07-31T14:22:49.407484Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=238.055049052s apply_state=11.745363779s apply_post_state=126.847613ms merge_transitions=1616.62041863s receipt_root=20.900546752s sender_recovery=0ns

Block fetch 22s
Execution 1888s
write 42s

In executor it is:
evm: 238s
apply: 11s
merge of transitions: 1616s

Transition merge needs to be addresses and optimized.

Multiple measurements to see consistency:

2023-07-31T12:56:19.835516Z  INFO sync::stages::execution:  Execution duration. block_fetch=20.212924323s execution=1236.299418251s write_preperation=40ns write=35.791067778s
2023-07-31T12:56:19.835533Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=215.968831806s apply_state=9.677413208s apply_post_state=116.836137ms merge_transitions=992.276540078s receipt_root=17.555241706s sender_recovery=0ns
2023-07-31T12:56:20.825651Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=9810149 checkpoint=28.5% eta=3days 18h 12m 21s
2023-07-31T13:21:23.090563Z  INFO sync::stages::execution:  Execution duration. block_fetch=20.417313433s execution=1440.418311105s write_preperation=50ns write=39.198417152s
2023-07-31T13:21:23.090579Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=235.363543857s apply_state=10.603295517s apply_post_state=122.403215ms merge_transitions=1173.554497736s receipt_root=20.017990135s sender_recovery=0ns
2023-07-31T13:21:24.224569Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=9860150 checkpoint=28.8% eta=4days 2h 26m 59s
2023-07-31T13:50:11.676162Z  INFO sync::stages::execution:  Execution duration. block_fetch=21.469254058s execution=1666.370644562s write_preperation=130ns write=38.054568444s
2023-07-31T13:50:11.676179Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=234.083179366s apply_state=11.128415448s apply_post_state=123.495721ms merge_transitions=1399.261493718s receipt_root=20.965096867s sender_recovery=0ns
2023-07-31T13:50:12.824365Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=9910151 checkpoint=29.1% eta=4days 14h 38m 40s
2023-07-31T14:22:49.407467Z  INFO sync::stages::execution:  Execution duration. block_fetch=22.201081063s execution=1888.288018182s write_preperation=40ns write=41.954709198s
2023-07-31T14:22:49.407484Z  INFO reth_provider::traits::executor: Execution time target="sync::stages::execution" evm_transact=238.055049052s apply_state=11.745363779s apply_post_state=126.847613ms merge_transitions=1616.62041863s receipt_root=20.900546752s sender_recovery=0ns
2023-07-31T14:22:50.733850Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=9960152 checkpoint=29.4% eta=5days 1h 10m 39s

@rakita
Copy link
Collaborator Author

rakita commented Aug 1, 2023

I forgot to remove some test cloning, now it is a lot better.

Logs are with 50k blocks:

2023-08-01T17:15:03.360160Z  INFO sync::stages::execution:  Execution duration. block_fetch=18.069913646s execution=382.326806547s write_preperation=30ns write=61.731649577s
2023-08-01T17:15:03.360177Z  INFO evm: Execution time evm_transact=313.494075637s apply_state=14.945972929s apply_post_state=61.172809ms merge_transitions=19.90177185s receipt_root=32.947068998s sender_recovery=0ns
2023-08-01T17:15:05.061917Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=11310179 checkpoint=40.3% eta=unknown

2023-08-01T17:23:04.294565Z  INFO sync::stages::execution:  Execution duration. block_fetch=25.44984107s execution=387.771829739s write_preperation=30ns write=61.087730337s
2023-08-01T17:23:04.294583Z  INFO evm: Execution time evm_transact=320.040259415s apply_state=14.716598765s apply_post_state=65.692842ms merge_transitions=19.232828034s receipt_root=32.655203746s sender_recovery=0ns
2023-08-01T17:23:06.203568Z  INFO reth::node::events: Stage committed progress pipeline_stages=5/13 stage=Execution block=11360180 checkpoint=40.7% eta=18h 16m 6s

Time spend:

  • fetching blocks is 25s
  • execution 388s
  • write to db 61s

In total for this sample, it takes 474s.

Things that can be done in parallel are:

  • block fetching: 25s
  • merge transitions: 19s.
  • receipt root: 32s

Parallel work in total is 76s that is just 16% of execution stage, while evm transact is 320s which is 67%, writing to db is 61s or 12,8% and apply of revm output is 14.7s or 2.5%.

We can additionally write changesets in the background it is just append operation while writing plain state at the end.

@codecov
Copy link

codecov bot commented Aug 16, 2023

Codecov Report

Merging #3512 (79345c5) into main (62e7d98) will decrease coverage by 0.80%.
The diff coverage is 75.47%.

Impacted file tree graph

Files Changed Coverage Δ
bin/reth/src/chain/import.rs 6.89% <0.00%> (-0.06%) ⬇️
bin/reth/src/debug_cmd/execution.rs 1.12% <0.00%> (-0.03%) ⬇️
bin/reth/src/debug_cmd/in_memory_merkle.rs 1.26% <0.00%> (-0.04%) ⬇️
bin/reth/src/debug_cmd/merkle.rs 0.80% <0.00%> (-0.02%) ⬇️
bin/reth/src/node/mod.rs 26.19% <0.00%> (-0.04%) ⬇️
bin/reth/src/stage/dump/merkle.rs 0.00% <0.00%> (ø)
bin/reth/src/stage/run.rs 1.36% <0.00%> (-0.01%) ⬇️
crates/blockchain-tree/src/shareable.rs 56.20% <0.00%> (-0.42%) ⬇️
crates/consensus/auto-seal/src/lib.rs 0.00% <0.00%> (ø)
crates/consensus/auto-seal/src/task.rs 0.00% <0.00%> (ø)
... and 67 more

... and 20 files with indirect coverage changes

Flag Coverage Δ
integration-tests 16.99% <0.32%> (+0.20%) ⬆️
unit-tests 63.18% <75.24%> (-0.86%) ⬇️

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

Components Coverage Δ
reth binary 31.37% <63.29%> (+0.28%) ⬆️
blockchain tree 83.59% <71.15%> (+0.01%) ⬆️
pipeline 88.54% <83.60%> (-2.00%) ⬇️
storage (db) 73.44% <89.63%> (-1.89%) ⬇️
trie 94.77% <ø> (-0.12%) ⬇️
txpool 49.16% <16.66%> (-0.47%) ⬇️
networking 77.20% <ø> (-0.16%) ⬇️
rpc 57.36% <10.00%> (-0.04%) ⬇️
consensus 62.42% <12.19%> (-0.99%) ⬇️
revm 19.67% <63.97%> (-11.89%) ⬇️
payload builder 9.08% <0.00%> (+0.10%) ⬆️
primitives 86.45% <55.55%> (-0.10%) ⬇️

Copy link
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.

This is a great start - thank you.

Main thought is we should split this up into a stacked PR, starting with the deeper changes:, and ensuring each type is well documented and we know why it's needed. Right now things are super verbose and require fine handling to set them up correctly, or a lot of context is needed in mind to use it properly.

Suggested path forward is to split into a few PRs which we stack on top of each other

  1. The glue code between Revm and Reth, mostly in cache.rs, with clear description on what the wrapper BundleState is doing
  2. Modify the actual executor & processor code
  3. RPC & TxPool changes (if any required after our review)

Any driveby changes like some type casts to u128 etc. should go in separate PR

crates/storage/provider/src/test_utils/blocks.rs Outdated Show resolved Hide resolved
crates/storage/provider/src/providers/database/provider.rs Outdated Show resolved Hide resolved
crates/stages/src/stages/mod.rs Outdated Show resolved Hide resolved
crates/stages/src/stages/execution.rs Show resolved Hide resolved
crates/primitives/src/withdrawal.rs Show resolved Hide resolved
crates/revm/revm-inspectors/src/tracing/builder/parity.rs Outdated Show resolved Hide resolved
crates/revm/revm-primitives/src/env.rs Show resolved Hide resolved
crates/revm/src/database.rs Show resolved Hide resolved
crates/storage/provider/src/providers/database/provider.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

I can see how this will work, and overall this is a big improvement.

I went over most of it and left a lot of comments on everything that caught my eye.

for the alias issues,

I'd like to avoid Revm aliases, because this makes it very confusing if we don't use the revm aliases everywhere, perhaps a better solution here is if we need to have wrappers, then these could be prefixed with Reth instead or something else.

re rpc related changes:

what's the motivation behind replacing CacheDB with RevmState if we always disable the bundle state anyway?

we're only interested in the statediff, does the statediff output of revmState and cacheDB now differ?

crates/storage/provider/src/providers/database/provider.rs Outdated Show resolved Hide resolved
}

if TAKE {
if UNWIND {
Copy link
Collaborator

Choose a reason for hiding this comment

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

what are these constants?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

UNWIND (Or previously TAKE) would remove (take/unwind) things from the database. We can maybe continue here: https://github.com/paradigmxyz/reth/pull/3512/files#r1309408492

use std::{sync::Arc, time::Instant};
use tracing::{debug, trace};

/// Main block executor
Copy link
Collaborator

Choose a reason for hiding this comment

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

This needs docs that explain what this type does

crates/rpc/rpc/src/debug.rs Outdated Show resolved Hide resolved
crates/payload/basic/src/lib.rs Outdated Show resolved Hide resolved
crates/interfaces/src/executor.rs Outdated Show resolved Hide resolved
crates/revm/src/processor.rs Outdated Show resolved Hide resolved
crates/revm/src/processor.rs Outdated Show resolved Hide resolved
/// Write reverts to database.
///
/// Note:: Reverts will delete all wiped storage from plain state.
pub fn write_to_db<'a, TX: DbTxMut<'a> + DbTx<'a>>(
Copy link
Collaborator

Choose a reason for hiding this comment

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

the naming is very confusing to me, because writing reverts results in wiped storage, because this does not actually write anything and instead deletes?

Copy link
Collaborator Author

@rakita rakita Aug 31, 2023

Choose a reason for hiding this comment

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

I inherited this, can bikeshed a little on this, should be fruitful.

little history, this pattern was used when we still were not sure how to handle Provider and needed to decide on the pattern for how to write things to the database. At that point in time this was one of the promising paths that we had.

What we have decided and have now is @joshieDo had split the Provider with the traits so I think this should be moved there and have BundeStateProvider trait that will have commit_state(bundle: State) and commit_reverts(reverts:Reverts). This feels nicer imo and it shouldn't be a big change.

Copy link
Member

Choose a reason for hiding this comment

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

This function both writes/cleans up empty plainstate, but it also appends (the reverts) to the changesets tables. Makes me wonder if we should call reverts Prestate's or something.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Created the issue for this as it is debt from before revm state: #4620

Co-authored-by: Alexey Shekhirin <a.shekhirin@gmail.com>
rakita and others added 9 commits September 15, 2023 19:03
Co-authored-by: Bjerg <onbjerg@users.noreply.github.com>
Co-authored-by: Bjerg <onbjerg@users.noreply.github.com>
Co-authored-by: Bjerg <onbjerg@users.noreply.github.com>
Co-authored-by: Bjerg <onbjerg@users.noreply.github.com>
Co-authored-by: Bjerg <onbjerg@users.noreply.github.com>
Co-authored-by: Bjerg <onbjerg@users.noreply.github.com>
Co-authored-by: Bjerg <onbjerg@users.noreply.github.com>
Copy link
Collaborator

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

amazing

left my last (very) pedantic nits

@@ -950,10 +957,17 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
let old_tip = self.block_indices.canonical_tip();
// Merge all chain into one chain.
let mut new_canon_chain = chains_to_promote.pop().expect("There is at least one block");
trace!(target: "blockchain_tree", ?new_canon_chain, "Merging chains");
let mut have_append = false;
Copy link
Collaborator

Choose a reason for hiding this comment

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

let's rename this variable, to something like chain_promoted|appended

post_state: &PostState,
executor: &mut Executor<DB>,
bundle_state: &BundleStateWithReceipts,
client: &impl StateProviderFactory,
Copy link
Collaborator

@mattsse mattsse Sep 15, 2023

Choose a reason for hiding this comment

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

I dislike this refs to impl style,
would prefer &S here and add generic to function

Copy link
Member

Choose a reason for hiding this comment

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

same

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Would prefer &impl here but don't mind changing it

pub fn populate_account_balance_nonce_diffs<DB, I>(
state_diff: &mut StateDiff,
db: DB,
db: &DB,
Copy link
Collaborator

Choose a reason for hiding this comment

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

DB is autoimpl for &

Suggested change
db: &DB,
db: DB,

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Removed it from few places: d3cec9f

use std::{sync::Arc, time::Instant};
use tracing::{debug, trace};

/// Main block executor
Copy link
Collaborator

Choose a reason for hiding this comment

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

still would like to see more docs here

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I missed those, will add

}

/// Creates a new executor from the given chain spec and database.
pub fn new_with_db<DB: StateProvider + 'a>(
Copy link
Collaborator

Choose a reason for hiding this comment

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

style:

Suggested change
pub fn new_with_db<DB: StateProvider + 'a>(
pub fn with_db<DB: StateProvider + 'a>(

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I prefer constructors to be prefixed with new_, as I relate with_ to the builders.

@@ -278,6 +278,9 @@ pub enum RpcInvalidTransactionError {
/// The transaction is before Spurious Dragon and has a chain ID
#[error("Transactions before Spurious Dragon should not have a chain ID.")]
OldLegacyChainId,
/// The transitions is before Berlin and has access list
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
/// The transitions is before Berlin and has access list
/// The transaction is before Berlin and has access list

Comment on lines 41 to 49
/// Type used to initialize revms bundle state.
pub type BundleStateInit =
HashMap<Address, (Option<Account>, Option<Account>, HashMap<H256, (U256, U256)>)>;

/// Types used inside RevertsInit to initialize revms reverts.
pub type AccountRevertInit = (Option<Option<Account>>, Vec<StorageEntry>);

/// Type used to initialize revms reverts.
pub type RevertsInit = HashMap<BlockNumber, HashMap<Address, AccountRevertInit>>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I still really want to get rid of these,

In any case they should not be public and it should be explained what these represent, but I'd prefer actual types over aliases

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Would be work related to this: #4614


/// A change to the state of the world.
#[derive(Default)]
pub struct StateChange(pub StateChangeset);
Copy link
Collaborator

Choose a reason for hiding this comment

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

many changes?

Suggested change
pub struct StateChange(pub StateChangeset);
pub struct StateChanges(pub StateChangeset);

pub execution_duration: Duration,
/// The amount of time it took to apply state changes to cached state
pub apply_state_duration: Duration,
/// Apply Post state execution changes duration.
Copy link
Collaborator

Choose a reason for hiding this comment

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

this doc is not very informative and uses outdated post state terminology

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It should have been post execution state change as the name implies we have state change post execution.
Would update docs

Comment on lines 23 to 25
/// Block execution statistics
#[derive(Clone, Debug, Default)]
pub struct BlockExecutorStats {
Copy link
Collaborator

Choose a reason for hiding this comment

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

this type feels a bit out of place here in between the traits, can move to end of file?

Copy link
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.

Really excited for this work. Finally!

Main reaction is as usual...documentation & further simplification of the components / terminology. There's a few moving parts so the more we can document things like the processor the better.

Things I find confusing:

  • change.rs file is big / a lot of things going on, would love more docs & refactoring in structs vs type re-exports and being sensitive about what gets exposed to consumers of libraries
  • provider that has UNWIND/TAKE is still a bit "a lot of things in one place" so would love if we can break that down

Otherwise mainly nits and nothing from my side blocking this going forward.

I am also realizing an example on the Revm repo which shows how to the new API can be consumed, as well as comparing it with CacheDB could be powerful)

Comment on lines 131 to 133
/// Post execution state change that include block reward, withdrawals and iregular DAO hardfork
/// state change.
pub fn post_execution_state_change(
Copy link
Member

Choose a reason for hiding this comment

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

nit: post is a bit weird word here - apply maybe

Cargo.toml Outdated
@@ -59,7 +59,7 @@ resolver = "2"
[workspace.package]
version = "0.1.0-alpha.8"
edition = "2021"
rust-version = "1.70" # Remember to update .clippy.toml and README.md
rust-version = "1.70" # Remember to update .clippy.toml and README.md
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
rust-version = "1.70" # Remember to update .clippy.toml and README.md
rust-version = "1.70" # Remember to update .clippy.toml and README.md

nit

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was auto formating by plugin, will revert back, but we should address what is our default formatting for toml. Had the same problem with revm where Dani has its own config (width 100 iirc)

Comment on lines -177 to -181
[patch.crates-io]
revm = { git = "https://github.com/bluealloy/revm", branch = "release/v25" }
revm-interpreter = { git = "https://github.com/bluealloy/revm", branch = "release/v25" }
revm-precompile = { git = "https://github.com/bluealloy/revm", branch = "release/v25" }
revm-primitives = { git = "https://github.com/bluealloy/revm", branch = "release/v25" }
Copy link
Member

Choose a reason for hiding this comment

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

wooo

*address,
Account { nonce: account.nonce.unwrap_or(0), balance: account.balance, bytecode_hash },
(Some(None), storage.keys().map(|k| StorageEntry::new(*k, U256::ZERO)).collect()),
Copy link
Member

Choose a reason for hiding this comment

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

nit this Some(None) is a bit overhead to think about - maybe the bundle builder helps

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Should be, linked the issue for crossreference #4614

Comment on lines 141 to 142
let mut all_reverts_init: RevertsInit = HashMap::new();
all_reverts_init.insert(0, reverts_init);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
let mut all_reverts_init: RevertsInit = HashMap::new();
all_reverts_init.insert(0, reverts_init);
let all_reverts_init: RevertsInit = HashMap::from([(0, reverts_init)]);

think this should work also

}

// Create header log bloom.
let logs_bloom = receipts_with_bloom.iter().fold(Bloom::zero(), |bloom, r| bloom | r.bloom);
Copy link
Member

Choose a reason for hiding this comment

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

nit i'd just add a method on the struct which does this as it seems like a common operation

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Can be addressed by Receipts type: #4621

Comment on lines +309 to +322
gas_spent_by_tx: self
.receipts
.last()
.map(|block_r| {
block_r
.iter()
.enumerate()
.map(|(id, tx_r)| {
(
id as u64,
tx_r.as_ref()
.expect("receipts have not been pruned")
.cumulative_gas_used,
)
Copy link
Member

Choose a reason for hiding this comment

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

would consider making a method on receipts

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Can be addressed by Receipts type: #4621

Comment on lines 35 to 36
/// Receipts.
receipts: Vec<Vec<Option<Receipt>>>,
Copy link
Member

Choose a reason for hiding this comment

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

What does this Vec<Vec<Option<_>> represent? Can we document what the outer/inner vec mean and when a Receipt can be none

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Documented it. And can be addressed by Receipts type: #4621


/// Type used to initialize revms bundle state.
pub type BundleStateInit =
HashMap<Address, (Option<Account>, Option<Account>, HashMap<H256, (U256, U256)>)>;
Copy link
Member

Choose a reason for hiding this comment

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

the double option i wonder if we could replace it with an enum

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Related to this: #4614

/// Write reverts to database.
///
/// Note:: Reverts will delete all wiped storage from plain state.
pub fn write_to_db<'a, TX: DbTxMut<'a> + DbTx<'a>>(
Copy link
Member

Choose a reason for hiding this comment

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

This function both writes/cleans up empty plainstate, but it also appends (the reverts) to the changesets tables. Makes me wonder if we should call reverts Prestate's or something.

@rakita
Copy link
Collaborator Author

rakita commented Sep 16, 2023

Addressed nits and comments, from both here and from Discord.
Synced mainnet and sepolia without problem, and bumped to the newest code and left in live sync.

@gakonst @mattsse this seems ready to be merged

Copy link
Collaborator

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

lfg

@rakita rakita added this pull request to the merge queue Sep 16, 2023
Merged via the queue into main with commit f153d8f Sep 16, 2023
23 checks passed
@rakita rakita deleted the rakita/revm_state branch September 16, 2023 11:13
@mattsse mattsse mentioned this pull request Sep 19, 2023
@mattsse mattsse added the M-changelog This change should be included in the changelog label Sep 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-execution Related to the Execution and EVM C-enhancement New feature or request M-changelog This change should be included in the changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants