pod2/src/frontend/error.rs
Eduard S. 6249406cb2
Complete the verification in MainMockPod (#302)
- Update the `RecursivePod` trait to return `vd_set` instead of `vds_root`
  - A native verifier requires the entire set to reason about the circuits that have been used in the recursive tree
- Implement serialization/deserialization for `VDSet`
- Remove `DynError` and use `BackendError` instead for middleware functions that wrap or define trait functions implemented in the backend.  This is based on the fact that we will only have a single backend enabled at a time, so there's no need for a `dyn Error`
  - Move the implementations of `_verify` functions to `verify` and similarly for `_prove`
- Complete the verification of a MockMainPod: the verification of input pods was missing.  The inclusion of these input pods in the serialization was also missing.  With this change a `MockMainPod` will grow after each recursion.  This was expected from the design but was not the case because of the missing recursive native verification implementation.

* apply feedback from @arnaucube
2025-06-19 16:28:25 +02:00

81 lines
2.2 KiB
Rust

use std::{backtrace::Backtrace, fmt::Debug};
use crate::middleware::{BackendError, Statement, StatementTmpl, Value};
pub type Result<T, E = Error> = core::result::Result<T, E>;
fn display_wc_map(wc_map: &[Option<Value>]) -> String {
let mut out = String::new();
use std::fmt::Write;
for (i, v) in wc_map.iter().enumerate() {
write!(out, "- {}: ", i).unwrap();
if let Some(v) = v {
writeln!(out, "{}", v).unwrap();
} else {
writeln!(out, "none").unwrap();
}
}
out
}
#[derive(thiserror::Error, Debug)]
pub enum InnerError {
#[error("{0} {1} is over the limit {2}")]
MaxLength(String, usize, usize),
#[error("{0} doesn't match {1:#}.\nWildcard map:\n{map}", map=display_wc_map(.2))]
StatementsDontMatch(Statement, StatementTmpl, Vec<Option<Value>>),
#[error("invalid arguments to {0} operation")]
OpInvalidArgs(String),
// Other
#[error("{0}")]
Custom(String),
}
#[derive(thiserror::Error)]
pub enum Error {
#[error("Inner: {inner}\n{backtrace}")]
Inner {
inner: Box<InnerError>,
backtrace: Box<Backtrace>,
},
#[error(transparent)]
Infallible(#[from] std::convert::Infallible),
#[error(transparent)]
Backend(#[from] BackendError),
#[error(transparent)]
Middleware(#[from] crate::middleware::Error),
}
impl Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self, f)
}
}
macro_rules! new {
($inner:expr) => {
Error::Inner {
inner: Box::new($inner),
backtrace: Box::new(Backtrace::capture()),
}
};
}
use InnerError::*;
impl Error {
pub(crate) fn custom(s: impl Into<String>) -> Self {
new!(Custom(s.into()))
}
pub(crate) fn op_invalid_args(s: String) -> Self {
new!(OpInvalidArgs(s))
}
pub(crate) fn statements_dont_match(
s0: Statement,
s1: StatementTmpl,
wc_map: Vec<Option<Value>>,
) -> Self {
new!(StatementsDontMatch(s0, s1, wc_map))
}
pub(crate) fn max_length(obj: String, found: usize, expect: usize) -> Self {
new!(MaxLength(obj, found, expect))
}
}