-
Notifications
You must be signed in to change notification settings - Fork 1.9k
chore(trie): Use trie changesets for engine unwinding #18878
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
base: 18460-trie-changesets
Are you sure you want to change the base?
chore(trie): Use trie changesets for engine unwinding #18878
Conversation
bdaeb41
to
70d24d4
Compare
self.write_trie_updates_sorted(&trie_revert)?; | ||
|
||
// Clear trie changesets which have been unwound. | ||
self.clear_trie_changesets_from(*range.start())?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shekhirin you mentioned in a previous PR that we don't want to have deletion from changesets done on a range, but this method only accepts a range. Do you think it's fine to leave this like this? or better to re-introduce clear_trie_changesets_from
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that this makes things simpler, I have a question and suggestion for a helper method but otherwise this looks good to me
let trie_revert = self.trie_reverts(range.clone())?; | ||
self.write_trie_updates_sorted(&trie_revert)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice, i like that this is now just a call to a provider fn
/// | ||
/// Returns the number of entries modified. | ||
fn write_trie_updates_sorted(&self, trie_updates: &TrieUpdatesSorted) -> ProviderResult<usize> { | ||
if trie_updates.account_nodes.is_empty() && trie_updates.storage_tries.is_empty() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could probably just introduce TrieUpdatesSorted::is_empty
// Sanity check that we have static files available to unwind to the target block. | ||
let highest_static_file_block = | ||
provider_factory.static_file_provider().get_highest_static_files().max_block_num(); | ||
if highest_static_file_block | ||
.filter(|highest_static_file_block| *highest_static_file_block > target) | ||
.is_none() | ||
{ | ||
return Err(eyre::eyre!("static files not available for target block {target}, highest is {highest_static_file_block:?}")); | ||
} | ||
|
||
// Move all applicable data from database to static files. | ||
pipeline.move_to_static_files()?; | ||
if self.offline { | ||
info!(target: "reth::cli", "Performing an unwind for offline-only data!"); | ||
} | ||
|
||
pipeline.unwind(target, None)?; | ||
if let Some(highest_static_file_block) = highest_static_file_block { | ||
info!(target: "reth::cli", ?target, ?highest_static_file_block, "Executing a pipeline unwind."); | ||
} else { | ||
info!(target: "reth::cli", ?target, "Executing a database unwind."); | ||
let provider = provider_factory.provider_rw()?; | ||
info!(target: "reth::cli", ?target, "Executing a pipeline unwind."); | ||
} | ||
info!(target: "reth::cli", prune_config=?config.prune, "Using prune settings"); | ||
|
||
provider | ||
.remove_block_and_execution_above(target) | ||
.map_err(|err| eyre::eyre!("Transaction error on unwind: {err}"))?; | ||
// This will build an offline-only pipeline if the `offline` flag is enabled | ||
let mut pipeline = | ||
self.build_pipeline(config, provider_factory, components.evm_config().clone())?; | ||
|
||
// update finalized block if needed | ||
let last_saved_finalized_block_number = provider.last_finalized_block_number()?; | ||
if last_saved_finalized_block_number.is_none_or(|f| f > target) { | ||
provider.save_finalized_block_number(target)?; | ||
} | ||
// Move all applicable data from database to static files. | ||
pipeline.move_to_static_files()?; | ||
|
||
provider.commit()?; | ||
} | ||
pipeline.unwind(target, None)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the reasoning behind this, that currently we pretty much always have static files and will now always be doing a pipeline unwind?
Closes #18517
This PR primarily targets the
unwind_trie_state_range
provider method, which is used by the engine API to unwind the db during reorgs.This method was previously also potentially used by the unwind pipeline stage, but only in an
else
block which should never get hit anymore. This else block was replaced with an error.unwind_trie_state_range
was previously recomputing trie updates using a StateRoot calculation, but it is now able to skip that step and simply read trie updates from the trie changeset tables instead. To make applying these updates easier thewrite_trie_updates
method is superceded bywrite_trie_updates_sorted
.