Skip to content

Commit

Permalink
Introduce SmtProof (#270)
Browse files Browse the repository at this point in the history
* add conversion for `SmtLeaf`

* introduce `SmtProof` scaffolding

* implement `verify_membership()`

* SmtLeaf: knows its index

* `SmtLeaf::index`

* `SmtLeaf::get_value()` returns an Option

* fix `verify_membership()`

* impl `SmtProof::get`

* impl `into_parts()`

* `SmtProof::compute_root`

* use `SmtProof` in `Smt::open`

* `SmtLeaf` constructors

* Vec

* impl `Error` for `SmtLeafError`

* fix std Error

* move Word/Digest conversions to LeafIndex

* `SmtProof::new()` returns an error

* `SparseMerkleTree::path_and_leaf_to_opening`

* `SmtLeaf`: serializable/deserializable

* `SmtProof`: serializable/deserializable

* add tests for SmtLeaf serialization

* move `SmtLeaf` to submodule

* use constructors internally

* fix docs

* Add `Vec`

* add `Vec` to tests

* no_std use statements

* fmt

* `Errors`: make heading

* use `SMT_DEPTH`

* SmtLeaf single case: check leaf index

* Multiple case: check consistency with leaf index

* use `pub(super)` instead of `pub(crate)`

* use `pub(super)`

* `SmtLeaf`: add `num_entries()` accessor

* Fix `SmtLeaf` serialization

* improve leaf serialization tests
  • Loading branch information
plafer authored and bobbinth committed Feb 14, 2024
1 parent 61a0764 commit e55b3ed
Show file tree
Hide file tree
Showing 8 changed files with 678 additions and 216 deletions.
10 changes: 10 additions & 0 deletions src/merkle/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use crate::{
};
use core::fmt;

use super::smt::SmtLeafError;

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum MerkleError {
ConflictingRoots(Vec<RpoDigest>),
Expand All @@ -20,6 +22,7 @@ pub enum MerkleError {
NodeNotInStore(RpoDigest, NodeIndex),
NumLeavesNotPowerOfTwo(usize),
RootNotInStore(RpoDigest),
SmtLeaf(SmtLeafError),
}

impl fmt::Display for MerkleError {
Expand Down Expand Up @@ -50,9 +53,16 @@ impl fmt::Display for MerkleError {
write!(f, "the leaves count {leaves} is not a power of 2")
}
RootNotInStore(root) => write!(f, "the root {:?} is not in the store", root),
SmtLeaf(smt_leaf_error) => write!(f, "smt leaf error: {smt_leaf_error}"),
}
}
}

#[cfg(feature = "std")]
impl std::error::Error for MerkleError {}

impl From<SmtLeafError> for MerkleError {
fn from(value: SmtLeafError) -> Self {
Self::SmtLeaf(value)
}
}
86 changes: 86 additions & 0 deletions src/merkle/smt/full/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use core::fmt;

use crate::{
hash::rpo::RpoDigest,
merkle::{LeafIndex, SMT_DEPTH},
utils::collections::Vec,
Word,
};

// SMT LEAF ERROR
// =================================================================================================

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SmtLeafError {
InconsistentKeys {
entries: Vec<(RpoDigest, Word)>,
key_1: RpoDigest,
key_2: RpoDigest,
},
InvalidNumEntriesForMultiple(usize),
SingleKeyInconsistentWithLeafIndex {
key: RpoDigest,
leaf_index: LeafIndex<SMT_DEPTH>,
},
MultipleKeysInconsistentWithLeafIndex {
leaf_index_from_keys: LeafIndex<SMT_DEPTH>,
leaf_index_supplied: LeafIndex<SMT_DEPTH>,
},
}

#[cfg(feature = "std")]
impl std::error::Error for SmtLeafError {}

impl fmt::Display for SmtLeafError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use SmtLeafError::*;
match self {
InvalidNumEntriesForMultiple(num_entries) => {
write!(f, "Multiple leaf requires 2 or more entries. Got: {num_entries}")
}
InconsistentKeys { entries, key_1, key_2 } => {
write!(f, "Multiple leaf requires all keys to map to the same leaf index. Offending keys: {key_1} and {key_2}. Entries: {entries:?}.")
}
SingleKeyInconsistentWithLeafIndex { key, leaf_index } => {
write!(
f,
"Single key in leaf inconsistent with leaf index. Key: {key}, leaf index: {}",
leaf_index.value()
)
}
MultipleKeysInconsistentWithLeafIndex {
leaf_index_from_keys,
leaf_index_supplied,
} => {
write!(
f,
"Keys in entries map to leaf index {}, but leaf index {} was supplied",
leaf_index_from_keys.value(),
leaf_index_supplied.value()
)
}
}
}
}

// SMT PROOF ERROR
// =================================================================================================

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SmtProofError {
InvalidPathLength(usize),
}

#[cfg(feature = "std")]
impl std::error::Error for SmtProofError {}

impl fmt::Display for SmtProofError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use SmtProofError::*;
match self {
InvalidPathLength(path_length) => {
write!(f, "Invalid Merkle path length. Expected {SMT_DEPTH}, got {path_length}")
}
}
}
}
Loading

0 comments on commit e55b3ed

Please sign in to comment.