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:
parent
22db6ce4c6
commit
fee70af12b
4 changed files with 111 additions and 1 deletions
|
|
@ -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 }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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(¶ms);
|
||||||
|
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, ¶ms).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(¶ms);
|
||||||
|
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, ¶ms).unwrap();
|
||||||
|
pod.pod.verify();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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::*;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue