mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
fix(trie): use correct store_in_db_trie value for sparse extension nodes (#13826)
This commit is contained in:
@ -381,6 +381,7 @@ impl<P> RevealedSparseTrie<P> {
|
|||||||
// Memoize the hash of a previously blinded node in a new extension
|
// Memoize the hash of a previously blinded node in a new extension
|
||||||
// node.
|
// node.
|
||||||
hash: Some(*hash),
|
hash: Some(*hash),
|
||||||
|
store_in_db_trie: None,
|
||||||
});
|
});
|
||||||
self.reveal_node_or_hash(child_path, &ext.child)?;
|
self.reveal_node_or_hash(child_path, &ext.child)?;
|
||||||
}
|
}
|
||||||
@ -602,14 +603,14 @@ impl<P> RevealedSparseTrie<P> {
|
|||||||
while let Some((mut path, level)) = paths.pop() {
|
while let Some((mut path, level)) = paths.pop() {
|
||||||
match self.nodes.get(&path).unwrap() {
|
match self.nodes.get(&path).unwrap() {
|
||||||
SparseNode::Empty | SparseNode::Hash(_) => {}
|
SparseNode::Empty | SparseNode::Hash(_) => {}
|
||||||
SparseNode::Leaf { hash, .. } => {
|
SparseNode::Leaf { key: _, hash } => {
|
||||||
if hash.is_some() && !prefix_set.contains(&path) {
|
if hash.is_some() && !prefix_set.contains(&path) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
targets.push(path);
|
targets.push(path);
|
||||||
}
|
}
|
||||||
SparseNode::Extension { key, hash } => {
|
SparseNode::Extension { key, hash, store_in_db_trie: _ } => {
|
||||||
if hash.is_some() && !prefix_set.contains(&path) {
|
if hash.is_some() && !prefix_set.contains(&path) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -621,7 +622,7 @@ impl<P> RevealedSparseTrie<P> {
|
|||||||
paths.push((path, level + 1));
|
paths.push((path, level + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SparseNode::Branch { state_mask, hash, .. } => {
|
SparseNode::Branch { state_mask, hash, store_in_db_trie: _ } => {
|
||||||
if hash.is_some() && !prefix_set.contains(&path) {
|
if hash.is_some() && !prefix_set.contains(&path) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -673,26 +674,37 @@ impl<P> RevealedSparseTrie<P> {
|
|||||||
(rlp_node, SparseNodeType::Leaf)
|
(rlp_node, SparseNodeType::Leaf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SparseNode::Extension { key, hash } => {
|
SparseNode::Extension { key, hash, store_in_db_trie } => {
|
||||||
let mut child_path = path.clone();
|
let mut child_path = path.clone();
|
||||||
child_path.extend_from_slice_unchecked(key);
|
child_path.extend_from_slice_unchecked(key);
|
||||||
if let Some(hash) = hash.filter(|_| !prefix_set_contains(&path)) {
|
if let Some((hash, store_in_db_trie)) =
|
||||||
(
|
hash.zip(*store_in_db_trie).filter(|_| !prefix_set_contains(&path))
|
||||||
RlpNode::word_rlp(&hash),
|
{
|
||||||
SparseNodeType::Extension { store_in_db_trie: true },
|
(RlpNode::word_rlp(&hash), SparseNodeType::Extension { store_in_db_trie })
|
||||||
)
|
|
||||||
} else if buffers.rlp_node_stack.last().is_some_and(|e| e.0 == child_path) {
|
} else if buffers.rlp_node_stack.last().is_some_and(|e| e.0 == child_path) {
|
||||||
let (_, child, child_node_type) = buffers.rlp_node_stack.pop().unwrap();
|
let (_, child, child_node_type) = buffers.rlp_node_stack.pop().unwrap();
|
||||||
self.rlp_buf.clear();
|
self.rlp_buf.clear();
|
||||||
let rlp_node = ExtensionNodeRef::new(key, &child).rlp(&mut self.rlp_buf);
|
let rlp_node = ExtensionNodeRef::new(key, &child).rlp(&mut self.rlp_buf);
|
||||||
*hash = rlp_node.as_hash();
|
*hash = rlp_node.as_hash();
|
||||||
|
|
||||||
|
let store_in_db_trie_value = child_node_type.store_in_db_trie();
|
||||||
|
|
||||||
|
trace!(
|
||||||
|
target: "trie::sparse",
|
||||||
|
?path,
|
||||||
|
?child_path,
|
||||||
|
?child_node_type,
|
||||||
|
"Extension node"
|
||||||
|
);
|
||||||
|
|
||||||
|
*store_in_db_trie = Some(store_in_db_trie_value);
|
||||||
|
|
||||||
(
|
(
|
||||||
rlp_node,
|
rlp_node,
|
||||||
SparseNodeType::Extension {
|
SparseNodeType::Extension {
|
||||||
// Inherit the `store_in_db_trie` flag from the child node, which is
|
// Inherit the `store_in_db_trie` flag from the child node, which is
|
||||||
// always the branch node
|
// always the branch node
|
||||||
store_in_db_trie: child_node_type.store_in_db_trie(),
|
store_in_db_trie: store_in_db_trie_value,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@ -1228,7 +1240,14 @@ pub enum SparseNode {
|
|||||||
key: Nibbles,
|
key: Nibbles,
|
||||||
/// Pre-computed hash of the sparse node.
|
/// Pre-computed hash of the sparse node.
|
||||||
/// Can be reused unless this trie path has been updated.
|
/// Can be reused unless this trie path has been updated.
|
||||||
|
///
|
||||||
|
/// If [`None`], then the value is not known and should be calculated from scratch.
|
||||||
hash: Option<B256>,
|
hash: Option<B256>,
|
||||||
|
/// Pre-computed flag indicating whether the trie node should be stored in the database.
|
||||||
|
/// Can be reused unless this trie path has been updated.
|
||||||
|
///
|
||||||
|
/// If [`None`], then the value is not known and should be calculated from scratch.
|
||||||
|
store_in_db_trie: Option<bool>,
|
||||||
},
|
},
|
||||||
/// Sparse branch node with state mask.
|
/// Sparse branch node with state mask.
|
||||||
Branch {
|
Branch {
|
||||||
@ -1236,9 +1255,13 @@ pub enum SparseNode {
|
|||||||
state_mask: TrieMask,
|
state_mask: TrieMask,
|
||||||
/// Pre-computed hash of the sparse node.
|
/// Pre-computed hash of the sparse node.
|
||||||
/// Can be reused unless this trie path has been updated.
|
/// Can be reused unless this trie path has been updated.
|
||||||
|
///
|
||||||
|
/// If [`None`], then the value is not known and should be calculated from scratch.
|
||||||
hash: Option<B256>,
|
hash: Option<B256>,
|
||||||
/// Pre-computed flag indicating whether the trie node should be stored in the database.
|
/// Pre-computed flag indicating whether the trie node should be stored in the database.
|
||||||
/// Can be reused unless this trie path has been updated.
|
/// Can be reused unless this trie path has been updated.
|
||||||
|
///
|
||||||
|
/// If [`None`], then the value is not known and should be calculated from scratch.
|
||||||
store_in_db_trie: Option<bool>,
|
store_in_db_trie: Option<bool>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -1270,7 +1293,7 @@ impl SparseNode {
|
|||||||
|
|
||||||
/// Create new [`SparseNode::Extension`] from the key slice.
|
/// Create new [`SparseNode::Extension`] from the key slice.
|
||||||
pub const fn new_ext(key: Nibbles) -> Self {
|
pub const fn new_ext(key: Nibbles) -> Self {
|
||||||
Self::Extension { key, hash: None }
|
Self::Extension { key, hash: None, store_in_db_trie: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new [`SparseNode::Leaf`] from leaf key and value.
|
/// Create new [`SparseNode::Leaf`] from leaf key and value.
|
||||||
@ -2308,7 +2331,7 @@ mod tests {
|
|||||||
// Check that the root extension node exists
|
// Check that the root extension node exists
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
sparse.nodes.get(&Nibbles::default()),
|
sparse.nodes.get(&Nibbles::default()),
|
||||||
Some(SparseNode::Extension { key, hash: None }) if *key == Nibbles::from_nibbles([0x00])
|
Some(SparseNode::Extension { key, hash: None, store_in_db_trie: None }) if *key == Nibbles::from_nibbles([0x00])
|
||||||
);
|
);
|
||||||
|
|
||||||
// Insert the leaf with a different prefix
|
// Insert the leaf with a different prefix
|
||||||
|
|||||||
Reference in New Issue
Block a user