Print debugging info if a pod does not verify (#141)

* Print debugging info if a pod does not verify

* Use logging for incorrect pods; add additional test
This commit is contained in:
tideofwords 2025-03-20 10:36:26 -07:00 committed by GitHub
parent 22db6ce4c6
commit fee70af12b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 111 additions and 1 deletions

View file

@ -1,5 +1,6 @@
use anyhow::{anyhow, Result};
use itertools::Itertools;
use log::error;
use plonky2::hash::poseidon::PoseidonHash;
use plonky2::plonk::config::Hasher;
use std::any::Any;
@ -434,10 +435,22 @@ impl Pod for MockMainPod {
self.operations[i]
.deref(&self.statements[..input_statement_offset + i])
.unwrap()
.check(&self.params, &s.clone().try_into().unwrap())
.check_and_log(&self.params, &s.clone().try_into().unwrap())
})
.collect::<Result<Vec<_>>>()
.unwrap();
if !ids_match {
error!("Verification failed: POD ID is incorrect.");
}
if !has_type_statement {
error!("Verification failed: POD does not have type statement.");
}
if !value_ofs_unique {
error!("Verification failed: Repeated ValueOf");
}
if !statement_check.iter().all(|b| *b) {
error!("Verification failed: Statement did not check.")
}
ids_match && has_type_statement && value_ofs_unique & statement_check.into_iter().all(|b| b)
}
fn id(&self) -> PodId {

View file

@ -2,7 +2,9 @@
//! with Pods.
use anyhow::{anyhow, Error, Result};
use env_logger;
use itertools::Itertools;
use log::error;
use std::collections::HashMap;
use std::convert::From;
use std::{fmt, hash as h};
@ -1152,4 +1154,87 @@ pub mod tests {
println!("{}", builder);
println!("{}", false_pod);
}
#[test]
#[should_panic]
fn test_incorrect_pod() {
// try to insert the same key multiple times
// right now this is not caught when you build the pod,
// but it is caught on verify
env_logger::init();
let params = Params::default();
let mut builder = MainPodBuilder::new(&params);
builder.insert((
Statement(
Predicate::Native(NativePredicate::ValueOf),
vec![
StatementArg::Key(AnchoredKey(Origin(PodClass::Main, SELF), "a".into())),
StatementArg::Literal(Value::Int(3)),
],
),
Operation(OperationType::Native(NativeOperation::NewEntry), vec![]),
));
builder.insert((
Statement(
Predicate::Native(NativePredicate::ValueOf),
vec![
StatementArg::Key(AnchoredKey(Origin(PodClass::Main, SELF), "a".into())),
StatementArg::Literal(Value::Int(28)),
],
),
Operation(OperationType::Native(NativeOperation::NewEntry), vec![]),
));
let mut prover = MockProver {};
let pod = builder.prove(&mut prover, &params).unwrap();
pod.pod.verify();
// try to insert a statement that doesn't follow from the operation
// right now the mock prover catches this when it calls compile()
let params = Params::default();
let mut builder = MainPodBuilder::new(&params);
let self_a = AnchoredKey(Origin(PodClass::Main, SELF), "a".into());
let self_b = AnchoredKey(Origin(PodClass::Main, SELF), "b".into());
let value_of_a = Statement(
Predicate::Native(NativePredicate::ValueOf),
vec![
StatementArg::Key(AnchoredKey(Origin(PodClass::Main, SELF), "a".into())),
StatementArg::Literal(Value::Int(3)),
],
);
let value_of_b = Statement(
Predicate::Native(NativePredicate::ValueOf),
vec![
StatementArg::Key(AnchoredKey(Origin(PodClass::Main, SELF), "b".into())),
StatementArg::Literal(Value::Int(27)),
],
);
builder.insert((
value_of_a.clone(),
Operation(OperationType::Native(NativeOperation::NewEntry), vec![]),
));
builder.insert((
value_of_b.clone(),
Operation(OperationType::Native(NativeOperation::NewEntry), vec![]),
));
builder.insert((
Statement(
Predicate::Native(NativePredicate::Equal),
vec![StatementArg::Key(self_a), StatementArg::Key(self_b)],
),
Operation(
OperationType::Native(NativeOperation::EqualFromEntries),
vec![
OperationArg::Statement(value_of_a),
OperationArg::Statement(value_of_b),
],
),
));
let mut prover = MockProver {};
let pod = builder.prove(&mut prover, &params).unwrap();
pod.pod.verify();
}
}

View file

@ -1,6 +1,7 @@
use std::fmt;
use anyhow::{anyhow, Result};
use log::error;
use super::{CustomPredicateRef, NativePredicate, Statement, StatementArg};
use crate::middleware::{AnchoredKey, Params, Predicate, Value, SELF};
@ -308,6 +309,15 @@ impl Operation {
.map(|(pred, st_args)| Statement::from_args(pred, st_args));
x.transpose()
}
/// Checks the given operation against a statement, and prints information if the check does not pass
pub fn check_and_log(&self, params: &Params, output_statement: &Statement) -> Result<bool> {
let valid: bool = self.check(params, output_statement)?;
if !valid {
error!("Check failed on the following statement");
error!("{}", output_statement);
}
Ok(valid)
}
/// Checks the given operation against a statement.
pub fn check(&self, _params: &Params, output_statement: &Statement) -> Result<bool> {
use Statement::*;