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

@ -14,6 +14,8 @@ strum = "0.26"
strum_macros = "0.26" strum_macros = "0.26"
anyhow = "1.0.56" anyhow = "1.0.56"
dyn-clone = "1.0.18" dyn-clone = "1.0.18"
log = "0.4"
env_logger = "0.11"
# enabled by features: # enabled by features:
plonky2 = { git = "https://github.com/0xPolygonZero/plonky2", optional = true } plonky2 = { git = "https://github.com/0xPolygonZero/plonky2", optional = true }

View file

@ -1,5 +1,6 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use itertools::Itertools; use itertools::Itertools;
use log::error;
use plonky2::hash::poseidon::PoseidonHash; use plonky2::hash::poseidon::PoseidonHash;
use plonky2::plonk::config::Hasher; use plonky2::plonk::config::Hasher;
use std::any::Any; use std::any::Any;
@ -434,10 +435,22 @@ impl Pod for MockMainPod {
self.operations[i] self.operations[i]
.deref(&self.statements[..input_statement_offset + i]) .deref(&self.statements[..input_statement_offset + i])
.unwrap() .unwrap()
.check(&self.params, &s.clone().try_into().unwrap()) .check_and_log(&self.params, &s.clone().try_into().unwrap())
}) })
.collect::<Result<Vec<_>>>() .collect::<Result<Vec<_>>>()
.unwrap(); .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) ids_match && has_type_statement && value_ofs_unique & statement_check.into_iter().all(|b| b)
} }
fn id(&self) -> PodId { fn id(&self) -> PodId {

View file

@ -2,7 +2,9 @@
//! with Pods. //! with Pods.
use anyhow::{anyhow, Error, Result}; use anyhow::{anyhow, Error, Result};
use env_logger;
use itertools::Itertools; use itertools::Itertools;
use log::error;
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::From; use std::convert::From;
use std::{fmt, hash as h}; use std::{fmt, hash as h};
@ -1152,4 +1154,87 @@ pub mod tests {
println!("{}", builder); println!("{}", builder);
println!("{}", false_pod); 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 std::fmt;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use log::error;
use super::{CustomPredicateRef, NativePredicate, Statement, StatementArg}; use super::{CustomPredicateRef, NativePredicate, Statement, StatementArg};
use crate::middleware::{AnchoredKey, Params, Predicate, Value, SELF}; use crate::middleware::{AnchoredKey, Params, Predicate, Value, SELF};
@ -308,6 +309,15 @@ impl Operation {
.map(|(pred, st_args)| Statement::from_args(pred, st_args)); .map(|(pred, st_args)| Statement::from_args(pred, st_args));
x.transpose() 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. /// Checks the given operation against a statement.
pub fn check(&self, _params: &Params, output_statement: &Statement) -> Result<bool> { pub fn check(&self, _params: &Params, output_statement: &Statement) -> Result<bool> {
use Statement::*; use Statement::*;