This simplifies the MerkleTree (and container) API. Defer the max depth check when assigning the witness (merkle proof siblings) to the merkle tree circuit. In this implementation the native Merkle Tree branches grow as much as they needed. There are no checks of max depth in the merkle tree. All keys are 256 bits (I added a debug_assert for this); so in the worst case a path will have depth 256. It can't have a longer depth because the `insert` method calls `prove_nonexistence` which errors if the key already exists; another one may exist which must be different and thus require a path <= 256 depth. Resolve #436
84 lines
2.4 KiB
Rust
84 lines
2.4 KiB
Rust
//! tree errors
|
|
|
|
use std::{backtrace::Backtrace, fmt::Debug};
|
|
|
|
pub type TreeResult<T, E = TreeError> = core::result::Result<T, E>;
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum TreeInnerError {
|
|
#[error("key not found")]
|
|
KeyNotFound,
|
|
#[error("key already exists")]
|
|
KeyExists,
|
|
#[error("max depth reached")]
|
|
MaxDepth,
|
|
#[error("proof of {0} does not verify")]
|
|
ProofFail(String), // inclusion / exclusion
|
|
#[error("invalid {0} proof")]
|
|
InvalidProof(String),
|
|
#[error("invalid state transition proof argument: {0}")]
|
|
InvalidStateTransitionProogArg(String),
|
|
#[error("state transition proof does not verify, reason: {0}")]
|
|
StateTransitionProofFail(String),
|
|
#[error("circuit max_depth {0} is smaller than proof depth {1}")]
|
|
CircuitDepthTooSmall(usize, usize),
|
|
}
|
|
|
|
#[derive(thiserror::Error)]
|
|
pub enum TreeError {
|
|
#[error("Inner: {inner}\n{backtrace}")]
|
|
Inner {
|
|
inner: Box<TreeInnerError>,
|
|
backtrace: Box<Backtrace>,
|
|
},
|
|
#[error("anyhow::Error: {0}")]
|
|
Anyhow(#[from] anyhow::Error),
|
|
}
|
|
|
|
impl Debug for TreeError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
std::fmt::Display::fmt(self, f)
|
|
}
|
|
}
|
|
|
|
macro_rules! new {
|
|
($inner:expr) => {
|
|
TreeError::Inner {
|
|
inner: Box::new($inner),
|
|
backtrace: Box::new(Backtrace::capture()),
|
|
}
|
|
};
|
|
}
|
|
use TreeInnerError::*;
|
|
impl TreeError {
|
|
pub fn inner(&self) -> Option<&TreeInnerError> {
|
|
match self {
|
|
Self::Inner { inner, .. } => Some(inner),
|
|
_ => None,
|
|
}
|
|
}
|
|
pub(crate) fn key_not_found() -> Self {
|
|
new!(KeyNotFound)
|
|
}
|
|
pub(crate) fn key_exists() -> Self {
|
|
new!(KeyExists)
|
|
}
|
|
pub(crate) fn max_depth() -> Self {
|
|
new!(MaxDepth)
|
|
}
|
|
pub(crate) fn proof_fail(obj: String) -> Self {
|
|
new!(ProofFail(obj))
|
|
}
|
|
pub(crate) fn invalid_proof(obj: String) -> Self {
|
|
new!(InvalidProof(obj))
|
|
}
|
|
pub(crate) fn invalid_state_transition_proof_arg(reason: String) -> Self {
|
|
new!(InvalidStateTransitionProogArg(reason))
|
|
}
|
|
pub(crate) fn state_transition_fail(reason: String) -> Self {
|
|
new!(StateTransitionProofFail(reason))
|
|
}
|
|
pub(crate) fn circuit_depth_too_small(circuit_depth: usize, proof_depth: usize) -> Self {
|
|
new!(CircuitDepthTooSmall(circuit_depth, proof_depth))
|
|
}
|
|
}
|