Skip to content

Commit

Permalink
also save db value in diffs
Browse files Browse the repository at this point in the history
  • Loading branch information
shekhirin committed Jan 10, 2025
1 parent eb5b066 commit cc26cf2
Showing 1 changed file with 54 additions and 39 deletions.
93 changes: 54 additions & 39 deletions crates/engine/tree/src/tree/trie_updates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,17 @@ use reth_trie::{
use reth_trie_db::DatabaseTrieCursorFactory;
use tracing::debug;

#[derive(Debug)]
struct EntryDiff<T> {
task: T,
regular: T,
database: T,
}

#[derive(Debug, Default)]
struct TrieUpdatesDiff {
account_nodes: HashMap<Nibbles, (Option<BranchNodeCompact>, Option<BranchNodeCompact>)>,
removed_nodes: HashMap<Nibbles, (bool, bool)>,
account_nodes: HashMap<Nibbles, EntryDiff<Option<BranchNodeCompact>>>,
removed_nodes: HashMap<Nibbles, EntryDiff<bool>>,
storage_tries: HashMap<B256, StorageTrieDiffEntry>,
}

Expand All @@ -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 {
Expand All @@ -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");
}
}
}
Expand All @@ -76,9 +84,9 @@ impl StorageTrieDiffEntry {

#[derive(Debug, Default)]
struct StorageTrieUpdatesDiff {
is_deleted: Option<(bool, bool)>,
storage_nodes: HashMap<Nibbles, (Option<BranchNodeCompact>, Option<BranchNodeCompact>)>,
removed_nodes: HashMap<Nibbles, (bool, bool)>,
is_deleted: Option<EntryDiff<bool>>,
storage_nodes: HashMap<Nibbles, EntryDiff<Option<BranchNodeCompact>>>,
removed_nodes: HashMap<Nibbles, EntryDiff<bool>>,
}

impl StorageTrieUpdatesDiff {
Expand Down Expand Up @@ -112,10 +120,11 @@ pub(super) fn compare_trie_updates(
.cloned()
.collect::<HashSet<_>>()
{
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 });
}
}

Expand All @@ -127,10 +136,11 @@ pub(super) fn compare_trie_updates(
.cloned()
.collect::<HashSet<_>>()
{
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 });
}
}

Expand All @@ -142,12 +152,13 @@ pub(super) fn compare_trie_updates(
.copied()
.collect::<HashSet<_>>()
{
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));
}
Expand All @@ -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<StorageTrieUpdatesDiff, DatabaseError> {
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()
};

Expand All @@ -185,9 +200,10 @@ fn compare_storage_trie_updates(
.cloned()
.collect::<HashSet<_>>()
{
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 });
}
}

Expand All @@ -199,10 +215,11 @@ fn compare_storage_trie_updates(
.cloned()
.collect::<HashSet<_>>()
{
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 });
}
}

Expand Down Expand Up @@ -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<bool, DatabaseError> {
Ok(match (task, regular) {
(Some(task), Some(regular)) => {
Expand All @@ -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
}
}
})
Expand Down

0 comments on commit cc26cf2

Please sign in to comment.