perf(trie): set trie mask bits directly (#13724)

This commit is contained in:
Roman Krasiuk
2025-01-08 13:49:39 +01:00
committed by GitHub
parent a3f8a9d38b
commit bd4947112d

View File

@ -700,9 +700,8 @@ impl<P> RevealedSparseTrie<P> {
.resize(buffers.branch_child_buf.len(), Default::default()); .resize(buffers.branch_child_buf.len(), Default::default());
let mut added_children = false; let mut added_children = false;
// TODO(alexey): set the `TrieMask` bits directly let mut tree_mask = TrieMask::default();
let mut tree_mask_values = Vec::new(); let mut hash_mask = TrieMask::default();
let mut hash_mask_values = Vec::new();
let mut hashes = Vec::new(); let mut hashes = Vec::new();
for (i, child_path) in buffers.branch_child_buf.iter().enumerate() { for (i, child_path) in buffers.branch_child_buf.iter().enumerate() {
if buffers.rlp_node_stack.last().is_some_and(|e| &e.0 == child_path) { if buffers.rlp_node_stack.last().is_some_and(|e| &e.0 == child_path) {
@ -711,18 +710,21 @@ impl<P> RevealedSparseTrie<P> {
// Update the masks only if we need to retain trie updates // Update the masks only if we need to retain trie updates
if retain_updates { if retain_updates {
// Set the trie mask // SAFETY: it's a child, so it's never empty
let tree_mask_value = if node_type.store_in_db_trie() { let last_child_nibble = child_path.last().unwrap();
// Determine whether we need to set trie mask bit.
let should_set_tree_mask_bit =
// A branch or an extension node explicitly set the // A branch or an extension node explicitly set the
// `store_in_db_trie` flag // `store_in_db_trie` flag
true node_type.store_in_db_trie() ||
} else {
// Set the flag according to whether a child node was // Set the flag according to whether a child node was
// pre-calculated (`calculated = false`), meaning that it wasn't // pre-calculated (`calculated = false`), meaning that it wasn't
// in the database // in the database
!calculated !calculated;
}; if should_set_tree_mask_bit {
tree_mask_values.push(tree_mask_value); tree_mask.set_bit(last_child_nibble);
}
// Set the hash mask. If a child node is a revealed branch node OR // Set the hash mask. If a child node is a revealed branch node OR
// is a blinded node that has its hash mask bit set according to the // is a blinded node that has its hash mask bit set according to the
@ -733,12 +735,11 @@ impl<P> RevealedSparseTrie<P> {
self.branch_node_hash_masks self.branch_node_hash_masks
.get(&path) .get(&path)
.is_some_and(|mask| { .is_some_and(|mask| {
mask.is_bit_set(child_path.last().unwrap()) mask.is_bit_set(last_child_nibble)
})) }))
}); });
let hash_mask_value = hash.is_some();
hash_mask_values.push(hash_mask_value);
if let Some(hash) = hash { if let Some(hash) = hash {
hash_mask.set_bit(last_child_nibble);
hashes.push(hash); hashes.push(hash);
} }
@ -746,16 +747,17 @@ impl<P> RevealedSparseTrie<P> {
target: "trie::sparse", target: "trie::sparse",
?path, ?path,
?child_path, ?child_path,
?tree_mask_value, tree_mask_bit_set = should_set_tree_mask_bit,
?hash_mask_value, hash_mask_bit_set = hash.is_some(),
"Updating branch node child masks" "Updating branch node child masks"
); );
} }
// Insert children in the resulting buffer in a normal order, // Insert children in the resulting buffer in a normal order,
// because initially we iterated in reverse. // because initially we iterated in reverse.
buffers.branch_value_stack_buf // SAFETY: i < len and len is never 0
[buffers.branch_child_buf.len() - i - 1] = child; let original_idx = buffers.branch_child_buf.len() - i - 1;
buffers.branch_value_stack_buf[original_idx] = child;
added_children = true; added_children = true;
} else { } else {
debug_assert!(!added_children); debug_assert!(!added_children);
@ -778,21 +780,6 @@ impl<P> RevealedSparseTrie<P> {
let store_in_db_trie_value = if let Some(updates) = let store_in_db_trie_value = if let Some(updates) =
self.updates.as_mut().filter(|_| retain_updates && !path.is_empty()) self.updates.as_mut().filter(|_| retain_updates && !path.is_empty())
{ {
let mut tree_mask_values = tree_mask_values.into_iter().rev();
let mut hash_mask_values = hash_mask_values.into_iter().rev();
let mut tree_mask = TrieMask::default();
let mut hash_mask = TrieMask::default();
for (i, child) in branch_node_ref.children() {
if child.is_some() {
if hash_mask_values.next().unwrap() {
hash_mask.set_bit(i);
}
if tree_mask_values.next().unwrap() {
tree_mask.set_bit(i);
}
}
}
// Store in DB trie if there are either any children that are stored in the // Store in DB trie if there are either any children that are stored in the
// DB trie, or any children represent hashed values // DB trie, or any children represent hashed values
let store_in_db_trie = !tree_mask.is_empty() || !hash_mask.is_empty(); let store_in_db_trie = !tree_mask.is_empty() || !hash_mask.is_empty();