diff --git a/.github/workflows/mdbook-check.yml b/.github/workflows/mdbook-check.yml index 1f991e4..4d693b2 100644 --- a/.github/workflows/mdbook-check.yml +++ b/.github/workflows/mdbook-check.yml @@ -21,6 +21,7 @@ jobs: run: | curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf -y | sh rustup update + rustup toolchain install nightly-x86_64-unknown-linux-gnu cargo install --version ${MDBOOK_VERSION} mdbook cargo install --version ${MDBOOKKATEX_VERSION} mdbook-katex - name: Build with mdBook diff --git a/src/backends/plonky2/mock_main/mod.rs b/src/backends/plonky2/mock_main/mod.rs index f5352e5..a033f7b 100644 --- a/src/backends/plonky2/mock_main/mod.rs +++ b/src/backends/plonky2/mock_main/mod.rs @@ -507,7 +507,7 @@ pub mod tests { zu_kyc_pod_builder(¶ms, &gov_id_pod, &pay_stub_pod, &sanction_list_pod)?; let mut prover = MockProver {}; - let kyc_pod = kyc_builder.prove(&mut prover)?; + let kyc_pod = kyc_builder.prove(&mut prover, ¶ms)?; let pod = kyc_pod.pod.into_any().downcast::().unwrap(); println!("{:#}", pod); @@ -520,10 +520,11 @@ pub mod tests { #[test] fn test_mock_main_great_boy() -> Result<()> { + let params = middleware::Params::default(); let great_boy_builder = great_boy_pod_full_flow()?; let mut prover = MockProver {}; - let great_boy_pod = great_boy_builder.prove(&mut prover)?; + let great_boy_pod = great_boy_builder.prove(&mut prover, ¶ms)?; let pod = great_boy_pod .pod .into_any() @@ -539,9 +540,10 @@ pub mod tests { #[test] fn test_mock_main_tickets() -> Result<()> { + let params = middleware::Params::default(); let tickets_builder = tickets_pod_full_flow()?; let mut prover = MockProver {}; - let proof_pod = tickets_builder.prove(&mut prover)?; + let proof_pod = tickets_builder.prove(&mut prover, ¶ms)?; let pod = proof_pod.pod.into_any().downcast::().unwrap(); println!("{}", pod); diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs index fe53261..7525752 100644 --- a/src/frontend/mod.rs +++ b/src/frontend/mod.rs @@ -1,7 +1,7 @@ //! The frontend includes the user-level abstractions and user-friendly types to define and work //! with Pods. -use anyhow::Result; +use anyhow::{anyhow, Error, Result}; use itertools::Itertools; use std::collections::HashMap; use std::convert::From; @@ -348,7 +348,7 @@ impl MainPodBuilder { self.public_statements.push(st.clone()); } - pub fn prove(&self, prover: &mut P) -> Result { + pub fn prove(&self, prover: &mut P, params: &Params) -> Result { let compiler = MainPodCompiler::new(&self.params); let inputs = MainPodCompilerInputs { // signed_pods: &self.input_signed_pods, @@ -357,7 +357,7 @@ impl MainPodBuilder { operations: &self.operations, public_statements: &self.public_statements, }; - let (statements, operations, public_statements) = compiler.compile(inputs)?; + let (statements, operations, public_statements) = compiler.compile(inputs, params)?; let inputs = MainPodInputs { signed_pods: &self.input_signed_pods.iter().map(|p| &p.pod).collect_vec(), @@ -462,15 +462,27 @@ impl MainPodCompiler { middleware::Operation::op(mop_code, &mop_args).unwrap() } - fn compile_st_op(&mut self, st: &Statement, op: &Operation) { + fn compile_st_op(&mut self, st: &Statement, op: &Operation, params: &Params) -> Result<()> { let middle_st = self.compile_st(st); let middle_op = self.compile_op(op); - self.push_st_op(middle_st, middle_op); + let is_correct = middle_op.check(params, &middle_st)?; + if !is_correct { + // todo: improve error handling + Err(anyhow!( + "Compile failed due to invalid deduction:\n {} ⇏ {}", + middle_op, + middle_st + )) + } else { + self.push_st_op(middle_st, middle_op); + Ok(()) + } } pub fn compile<'a>( mut self, inputs: MainPodCompilerInputs<'a>, + params: &Params, ) -> Result<( Vec, // input statements Vec, @@ -484,7 +496,7 @@ impl MainPodCompiler { public_statements, } = inputs; for (st, op) in statements.iter().zip_eq(operations.iter()) { - self.compile_st_op(st, op); + self.compile_st_op(st, op, params)?; if self.statements.len() > self.params.max_statements { panic!("too many statements"); } @@ -570,7 +582,7 @@ pub mod tests { println!("{}", kyc); let mut prover = MockProver {}; - let kyc = kyc.prove(&mut prover)?; + let kyc = kyc.prove(&mut prover, ¶ms)?; // TODO: prove kyc with MockProver and print it println!("{}", kyc); @@ -595,4 +607,30 @@ pub mod tests { Ok(()) } + + #[test] + #[should_panic] + fn test_false_st() { + let params = Params::default(); + let mut builder = SignedPodBuilder::new(¶ms); + + builder.insert("num", 2); + + let mut signer = MockSigner { + pk: "signer".into(), + }; + let pod = builder.sign(&mut signer).unwrap(); + + println!("{}", pod); + + let mut builder = MainPodBuilder::new(¶ms); + builder.add_signed_pod(&pod); + builder.pub_op(op!(gt, (&pod, "num"), 5)); + + let mut prover = MockProver {}; + let false_pod = builder.prove(&mut prover, ¶ms).unwrap(); + + println!("{}", builder); + println!("{}", false_pod); + } } diff --git a/src/middleware/operation.rs b/src/middleware/operation.rs index 3b921b1..fac4437 100644 --- a/src/middleware/operation.rs +++ b/src/middleware/operation.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::fmt; use anyhow::{anyhow, Result}; @@ -265,3 +266,14 @@ impl Operation { } } } + +impl fmt::Display for Operation { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + writeln!(f, "middleware::Operation:")?; + writeln!(f, " {:?} ", self.code())?; + for (i, arg) in self.args().iter().enumerate() { + writeln!(f, " {}", arg)?; + } + Ok(()) + } +}