diff --git a/mpt_trie/src/debug_tools/query.rs b/mpt_trie/src/debug_tools/query.rs index 0fb6ade96..dcfff397d 100644 --- a/mpt_trie/src/debug_tools/query.rs +++ b/mpt_trie/src/debug_tools/query.rs @@ -66,19 +66,19 @@ pub struct DebugQueryParamsBuilder { impl DebugQueryParamsBuilder { /// Defaults to `true`. - pub const fn print_key_pieces(mut self, enabled: bool) -> Self { + pub const fn include_key_pieces(mut self, enabled: bool) -> Self { self.params.include_key_piece_per_node = enabled; self } /// Defaults to `true`. - pub const fn print_node_type(mut self, enabled: bool) -> Self { + pub const fn include_node_type(mut self, enabled: bool) -> Self { self.params.include_node_type = enabled; self } /// Defaults to `false`. - pub const fn print_node_specific_values(mut self, enabled: bool) -> Self { + pub const fn include_node_specific_values(mut self, enabled: bool) -> Self { self.params.include_node_specific_values = enabled; self } diff --git a/mpt_trie/src/trie_subsets.rs b/mpt_trie/src/trie_subsets.rs index 13e9d0d9f..eadb6b3e2 100644 --- a/mpt_trie/src/trie_subsets.rs +++ b/mpt_trie/src/trie_subsets.rs @@ -12,6 +12,7 @@ use log::trace; use thiserror::Error; use crate::{ + debug_tools::query::{get_path_from_query, DebugQueryOutput, DebugQueryParamsBuilder}, nibbles::Nibbles, partial_trie::{Node, PartialTrie, WrappedNode}, trie_hashing::EncodedNode, @@ -21,13 +22,10 @@ use crate::{ /// The output type of trie_subset operations. pub type SubsetTrieResult = Result; -/// Errors that may occur when creating a subset [`PartialTrie`]. +/// We encountered a `hash` node when marking nodes during sub-trie creation. #[derive(Clone, Debug, Error, Hash)] -pub enum SubsetTrieError { - #[error("Tried to mark nodes in a tracked trie for a key that does not exist! (Key: {0}, trie: {1})")] - /// The key does not exist in the trie. - UnexpectedKey(Nibbles, String), -} +#[error("Encountered a hash node when marking nodes to not hash when traversing a key to not hash!\nPath: {0}")] +pub struct SubsetTrieError(DebugQueryOutput); #[derive(Debug)] enum TrackedNodeIntern { @@ -256,8 +254,17 @@ where N: PartialTrie, K: Into, { - for k in keys_involved { - mark_nodes_that_are_needed(tracked_trie, &mut k.into())?; + for mut k in keys_involved.map(|k| k.into()) { + mark_nodes_that_are_needed(tracked_trie, &mut k).map_err(|_| { + // We need to unwind back to this callsite in order to produce the actual error. + let query = DebugQueryParamsBuilder::default() + .include_node_specific_values(true) + .build(k); + + let res = get_path_from_query(&tracked_trie.info.underlying_node, query); + + SubsetTrieError(res) + })?; } Ok(create_partial_trie_subset_from_tracked_trie(tracked_trie)) @@ -270,10 +277,14 @@ where /// - For the key `0x1`, the marked nodes would be [B(0x), B(0x1)]. /// - For the key `0x12`, the marked nodes still would be [B(0x), B(0x1)]. /// - For the key `0x123`, the marked nodes would be [B(0x), B(0x1), L(0x123)]. +/// +/// Also note that we can't construct the error until we back out of this +/// recursive function. We need to know the full key that hit the hash +/// node, and that's only available at the initial call site. fn mark_nodes_that_are_needed( trie: &mut TrackedNode, curr_nibbles: &mut Nibbles, -) -> SubsetTrieResult<()> { +) -> Result<(), ()> { trace!( "Sub-trie marking at {:x}, (type: {})", curr_nibbles, @@ -286,10 +297,7 @@ fn mark_nodes_that_are_needed( } TrackedNodeIntern::Hash => match curr_nibbles.is_empty() { false => { - return Err(SubsetTrieError::UnexpectedKey( - *curr_nibbles, - format!("{:?}", trie), - )); + return Err(()); } true => { trie.info.touched = true;