Skip to content

Commit

Permalink
refactor consistent view and trie input
Browse files Browse the repository at this point in the history
  • Loading branch information
fgimenez committed Nov 21, 2024
1 parent f829582 commit fdba696
Showing 1 changed file with 33 additions and 28 deletions.
61 changes: 33 additions & 28 deletions crates/engine/tree/src/tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2193,12 +2193,14 @@ where
let exec_time = Instant::now();

let (state_root_tx, state_root_rx) = std::sync::mpsc::channel();
// TODO: create consistent_view using `new_with_latest_tip` when we
// switch to `StateRootTask`.
let consistent_view = ConsistentDbView::new(self.provider.clone(), None);
// TODO: calculate `TrieInput` like in `self.compute_state_root_parallel`.
let input = Arc::new(TrieInput::default());
let state_root_config = StateRootConfig { consistent_view, input };

let consistent_view = ConsistentDbView::new_with_latest_tip(self.provider.clone())?;

let input = self
.compute_trie_input(consistent_view.clone(), block.parent_hash)
.map_err(|e| InsertBlockErrorKindTwo::Other(Box::new(e)))?;
let state_root_config =
StateRootConfig { consistent_view: consistent_view.clone(), input: Arc::new(input) };
let receiver_stream = StdReceiverStream::new(state_root_rx);
let state_root_task = StateRootTask::new(state_root_config, receiver_stream);
let state_root_handle = state_root_task.spawn();
Expand Down Expand Up @@ -2234,18 +2236,20 @@ where
let root_time = Instant::now();
let mut state_root_result = None;

// TODO: switch to calculate state root using `StateRootTask`.

// We attempt to compute state root in parallel if we are currently not persisting anything
// to database. This is safe, because the database state cannot change until we
// finish parallel computation. It is important that nothing is being persisted as
// we are computing in parallel, because we initialize a different database transaction
// per thread and it might end up with a different view of the database.
let persistence_in_progress = self.persistence_state.in_progress();
if !persistence_in_progress {
state_root_result = match self
.compute_state_root_parallel(block.parent_hash, &hashed_state)
{
let mut input = self
.compute_trie_input(consistent_view.clone(), block.parent_hash)
.map_err(|e| InsertBlockErrorKindTwo::Other(Box::new(e)))?;
// Extend with block we are validating root for.
input.append_ref(&hashed_state);

state_root_result = match self.compute_state_root_parallel(consistent_view, input) {
Ok((state_root, trie_output)) => Some((state_root, trie_output)),
Err(ParallelStateRootError::Provider(ProviderError::ConsistentView(error))) => {
debug!(target: "engine", %error, "Parallel state root computation failed consistency check, falling back");
Expand Down Expand Up @@ -2313,23 +2317,11 @@ where
Ok(InsertPayloadOk2::Inserted(BlockStatus2::Valid))
}

/// Compute state root for the given hashed post state in parallel.
///
/// # Returns
///
/// Returns `Ok(_)` if computed successfully.
/// Returns `Err(_)` if error was encountered during computation.
/// `Err(ProviderError::ConsistentView(_))` can be safely ignored and fallback computation
/// should be used instead.
fn compute_state_root_parallel(
fn compute_trie_input(
&self,
consistent_view: ConsistentDbView<P>,
parent_hash: B256,
hashed_state: &HashedPostState,
) -> Result<(B256, TrieUpdates), ParallelStateRootError> {
// TODO: when we switch to calculate state root using `StateRootTask` this
// method can be still useful to calculate the required `TrieInput` to
// create the task.
let consistent_view = ConsistentDbView::new_with_latest_tip(self.provider.clone())?;
) -> Result<TrieInput, ParallelStateRootError> {
let mut input = TrieInput::default();

if let Some((historical, blocks)) = self.state.tree_state.blocks_by_hash(parent_hash) {
Expand All @@ -2349,9 +2341,22 @@ where
input.append(revert_state);
}

// Extend with block we are validating root for.
input.append_ref(hashed_state);
Ok(input)
}

/// Compute state root for the given hashed post state in parallel.
///
/// # Returns
///
/// Returns `Ok(_)` if computed successfully.
/// Returns `Err(_)` if error was encountered during computation.
/// `Err(ProviderError::ConsistentView(_))` can be safely ignored and fallback computation
/// should be used instead.
fn compute_state_root_parallel(
&self,
consistent_view: ConsistentDbView<P>,
input: TrieInput,
) -> Result<(B256, TrieUpdates), ParallelStateRootError> {
ParallelStateRoot::new(consistent_view, input).incremental_root_with_updates()
}

Expand Down

0 comments on commit fdba696

Please sign in to comment.