Skip to content

Commit

Permalink
incrementalmerkletree: Check IncrementalWitness at construction
Browse files Browse the repository at this point in the history
A witness cannot exist for an empty tree.

Part of #118.
  • Loading branch information
str4d committed Nov 23, 2024
1 parent c06b836 commit 2edacb0
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 14 deletions.
5 changes: 5 additions & 0 deletions incrementalmerkletree/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to Rust's notion of

## Unreleased

### Changed
- `incrementalmerkletree::witness`:
- `IncrementalWitness::{from_tree, from_parts}` now return `Option<Self>`
(returning `None` if a witness cannot be constructed).

## [0.7.0] - 2024-09-25

### Changed
Expand Down
36 changes: 22 additions & 14 deletions incrementalmerkletree/src/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::{
///
/// tree.append(TestNode(0));
/// tree.append(TestNode(1));
/// let mut witness = IncrementalWitness::from_tree(tree.clone());
/// let mut witness = IncrementalWitness::from_tree(tree.clone()).expect("tree is not empty");
/// assert_eq!(witness.witnessed_position(), Position::from(1));
/// assert_eq!(tree.root(), witness.root());
///
Expand All @@ -45,30 +45,38 @@ pub struct IncrementalWitness<H, const DEPTH: u8> {
impl<H, const DEPTH: u8> IncrementalWitness<H, DEPTH> {
/// Creates an `IncrementalWitness` for the most recent commitment added to the given
/// [`CommitmentTree`].
pub fn from_tree(tree: CommitmentTree<H, DEPTH>) -> Self {
IncrementalWitness {
///
/// Returns `None` if `tree` is empty (and thus there is no position to witness).
pub fn from_tree(tree: CommitmentTree<H, DEPTH>) -> Option<Self> {
(!tree.is_empty()).then(|| IncrementalWitness {
tree,
filled: vec![],
cursor_depth: 0,
cursor: None,
}
})
}

/// Constructs an `IncrementalWitness` from its parts.
///
/// Returns `None` if the parts do not form a valid witness, for example if `tree` is
/// empty (and thus there is no position to witness).
pub fn from_parts(
tree: CommitmentTree<H, DEPTH>,
filled: Vec<H>,
cursor: Option<CommitmentTree<H, DEPTH>>,
) -> Self {
let mut witness = IncrementalWitness {
tree,
filled,
cursor_depth: 0,
cursor,
};
) -> Option<Self> {
(!tree.is_empty()).then(|| {
let mut witness = IncrementalWitness {
tree,
filled,
cursor_depth: 0,
cursor,
};

witness.cursor_depth = witness.next_depth();
witness.cursor_depth = witness.next_depth();

witness
witness
})
}

pub fn tree(&self) -> &CommitmentTree<H, DEPTH> {
Expand Down Expand Up @@ -248,7 +256,7 @@ mod tests {
for c in 'a'..'h' {
base_tree.append(c.to_string()).unwrap();
}
let mut witness = IncrementalWitness::from_tree(base_tree);
let mut witness = IncrementalWitness::from_tree(base_tree).unwrap();
for c in 'h'..'z' {
witness.append(c.to_string()).unwrap();
}
Expand Down

0 comments on commit 2edacb0

Please sign in to comment.