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

core/state/snapshot: replace diffToDisk ideal batch size with 64MB #27977

Merged
merged 1 commit into from
Aug 25, 2023

Conversation

aaronbuchwald
Copy link
Contributor

This PR updates diffToDisk(...) within snapshot flattening to write the entire diff to disk in a single batch.

Writing the diff to disk across multiple batches leads to the possibility that the snapshot will be corrupted during an ungraceful shutdown and can cause degraded performance during snapshot re-generation on startup.

@rjl493456442
Copy link
Member

Unfortunately, this will be problematic. In Ethereum, it's possible some contracts will be deleted, and the associated storage should be deleted from the snapshot. However, these contracts can be unbound and might result in out-of-memory(theoretically possible to build such contract, but have the cost to fulfill the slots though).

Therefore, we split the big write into several small ones.

@holiman
Copy link
Contributor

holiman commented Aug 23, 2023

These checks were added because they were needed, see #22582 for more details, and also #22497 (comment) for some history:

The ropsten BitlleGasStation was self-destructed at block 6490899, in this tx .

@holiman holiman closed this Aug 23, 2023
@aaronbuchwald
Copy link
Contributor Author

Thanks for the context! I was under the mistaken impression that this change was made as a performance optimization as opposed to avoid an OOM.

@aaronbuchwald
Copy link
Contributor Author

As an alternative to avoid snapshot corruption. Applying the diff from the same block should be an idempotent operation. Would you be open to a PR that:

  • write the previous and next block hash when applying a snapshot diffToDisk operation so that there's a marker when in the middle of a flatten operation of exactly which diff is being applied
  • on restart, if you observe a corrupted snapshot, re-process the same block to re-create the same diff and apply it to complete the incomplete diffToDisk operation

I understand that this may break some abstractions, so curious whether you'd be open to this idea, think it would be too gross to add, or even if snapshot corruption is not much of a concern in your view.

@karalabe
Copy link
Member

Can't we have a middle ground? The IdealBatchSize is something like 100KB. That will trigger on a lot of contracts. But if we cap it at some significantly higher number (something reasonable in comparison with the max allowed deletion), then it should be fine almost always, except if you nuke your node exactly when it's deleting something larger?

@karalabe
Copy link
Member

I guess there's no max allowed deletion in the snapshots. Still, could we special case this and cap it at a significantly higher number instead of 100KB? Say 64MB-256MB?

@holiman
Copy link
Contributor

holiman commented Aug 23, 2023

Say 64MB-256MB?

Should be fine; IMO rather 64 than 256

@karalabe karalabe reopened this Aug 24, 2023
@karalabe karalabe added this to the 1.13.0 milestone Aug 24, 2023
// Ensure we don't delete too much data blindly (contract can be
// huge). It's ok to flush, the root will go missing in case of a
// crash and we'll detect and regenerate the snapshot.
if batch.ValueSize() > ethdb.IdealBatchSize {
Copy link
Member

Choose a reason for hiding this comment

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

Can we keep the code for now and replace ethdb.IdealBatchSize with 64 * 1024 * 1024 in both invocations? When removing SELFDESTRUCT lands in Cancun, we can nuke it out according to the original PR. In between we'd at least have a more robust code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just updated during only those two invocations.

@aaronbuchwald aaronbuchwald changed the title core/state/snapshot: make diffToDisk atomic to prevent snapshot corruption ethdb: update IdealBatchSize to 64MB to reduce likelihood of corrupted snapshot Aug 24, 2023
@aaronbuchwald aaronbuchwald changed the title ethdb: update IdealBatchSize to 64MB to reduce likelihood of corrupted snapshot core/state/snapshot: replace diffToDisk ideal batch size with 64MB Aug 24, 2023
@karalabe karalabe merged commit 56d2366 into ethereum:master Aug 25, 2023
1 check passed
devopsbo3 pushed a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants