incrementalmerkletree: Check `IncrementalWitness` at construction
A witness cannot exist for an empty tree. Part of zcash/incrementalmerkletree#118.
This commit is contained in:
parent
c06b836e3f
commit
2edacb0191
|
@ -7,6 +7,11 @@ and this project adheres to Rust's notion of
|
||||||
|
|
||||||
## Unreleased
|
## 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
|
## [0.7.0] - 2024-09-25
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -25,7 +25,7 @@ use crate::{
|
||||||
///
|
///
|
||||||
/// tree.append(TestNode(0));
|
/// tree.append(TestNode(0));
|
||||||
/// tree.append(TestNode(1));
|
/// 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!(witness.witnessed_position(), Position::from(1));
|
||||||
/// assert_eq!(tree.root(), witness.root());
|
/// assert_eq!(tree.root(), witness.root());
|
||||||
///
|
///
|
||||||
|
@ -45,30 +45,38 @@ pub struct IncrementalWitness<H, const DEPTH: u8> {
|
||||||
impl<H, const DEPTH: u8> IncrementalWitness<H, DEPTH> {
|
impl<H, const DEPTH: u8> IncrementalWitness<H, DEPTH> {
|
||||||
/// Creates an `IncrementalWitness` for the most recent commitment added to the given
|
/// Creates an `IncrementalWitness` for the most recent commitment added to the given
|
||||||
/// [`CommitmentTree`].
|
/// [`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,
|
tree,
|
||||||
filled: vec![],
|
filled: vec![],
|
||||||
cursor_depth: 0,
|
cursor_depth: 0,
|
||||||
cursor: None,
|
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(
|
pub fn from_parts(
|
||||||
tree: CommitmentTree<H, DEPTH>,
|
tree: CommitmentTree<H, DEPTH>,
|
||||||
filled: Vec<H>,
|
filled: Vec<H>,
|
||||||
cursor: Option<CommitmentTree<H, DEPTH>>,
|
cursor: Option<CommitmentTree<H, DEPTH>>,
|
||||||
) -> Self {
|
) -> Option<Self> {
|
||||||
let mut witness = IncrementalWitness {
|
(!tree.is_empty()).then(|| {
|
||||||
tree,
|
let mut witness = IncrementalWitness {
|
||||||
filled,
|
tree,
|
||||||
cursor_depth: 0,
|
filled,
|
||||||
cursor,
|
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> {
|
pub fn tree(&self) -> &CommitmentTree<H, DEPTH> {
|
||||||
|
@ -248,7 +256,7 @@ mod tests {
|
||||||
for c in 'a'..'h' {
|
for c in 'a'..'h' {
|
||||||
base_tree.append(c.to_string()).unwrap();
|
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' {
|
for c in 'h'..'z' {
|
||||||
witness.append(c.to_string()).unwrap();
|
witness.append(c.to_string()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue