Skip to content

Commit

Permalink
Merge pull request #1046 from 0xPolygonMiden/bobbin-tsmt-delete
Browse files Browse the repository at this point in the history
Implement TSMT delete procedures
  • Loading branch information
bobbinth authored Aug 29, 2023
2 parents 0d47b0e + bdc7109 commit 5adec34
Show file tree
Hide file tree
Showing 9 changed files with 914 additions and 56 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
- Added `TraceLenSummary` struct which holds information about traces lengths to the `ExecutionTrace` (#1029).
- Imposed the 2^32 limit for the memory addresses used in the memory chiplet (#1049).

#### Stdlib
- Completed `std::collections::smt` module by implementing `insert` and `set` procedures (#1036, #1038, #1046).

## 0.6.1 (2023-06-29)

- Fixed `no-std` compilation for `miden-core`, `miden-assembly`, and `miden-processor` crates.
Expand Down
3 changes: 3 additions & 0 deletions core/src/operations/decorators/advice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ pub enum AdviceInjector {
/// - Simple insert at depth 16: [d0, d1, ONE (is_simple_insert), ZERO (is_update)]
/// - Simple insert at depth 32 or 48: [d0, d1, ONE (is_simple_insert), ZERO (is_update), P_NODE]
/// - Complex insert: [f0, f1, ZERO (is_simple_insert), ZERO (is_update), E_KEY, E_VALUE]
/// - Delete against an empty subtree: [d0, d1, ZERO (is_leaf), ONE (key_not_set)]
/// - Delete against another leaf: [d0, d1, ONE (is_leaf), ONE (key_not_set), KEY, VALUE]
/// - Delete against own leaf: [ZERO, ZERO, ZERO, ZERO (key_not_set), NEW_ROOT, OLD_VALUE]
///
/// Where:
/// - ROOT and NEW_ROOT are the roots of the TSMT before and after the insert respectively.
Expand Down
44 changes: 34 additions & 10 deletions processor/src/advice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ pub trait AdviceProvider {
/// Returns an error if the value specified by the advice source cannot be obtained.
fn push_stack(&mut self, source: AdviceSource) -> Result<(), ExecutionError>;

// ADVICE MAP
// --------------------------------------------------------------------------------------------

/// Returns a reference to the value(s) associated with the specified key in the advice map.
fn get_mapped_values(&self, key: &[u8; 32]) -> Option<&[Felt]>;

/// Inserts the provided value into the advice map under the specified key.
///
/// The values in the advice map can be moved onto the advice stack by invoking
Expand All @@ -101,13 +107,7 @@ pub trait AdviceProvider {
/// are replaced with the specified values.
fn insert_into_map(&mut self, key: Word, values: Vec<Felt>) -> Result<(), ExecutionError>;

// ADVICE MAP
// --------------------------------------------------------------------------------------------

/// Returns a reference to the value(s) associated with the specified key in the advice map.
fn get_mapped_values(&self, key: &[u8; 32]) -> Option<&[Felt]>;

// ADVISE SETS
// MERKLE STORE
// --------------------------------------------------------------------------------------------

/// Returns a node at the specified depth and index in a Merkle tree with the given root.
Expand Down Expand Up @@ -152,8 +152,23 @@ pub trait AdviceProvider {
index: &Felt,
) -> Result<u8, ExecutionError>;

/// Returns node value and index of a leaf node in the subtree of the specified root, if and
/// only if this is the only leaf in the entire subtree. Otherwise, None is returned.
///
/// The root itself is assumed to be located at the specified index in a tree with the provided
/// depth.
///
/// # Errors
/// Returns an error if a three for the specified root does not exist in the advice provider.
fn find_lone_leaf(
&self,
root: Word,
root_index: NodeIndex,
tree_depth: u8,
) -> Result<Option<(NodeIndex, Word)>, ExecutionError>;

/// Updates a node at the specified depth and index in a Merkle tree with the specified root;
/// returns the Merkle path from the updated node to the new root.
/// returns the Merkle path from the updated node to the new root, together with the new root.
///
/// The tree is cloned prior to the update. Thus, the advice provider retains the original and
/// the updated tree.
Expand All @@ -171,7 +186,7 @@ pub trait AdviceProvider {
depth: &Felt,
index: &Felt,
value: Word,
) -> Result<MerklePath, ExecutionError>;
) -> Result<(MerklePath, Word), ExecutionError>;

/// Creates a new Merkle tree in the advice provider by combining Merkle trees with the
/// specified roots. The root of the new tree is defined as `hash(left_root, right_root)`.
Expand Down Expand Up @@ -261,13 +276,22 @@ where
T::get_leaf_depth(self, root, tree_depth, index)
}

fn find_lone_leaf(
&self,
root: Word,
root_index: NodeIndex,
tree_depth: u8,
) -> Result<Option<(NodeIndex, Word)>, ExecutionError> {
T::find_lone_leaf(self, root, root_index, tree_depth)
}

fn update_merkle_node(
&mut self,
root: Word,
depth: &Felt,
index: &Felt,
value: Word,
) -> Result<MerklePath, ExecutionError> {
) -> Result<(MerklePath, Word), ExecutionError> {
T::update_merkle_node(self, root, depth, index, value)
}

Expand Down
41 changes: 31 additions & 10 deletions processor/src/advice/providers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,18 +103,19 @@ where
Ok(())
}

fn insert_into_map(&mut self, key: Word, values: Vec<Felt>) -> Result<(), ExecutionError> {
self.map.insert(key.into_bytes(), values);
Ok(())
}

// ADVICE MAP
// --------------------------------------------------------------------------------------------

fn get_mapped_values(&self, key: &[u8; 32]) -> Option<&[Felt]> {
self.map.get(key).map(|v| v.as_slice())
}

// ADVISE SETS
fn insert_into_map(&mut self, key: Word, values: Vec<Felt>) -> Result<(), ExecutionError> {
self.map.insert(key.into_bytes(), values);
Ok(())
}

// MERKLE STORE
// --------------------------------------------------------------------------------------------

fn get_tree_node(
Expand Down Expand Up @@ -166,13 +167,25 @@ where
.map_err(ExecutionError::MerkleStoreLookupFailed)
}

fn find_lone_leaf(
&self,
root: Word,
root_index: NodeIndex,
tree_depth: u8,
) -> Result<Option<(NodeIndex, Word)>, ExecutionError> {
self.store
.find_lone_leaf(root.into(), root_index, tree_depth)
.map(|leaf| leaf.map(|(index, leaf)| (index, leaf.into())))
.map_err(ExecutionError::MerkleStoreLookupFailed)
}

fn update_merkle_node(
&mut self,
root: Word,
depth: &Felt,
index: &Felt,
value: Word,
) -> Result<MerklePath, ExecutionError> {
) -> Result<(MerklePath, Word), ExecutionError> {
let node_index = NodeIndex::from_elements(depth, index).map_err(|_| {
ExecutionError::InvalidTreeNodeIndex {
depth: *depth,
Expand All @@ -181,7 +194,7 @@ where
})?;
self.store
.set_node(root.into(), node_index, value.into())
.map(|root| root.path)
.map(|root| (root.path, root.root.into()))
.map_err(ExecutionError::MerkleStoreUpdateFailed)
}

Expand Down Expand Up @@ -289,7 +302,11 @@ impl AdviceProvider for MemAdviceProvider {
self.provider.get_leaf_depth(root, tree_depth, index)
}

fn update_merkle_node(&mut self, root: Word, depth: &Felt, index: &Felt, value: Word) -> Result<MerklePath, ExecutionError> {
fn find_lone_leaf(&self, root: Word, root_index: NodeIndex, tree_depth: u8) -> Result<Option<(NodeIndex, Word)>, ExecutionError> {
self.provider.find_lone_leaf(root, root_index, tree_depth)
}

fn update_merkle_node(&mut self, root: Word, depth: &Felt, index: &Felt, value: Word) -> Result<(MerklePath, Word), ExecutionError> {
self.provider.update_merkle_node(root, depth, index, value)
}

Expand Down Expand Up @@ -414,7 +431,11 @@ impl AdviceProvider for RecAdviceProvider {
self.provider.get_leaf_depth(root, tree_depth, index)
}

fn update_merkle_node(&mut self, root: Word, depth: &Felt, index: &Felt, value: Word) -> Result<MerklePath, ExecutionError> {
fn find_lone_leaf(&self, root: Word, root_index: NodeIndex, tree_depth: u8) -> Result<Option<(NodeIndex, Word)>, ExecutionError> {
self.provider.find_lone_leaf(root, root_index, tree_depth)
}

fn update_merkle_node(&mut self, root: Word, depth: &Felt, index: &Felt, value: Word) -> Result<(MerklePath, Word), ExecutionError> {
self.provider.update_merkle_node(root, depth, index, value)
}

Expand Down
Loading

0 comments on commit 5adec34

Please sign in to comment.