From 83a4f8969ff4c6dcc506e157d03296337adb39d5 Mon Sep 17 00:00:00 2001 From: Richard Liu Date: Tue, 18 Feb 2025 10:16:46 -0800 Subject: [PATCH] feat: add bool frontend type (#63) --- src/backends/mock_main.rs | 13 ++++++++++++- src/examples.rs | 35 +++++++++++++++++++++++++++++++++-- src/frontend.rs | 28 ++++++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/backends/mock_main.rs b/src/backends/mock_main.rs index 25a8ebf..648d9d3 100644 --- a/src/backends/mock_main.rs +++ b/src/backends/mock_main.rs @@ -505,7 +505,7 @@ impl Pod for MockMainPod { pub mod tests { use super::*; use crate::backends::mock_signed::MockSigner; - use crate::examples::{great_boy_pod_full_flow, zu_kyc_pod_builder, zu_kyc_sign_pod_builders}; + use crate::examples::{great_boy_pod_full_flow, tickets_pod_full_flow, zu_kyc_pod_builder, zu_kyc_sign_pod_builders}; use crate::middleware; #[test] @@ -550,4 +550,15 @@ pub mod tests { assert_eq!(pod.verify(), true); } + + #[test] + fn test_mock_main_tickets() { + let tickets_builder = tickets_pod_full_flow(); + let mut prover = MockProver {}; + let proof_pod = tickets_builder.prove(&mut prover).unwrap(); + let pod = proof_pod.pod.into_any().downcast::().unwrap(); + + println!("{}", pod); + assert_eq!(pod.verify(), true); + } } diff --git a/src/examples.rs b/src/examples.rs index 52e0a68..8ffba33 100644 --- a/src/examples.rs +++ b/src/examples.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use crate::backends::mock_signed::MockSigner; use crate::frontend::{MainPodBuilder, SignedPod, SignedPodBuilder, Value}; use crate::middleware::{containers::Dictionary, Params, PodType, KEY_SIGNER, KEY_TYPE}; use crate::op; @@ -130,8 +131,6 @@ pub fn great_boy_pod_builder( } pub fn great_boy_pod_full_flow() -> MainPodBuilder { - use crate::backends::mock_signed::MockSigner; - let params = Params { max_input_signed_pods: 6, max_statements: 100, @@ -194,3 +193,35 @@ pub fn great_boy_pod_full_flow() -> MainPodBuilder { alice, ) } + +// Tickets + +pub fn tickets_sign_pod_builder(params: &Params) -> SignedPodBuilder { + // Create a signed pod with all atomic types (string, int, bool) + let mut builder = SignedPodBuilder::new(params); + builder.insert("eventId", 123); + builder.insert("productId", 456); + builder.insert("attendeeName", "John Doe"); + builder.insert("attendeeEmail", "john.doe@example.com"); + builder.insert("isConsumed", true); + builder.insert("isRevoked", false); + builder +} + +pub fn tickets_pod_builder(params: &Params, signed_pod: &SignedPod, expected_event_id: i64, expect_consumed: bool, blacklisted_emails: &Value) -> MainPodBuilder { + // Create a main pod referencing this signed pod with some statements + let mut builder = MainPodBuilder::new(params); + builder.add_signed_pod(signed_pod); + builder.pub_op(op!(eq, (signed_pod, "eventId"), expected_event_id)); + builder.pub_op(op!(eq, (signed_pod, "isConsumed"), expect_consumed)); + builder.pub_op(op!(eq, (signed_pod, "isRevoked"), false)); + builder.pub_op(op!(not_contains, blacklisted_emails, (signed_pod, "attendeeEmail"))); + builder +} + +pub fn tickets_pod_full_flow() -> MainPodBuilder { + let params = Params::default(); + let builder = tickets_sign_pod_builder(¶ms); + let signed_pod = builder.sign(&mut MockSigner { pk: "test".into() }).unwrap(); + tickets_pod_builder(¶ms, &signed_pod, 123, true, &Value::Dictionary(Dictionary::new(&HashMap::new()))) +} diff --git a/src/frontend.rs b/src/frontend.rs index 4b86129..b949ef9 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -30,6 +30,7 @@ pub struct Origin(pub PodClass, pub PodId); pub enum Value { String(String), Int(i64), + Bool(bool), Dictionary(Dictionary), Set(Set), Array(Array), @@ -47,11 +48,18 @@ impl From for Value { } } +impl From for Value { + fn from(b: bool) -> Self { + Value::Bool(b) + } +} + impl From<&Value> for middleware::Value { fn from(v: &Value) -> Self { match v { Value::String(s) => middleware::Value(hash_str(s).0), Value::Int(v) => middleware::Value::from(*v), + Value::Bool(b) => middleware::Value::from(*b as i64), Value::Dictionary(d) => middleware::Value(d.commitment().0), Value::Set(s) => middleware::Value(s.commitment().0), Value::Array(a) => middleware::Value(a.commitment().0), @@ -64,6 +72,7 @@ impl fmt::Display for Value { match self { Value::String(s) => write!(f, "\"{}\"", s), Value::Int(v) => write!(f, "{}", v), + Value::Bool(b) => write!(f, "{}", b), Value::Dictionary(d) => write!(f, "dict:{}", d.commitment()), Value::Set(s) => write!(f, "set:{}", s.commitment()), Value::Array(a) => write!(f, "arr:{}", a.commitment()), @@ -224,6 +233,12 @@ impl From for OperationArg { } } +impl From for OperationArg { + fn from(b: bool) -> Self { + Self::Literal(Value::from(b)) + } +} + impl From<(Origin, &str)> for OperationArg { fn from((origin, key): (Origin, &str)) -> Self { Self::Key(AnchoredKey(origin, key.to_string())) @@ -578,8 +593,9 @@ pub mod build_utils { #[cfg(test)] pub mod tests { use super::*; + use crate::backends::mock_main::MockProver; use crate::backends::mock_signed::MockSigner; - use crate::examples::{great_boy_pod_full_flow, zu_kyc_pod_builder, zu_kyc_sign_pod_builders}; + use crate::examples::{great_boy_pod_full_flow, tickets_pod_full_flow, zu_kyc_pod_builder, zu_kyc_sign_pod_builders}; #[test] fn test_front_zu_kyc() -> Result<()> { @@ -617,4 +633,12 @@ pub mod tests { Ok(()) } -} \ No newline at end of file + + #[test] + fn test_front_tickets() -> Result<()> { + let builder = tickets_pod_full_flow(); + println!("{}", builder); + + Ok(()) + } +}