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

Statemanager: Add Separate Cache-Free StateManager version for Client Execution / copy() Options Fix #2582

Conversation

holgerd77
Copy link
Member

@holgerd77 holgerd77 commented Mar 13, 2023

Part of #1536

Extracted (variant) from #2578

Ugh.

This is a hard one. 🙂

During the last couple of days I experimented a lot with the StateManager cache. The cache also has the problem of being very inefficient and memory-bloating, by just copying over the whole cache during a commit().

In fact this is the substantially more important cache (inefficiency) since this cache is a lot larger than the one being optimized in #2581 (touched accounts in VM). I did two substantial rewrites of this cache transforming to a diff-based structure, each taking me several hours and I both made it to the point that blocks from mainnet can be executed subsequently. The first can be seen here (+ the follow-up commit) which uses a somewhat more complex structure for account entries containing not the values itself but an OrderedMap associating checkpoint heights with respective changes on the account. I then did another version of this with a simpler native datastructure (assuming better performance), taking just an array containing the CP height and cache entry somewhat like this `[ CPHeight (e.g. 3), CacheEntry (the old {val, modified,... } ].

To make it short: at the end it turned out that the by far fastest/most performant version was to use no cache at all respectively eliminate. 😂 (for the rescue: the diff based caches at least solved (like the no cache version), the memory crash).

The non-cache version is superior on the problematic blocks by a factor of 4-10 (!) (14 sec vs 2+ min for the memory crash block e.g.) and has no noticeable downturns on "normal" block executions.

Ugh. Mumble. 😋

This took me a while to let this sink in. After a couple of days of having let this sink in I would then say: ok. If this is a viable solution to make things better then let's remove, at least for the client.

To not side-affect existing users by this I would then just create a new CachelessStatemanager separate to the normal default state manager, which we can separately use for the client (and eventually also collect some more experiences with this on our own use case) and we can then see what we will take from this and how to proceed along our breaking releases.

Additionally we can also label this new CachelessStatemanager as experimental if we want to discourage usage for now.

WIP, need to clean things up, will drop a note once ready. 🙂

@holgerd77 holgerd77 changed the base branch from master to vm-diff-based-touched-account-checkpointing March 13, 2023 12:45
@codecov
Copy link

codecov bot commented Mar 13, 2023

Codecov Report

Merging #2582 (d3b4acd) into vm-diff-based-touched-account-checkpointing (a687ccf) will increase coverage by 0.45%.
The diff coverage is 76.86%.

Additional details and impacted files

Impacted file tree graph

Flag Coverage Δ
block 90.13% <ø> (?)
blockchain 90.40% <ø> (?)
client 87.70% <100.00%> (+0.01%) ⬆️
common 95.82% <ø> (?)
devp2p 91.78% <ø> (?)
ethash ∅ <ø> (∅)
statemanager 89.20% <76.69%> (?)
trie 90.66% <ø> (?)
tx 94.16% <ø> (ø)
util 84.50% <ø> (?)
vm 84.21% <ø> (?)

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

@holgerd77 holgerd77 force-pushed the statemanager-cache-free-version branch from a1e6fc3 to d3b4acd Compare March 13, 2023 13:41
@holgerd77 holgerd77 changed the title Statemanager: Add Separate Cache-Free StateManager version for Client Execution Statemanager: Add Separate Cache-Free StateManager version for Client Execution / copy() Options Fix Mar 13, 2023
@holgerd77
Copy link
Member Author

Update: I know settled with a new deactivateCache option in the normal default state manager, since otherwise there would have been too much copy-and-paste of code.

I think this is still sufficiently clean enough and all current SM functionality/extensibility should be preserved. It might eventually be nice if we are able to abstract the cache generally a bit more out and decouple along the next breaking releases, just as some additional general note.

This should be open for review now.

Together with #2581 this now allows to sync on mainnet past the first round of problematic Shanghai dDoS blocks or re-run with:

npm run client:start -- --discDns=false --discV4=false --maxPeers=0 --executeBlocks=2283416

🙂

@holgerd77
Copy link
Member Author

Side note: when looking at this with a step back I have to say that this new option generally makes sense to allow for easier cache/no-cache run comparisons, generally people might want to switch off cache for whatever reasons.

Also to note, forgot to mention: this PR also fixes a StateManager.copy() bug not copying the constructor option settings along.

@holgerd77
Copy link
Member Author

holgerd77 commented Mar 14, 2023

Some additional note on this after some more reflection: I still DO think that the functionality here (to have the possibility to deactivate SM cache) is useful and we should merge this.

This does not however mean that we need to live without the SM cache for now on forewards. At the moment it seems the better option for the client. We can still easily experiment with the cache code we have though and eventually re-activate. I was just thinking that in fact it might also already work if we track (within the SM cache) if there are cache changes during a CP period with a flag, and only copy over the whole cache in the Cache.checkpoint() method if there were changes. Additionally we can save the commit level along there and have some additional logic on Cache.commit() and Cache.revert() on what cache to take.

Absolutely no hurry here but we can just test this out in the coming days as well. Eventually this will already solve a lot of (all?) practical out-of-memory EVM code run situations.

@holgerd77 holgerd77 force-pushed the vm-diff-based-touched-account-checkpointing branch 2 times, most recently from 4f58424 to a5fb9be Compare March 17, 2023 10:37
@holgerd77
Copy link
Member Author

Closed in favor of #2592

@holgerd77 holgerd77 closed this Mar 17, 2023
@holgerd77 holgerd77 deleted the statemanager-cache-free-version branch June 6, 2023 08:43
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.

1 participant