-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: move updated skeleton and original skeleton to sub director…
…ies (#57)
- Loading branch information
1 parent
869bec1
commit 1e9eb88
Showing
12 changed files
with
218 additions
and
217 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,5 @@ | ||
pub mod errors; | ||
pub mod filled_tree; | ||
pub mod original_skeleton_calc; | ||
pub mod original_skeleton_node; | ||
pub mod original_skeleton_tree; | ||
pub mod types; | ||
pub mod updated_skeleton_node; | ||
pub mod updated_skeleton_tree; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
crates/committer/src/patricia_merkle_tree/filled_tree/node_serde.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 3 additions & 29 deletions
32
crates/committer/src/patricia_merkle_tree/original_skeleton_tree.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,3 @@ | ||
use std::collections::HashMap; | ||
|
||
use crate::hash::hash_trait::HashOutput; | ||
use crate::patricia_merkle_tree::errors::OriginalSkeletonTreeError; | ||
use crate::patricia_merkle_tree::types::{LeafDataTrait, NodeIndex, TreeHeight}; | ||
use crate::patricia_merkle_tree::updated_skeleton_tree::UpdatedSkeletonTree; | ||
use crate::storage::storage_trait::Storage; | ||
|
||
#[allow(dead_code)] | ||
pub(crate) type OriginalSkeletonTreeResult<T> = Result<T, OriginalSkeletonTreeError>; | ||
|
||
/// Consider a Patricia-Merkle Tree which should be updated with new leaves. | ||
/// This trait represents the structure of the subtree which will be modified in the | ||
/// update. It also contains the hashes (for edge siblings - also the edge data) of the Sibling | ||
/// nodes on the Merkle paths from the updated leaves to the root. | ||
pub(crate) trait OriginalSkeletonTree<L: LeafDataTrait + std::clone::Clone> { | ||
fn create_tree( | ||
storage: &impl Storage, | ||
leaf_indices: &[NodeIndex], | ||
root_hash: HashOutput, | ||
tree_height: TreeHeight, | ||
) -> OriginalSkeletonTreeResult<impl OriginalSkeletonTree<L>>; | ||
|
||
/// Computes and returns updated skeleton tree. | ||
fn compute_updated_skeleton_tree( | ||
&self, | ||
index_to_updated_leaf: HashMap<NodeIndex, L>, | ||
) -> OriginalSkeletonTreeResult<impl UpdatedSkeletonTree<L>>; | ||
} | ||
pub mod node; | ||
pub mod original_skeleton_calc; | ||
pub mod tree; |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 3 additions & 3 deletions
6
...erkle_tree/original_skeleton_calc_test.rs → ...leton_tree/original_skeleton_calc_test.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
crates/committer/src/patricia_merkle_tree/original_skeleton_tree/tree.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
use std::collections::HashMap; | ||
|
||
use crate::hash::hash_trait::HashOutput; | ||
use crate::patricia_merkle_tree::errors::OriginalSkeletonTreeError; | ||
use crate::patricia_merkle_tree::types::{LeafDataTrait, NodeIndex, TreeHeight}; | ||
use crate::patricia_merkle_tree::updated_skeleton_tree::tree::UpdatedSkeletonTree; | ||
use crate::storage::storage_trait::Storage; | ||
|
||
#[allow(dead_code)] | ||
pub(crate) type OriginalSkeletonTreeResult<T> = Result<T, OriginalSkeletonTreeError>; | ||
|
||
/// Consider a Patricia-Merkle Tree which should be updated with new leaves. | ||
/// This trait represents the structure of the subtree which will be modified in the | ||
/// update. It also contains the hashes (for edge siblings - also the edge data) of the Sibling | ||
/// nodes on the Merkle paths from the updated leaves to the root. | ||
pub(crate) trait OriginalSkeletonTree<L: LeafDataTrait + std::clone::Clone> { | ||
fn create_tree( | ||
storage: &impl Storage, | ||
leaf_indices: &[NodeIndex], | ||
root_hash: HashOutput, | ||
tree_height: TreeHeight, | ||
) -> OriginalSkeletonTreeResult<impl OriginalSkeletonTree<L>>; | ||
|
||
/// Computes and returns updated skeleton tree. | ||
fn compute_updated_skeleton_tree( | ||
&self, | ||
index_to_updated_leaf: HashMap<NodeIndex, L>, | ||
) -> OriginalSkeletonTreeResult<impl UpdatedSkeletonTree<L>>; | ||
} |
174 changes: 2 additions & 172 deletions
174
crates/committer/src/patricia_merkle_tree/updated_skeleton_tree.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,172 +1,2 @@ | ||
use std::collections::HashMap; | ||
use std::sync::{Arc, Mutex}; | ||
|
||
use crate::hash::hash_trait::{HashFunction, HashOutput}; | ||
use crate::patricia_merkle_tree::errors::UpdatedSkeletonTreeError; | ||
use crate::patricia_merkle_tree::filled_tree::tree::FilledTree; | ||
use crate::patricia_merkle_tree::types::{LeafDataTrait, NodeIndex, TreeHashFunction}; | ||
use crate::patricia_merkle_tree::updated_skeleton_node::UpdatedSkeletonNode; | ||
use crate::types::Felt; | ||
|
||
use crate::patricia_merkle_tree::filled_tree::node::{BinaryData, FilledNode, NodeData}; | ||
use crate::patricia_merkle_tree::filled_tree::tree::FilledTreeImpl; | ||
use crate::patricia_merkle_tree::types::EdgeData; | ||
|
||
#[cfg(test)] | ||
#[path = "updated_skeleton_tree_test.rs"] | ||
pub mod updated_skeleton_tree_test; | ||
|
||
/// Consider a Patricia-Merkle Tree which has been updated with new leaves. | ||
/// This trait represents the structure of the subtree which was modified in the update. | ||
/// It also contains the hashes of the Sibling nodes on the Merkle paths from the updated leaves | ||
/// to the root. | ||
pub(crate) trait UpdatedSkeletonTree<L: LeafDataTrait + std::clone::Clone> { | ||
/// Computes and returns the filled tree. | ||
fn compute_filled_tree<H: HashFunction, TH: TreeHashFunction<L, H>>( | ||
&self, | ||
) -> Result<impl FilledTree<L>, UpdatedSkeletonTreeError<L>>; | ||
} | ||
|
||
pub(crate) struct UpdatedSkeletonTreeImpl<L: LeafDataTrait + std::clone::Clone> { | ||
skeleton_tree: HashMap<NodeIndex, UpdatedSkeletonNode<L>>, | ||
} | ||
|
||
impl<L: LeafDataTrait + std::clone::Clone + std::marker::Sync + std::marker::Send> | ||
UpdatedSkeletonTreeImpl<L> | ||
{ | ||
fn get_node( | ||
&self, | ||
index: NodeIndex, | ||
) -> Result<&UpdatedSkeletonNode<L>, UpdatedSkeletonTreeError<L>> { | ||
match self.skeleton_tree.get(&index) { | ||
Some(node) => Ok(node), | ||
None => Err(UpdatedSkeletonTreeError::MissingNode(index)), | ||
} | ||
} | ||
|
||
/// Writes the hash and data to the output map. The writing is done in a thread-safe manner with | ||
/// interior mutability to avoid thread contention. | ||
fn write_to_output_map( | ||
output_map: Arc<HashMap<NodeIndex, Mutex<Option<FilledNode<L>>>>>, | ||
index: NodeIndex, | ||
hash: HashOutput, | ||
data: NodeData<L>, | ||
) -> Result<(), UpdatedSkeletonTreeError<L>> { | ||
match output_map.get(&index) { | ||
Some(node) => { | ||
let mut node = node.lock().map_err(|_| { | ||
UpdatedSkeletonTreeError::PoisonedLock("Cannot lock node.".to_owned()) | ||
})?; | ||
match node.take() { | ||
Some(existing_node) => Err(UpdatedSkeletonTreeError::DoubleUpdate { | ||
index, | ||
existing_value: Box::new(existing_node), | ||
}), | ||
None => { | ||
*node = Some(FilledNode { hash, data }); | ||
Ok(()) | ||
} | ||
} | ||
} | ||
None => Err(UpdatedSkeletonTreeError::MissingNode(index)), | ||
} | ||
} | ||
|
||
fn initialize_with_placeholders(&self) -> HashMap<NodeIndex, Mutex<Option<FilledNode<L>>>> { | ||
let mut filled_tree_map = HashMap::new(); | ||
for (index, node) in &self.skeleton_tree { | ||
if !matches!(node, UpdatedSkeletonNode::Sibling(_)) { | ||
filled_tree_map.insert(*index, Mutex::new(None)); | ||
} | ||
} | ||
filled_tree_map | ||
} | ||
|
||
fn remove_arc_mutex_and_option( | ||
hash_map_in: Arc<HashMap<NodeIndex, Mutex<Option<FilledNode<L>>>>>, | ||
) -> Result<HashMap<NodeIndex, FilledNode<L>>, UpdatedSkeletonTreeError<L>> { | ||
let mut hash_map_out = HashMap::new(); | ||
for (key, value) in hash_map_in.iter() { | ||
let mut value = value.lock().map_err(|_| { | ||
UpdatedSkeletonTreeError::PoisonedLock("Cannot lock node.".to_owned()) | ||
})?; | ||
match value.take() { | ||
Some(value) => { | ||
hash_map_out.insert(*key, value); | ||
} | ||
None => return Err(UpdatedSkeletonTreeError::MissingNode(*key)), | ||
} | ||
} | ||
Ok(hash_map_out) | ||
} | ||
|
||
fn compute_filled_tree_rec<H: HashFunction, TH: TreeHashFunction<L, H>>( | ||
&self, | ||
index: NodeIndex, | ||
output_map: Arc<HashMap<NodeIndex, Mutex<Option<FilledNode<L>>>>>, | ||
) -> Result<HashOutput, UpdatedSkeletonTreeError<L>> { | ||
let node = self.get_node(index)?; | ||
match node { | ||
UpdatedSkeletonNode::Binary => { | ||
let left_index = NodeIndex(index.0 * Felt::TWO); | ||
let right_index = NodeIndex(left_index.0 + Felt::ONE); | ||
|
||
let (left_hash, right_hash) = rayon::join( | ||
|| self.compute_filled_tree_rec::<H, TH>(left_index, Arc::clone(&output_map)), | ||
|| self.compute_filled_tree_rec::<H, TH>(right_index, Arc::clone(&output_map)), | ||
); | ||
|
||
let data = NodeData::Binary(BinaryData { | ||
left_hash: left_hash?, | ||
right_hash: right_hash?, | ||
}); | ||
|
||
let hash_value = TH::compute_node_hash(&data); | ||
Self::write_to_output_map(output_map, index, hash_value, data)?; | ||
Ok(hash_value) | ||
} | ||
UpdatedSkeletonNode::Edge { path_to_bottom } => { | ||
let bottom_node_index = NodeIndex::compute_bottom_index(index, path_to_bottom); | ||
let bottom_hash = self | ||
.compute_filled_tree_rec::<H, TH>(bottom_node_index, Arc::clone(&output_map))?; | ||
let data = NodeData::Edge(EdgeData { | ||
path_to_bottom: *path_to_bottom, | ||
bottom_hash, | ||
}); | ||
let hash_value = TH::compute_node_hash(&data); | ||
Self::write_to_output_map(output_map, index, hash_value, data)?; | ||
Ok(hash_value) | ||
} | ||
UpdatedSkeletonNode::Sibling(hash_result) => Ok(*hash_result), | ||
UpdatedSkeletonNode::Leaf(node_data) => { | ||
let data = NodeData::Leaf(node_data.clone()); | ||
let hash_value = TH::compute_node_hash(&data); | ||
Self::write_to_output_map(output_map, index, hash_value, data)?; | ||
Ok(hash_value) | ||
} | ||
} | ||
} | ||
} | ||
|
||
impl<L: LeafDataTrait + std::clone::Clone + std::marker::Sync + std::marker::Send> | ||
UpdatedSkeletonTree<L> for UpdatedSkeletonTreeImpl<L> | ||
{ | ||
fn compute_filled_tree<H: HashFunction, TH: TreeHashFunction<L, H>>( | ||
&self, | ||
) -> Result<FilledTreeImpl<L>, UpdatedSkeletonTreeError<L>> { | ||
// Compute the filled tree in two steps: | ||
// 1. Create a map containing the tree structure without hash values. | ||
// 2. Fill in the hash values. | ||
let filled_tree_map = Arc::new(self.initialize_with_placeholders()); | ||
|
||
self.compute_filled_tree_rec::<H, TH>( | ||
NodeIndex::root_index(), | ||
Arc::clone(&filled_tree_map), | ||
)?; | ||
|
||
// Create and return a new FilledTreeImpl from the hashmap. | ||
Ok(FilledTreeImpl::new(Self::remove_arc_mutex_and_option( | ||
filled_tree_map, | ||
)?)) | ||
} | ||
} | ||
pub mod node; | ||
pub mod tree; |
File renamed without changes.
Oops, something went wrong.