diff --git a/crates/engine/tree/src/tree/trie_updates.rs b/crates/engine/tree/src/tree/trie_updates.rs index 34946becd676..9ec29f9c8b5e 100644 --- a/crates/engine/tree/src/tree/trie_updates.rs +++ b/crates/engine/tree/src/tree/trie_updates.rs @@ -11,10 +11,17 @@ use reth_trie::{ use reth_trie_db::DatabaseTrieCursorFactory; use tracing::debug; +#[derive(Debug)] +struct EntryDiff { + task: T, + regular: T, + database: T, +} + #[derive(Debug, Default)] struct TrieUpdatesDiff { - account_nodes: HashMap, Option)>, - removed_nodes: HashMap, + account_nodes: HashMap>>, + removed_nodes: HashMap>, storage_tries: HashMap, } @@ -27,12 +34,12 @@ impl TrieUpdatesDiff { pub(super) fn log_differences(mut self) { if self.has_differences() { - for (path, (task, regular)) in &mut self.account_nodes { - debug!(target: "engine::tree", ?path, ?task, ?regular, "Difference in account trie updates"); + for (path, EntryDiff { task, regular, database }) in &mut self.account_nodes { + debug!(target: "engine::tree", ?path, ?task, ?regular, ?database, "Difference in account trie updates"); } - for (path, (task, regular)) in &self.removed_nodes { - debug!(target: "engine::tree", ?path, ?task, ?regular, "Difference in removed account trie nodes"); + for (path, EntryDiff { task, regular, database }) in &self.removed_nodes { + debug!(target: "engine::tree", ?path, ?task, ?regular, ?database, "Difference in removed account trie nodes"); } for (address, storage_diff) in self.storage_tries { @@ -58,16 +65,17 @@ impl StorageTrieDiffEntry { debug!(target: "engine::tree", ?address, ?task, ?regular, "Difference in storage trie existence"); } Self::Value(mut storage_diff) => { - if let Some((task, regular)) = storage_diff.is_deleted { - debug!(target: "engine::tree", ?address, ?task, ?regular, "Difference in storage trie deletion"); + if let Some(EntryDiff { task, regular, database }) = storage_diff.is_deleted { + debug!(target: "engine::tree", ?address, ?task, ?regular, ?database, "Difference in storage trie deletion"); } - for (path, (task, regular)) in &mut storage_diff.storage_nodes { - debug!(target: "engine::tree", ?address, ?path, ?task, ?regular, "Difference in storage trie updates"); + for (path, EntryDiff { task, regular, database }) in &mut storage_diff.storage_nodes + { + debug!(target: "engine::tree", ?address, ?path, ?task, ?regular, ?database, "Difference in storage trie updates"); } - for (path, (task, regular)) in &storage_diff.removed_nodes { - debug!(target: "engine::tree", ?address, ?path, ?task, ?regular, "Difference in removed account trie nodes"); + for (path, EntryDiff { task, regular, database }) in &storage_diff.removed_nodes { + debug!(target: "engine::tree", ?address, ?path, ?task, ?regular, ?database, "Difference in removed account trie nodes"); } } } @@ -76,9 +84,9 @@ impl StorageTrieDiffEntry { #[derive(Debug, Default)] struct StorageTrieUpdatesDiff { - is_deleted: Option<(bool, bool)>, - storage_nodes: HashMap, Option)>, - removed_nodes: HashMap, + is_deleted: Option>, + storage_nodes: HashMap>>, + removed_nodes: HashMap>, } impl StorageTrieUpdatesDiff { @@ -112,10 +120,11 @@ pub(super) fn compare_trie_updates( .cloned() .collect::>() { - let (left, right) = (task.account_nodes.remove(&key), regular.account_nodes.remove(&key)); + let (task, regular) = (task.account_nodes.remove(&key), regular.account_nodes.remove(&key)); + let database = account_trie_cursor.seek_exact(key.clone())?.map(|x| x.1); - if !branch_nodes_equal(&mut account_trie_cursor, &key, left.as_ref(), right.as_ref())? { - diff.account_nodes.insert(key, (left, right)); + if !branch_nodes_equal(task.as_ref(), regular.as_ref(), database.as_ref())? { + diff.account_nodes.insert(key, EntryDiff { task, regular, database }); } } @@ -127,10 +136,11 @@ pub(super) fn compare_trie_updates( .cloned() .collect::>() { - let (left, right) = + let (task, regular) = (task.removed_nodes.contains(&key), regular.removed_nodes.contains(&key)); - if left != right && account_trie_cursor.seek_exact(key.clone())?.is_some() { - diff.removed_nodes.insert(key, (left, right)); + let database = account_trie_cursor.seek_exact(key.clone())?.is_none(); + if task != regular { + diff.removed_nodes.insert(key, EntryDiff { task, regular, database }); } } @@ -142,12 +152,13 @@ pub(super) fn compare_trie_updates( .copied() .collect::>() { - let (task, regular) = (task.storage_tries.remove(&key), regular.storage_tries.remove(&key)); + let (mut task, mut regular) = + (task.storage_tries.remove(&key), regular.storage_tries.remove(&key)); if task != regular { let mut storage_trie_cursor = trie_cursor_factory.storage_trie_cursor(key)?; - if let Some((left, right)) = task.as_ref().zip(regular.as_ref()) { + if let Some((task, regular)) = task.as_mut().zip(regular.as_mut()) { let storage_diff = - compare_storage_trie_updates(&mut storage_trie_cursor, left, right)?; + compare_storage_trie_updates(&mut storage_trie_cursor, task, regular)?; if storage_diff.has_differences() { diff.storage_tries.insert(key, StorageTrieDiffEntry::Value(storage_diff)); } @@ -168,12 +179,16 @@ pub(super) fn compare_trie_updates( fn compare_storage_trie_updates( trie_cursor: &mut impl TrieCursor, - task: &StorageTrieUpdates, - regular: &StorageTrieUpdates, + task: &mut StorageTrieUpdates, + regular: &mut StorageTrieUpdates, ) -> Result { + let database_deleted = trie_cursor.next()?.is_none(); let mut diff = StorageTrieUpdatesDiff { - is_deleted: (task.is_deleted != regular.is_deleted) - .then_some((task.is_deleted, regular.is_deleted)), + is_deleted: (task.is_deleted != regular.is_deleted).then_some(EntryDiff { + task: task.is_deleted, + regular: regular.is_deleted, + database: database_deleted, + }), ..Default::default() }; @@ -185,9 +200,10 @@ fn compare_storage_trie_updates( .cloned() .collect::>() { - let (left, right) = (task.storage_nodes.get(&key), regular.storage_nodes.get(&key)); - if !branch_nodes_equal(trie_cursor, &key, left, right)? { - diff.storage_nodes.insert(key, (left.cloned(), right.cloned())); + let (task, regular) = (task.storage_nodes.remove(&key), regular.storage_nodes.remove(&key)); + let database = trie_cursor.seek_exact(key.clone())?.map(|x| x.1); + if !branch_nodes_equal(task.as_ref(), regular.as_ref(), database.as_ref())? { + diff.storage_nodes.insert(key, EntryDiff { task, regular, database }); } } @@ -199,10 +215,11 @@ fn compare_storage_trie_updates( .cloned() .collect::>() { - let (left, right) = + let (task, regular) = (task.removed_nodes.contains(&key), regular.removed_nodes.contains(&key)); - if left != right && trie_cursor.seek_exact(key.clone())?.is_some() { - diff.removed_nodes.insert(key, (left, right)); + let database = trie_cursor.seek_exact(key.clone())?.map(|x| x.1).is_none(); + if task != regular { + diff.removed_nodes.insert(key, EntryDiff { task, regular, database }); } } @@ -246,10 +263,9 @@ fn adjust_trie_updates(trie_updates: TrieUpdates) -> TrieUpdates { /// /// Returns `true` if they are equal. fn branch_nodes_equal( - trie_cursor: &mut impl TrieCursor, - key: &Nibbles, task: Option<&BranchNodeCompact>, regular: Option<&BranchNodeCompact>, + database: Option<&BranchNodeCompact>, ) -> Result { Ok(match (task, regular) { (Some(task), Some(regular)) => { @@ -261,11 +277,10 @@ fn branch_nodes_equal( } (None, None) => true, _ => { - let db_branch_node = trie_cursor.seek_exact(key.clone())?.map(|x| x.1); if task.is_some() { - task == db_branch_node.as_ref() + task == database } else { - regular == db_branch_node.as_ref() + regular == database } } })