Skip to content

Commit

Permalink
fix: panic in PartialMmr::untrack (#382)
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilippGackstatter authored Feb 18, 2025
1 parent ed14eaa commit 535637d
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## 0.13.3 (tbd)

- Implement `PartialSmt` (#372, #381).
- Fix panic in `PartialMmr::untrack` (#382).

## 0.13.2 (2025-01-24)

Expand Down
33 changes: 29 additions & 4 deletions src/merkle/mmr/partial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,16 +341,13 @@ impl PartialMmr {
pub fn untrack(&mut self, leaf_pos: usize) {
let mut idx = InOrderIndex::from_leaf_pos(leaf_pos);

self.nodes.remove(&idx.sibling());

// `idx` represent the element that can be computed by the authentication path, because
// these elements can be computed they are not saved for the authentication of the current
// target. In other words, if the idx is present it was added for the authentication of
// another element, and no more elements should be removed otherwise it would remove that
// element's authentication data.
while !self.nodes.contains_key(&idx) {
while self.nodes.remove(&idx.sibling()).is_some() && !self.nodes.contains_key(&idx) {
idx = idx.parent();
self.nodes.remove(&idx.sibling());
}
}

Expand Down Expand Up @@ -949,4 +946,32 @@ mod tests {

assert_eq!(partial_mmr, decoded);
}

#[test]
fn test_partial_mmr_untrack() {
// build the MMR
let mmr: Mmr = LEAVES.into();

// get path and node for position 1
let node1 = mmr.get(1).unwrap();
let proof1 = mmr.open(1).unwrap();

// get path and node for position 2
let node2 = mmr.get(2).unwrap();
let proof2 = mmr.open(2).unwrap();

// create partial MMR and add authentication path to nodes at position 1 and 2
let mut partial_mmr: PartialMmr = mmr.peaks().into();
partial_mmr.track(1, node1, &proof1.merkle_path).unwrap();
partial_mmr.track(2, node2, &proof2.merkle_path).unwrap();

// untrack nodes at positions 1 and 2
partial_mmr.untrack(1);
partial_mmr.untrack(2);

// nodes should not longer be tracked
assert!(!partial_mmr.is_tracked(1));
assert!(!partial_mmr.is_tracked(2));
assert_eq!(partial_mmr.nodes().count(), 0);
}
}

0 comments on commit 535637d

Please sign in to comment.