Check statement correctness on compile (#104)

* Check statement correctness on compile

* format

* Update src/frontend/mod.rs

Co-authored-by: Ahmad Afuni <root@ahmadafuni.com>

* clean error handling

Co-authored-by: Ahmad Afuni <root@ahmadafuni.com>

* clean coding style

Co-authored-by: Ahmad Afuni <root@ahmadafuni.com>

* don't need to return ()

Co-authored-by: Ahmad Afuni <root@ahmadafuni.com>

* Update github workflow for mdbook

* Resolve issue from merge: pass params to check()

---------

Co-authored-by: Ahmad Afuni <root@ahmadafuni.com>
This commit is contained in:
tideofwords 2025-03-03 15:12:09 -08:00 committed by GitHub
parent c92839d897
commit 5092149f9f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 63 additions and 10 deletions

View file

@ -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

View file

@ -507,7 +507,7 @@ pub mod tests {
zu_kyc_pod_builder(&params, &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, &params)?;
let pod = kyc_pod.pod.into_any().downcast::<MockMainPod>().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, &params)?;
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, &params)?;
let pod = proof_pod.pod.into_any().downcast::<MockMainPod>().unwrap();
println!("{}", pod);

View file

@ -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<P: PodProver>(&self, prover: &mut P) -> Result<MainPod> {
pub fn prove<P: PodProver>(&self, prover: &mut P, params: &Params) -> Result<MainPod> {
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<middleware::Statement>, // input statements
Vec<middleware::Operation>,
@ -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, &params)?;
// 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(&params);
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(&params);
builder.add_signed_pod(&pod);
builder.pub_op(op!(gt, (&pod, "num"), 5));
let mut prover = MockProver {};
let false_pod = builder.prove(&mut prover, &params).unwrap();
println!("{}", builder);
println!("{}", false_pod);
}
}

View file

@ -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(())
}
}