diff --git a/src/backends/plonky2/circuits/common.rs b/src/backends/plonky2/circuits/common.rs index 09d7a4e..2b6187a 100644 --- a/src/backends/plonky2/circuits/common.rs +++ b/src/backends/plonky2/circuits/common.rs @@ -31,9 +31,8 @@ use crate::{ middleware::{ CustomPredicate, CustomPredicateBatch, CustomPredicateRef, NativeOperation, NativePredicate, OperationType, Params, Predicate, PredicatePrefix, RawValue, StatementArg, - StatementTmpl, StatementTmplArg, StatementTmplArgPrefix, ToFields, Value, WildcardValue, - EMPTY_VALUE, F, HASH_SIZE, OPERATION_ARG_F_LEN, OPERATION_AUX_F_LEN, STATEMENT_ARG_F_LEN, - VALUE_SIZE, + StatementTmpl, StatementTmplArg, StatementTmplArgPrefix, ToFields, Value, EMPTY_VALUE, F, + HASH_SIZE, OPERATION_ARG_F_LEN, OPERATION_AUX_F_LEN, STATEMENT_ARG_F_LEN, VALUE_SIZE, }, }; @@ -597,7 +596,7 @@ impl CustomPredicateVerifyEntryTarget { // Replace statement templates of batch-self with (id,index) self.custom_predicate .set_targets(pw, params, &cpv.custom_predicate)?; - let pad_arg = WildcardValue::None; + let pad_arg = Value::from(0); for (arg_target, arg) in self.args.iter().zip_eq( cpv.args .iter() @@ -1427,11 +1426,8 @@ pub(crate) mod tests { use super::*; use crate::{ - backends::plonky2::basetypes::C, - examples::custom::{eth_dos_batch, eth_friend_batch}, - frontend, - frontend::CustomPredicateBatchBuilder, - middleware::CustomPredicateBatch, + backends::plonky2::basetypes::C, examples::custom::eth_dos_batch, frontend, + frontend::CustomPredicateBatchBuilder, middleware::CustomPredicateBatch, }; pub(crate) const I64_TEST_PAIRS: [(i64, i64); 36] = [ @@ -1481,7 +1477,7 @@ pub(crate) mod tests { let params = Params::default(); let config = CircuitConfig::standard_recursion_config(); - let custom_predicate_batch = eth_friend_batch(¶ms, false)?; + let custom_predicate_batch = eth_dos_batch(¶ms, false)?; for (i, cp) in custom_predicate_batch.predicates().iter().enumerate() { let mut builder = CircuitBuilder::::new(config.clone()); @@ -1544,9 +1540,6 @@ pub(crate) mod tests { helper_custom_predicate_batch_target_id(¶ms, &custom_predicate_batch).unwrap(); // Some cases from the examples - let custom_predicate_batch = eth_friend_batch(¶ms, false)?; - helper_custom_predicate_batch_target_id(¶ms, &custom_predicate_batch).unwrap(); - let custom_predicate_batch = eth_dos_batch(¶ms, false)?; helper_custom_predicate_batch_target_id(¶ms, &custom_predicate_batch).unwrap(); diff --git a/src/backends/plonky2/circuits/mainpod.rs b/src/backends/plonky2/circuits/mainpod.rs index 9772db4..d087169 100644 --- a/src/backends/plonky2/circuits/mainpod.rs +++ b/src/backends/plonky2/circuits/mainpod.rs @@ -41,7 +41,7 @@ use crate::{ middleware::{ AnchoredKey, CustomPredicate, CustomPredicateBatch, CustomPredicateRef, NativeOperation, NativePredicate, Params, PodType, PredicatePrefix, Statement, StatementArg, ToFields, - Value, ValueRef, WildcardValue, EMPTY_VALUE, F, HASH_SIZE, KEY_TYPE, SELF, VALUE_SIZE, + Value, ValueRef, EMPTY_VALUE, F, HASH_SIZE, KEY_TYPE, SELF, VALUE_SIZE, }, }; @@ -1338,7 +1338,7 @@ impl MainPodVerifyGadget { &builder.constants( &Statement::equal( ValueRef::Key(AnchoredKey::from((SELF, KEY_TYPE))), - ValueRef::Literal(Value::from(PodType::MockMain)), + ValueRef::Literal(Value::from(PodType::Main)), ) .to_fields(params), ), @@ -1399,7 +1399,7 @@ pub struct MainPodVerifyTarget { pub struct CustomPredicateVerification { pub custom_predicate_table_index: usize, pub custom_predicate: CustomPredicateRef, - pub args: Vec, + pub args: Vec, pub op_args: Vec, } @@ -1612,10 +1612,10 @@ mod tests { mainpod::{calculate_id, OperationArg, OperationAux}, primitives::merkletree::{MerkleClaimAndProof, MerkleTree}, }, - frontend::{self, key, literal, CustomPredicateBatchBuilder, StatementTmplBuilder}, + frontend::{self, literal, CustomPredicateBatchBuilder, StatementTmplBuilder}, middleware::{ - hash_str, hash_values, Hash, Key, KeyOrWildcard, OperationType, PodId, Predicate, - RawValue, SelfOrWildcard, StatementTmpl, StatementTmplArg, Wildcard, WildcardValue, + hash_str, hash_values, Hash, Key, OperationType, PodId, Predicate, RawValue, + StatementTmpl, StatementTmplArg, Wildcard, }, }; @@ -2558,45 +2558,16 @@ mod tests { helper_statement_arg_from_template(¶ms, st_tmpl_arg, args, expected_st_arg)?; // case: AnchoredKey(id_wildcard, key_literal) - let st_tmpl_arg = StatementTmplArg::AnchoredKey( - SelfOrWildcard::Wildcard(Wildcard::new("a".to_string(), 1)), - KeyOrWildcard::Key(Key::from("foo")), - ); - let args = vec![Value::from(1), Value::from(pod_id.0), Value::from(3)]; + let st_tmpl_arg = + StatementTmplArg::AnchoredKey(Wildcard::new("a".to_string(), 1), Key::from("foo")); + let args = vec![Value::from(1), Value::from(pod_id), Value::from(3)]; let expected_st_arg = StatementArg::Key(AnchoredKey::new(pod_id, Key::from("foo"))); helper_statement_arg_from_template(¶ms, st_tmpl_arg, args, expected_st_arg)?; - // case: AnchoredKey(id_wildcard, key_wildcard) - let st_tmpl_arg = StatementTmplArg::AnchoredKey( - SelfOrWildcard::Wildcard(Wildcard::new("a".to_string(), 1)), - KeyOrWildcard::Wildcard(Wildcard::new("b".to_string(), 2)), - ); - let args = vec![Value::from(1), Value::from(pod_id.0), Value::from("key")]; - let expected_st_arg = StatementArg::Key(AnchoredKey::new(pod_id, Key::from("key"))); - helper_statement_arg_from_template(¶ms, st_tmpl_arg, args, expected_st_arg)?; - - // case: AnchoredKey(SELF, key_literal) - let st_tmpl_arg = StatementTmplArg::AnchoredKey( - SelfOrWildcard::SELF, - KeyOrWildcard::Key(Key::from("foo")), - ); - let args = vec![Value::from(1), Value::from(pod_id.0), Value::from(3)]; - let expected_st_arg = StatementArg::Key(AnchoredKey::new(SELF, Key::from("foo"))); - helper_statement_arg_from_template(¶ms, st_tmpl_arg, args, expected_st_arg)?; - - // case: AnchoredKey(SELF, key_wildcard) - let st_tmpl_arg = StatementTmplArg::AnchoredKey( - SelfOrWildcard::SELF, - KeyOrWildcard::Wildcard(Wildcard::new("b".to_string(), 2)), - ); - let args = vec![Value::from(1), Value::from(pod_id.0), Value::from("key")]; - let expected_st_arg = StatementArg::Key(AnchoredKey::new(SELF, Key::from("key"))); - helper_statement_arg_from_template(¶ms, st_tmpl_arg, args, expected_st_arg)?; - // case: WildcardLiteral(wildcard) - let st_tmpl_arg = StatementTmplArg::WildcardLiteral(Wildcard::new("a".to_string(), 1)); + let st_tmpl_arg = StatementTmplArg::Wildcard(Wildcard::new("a".to_string(), 1)); let args = vec![Value::from(1), Value::from("key"), Value::from(3)]; - let expected_st_arg = StatementArg::WildcardLiteral(WildcardValue::Key(Key::from("key"))); + let expected_st_arg = StatementArg::Literal(Value::from("key")); helper_statement_arg_from_template(¶ms, st_tmpl_arg, args, expected_st_arg)?; Ok(()) @@ -2648,10 +2619,7 @@ mod tests { let st_tmpl = StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), args: vec![ - StatementTmplArg::AnchoredKey( - SelfOrWildcard::Wildcard(Wildcard::new("a".to_string(), 1)), - KeyOrWildcard::Key(Key::from("key")), - ), + StatementTmplArg::AnchoredKey(Wildcard::new("a".to_string(), 1), Key::from("key")), StatementTmplArg::Literal(Value::from("value")), ], }; @@ -2669,7 +2637,7 @@ mod tests { params: &Params, custom_predicate: CustomPredicateRef, op_args: Vec, - args: Vec, + args: Vec, expected_st: Option, ) -> Result<()> { let config = CircuitConfig::standard_recursion_config(); @@ -2732,19 +2700,15 @@ mod tests { use NativePredicate as NP; use StatementTmplBuilder as STB; let mut builder = CustomPredicateBatchBuilder::new(params.clone(), "batch".into()); - let stb0 = STB::new(NP::Equal) - .arg(("id", key("score"))) - .arg(literal(42)); - let stb1 = STB::new(NP::Equal) - .arg(("id", "secret_key")) - .arg(literal(1234)); + let stb0 = STB::new(NP::Equal).arg(("id", "score")).arg(literal(42)); + let stb1 = STB::new(NP::Equal).arg(("id", "key")).arg("secret"); let _ = builder.predicate_and( "pred_and", &["id"], - &["secret_key"], + &["secret"], &[stb0.clone(), stb1.clone()], )?; - let _ = builder.predicate_or("pred_or", &["id"], &["secret_key"], &[stb0, stb1])?; + let _ = builder.predicate_or("pred_or", &["id"], &["secret"], &[stb0, stb1])?; let batch = builder.finish(); let pod_id = PodId(hash_str("pod_id")); @@ -2757,17 +2721,14 @@ mod tests { Value::from(42), ), Statement::equal( - AnchoredKey::new(pod_id, Key::from("foo")), + AnchoredKey::new(pod_id, Key::from("key")), Value::from(1234), ), ]; - let args = vec![ - WildcardValue::PodId(pod_id), - WildcardValue::Key(Key::from("foo")), - ]; + let args = vec![Value::from(pod_id), Value::from(1234)]; let expected_st = Statement::Custom( custom_predicate.clone(), - vec![args[0].clone(), WildcardValue::None], + vec![args[0].clone(), Value::from(0)], ); helper_custom_operation_verify_gadget( @@ -2788,10 +2749,10 @@ mod tests { ), Statement::None, ]; - let args = vec![WildcardValue::PodId(pod_id), WildcardValue::None]; + let args = vec![Value::from(pod_id), Value::from(0)]; let expected_st = Statement::Custom( custom_predicate.clone(), - vec![args[0].clone(), WildcardValue::None], + vec![args[0].clone(), Value::from(0)], ); helper_custom_operation_verify_gadget( @@ -2808,17 +2769,14 @@ mod tests { let op_args = vec![ Statement::None, Statement::equal( - AnchoredKey::new(pod_id, Key::from("foo")), + AnchoredKey::new(pod_id, Key::from("key")), Value::from(1234), ), ]; - let args = vec![ - WildcardValue::PodId(pod_id), - WildcardValue::Key(Key::from("foo")), - ]; + let args = vec![Value::from(pod_id), Value::from(1234)]; let expected_st = Statement::Custom( custom_predicate.clone(), - vec![args[0].clone(), WildcardValue::None], + vec![args[0].clone(), Value::from(0)], ); helper_custom_operation_verify_gadget( @@ -2848,22 +2806,21 @@ mod tests { use NativePredicate as NP; use StatementTmplBuilder as STB; let mut builder = CustomPredicateBatchBuilder::new(params.clone(), "batch".into()); - let stb0 = STB::new(NP::Equal) - .arg(("id", key("score"))) - .arg(literal(42)); + let stb0 = STB::new(NP::Equal).arg(("id", "score")).arg(literal(42)); let stb1 = STB::new(NP::Equal) - .arg(("id", "secret_key")) - .arg(("id", key("score"))); + .arg(("secret_id", "key")) + .arg(("id", "score")); let _ = builder.predicate_and( "pred_and", &["id"], - &["secret_key"], + &["secret_id"], &[stb0.clone(), stb1.clone()], )?; - let _ = builder.predicate_or("pred_or", &["id"], &["secret_key"], &[stb0, stb1])?; + let _ = builder.predicate_or("pred_or", &["id"], &["secret_id"], &[stb0, stb1])?; let batch = builder.finish(); let pod_id = PodId(hash_str("pod_id")); + let secret_pod_id = PodId(hash_str("secret_pod_id")); // AND (0) Sanity check with correct values let custom_predicate = CustomPredicateRef::new(batch.clone(), 0); @@ -2873,17 +2830,14 @@ mod tests { Value::from(42), ), Statement::equal( - AnchoredKey::new(pod_id, Key::from("foo")), + AnchoredKey::new(secret_pod_id, Key::from("key")), AnchoredKey::new(pod_id, Key::from("score")), ), ]; - let args = vec![ - WildcardValue::PodId(pod_id), - WildcardValue::Key(Key::from("foo")), - ]; + let args = vec![Value::from(pod_id), Value::from(secret_pod_id)]; let expected_st = Statement::Custom( custom_predicate.clone(), - vec![args[0].clone(), WildcardValue::None], + vec![args[0].clone(), Value::from(0)], ); helper_custom_operation_verify_gadget( @@ -2903,14 +2857,11 @@ mod tests { Value::from(42), ), Statement::equal( - AnchoredKey::new(PodId(hash_str("BAD")), Key::from("foo")), - AnchoredKey::new(pod_id, Key::from("score")), + AnchoredKey::new(secret_pod_id, Key::from("key")), + AnchoredKey::new(PodId(hash_str("BAD")), Key::from("score")), ), ]; - let args = vec![ - WildcardValue::PodId(pod_id), - WildcardValue::Key(Key::from("foo")), - ]; + let args = vec![Value::from(pod_id), Value::from(secret_pod_id)]; assert!(helper_custom_operation_verify_gadget( ¶ms, @@ -2926,14 +2877,11 @@ mod tests { let op_args = vec![ Statement::equal(AnchoredKey::new(pod_id, Key::from("BAD")), Value::from(42)), Statement::equal( - AnchoredKey::new(pod_id, Key::from("foo")), + AnchoredKey::new(secret_pod_id, Key::from("key")), AnchoredKey::new(pod_id, Key::from("score")), ), ]; - let args = vec![ - WildcardValue::PodId(pod_id), - WildcardValue::Key(Key::from("foo")), - ]; + let args = vec![Value::from(pod_id), Value::from(secret_pod_id)]; assert!(helper_custom_operation_verify_gadget( ¶ms, @@ -2952,14 +2900,11 @@ mod tests { Value::from(0xbad), ), Statement::equal( - AnchoredKey::new(pod_id, Key::from("foo")), + AnchoredKey::new(secret_pod_id, Key::from("key")), AnchoredKey::new(pod_id, Key::from("score")), ), ]; - let args = vec![ - WildcardValue::PodId(pod_id), - WildcardValue::Key(Key::from("foo")), - ]; + let args = vec![Value::from(pod_id), Value::from(secret_pod_id)]; assert!(helper_custom_operation_verify_gadget( ¶ms, @@ -2978,14 +2923,11 @@ mod tests { Value::from(42), ), Statement::not_equal( - AnchoredKey::new(pod_id, Key::from("foo")), + AnchoredKey::new(secret_pod_id, Key::from("key")), AnchoredKey::new(pod_id, Key::from("score")), ), ]; - let args = vec![ - WildcardValue::PodId(pod_id), - WildcardValue::Key(Key::from("foo")), - ]; + let args = vec![Value::from(pod_id), Value::from(secret_pod_id)]; assert!(helper_custom_operation_verify_gadget( ¶ms, @@ -2999,7 +2941,7 @@ mod tests { // OR (1) Two Nones let custom_predicate = CustomPredicateRef::new(batch.clone(), 1); let op_args = vec![Statement::None, Statement::None]; - let args = vec![WildcardValue::PodId(pod_id), WildcardValue::None]; + let args = vec![Value::from(pod_id), Value::from(0)]; assert!(helper_custom_operation_verify_gadget( ¶ms, diff --git a/src/backends/plonky2/mainpod/mod.rs b/src/backends/plonky2/mainpod/mod.rs index a814a77..06525ac 100644 --- a/src/backends/plonky2/mainpod/mod.rs +++ b/src/backends/plonky2/mainpod/mod.rs @@ -315,7 +315,12 @@ pub(crate) fn layout_statements( } // Input statements - assert!(inputs.statements.len() <= params.max_priv_statements()); + assert!( + inputs.statements.len() <= params.max_priv_statements(), + "inputs.statements.len={} > params.max_priv_statements={}", + inputs.statements.len(), + params.max_priv_statements() + ); for i in 0..params.max_priv_statements() { let mut st = inputs .statements @@ -329,9 +334,14 @@ pub(crate) fn layout_statements( // Public statements assert!(inputs.public_statements.len() < params.max_public_statements); + let pod_type = if mock { + PodType::MockMain + } else { + PodType::Main + }; let mut type_st = middleware::Statement::Equal( AnchoredKey::from((SELF, KEY_TYPE)).into(), - middleware::Value::from(PodType::MockMain).into(), + middleware::Value::from(pod_type).into(), ) .into(); pad_statement(params, &mut type_st); @@ -709,16 +719,13 @@ pub mod tests { primitives::ec::schnorr::SecretKey, signedpod::Signer, }, - examples::{ - eth_dos_pod_builder, eth_friend_signed_pod_builder, zu_kyc_pod_builder, - zu_kyc_sign_pod_builders, - }, + examples::{attest_eth_friend, zu_kyc_pod_builder, zu_kyc_sign_pod_builders, EthDosHelper}, frontend::{ - key, literal, CustomPredicateBatchBuilder, MainPodBuilder, StatementTmplBuilder as STB, + literal, CustomPredicateBatchBuilder, MainPodBuilder, StatementTmplBuilder as STB, {self}, }, middleware, - middleware::{CustomPredicateRef, NativePredicate as NP, DEFAULT_VD_SET}, + middleware::{CustomPredicateRef, NativePredicate as NP, Value, DEFAULT_VD_SET}, op, }; @@ -847,52 +854,31 @@ pub mod tests { #[test] fn test_main_ethdos() -> frontend::Result<()> { - let params = Params { - max_input_signed_pods: 2, - max_input_recursive_pods: 1, - max_statements: 26, - max_public_statements: 5, - max_signed_pod_values: 8, - max_operation_args: 5, - max_custom_predicate_wildcards: 6, - max_custom_predicate_verifications: 8, - ..Default::default() - }; + let params = Params::default(); println!("{:#?}", params); let vd_set = &*DEFAULT_VD_SET; let mut alice = Signer(SecretKey(1u32.into())); - let bob = Signer(SecretKey(2u32.into())); - let mut charlie = Signer(SecretKey(3u32.into())); + let mut bob = Signer(SecretKey(2u32.into())); + let charlie = Signer(SecretKey(3u32.into())); - // Alice attests that she is ETH friends with Charlie and Charlie - // attests that he is ETH friends with Bob. + // Alice attests that she is ETH friends with Bob and Bob + // attests that he is ETH friends with Charlie. let alice_attestation = - eth_friend_signed_pod_builder(¶ms, charlie.public_key().into()).sign(&mut alice)?; - let charlie_attestation = - eth_friend_signed_pod_builder(¶ms, bob.public_key().into()).sign(&mut charlie)?; - - let alice_bob_ethdos_builder = eth_dos_pod_builder( - ¶ms, - &vd_set, - false, - &alice_attestation, - &charlie_attestation, - bob.public_key().into(), - )?; - - let mut prover = MockProver {}; - let pod = alice_bob_ethdos_builder.prove(&mut prover, ¶ms)?; - assert!(pod.pod.verify().is_ok()); + attest_eth_friend(¶ms, &mut alice, Value::from(bob.public_key())); + let bob_attestation = + attest_eth_friend(¶ms, &mut bob, Value::from(charlie.public_key())); + let helper = EthDosHelper::new(¶ms, vd_set, false, Value::from(alice.public_key()))?; let mut prover = Prover {}; - let alice_bob_ethdos = alice_bob_ethdos_builder.prove(&mut prover, ¶ms)?; - crate::measure_gates_print!(); - let pod = (alice_bob_ethdos.pod as Box) - .downcast::() - .unwrap(); - - Ok(pod.verify()?) + let dist_1 = helper + .dist_1(&alice_attestation)? + .prove(&mut prover, ¶ms)?; + dist_1.pod.verify()?; + let dist_2 = helper + .dist_n_plus_1(&dist_1, &bob_attestation)? + .prove(&mut prover, ¶ms)?; + Ok(dist_2.pod.verify()?) } #[test] @@ -914,19 +900,17 @@ pub mod tests { let vd_set = &*DEFAULT_VD_SET; let mut cpb_builder = CustomPredicateBatchBuilder::new(params.clone(), "cpb".into()); - let stb0 = STB::new(NP::Equal) - .arg(("id", key("score"))) - .arg(literal(42)); + let stb0 = STB::new(NP::Equal).arg(("id", "score")).arg(literal(42)); let stb1 = STB::new(NP::Equal) - .arg(("id", "secret_key")) - .arg(("id", key("score"))); + .arg(("secret_id", "key")) + .arg(("id", "score")); let _ = cpb_builder.predicate_and( "pred_and", &["id"], - &["secret_key"], + &["secret_id"], &[stb0.clone(), stb1.clone()], )?; - let _ = cpb_builder.predicate_or("pred_or", &["id"], &["secret_key"], &[stb0, stb1])?; + let _ = cpb_builder.predicate_or("pred_or", &["id"], &["secret_id"], &[stb0, stb1])?; let cpb = cpb_builder.finish(); let cpb_and = CustomPredicateRef::new(cpb.clone(), 0); @@ -934,8 +918,8 @@ pub mod tests { let mut pod_builder = MainPodBuilder::new(¶ms, &vd_set); - let st0 = pod_builder.priv_op(op!(new_entry, ("score", 42)))?; - let st1 = pod_builder.priv_op(op!(new_entry, ("foo", 42)))?; + let st0 = pod_builder.priv_op(op!(new_entry, "score", 42))?; + let st1 = pod_builder.priv_op(op!(new_entry, "key", 42))?; let st2 = pod_builder.priv_op(op!(eq, st1.clone(), st0.clone()))?; let _st3 = pod_builder.priv_op(op!(custom, cpb_and.clone(), st0, st2))?; diff --git a/src/backends/plonky2/mainpod/statement.rs b/src/backends/plonky2/mainpod/statement.rs index a02bee3..60c7c76 100644 --- a/src/backends/plonky2/mainpod/statement.rs +++ b/src/backends/plonky2/mainpod/statement.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::{ backends::plonky2::error::{Error, Result}, - middleware::{self, NativePredicate, Params, Predicate, StatementArg, ToFields, WildcardValue}, + middleware::{self, NativePredicate, Params, Predicate, StatementArg, ToFields, Value}, }; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -74,11 +74,11 @@ impl TryFrom for middleware::Statement { )))?, }, Predicate::Custom(cpr) => { - let vs: Vec = proper_args + let vs: Vec = proper_args .into_iter() .filter_map(|arg| match arg { SA::None => None, - SA::WildcardLiteral(v) => Some(v), + SA::Literal(v) => Some(v), _ => unreachable!(), }) .collect(); diff --git a/src/backends/plonky2/mock/signedpod.rs b/src/backends/plonky2/mock/signedpod.rs index c0ebaa6..d1d088a 100644 --- a/src/backends/plonky2/mock/signedpod.rs +++ b/src/backends/plonky2/mock/signedpod.rs @@ -10,9 +10,9 @@ use crate::{ }, constants::MAX_DEPTH, middleware::{ - containers::Dictionary, hash_str, serialization::ordered_map, AnchoredKey, DynError, Hash, - Key, Params, Pod, PodId, PodSigner, PodType, RawValue, Statement, Value, KEY_SIGNER, - KEY_TYPE, SELF, + containers::Dictionary, hash_str, serialization::ordered_map, AnchoredKey, DynError, Key, + Params, Pod, PodId, PodSigner, PodType, RawValue, Statement, Value, KEY_SIGNER, KEY_TYPE, + SELF, }, }; @@ -21,8 +21,8 @@ pub struct MockSigner { } impl MockSigner { - pub fn public_key(&self) -> Hash { - hash_str(&self.pk) + pub fn public_key(&self) -> Value { + Value::from(hash_str(&self.pk)) } } @@ -30,7 +30,7 @@ impl MockSigner { fn _sign(&mut self, params: &Params, kvs: &HashMap) -> Result { let mut kvs = kvs.clone(); let pubkey = self.public_key(); - kvs.insert(Key::from(KEY_SIGNER), Value::from(pubkey)); + kvs.insert(Key::from(KEY_SIGNER), pubkey.clone()); kvs.insert(Key::from(KEY_TYPE), Value::from(PodType::MockSigned)); let dict = Dictionary::new(params.max_depth_mt_containers, kvs.clone())?; diff --git a/src/examples/custom.rs b/src/examples/custom.rs index a64131c..4273f17 100644 --- a/src/examples/custom.rs +++ b/src/examples/custom.rs @@ -1,134 +1,70 @@ use std::sync::Arc; -use StatementTmplBuilder as STB; - use crate::{ - frontend::{key, literal, CustomPredicateBatchBuilder, Result, StatementTmplBuilder}, - middleware::{ - CustomPredicateBatch, CustomPredicateRef, NativePredicate as NP, Params, PodType, - Predicate, KEY_SIGNER, KEY_TYPE, - }, + frontend::Result, + lang::parse, + middleware::{CustomPredicateBatch, Params, PodType, Value, KEY_SIGNER, KEY_TYPE}, }; -/// Instantiates an ETH friend batch -pub fn eth_friend_batch(params: &Params, mock: bool) -> Result> { - let pod_type = if mock { +macro_rules! render { + ($tmpl: expr, $($arg:tt)*) => {{ + format!( + $tmpl, + KEY_TYPE = Value::from(KEY_TYPE), + KEY_SIGNER = Value::from(KEY_SIGNER), + $($arg)* + ) + }}; +} + +/// Instantiates an ETHDos batch +pub fn eth_dos_batch(params: &Params, mock: bool) -> Result> { + let pod_type = Value::from(if mock { PodType::MockSigned } else { PodType::Signed - }; - let mut builder = CustomPredicateBatchBuilder::new(params.clone(), "eth_friend".into()); - let _eth_friend = builder.predicate_and( - "eth_friend", - // arguments: - &["src_key", "dst_key"], - // private arguments: - &["attestation_pod"], - // statement templates: - &[ - // there is an attestation pod that's a SignedPod - STB::new(NP::Equal) - .arg(("attestation_pod", key(KEY_TYPE))) - .arg(literal(pod_type)), - // the attestation pod is signed by (src_or, src_key) - STB::new(NP::Equal) - .arg(("attestation_pod", key(KEY_SIGNER))) - .arg(("SELF", "src_key")), - // that same attestation pod has an "attestation" - STB::new(NP::Equal) - .arg(("attestation_pod", key("attestation"))) - .arg(("SELF", "dst_key")), - ], - )?; + }); + let input = render!( + r#" + eth_friend(src, dst, private: attestation_pod) = AND( + Equal(?attestation_pod[{KEY_TYPE}], {pod_type}) + Equal(?attestation_pod[{KEY_SIGNER}], ?src) + Equal(?attestation_pod["attestation"], ?dst) + ) - println!("a.0. {}", builder.predicates.last().unwrap()); - Ok(builder.finish()) + eth_dos_base(src, dst, distance) = AND( + Equal(?src, ?dst) + Equal(?distance, 0) + ) + + eth_dos_ind(src, dst, distance, private: shorter_distance, intermed) = AND( + eth_dos(?src, ?intermed, ?shorter_distance) + SumOf(?distance, ?shorter_distance, 1) + eth_friend(?intermed, ?dst) + ) + + eth_dos(src, dst, distance) = OR( + eth_dos_base(?src, ?dst, ?distance) + eth_dos_ind(?src, ?dst, ?distance) + ) + "#, + pod_type = pod_type, + ); + let batch = parse(&input, params, &[]).expect("lang parse").custom_batch; + println!("a.0. {}", batch.predicates[0]); + println!("a.1. {}", batch.predicates[1]); + println!("a.2. {}", batch.predicates[2]); + println!("a.3. {}", batch.predicates[3]); + Ok(batch) } -/// Instantiates an ETHDoS batch -pub fn eth_dos_batch(params: &Params, mock: bool) -> Result> { - let eth_friend = Predicate::Custom(CustomPredicateRef::new(eth_friend_batch(params, mock)?, 0)); - let mut builder = - CustomPredicateBatchBuilder::new(params.clone(), "eth_dos_distance_base".into()); +#[cfg(test)] +mod tests { + use super::*; - // eth_dos_distance_base(src_or, src_key, dst_or, dst_key, distance_or, distance_key) = and< - // eq(src_or, src_key, dst_or, dst_key), - // ValueOf(distance_or, distance_key, 0) - // > - let eth_dos_distance_base = builder.predicate_and( - "eth_dos_distance_base", - &[ - // arguments: - "src_key", - "dst_key", - "distance_key", - ], - &[ // private arguments: - ], - &[ - // statement templates: - STB::new(NP::Equal) - .arg(("SELF", "src_key")) - .arg(("SELF", "dst_key")), - STB::new(NP::Equal) - .arg(("SELF", "distance_key")) - .arg(literal(0)), - ], - )?; - println!("b.0. {}", builder.predicates.last().unwrap()); - - let eth_dos_distance = Predicate::BatchSelf(2); - - let eth_dos_distance_ind = builder.predicate_and( - "eth_dos_distance_ind", - &[ - // arguments: - "src_key", - "dst_key", - "distance_key", - ], - &[ - // private arguments: - "one_key", - "shorter_distance_key", - "intermed_key", - ], - &[ - // statement templates: - STB::new(eth_dos_distance) - .arg("src_key") - .arg("intermed_key") - .arg("shorter_distance_key"), - // distance == shorter_distance + 1 - STB::new(NP::Equal).arg(("SELF", "one_key")).arg(literal(1)), - STB::new(NP::SumOf) - .arg(("SELF", "distance_key")) - .arg(("SELF", "shorter_distance_key")) - .arg(("SELF", "one_key")), - // intermed is a friend of dst - STB::new(eth_friend).arg("intermed_key").arg("dst_key"), - ], - )?; - - println!("b.1. {}", builder.predicates.last().unwrap()); - - let _eth_dos_distance = builder.predicate_or( - "eth_dos_distance", - &["src_key", "dst_key", "distance_key"], - &[], - &[ - STB::new(eth_dos_distance_base) - .arg("src_key") - .arg("dst_key") - .arg("distance_key"), - STB::new(eth_dos_distance_ind) - .arg("src_key") - .arg("dst_key") - .arg("distance_key"), - ], - )?; - - println!("b.2. {}", builder.predicates.last().unwrap()); - - Ok(builder.finish()) + #[test] + fn test_eth_friend_batch() { + let params = Params::default(); + eth_dos_batch(¶ms, true).unwrap(); + } } diff --git a/src/examples/mod.rs b/src/examples/mod.rs index f8f6963..10213d2 100644 --- a/src/examples/mod.rs +++ b/src/examples/mod.rs @@ -1,15 +1,17 @@ pub mod custom; -use std::collections::HashSet; +use std::{collections::HashSet, sync::LazyLock}; -use custom::{eth_dos_batch, eth_friend_batch}; +use custom::eth_dos_batch; + +pub const MOCK_VD_SET: LazyLock = LazyLock::new(|| VDSet::new(6, &[]).unwrap()); use crate::{ backends::plonky2::mock::signedpod::MockSigner, - frontend::{MainPodBuilder, Result, SignedPod, SignedPodBuilder}, + frontend::{MainPod, MainPodBuilder, Result, SignedPod, SignedPodBuilder}, middleware::{ - containers::Set, CustomPredicateRef, Params, PodType, Statement, TypedValue, VDSet, Value, - DEFAULT_VD_SET, KEY_SIGNER, KEY_TYPE, + containers::Set, CustomPredicateRef, Params, PodSigner, PodType, Predicate, Statement, + StatementArg, TypedValue, VDSet, Value, KEY_SIGNER, KEY_TYPE, }, op, }; @@ -71,146 +73,167 @@ pub fn zu_kyc_pod_builder( // ETHDoS -pub fn eth_friend_signed_pod_builder(params: &Params, friend_pubkey: Value) -> SignedPodBuilder { +pub fn attest_eth_friend(params: &Params, src: &mut impl PodSigner, dst: Value) -> SignedPod { let mut attestation = SignedPodBuilder::new(params); - attestation.insert("attestation", friend_pubkey); - - attestation + attestation.insert("attestation", dst); + attestation.sign(src).unwrap() } -pub fn eth_dos_pod_builder( - params: &Params, - vd_set: &VDSet, +pub struct EthDosHelper { + params: Params, + vd_set: VDSet, mock: bool, - alice_attestation: &SignedPod, - charlie_attestation: &SignedPod, - bob_pubkey: Value, -) -> Result { - // Will need ETH friend and ETH DoS custom predicate batches. - let eth_friend = CustomPredicateRef::new(eth_friend_batch(params, mock)?, 0); - let eth_dos_batch = eth_dos_batch(params, mock)?; - let eth_dos_base = CustomPredicateRef::new(eth_dos_batch.clone(), 0); - let eth_dos_ind = CustomPredicateRef::new(eth_dos_batch.clone(), 1); - let eth_dos = CustomPredicateRef::new(eth_dos_batch.clone(), 2); + eth_friend: CustomPredicateRef, + eth_dos_base: CustomPredicateRef, + eth_dos_ind: CustomPredicateRef, + eth_dos: CustomPredicateRef, + src: Value, +} - // ETHDoS POD builder - let mut alice_bob_ethdos = MainPodBuilder::new(params, vd_set); - alice_bob_ethdos.add_signed_pod(alice_attestation); - alice_bob_ethdos.add_signed_pod(charlie_attestation); +impl EthDosHelper { + pub fn new(params: &Params, vd_set: &VDSet, mock: bool, src: Value) -> Result { + let eth_dos_batch = eth_dos_batch(params, mock)?; + let eth_friend = eth_dos_batch.predicate_ref_by_name("eth_friend").unwrap(); + let eth_dos_base = eth_dos_batch.predicate_ref_by_name("eth_dos_base").unwrap(); + let eth_dos_ind = eth_dos_batch.predicate_ref_by_name("eth_dos_ind").unwrap(); + let eth_dos = eth_dos_batch.predicate_ref_by_name("eth_dos").unwrap(); + Ok(Self { + params: params.clone(), + vd_set: vd_set.clone(), + mock, + eth_friend, + eth_dos_base, + eth_dos_ind, + eth_dos, + src, + }) + } - // Attestation POD entries - let alice_pubkey = alice_attestation - .get(KEY_SIGNER) - .expect("Could not find Alice's public key!") - .clone(); - let charlie_pubkey = charlie_attestation - .get(KEY_SIGNER) - .expect("Could not find Charlie's public key!") - .clone(); + pub fn dist_1(&self, src_attestation: &SignedPod) -> Result { + assert_eq!( + &self.src, + src_attestation.get(KEY_SIGNER).expect("get KEY_SIGNER") + ); - // Include Alice and Bob's keys as public statements. We don't - // want to reveal the middleman. - let alice_pubkey_copy = alice_bob_ethdos.pub_op(op!(new_entry, ("Alice", alice_pubkey)))?; - let bob_pubkey_copy = alice_bob_ethdos.pub_op(op!(new_entry, ("Bob", bob_pubkey.clone())))?; - let charlie_pubkey = alice_bob_ethdos.priv_op(op!(new_entry, ("Charlie", charlie_pubkey)))?; + let mut pod = MainPodBuilder::new(&self.params, &self.vd_set); + pod.add_signed_pod(src_attestation); - // The ETHDoS distance from Alice to Alice is 0. - let zero = alice_bob_ethdos.priv_literal(0)?; - let alice_equals_alice = alice_bob_ethdos.priv_op(op!( - eq, - alice_pubkey_copy.clone(), - alice_pubkey_copy.clone() - ))?; - let ethdos_alice_alice_is_zero_base = alice_bob_ethdos.priv_op(op!( - custom, - eth_dos_base.clone(), - alice_equals_alice, - zero.clone() - ))?; - let ethdos_alice_alice_is_zero = alice_bob_ethdos.priv_op(op!( - custom, - eth_dos.clone(), - ethdos_alice_alice_is_zero_base, - Statement::None - ))?; + let src_eq_src = pod.priv_op(op!(eq, self.src.clone(), self.src.clone()))?; + let distance_eq_zero = pod.priv_op(op!(eq, 0, 0))?; + let eth_dos_src_to_src_base = pod.priv_op(op!( + custom, + self.eth_dos_base.clone(), + src_eq_src, + distance_eq_zero + ))?; + let eth_dos_src_to_src = pod.priv_op(op!( + custom, + self.eth_dos.clone(), + eth_dos_src_to_src_base, + Statement::None + ))?; - // Alice and Charlie are ETH friends. - let attestation_is_signed_pod = alice_attestation.get_statement(KEY_TYPE).unwrap(); - let attestation_signed_by_alice = - alice_bob_ethdos.priv_op(op!(eq, (alice_attestation, KEY_SIGNER), alice_pubkey_copy))?; - let alice_attests_to_charlie = alice_bob_ethdos.priv_op(op!( - eq, - (alice_attestation, "attestation"), - charlie_pubkey.clone() - ))?; - let ethfriends_alice_charlie = alice_bob_ethdos.priv_op(op!( - custom, - eth_friend.clone(), - attestation_is_signed_pod, - attestation_signed_by_alice, - alice_attests_to_charlie - ))?; + // eth_dos src->dst dist=1 + self.n_plus_1(&mut pod, eth_dos_src_to_src, src_attestation, 0)?; - // ...and so are Chuck and Bob. - let attestation_is_signed_pod = charlie_attestation.get_statement(KEY_TYPE).unwrap(); - let attestation_signed_by_charlie = - alice_bob_ethdos.priv_op(op!(eq, (charlie_attestation, KEY_SIGNER), charlie_pubkey))?; - let charlie_attests_to_bob = alice_bob_ethdos.priv_op(op!( - eq, - (charlie_attestation, "attestation"), - bob_pubkey_copy - ))?; - let ethfriends_charlie_bob = alice_bob_ethdos.priv_op(op!( - custom, - eth_friend.clone(), - attestation_is_signed_pod, - attestation_signed_by_charlie, - charlie_attests_to_bob - ))?; + Ok(pod) + } - // The ETHDoS distance from Alice to Charlie is 1. - let one = alice_bob_ethdos.priv_literal(1)?; - // 1 = 0 + 1 - let ethdos_sum = - alice_bob_ethdos.priv_op(op!(sum_of, one.clone(), zero.clone(), one.clone()))?; - let ethdos_alice_charlie_is_one_ind = alice_bob_ethdos.priv_op(op!( - custom, - eth_dos_ind.clone(), - ethdos_alice_alice_is_zero, - one.clone(), - ethdos_sum, - ethfriends_alice_charlie - ))?; - let ethdos_alice_charlie_is_one = alice_bob_ethdos.priv_op(op!( - custom, - eth_dos.clone(), - Statement::None, - ethdos_alice_charlie_is_one_ind - ))?; + pub fn dist_n_plus_1( + &self, + eth_dos_src_to_int_pod: &MainPod, + int_attestation: &SignedPod, // int signs dst + ) -> Result { + assert_eq!( + Value::from(if self.mock { + PodType::MockMain + } else { + PodType::Main + }), + eth_dos_src_to_int_pod.get(KEY_TYPE).expect("get KEY_TYPE") + ); - // The ETHDoS distance from Alice to Bob is 2. - // The constant "TWO" and the final statement are both to be - // public. - let two = alice_bob_ethdos.pub_literal(2)?; - // 2 = 1 + 1 - let ethdos_sum = - alice_bob_ethdos.priv_op(op!(sum_of, two.clone(), one.clone(), one.clone()))?; - let ethdos_alice_bob_is_two_ind = alice_bob_ethdos.priv_op(op!( - custom, - eth_dos_ind.clone(), - ethdos_alice_charlie_is_one, - one.clone(), - ethdos_sum, - ethfriends_charlie_bob - ))?; - let _ethdos_alice_bob_is_two = alice_bob_ethdos.pub_op(op!( - custom, - eth_dos.clone(), - Statement::None, - ethdos_alice_bob_is_two_ind - ))?; + let mut pod = MainPodBuilder::new(&self.params, &self.vd_set); + pod.add_signed_pod(int_attestation); + pod.add_main_pod(eth_dos_src_to_int_pod.clone()); - Ok(alice_bob_ethdos) + let eth_dos_int_to_dst = eth_dos_src_to_int_pod + .pod + .pub_statements() + .into_iter() + .rev() // Find the last predicate because dist_1 has two: dist=0, dist=1 + .find(|st| st.predicate() == Predicate::Custom(self.eth_dos.clone())) + .expect("eth_dos custom predicate"); + let [_src, int, n] = { + let args: [_; 3] = eth_dos_int_to_dst.args().try_into().expect("Vec::len=3"); + args.map(|arg| match arg { + StatementArg::Literal(v) => v, + _ => panic!("expected StatementArg::Literal"), + }) + }; + assert_eq!( + &int, + int_attestation.get(KEY_SIGNER).expect("get KEY_SIGNER") + ); + + let n_i64 = if let TypedValue::Int(x) = n.typed() { + *x + } else { + panic!("distance value is not Int") + }; + + // eth_dos src->dst dist=n+1 + self.n_plus_1(&mut pod, eth_dos_int_to_dst, int_attestation, n_i64)?; + + Ok(pod) + } + + fn n_plus_1( + &self, + pod: &mut MainPodBuilder, + eth_dos_int_to_dst: Statement, + int_attestation: &SignedPod, + n: i64, + ) -> Result<()> { + assert_eq!( + &Value::from(if self.mock { + PodType::MockSigned + } else { + PodType::Signed + }), + int_attestation.get(KEY_TYPE).expect("get KEY_TYPE") + ); + + // eth_friend statement + let attestation_is_signed_pod = int_attestation.get_statement(KEY_TYPE).unwrap(); + let attestation_signed_by_int = int_attestation.get_statement(KEY_SIGNER).unwrap(); + let int_attests_to_dst = int_attestation.get_statement("attestation").unwrap(); + let ethfriends_int_dst = pod.priv_op(op!( + custom, + self.eth_friend.clone(), + attestation_is_signed_pod, + attestation_signed_by_int, + int_attests_to_dst + ))?; + + // distance = n + 1 + let ethdos_sum = pod.priv_op(op!(sum_of, n + 1, n, 1))?; + let eth_dos_src_to_dst_ind = pod.priv_op(op!( + custom, + self.eth_dos_ind.clone(), + eth_dos_int_to_dst, + ethdos_sum, + ethfriends_int_dst + ))?; + let _eth_dos_src_dst = pod.pub_op(op!( + custom, + self.eth_dos.clone(), + Statement::None, + eth_dos_src_to_dst_ind + ))?; + + Ok(()) + } } // GreatBoy @@ -309,7 +332,7 @@ pub fn great_boy_pod_full_flow() -> Result<(Params, MainPodBuilder)> { num_public_statements_id: 50, ..Default::default() }; - let vd_set = &*DEFAULT_VD_SET; + let vd_set = &*MOCK_VD_SET; let good_boy_issuers = ["Giggles", "Macrosoft", "FaeBook"]; let mut giggles_signer = MockSigner { @@ -413,7 +436,7 @@ pub fn tickets_pod_builder( pub fn tickets_pod_full_flow() -> Result { let params = Params::default(); - let vd_set = &*DEFAULT_VD_SET; + let vd_set = &*MOCK_VD_SET; let builder = tickets_sign_pod_builder(¶ms); let signed_pod = builder.sign(&mut MockSigner { pk: "test".into() }).unwrap(); tickets_pod_builder( diff --git a/src/frontend/custom.rs b/src/frontend/custom.rs index 095bf9d..a2a970b 100644 --- a/src/frontend/custom.rs +++ b/src/frontend/custom.rs @@ -6,67 +6,31 @@ use schemars::JsonSchema; use crate::{ frontend::{AnchoredKey, Error, Result, Statement, StatementArg}, middleware::{ - self, hash_str, CustomPredicate, CustomPredicateBatch, Key, KeyOrWildcard, NativePredicate, - Params, PodId, Predicate, SelfOrWildcard, StatementTmpl, StatementTmplArg, ToFields, Value, - Wildcard, + self, hash_str, CustomPredicate, CustomPredicateBatch, Key, NativePredicate, Params, PodId, + Predicate, StatementTmpl, StatementTmplArg, ToFields, Value, Wildcard, }, }; -#[derive(Clone, Debug, PartialEq, Eq)] -/// Argument to a statement template -pub enum KeyOrWildcardStr { - Key(String), // represents a literal key - Wildcard(String), -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum SelfOrWildcardStr { - SELF, - Wildcard(String), -} - -/// helper to build a literal KeyOrWildcardStr::Key from the given str -pub fn key(s: &str) -> KeyOrWildcardStr { - KeyOrWildcardStr::Key(s.to_string()) -} - /// Builder Argument for the StatementTmplBuilder #[derive(Clone, Debug)] pub enum BuilderArg { Literal(Value), - /// Key: (origin, key), where origin is SELF or Wildcard and key is Key or Wildcard - Key(SelfOrWildcardStr, KeyOrWildcardStr), + /// Key: (origin, key), where origin is Wildcard and key is Key + Key(String, String), WildcardLiteral(String), } -impl From<&str> for SelfOrWildcardStr { - fn from(origin: &str) -> Self { - if origin == "SELF" { - SelfOrWildcardStr::SELF - } else { - SelfOrWildcardStr::Wildcard(origin.into()) - } - } -} - /// When defining a `BuilderArg`, it can be done from 3 different inputs: -/// i. (&str, literal): this is to set a POD and a field, ie. (POD, literal("field")) -/// ii. (&str, &str): this is to define a origin-key wildcard pair, ie. (src_origin, src_dest) -/// iii. &str: this is to define a WildcardValue wildcard, ie. "src_or" +/// i. (&str, &str): this is to define a origin-key pair, ie. ?attestation_pod["attestation"]) +/// ii. &str: this is to define a Value wildcard, ie. ?distance /// /// case i. -impl From<(&str, KeyOrWildcardStr)> for BuilderArg { - fn from((origin, lit): (&str, KeyOrWildcardStr)) -> Self { - Self::Key(origin.into(), lit) +impl From<(&str, &str)> for BuilderArg { + fn from((origin, field): (&str, &str)) -> Self { + Self::Key(origin.to_string(), field.to_string()) } } /// case ii. -impl From<(&str, &str)> for BuilderArg { - fn from((origin, field): (&str, &str)) -> Self { - Self::Key(origin.into(), KeyOrWildcardStr::Wildcard(field.to_string())) - } -} -/// case iii. impl From<&str> for BuilderArg { fn from(wc: &str) -> Self { Self::WildcardLiteral(wc.to_string()) @@ -216,12 +180,12 @@ impl CustomPredicateBatchBuilder { .iter() .map(|a| match a { BuilderArg::Literal(v) => StatementTmplArg::Literal(v.clone()), - BuilderArg::Key(pod_id, key) => StatementTmplArg::AnchoredKey( - resolve_self_or_wildcard(args, priv_args, pod_id), - resolve_key_or_wildcard(args, priv_args, key), + BuilderArg::Key(pod_id_wc, key_str) => StatementTmplArg::AnchoredKey( + resolve_wildcard(args, priv_args, pod_id_wc), + Key::from(key_str), ), BuilderArg::WildcardLiteral(v) => { - StatementTmplArg::WildcardLiteral(resolve_wildcard(args, priv_args, v)) + StatementTmplArg::Wildcard(resolve_wildcard(args, priv_args, v)) } }) .collect(); @@ -251,32 +215,6 @@ impl CustomPredicateBatchBuilder { } } -fn resolve_self_or_wildcard( - args: &[&str], - priv_args: &[&str], - v: &SelfOrWildcardStr, -) -> SelfOrWildcard { - match v { - SelfOrWildcardStr::SELF => SelfOrWildcard::SELF, - SelfOrWildcardStr::Wildcard(s) => { - SelfOrWildcard::Wildcard(resolve_wildcard(args, priv_args, s)) - } - } -} - -fn resolve_key_or_wildcard( - args: &[&str], - priv_args: &[&str], - v: &KeyOrWildcardStr, -) -> KeyOrWildcard { - match v { - KeyOrWildcardStr::Key(k) => KeyOrWildcard::Key(Key::from(k)), - KeyOrWildcardStr::Wildcard(s) => { - KeyOrWildcard::Wildcard(resolve_wildcard(args, priv_args, s)) - } - } -} - fn resolve_wildcard(args: &[&str], priv_args: &[&str], s: &str) -> Wildcard { args.iter() .chain(priv_args.iter()) @@ -292,7 +230,7 @@ mod tests { use super::*; use crate::{ backends::plonky2::mock::mainpod::MockProver, - examples::custom::{eth_dos_batch, eth_friend_batch}, + examples::{custom::eth_dos_batch, MOCK_VD_SET}, frontend::MainPodBuilder, middleware::{self, containers::Set, CustomPredicateRef, Params, PodType, DEFAULT_VD_SET}, op, @@ -311,12 +249,11 @@ mod tests { params.print_serialized_sizes(); // ETH friend custom predicate batch - let eth_friend = eth_friend_batch(¶ms, true)?; + let eth_dos_batch = eth_dos_batch(¶ms, true)?; // This batch only has 1 predicate, so we pick it already for convenience - let eth_friend = Predicate::Custom(CustomPredicateRef::new(eth_friend, 0)); + let eth_friend = eth_dos_batch.predicate_ref_by_name("eth_friend").unwrap(); - let eth_dos_batch = eth_dos_batch(¶ms, true)?; let eth_dos_batch_mw: middleware::CustomPredicateBatch = Arc::unwrap_or_clone(eth_dos_batch); let fields = eth_dos_batch_mw.to_fields(¶ms); @@ -328,7 +265,7 @@ mod tests { #[test] fn test_desugared_gt_custom_pred() -> Result<()> { let params = Params::default(); - let vd_set = &*DEFAULT_VD_SET; + let vd_set = &*MOCK_VD_SET; let mut builder = CustomPredicateBatchBuilder::new(params.clone(), "gt_custom_pred".into()); let gt_stb = StatementTmplBuilder::new(NativePredicate::Gt) @@ -337,7 +274,7 @@ mod tests { builder.predicate_and( "gt_custom_pred", - &["s1_origin", "s1_key", "s2_origin", "s2_key"], + &["s1_origin", "s2_origin"], &[], &[gt_stb], )?; @@ -348,8 +285,8 @@ mod tests { let mut mp_builder = MainPodBuilder::new(¶ms, &vd_set); // 2 > 1 - let s1 = mp_builder.literal(true, Value::from(2))?; - let s2 = mp_builder.literal(true, Value::from(1))?; + let s1 = mp_builder.priv_op(op!(new_entry, "s1_key", Value::from(2)))?; + let s2 = mp_builder.priv_op(op!(new_entry, "s2_key", Value::from(1)))?; // Adding a gt operation will produce a desugared lt operation let desugared_gt = mp_builder.pub_op(op!(gt, s1, s2))?; @@ -377,7 +314,7 @@ mod tests { #[test] fn test_desugared_set_contains_custom_pred() -> Result<()> { let params = Params::default(); - let vd_set = &*DEFAULT_VD_SET; + let vd_set = &*MOCK_VD_SET; let mut builder = CustomPredicateBatchBuilder::new(params.clone(), "set_contains_custom_pred".into()); @@ -387,7 +324,7 @@ mod tests { builder.predicate_and( "set_contains_custom_pred", - &["s1_origin", "s1_key", "s2_origin", "s2_key"], + &["s1_origin", "s2_origin"], &[], &[set_contains_stb], )?; @@ -397,11 +334,12 @@ mod tests { let mut mp_builder = MainPodBuilder::new(¶ms, &vd_set); let set_values: HashSet = [1, 2, 3].iter().map(|i| Value::from(*i)).collect(); - let s1 = mp_builder.literal( - true, - Value::from(Set::new(params.max_depth_mt_containers, set_values)?), - )?; - let s2 = mp_builder.literal(true, Value::from(1))?; + let s1 = mp_builder.priv_op(op!( + new_entry, + "s1_key", + Value::from(Set::new(params.max_depth_mt_containers, set_values)?) + ))?; + let s2 = mp_builder.priv_op(op!(new_entry, "s2_key", Value::from(1)))?; let set_contains = mp_builder.pub_op(op!(set_contains, s1, s2))?; assert_eq!( diff --git a/src/frontend/error.rs b/src/frontend/error.rs index a578d56..2341300 100644 --- a/src/frontend/error.rs +++ b/src/frontend/error.rs @@ -1,15 +1,29 @@ use std::{backtrace::Backtrace, fmt::Debug}; -use crate::middleware::{DynError, Statement, StatementTmpl}; +use crate::middleware::{DynError, Statement, StatementTmpl, Value}; pub type Result = core::result::Result; +fn display_wc_map(wc_map: &[Option]) -> String { + let mut out = String::new(); + use std::fmt::Write; + for (i, v) in wc_map.iter().enumerate() { + write!(out, "- {}: ", i).unwrap(); + if let Some(v) = v { + writeln!(out, "{}", v).unwrap(); + } else { + writeln!(out, "none").unwrap(); + } + } + out +} + #[derive(thiserror::Error, Debug)] pub enum InnerError { #[error("{0} {1} is over the limit {2}")] MaxLength(String, usize, usize), - #[error("{0} doesn't match {1}")] - StatementsDontMatch(Statement, StatementTmpl), + #[error("{0} doesn't match {1:#}.\nWildcard map:\n{map}", map=display_wc_map(.2))] + StatementsDontMatch(Statement, StatementTmpl, Vec>), #[error("invalid arguments to {0} operation")] OpInvalidArgs(String), // Other @@ -54,8 +68,12 @@ impl Error { pub(crate) fn op_invalid_args(s: String) -> Self { new!(OpInvalidArgs(s)) } - pub(crate) fn statements_dont_match(s0: Statement, s1: StatementTmpl) -> Self { - new!(StatementsDontMatch(s0, s1)) + pub(crate) fn statements_dont_match( + s0: Statement, + s1: StatementTmpl, + wc_map: Vec>, + ) -> Self { + new!(StatementsDontMatch(s0, s1, wc_map)) } pub(crate) fn max_length(obj: String, found: usize, expect: usize) -> Self { new!(MaxLength(obj, found, expect)) diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs index d42644a..090134f 100644 --- a/src/frontend/mod.rs +++ b/src/frontend/mod.rs @@ -10,7 +10,7 @@ use serialization::{SerializedMainPod, SerializedSignedPod}; use crate::middleware::{ self, check_st_tmpl, hash_op, hash_str, max_op, prod_op, sum_op, AnchoredKey, Key, MainPodInputs, NativeOperation, OperationAux, OperationType, Params, PodId, PodProver, - PodSigner, Statement, StatementArg, VDSet, Value, ValueRef, WildcardValue, KEY_TYPE, SELF, + PodSigner, Statement, StatementArg, VDSet, Value, ValueRef, KEY_TYPE, SELF, }; mod custom; @@ -49,6 +49,8 @@ impl SignedPodBuilder { self.kvs.insert(key.into(), value.into()); } + // TODO: Remove mut because Schnorr signature doesn't need any mutability of the signer, the + // nonces are sourced from OS randomness. pub fn sign(&self, signer: &mut S) -> Result { // Sign POD with committed KV store. let pod = signer.sign(&self.params, &self.kvs)?; @@ -471,12 +473,15 @@ impl MainPodBuilder { let st_args = st.args(); for (st_tmpl_arg, st_arg) in st_tmpl.args.iter().zip(&st_args) { if !check_st_tmpl(st_tmpl_arg, st_arg, &mut wildcard_map) { - // TODO: Add wildcard_map in the error for better context - return Err(Error::statements_dont_match(st.clone(), st_tmpl.clone())); + return Err(Error::statements_dont_match( + st.clone(), + st_tmpl.clone(), + wildcard_map, + )); } } } - let v_default = WildcardValue::PodId(SELF); + let v_default = Value::from(0); let st_args: Vec<_> = wildcard_map .into_iter() .take(pred.args_len) @@ -762,7 +767,7 @@ pub mod build_utils { #[macro_export] macro_rules! op { - (new_entry, ($key:expr, $value:expr)) => { $crate::frontend::Operation( + (new_entry, $key:expr, $value:expr) => { $crate::frontend::Operation( $crate::middleware::OperationType::Native($crate::middleware::NativeOperation::NewEntry), $crate::op_args!(($key, $value)), $crate::middleware::OperationAux::None) }; (copy, $($arg:expr),+) => { $crate::frontend::Operation( @@ -821,14 +826,15 @@ pub mod build_utils { #[cfg(test)] pub mod tests { + use super::*; use crate::{ backends::plonky2::mock::{mainpod::MockProver, signedpod::MockSigner}, examples::{ - eth_dos_pod_builder, eth_friend_signed_pod_builder, great_boy_pod_full_flow, - tickets_pod_full_flow, zu_kyc_pod_builder, zu_kyc_sign_pod_builders, + attest_eth_friend, great_boy_pod_full_flow, tickets_pod_full_flow, zu_kyc_pod_builder, + zu_kyc_sign_pod_builders, EthDosHelper, MOCK_VD_SET, }, - middleware::{containers::Dictionary, Value, DEFAULT_VD_SET}, + middleware::{containers::Dictionary, Value}, }; // Check that frontend public statements agree with those @@ -863,7 +869,7 @@ pub mod tests { #[test] fn test_front_zu_kyc() -> Result<()> { let params = Params::default(); - let vd_set = &*DEFAULT_VD_SET; + let vd_set = &*MOCK_VD_SET; let (gov_id, pay_stub, sanction_list) = zu_kyc_sign_pod_builders(¶ms); println!("{}", gov_id); @@ -903,49 +909,45 @@ pub mod tests { } #[test] - fn test_ethdos() -> Result<()> { + fn test_ethdos_recursive() -> Result<()> { let params = Params { - max_input_signed_pods: 3, - max_input_recursive_pods: 3, - max_statements: 31, - max_signed_pod_values: 8, - max_public_statements: 10, - max_statement_args: 6, - max_operation_args: 5, - max_custom_predicate_arity: 5, - max_custom_batch_size: 5, - max_custom_predicate_wildcards: 12, + max_input_pods_public_statements: 8, + max_statements: 24, + max_public_statements: 8, ..Default::default() }; - let vd_set = &*DEFAULT_VD_SET; + let vd_set = &*MOCK_VD_SET; let mut alice = MockSigner { pk: "Alice".into() }; - let bob = MockSigner { pk: "Bob".into() }; + let mut bob = MockSigner { pk: "Bob".into() }; let mut charlie = MockSigner { pk: "Charlie".into(), }; + let david = MockSigner { pk: "David".into() }; - // Alice attests that she is ETH friends with Charlie and Charlie - // attests that he is ETH friends with Bob. - let alice_attestation = - eth_friend_signed_pod_builder(¶ms, charlie.public_key().into()).sign(&mut alice)?; - check_kvs(&alice_attestation)?; - let charlie_attestation = - eth_friend_signed_pod_builder(¶ms, bob.public_key().into()).sign(&mut charlie)?; - check_kvs(&charlie_attestation)?; + let helper = EthDosHelper::new(¶ms, vd_set, true, alice.public_key())?; let mut prover = MockProver {}; - let alice_bob_ethdos = eth_dos_pod_builder( - ¶ms, - &vd_set, - true, - &alice_attestation, - &charlie_attestation, - bob.public_key().into(), - )? - .prove(&mut prover, ¶ms)?; - check_public_statements(&alice_bob_ethdos) + let alice_attestation = attest_eth_friend(¶ms, &mut alice, bob.public_key()); + let dist_1 = helper + .dist_1(&alice_attestation)? + .prove(&mut prover, ¶ms)?; + dist_1.pod.verify()?; + + let bob_attestation = attest_eth_friend(¶ms, &mut bob, charlie.public_key()); + let dist_2 = helper + .dist_n_plus_1(&dist_1, &bob_attestation)? + .prove(&mut prover, ¶ms)?; + dist_2.pod.verify()?; + + let charlie_attestation = attest_eth_friend(¶ms, &mut charlie, david.public_key()); + let dist_3 = helper + .dist_n_plus_1(&dist_2, &charlie_attestation)? + .prove(&mut prover, ¶ms)?; + dist_3.pod.verify()?; + + Ok(()) } #[test] @@ -971,7 +973,7 @@ pub mod tests { #[should_panic] fn test_equal() { let params = Params::default(); - let vd_set = &*DEFAULT_VD_SET; + let vd_set = &*MOCK_VD_SET; let mut signed_builder = SignedPodBuilder::new(¶ms); signed_builder.insert("a", 1); @@ -1023,7 +1025,7 @@ pub mod tests { #[should_panic] fn test_false_st() { let params = Params::default(); - let vd_set = &*DEFAULT_VD_SET; + let vd_set = &*MOCK_VD_SET; let mut builder = SignedPodBuilder::new(¶ms); builder.insert("num", 2); @@ -1049,7 +1051,7 @@ pub mod tests { #[test] fn test_dictionaries() -> Result<()> { let params = Params::default(); - let vd_set = &*DEFAULT_VD_SET; + let vd_set = &*MOCK_VD_SET; let mut builder = SignedPodBuilder::new(¶ms); let mut my_dict_kvs: HashMap = HashMap::new(); @@ -1070,7 +1072,7 @@ pub mod tests { let mut builder = MainPodBuilder::new(¶ms, &vd_set); builder.add_signed_pod(&pod); let st0 = pod.get_statement("dict").unwrap(); - let st1 = builder.op(true, op!(new_entry, ("key", "a"))).unwrap(); + let st1 = builder.op(true, op!(new_entry, "key", "a")).unwrap(); let st2 = builder.literal(false, Value::from(1)).unwrap(); builder @@ -1103,7 +1105,7 @@ pub mod tests { env_logger::init(); let params = Params::default(); - let vd_set = &*DEFAULT_VD_SET; + let vd_set = &*MOCK_VD_SET; let mut builder = MainPodBuilder::new(¶ms, &vd_set); let st = Statement::equal(AnchoredKey::from((SELF, "a")), Value::from(3)); let op_new_entry = Operation( @@ -1127,7 +1129,7 @@ pub mod tests { // 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 vd_set = &*DEFAULT_VD_SET; + let vd_set = &*MOCK_VD_SET; let mut builder = MainPodBuilder::new(¶ms, &vd_set); let self_a = AnchoredKey::from((SELF, "a")); let self_b = AnchoredKey::from((SELF, "b")); diff --git a/src/frontend/serialization.rs b/src/frontend/serialization.rs index 62dc4f4..a7bb9b1 100644 --- a/src/frontend/serialization.rs +++ b/src/frontend/serialization.rs @@ -105,8 +105,8 @@ mod tests { signedpod::Signer, }, examples::{ - eth_dos_pod_builder, eth_friend_signed_pod_builder, zu_kyc_pod_builder, - zu_kyc_sign_pod_builders, + attest_eth_friend, zu_kyc_pod_builder, zu_kyc_sign_pod_builders, EthDosHelper, + MOCK_VD_SET, }, frontend::{Result, SignedPodBuilder}, middleware::{ @@ -251,7 +251,7 @@ mod tests { fn build_mock_zukyc_pod() -> Result { let params = middleware::Params::default(); - let vd_set = &*DEFAULT_VD_SET; + let vd_set = &*MOCK_VD_SET; let (gov_id_builder, pay_stub_builder, sanction_list_builder) = zu_kyc_sign_pod_builders(¶ms); @@ -341,45 +341,34 @@ mod tests { fn build_ethdos_pod() -> Result { let params = Params { - max_input_signed_pods: 3, - max_input_recursive_pods: 3, - max_statements: 31, - max_signed_pod_values: 8, - max_public_statements: 10, - max_statement_args: 6, - max_operation_args: 5, - max_custom_predicate_arity: 5, - max_custom_batch_size: 5, - max_custom_predicate_wildcards: 12, + max_input_pods_public_statements: 8, + max_statements: 24, + max_public_statements: 8, ..Default::default() }; - let vd_set = &*DEFAULT_VD_SET; + let vd_set = &*MOCK_VD_SET; let mut alice = MockSigner { pk: "Alice".into() }; - let bob = MockSigner { pk: "Bob".into() }; - let mut charlie = MockSigner { + let mut bob = MockSigner { pk: "Bob".into() }; + let charlie = MockSigner { pk: "Charlie".into(), }; - // Alice attests that she is ETH friends with Charlie and Charlie - // attests that he is ETH friends with Bob. - let alice_attestation = - eth_friend_signed_pod_builder(¶ms, charlie.public_key().into()).sign(&mut alice)?; - let charlie_attestation = - eth_friend_signed_pod_builder(¶ms, bob.public_key().into()).sign(&mut charlie)?; + // Alice attests that she is ETH friends with Bob and Bob + // attests that he is ETH friends with Charlie. + let alice_attestation = attest_eth_friend(¶ms, &mut alice, bob.public_key()); + let bob_attestation = attest_eth_friend(¶ms, &mut bob, charlie.public_key()); + let helper = EthDosHelper::new(¶ms, vd_set, true, alice.public_key())?; let mut prover = MockProver {}; - let alice_bob_ethdos = eth_dos_pod_builder( - ¶ms, - &vd_set, - true, - &alice_attestation, - &charlie_attestation, - bob.public_key().into(), - )? - .prove(&mut prover, ¶ms)?; + let dist_1 = helper + .dist_1(&alice_attestation)? + .prove(&mut prover, ¶ms)?; + let dist_2 = helper + .dist_n_plus_1(&dist_1, &bob_attestation)? + .prove(&mut prover, ¶ms)?; - Ok(alice_bob_ethdos) + Ok(dist_2) } #[test] diff --git a/src/lang/grammar.pest b/src/lang/grammar.pest index 0a7de02..ef0ce01 100644 --- a/src/lang/grammar.pest +++ b/src/lang/grammar.pest @@ -54,8 +54,8 @@ statement_arg_list = { statement_arg ~ ("," ~ statement_arg)* } statement = { identifier ~ "(" ~ statement_arg_list? ~ ")" } -// Anchored Key: (SELF | ?Var)["key_literal" | ?KeyVar] -anchored_key = { ( self_keyword | wildcard ) ~ "[" ~ (wildcard | literal_string) ~ "]" } +// Anchored Key: ?Var["key_literal"] +anchored_key = { wildcard ~ "[" ~ literal_string ~ "]" } // Literal Values (ordered to avoid ambiguity, e.g., string before int) literal_value = { diff --git a/src/lang/mod.rs b/src/lang/mod.rs index 0bbefed..1cdee76 100644 --- a/src/lang/mod.rs +++ b/src/lang/mod.rs @@ -29,9 +29,9 @@ mod tests { use crate::{ lang::error::ProcessorError, middleware::{ - CustomPredicate, CustomPredicateBatch, CustomPredicateRef, Key, KeyOrWildcard, - NativePredicate, Params, PodType, Predicate, SelfOrWildcard, StatementTmpl, - StatementTmplArg, Value, Wildcard, SELF_ID_HASH, + CustomPredicate, CustomPredicateBatch, CustomPredicateRef, Key, NativePredicate, + Params, PodType, Predicate, StatementTmpl, StatementTmplArg, Value, Wildcard, + SELF_ID_HASH, }, }; @@ -40,23 +40,12 @@ mod tests { Wildcard::new(name.to_string(), index) } - fn k(name: &str) -> KeyOrWildcard { - KeyOrWildcard::Key(Key::new(name.to_string())) + fn sta_ak(pod_var: (&str, usize), key: &str) -> StatementTmplArg { + StatementTmplArg::AnchoredKey(wc(pod_var.0, pod_var.1), Key::from(key)) } - fn ko_wc(name: &str, index: usize) -> KeyOrWildcard { - KeyOrWildcard::Wildcard(Wildcard::new(name.to_string(), index)) - } - - fn sta_ak(pod_var: (&str, usize), key_or_wc: KeyOrWildcard) -> StatementTmplArg { - StatementTmplArg::AnchoredKey( - SelfOrWildcard::Wildcard(wc(pod_var.0, pod_var.1)), - key_or_wc, - ) - } - - fn sta_ak_self(key_or_wc: KeyOrWildcard) -> StatementTmplArg { - StatementTmplArg::AnchoredKey(SelfOrWildcard::SELF, key_or_wc) + fn sta_wc_lit(name: &str, index: usize) -> StatementTmplArg { + StatementTmplArg::Wildcard(wc(name, index)) } fn sta_lit(value: impl Into) -> StatementTmplArg { @@ -89,8 +78,8 @@ mod tests { let expected_statements = vec![StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), args: vec![ - sta_ak(("PodA", 0), k("the_key")), // ?PodA["the_key"] -> Wildcard(0), Key("the_key") - sta_ak(("PodB", 1), k("the_key")), // ?PodB["the_key"] -> Wildcard(1), Key("the_key") + sta_ak(("PodA", 0), "the_key"), // ?PodA["the_key"] -> Wildcard(0), Key("the_key") + sta_ak(("PodB", 1), "the_key"), // ?PodB["the_key"] -> Wildcard(1), Key("the_key") ], }]; let expected_predicate = CustomPredicate::and( @@ -135,15 +124,15 @@ mod tests { StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), args: vec![ - sta_ak(("ConstPod", 0), k("my_val")), // ?ConstPod["my_val"] -> Wildcard(0), Key("my_val") + sta_ak(("ConstPod", 0), "my_val"), // ?ConstPod["my_val"] -> Wildcard(0), Key("my_val") sta_lit(SELF_ID_HASH), ], }, StatementTmpl { pred: Predicate::Native(NativePredicate::Lt), args: vec![ - sta_ak(("GovPod", 1), k("dob")), // ?GovPod["dob"] -> Wildcard(1), Key("dob") - sta_ak(("ConstPod", 0), k("my_val")), // ?ConstPod["my_val"] -> Wildcard(0), Key("my_val") + sta_ak(("GovPod", 1), "dob"), // ?GovPod["dob"] -> Wildcard(1), Key("dob") + sta_ak(("ConstPod", 0), "my_val"), // ?ConstPod["my_val"] -> Wildcard(0), Key("my_val") ], }, ]; @@ -177,15 +166,15 @@ mod tests { StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), args: vec![ - sta_ak(("A", 0), k("input_key")), // ?A["input_key"] -> Wildcard(0), Key("input_key") - sta_ak(("Temp", 1), k("const_key")), // ?Temp["const_key"] -> Wildcard(1), Key("const_key") + sta_ak(("A", 0), "input_key"), // ?A["input_key"] -> Wildcard(0), Key("input_key") + sta_ak(("Temp", 1), "const_key"), // ?Temp["const_key"] -> Wildcard(1), Key("const_key") ], }, StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), args: vec![ - sta_ak(("Temp", 1), k("const_key")), // ?Temp["const_key"] -> Wildcard(1), Key("const_key") - sta_lit("some_value"), // Literal("some_value") + sta_ak(("Temp", 1), "const_key"), // ?Temp["const_key"] -> Wildcard(1), Key("const_key") + sta_lit("some_value"), // Literal("some_value") ], }, ]; @@ -234,8 +223,8 @@ mod tests { let expected_pred_statements = vec![StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), args: vec![ - sta_ak(("X", 0), k("val")), // ?X["val"] -> Wildcard(0), Key("val") - sta_ak(("Y", 1), k("val")), // ?Y["val"] -> Wildcard(1), Key("val") + sta_ak(("X", 0), "val"), // ?X["val"] -> Wildcard(0), Key("val") + sta_ak(("Y", 1), "val"), // ?Y["val"] -> Wildcard(1), Key("val") ], }]; let expected_predicate = CustomPredicate::and( @@ -258,8 +247,8 @@ mod tests { let expected_request_templates = vec![StatementTmpl { pred: Predicate::Custom(CustomPredicateRef::new(expected_batch, 0)), args: vec![ - StatementTmplArg::WildcardLiteral(wc("Pod1", 0)), - StatementTmplArg::WildcardLiteral(wc("Pod2", 1)), + StatementTmplArg::Wildcard(wc("Pod1", 0)), + StatementTmplArg::Wildcard(wc("Pod2", 1)), ], }]; @@ -271,7 +260,7 @@ mod tests { #[test] fn test_e2e_request_with_various_args() -> Result<(), LangError> { let input = r#" - some_pred(A, B, C) = AND( Equal(?A["foo"], ?B["bar"]) ) + some_pred(A, B, C) = AND( Equal(?A["foo"], ?B["bar"]) ) REQUEST( some_pred( @@ -302,7 +291,7 @@ mod tests { StatementTmpl { pred: Predicate::Custom(CustomPredicateRef::new(batch_result, 0)), // Refers to some_pred args: vec![ - StatementTmplArg::WildcardLiteral(wc("Var1", 0)), // ?Var1 + StatementTmplArg::Wildcard(wc("Var1", 0)), // ?Var1 StatementTmplArg::Literal(Value::from(12345i64)), // 12345 StatementTmplArg::Literal(Value::from("hello_string")), // "hello_string" ], @@ -311,9 +300,9 @@ mod tests { pred: Predicate::Native(NativePredicate::Equal), args: vec![ // ?AnotherPod["another_key"] -> Wildcard(1), Key("another_key") - sta_ak(("AnotherPod", 1), k("another_key")), + sta_ak(("AnotherPod", 1), "another_key"), // ?Var1["some_field"] -> Wildcard(0), Key("some_field") - sta_ak(("Var1", 0), k("some_field")), + sta_ak(("Var1", 0), "some_field"), ], }, ]; @@ -348,30 +337,30 @@ mod tests { let expected_templates = vec![ StatementTmpl { pred: Predicate::Native(NativePredicate::LtEq), - args: vec![sta_ak(("B", 1), k("bar")), sta_ak(("A", 0), k("foo"))], + args: vec![sta_ak(("B", 1), "bar"), sta_ak(("A", 0), "foo")], }, StatementTmpl { pred: Predicate::Native(NativePredicate::Lt), - args: vec![sta_ak(("D", 3), k("qux")), sta_ak(("C", 2), k("baz"))], + args: vec![sta_ak(("D", 3), "qux"), sta_ak(("C", 2), "baz")], }, StatementTmpl { pred: Predicate::Native(NativePredicate::Contains), args: vec![ - sta_ak(("A", 0), k("foo")), - sta_ak(("B", 1), k("bar")), - sta_ak(("C", 2), k("baz")), + sta_ak(("A", 0), "foo"), + sta_ak(("B", 1), "bar"), + sta_ak(("C", 2), "baz"), ], }, StatementTmpl { pred: Predicate::Native(NativePredicate::NotContains), - args: vec![sta_ak(("A", 0), k("foo")), sta_ak(("B", 1), k("bar"))], + args: vec![sta_ak(("A", 0), "foo"), sta_ak(("B", 1), "bar")], }, StatementTmpl { pred: Predicate::Native(NativePredicate::Contains), args: vec![ - sta_ak(("A", 0), k("foo")), - sta_ak(("B", 1), k("bar")), - sta_ak(("C", 2), k("baz")), + sta_ak(("A", 0), "foo"), + sta_ak(("B", 1), "bar"), + sta_ak(("C", 2), "baz"), ], }, ]; @@ -386,12 +375,12 @@ mod tests { let input = r#" REQUEST( // Order matters for comparison with the hardcoded templates - SetNotContains(?sanctions["sanctionList"], ?gov["idNumber"]) - Lt(?gov["dateOfBirth"], ?SELF_HOLDER_18Y["const_18y"]) - Equal(?pay["startDate"], ?SELF_HOLDER_1Y["const_1y"]) - Equal(?gov["socialSecurityNumber"], ?pay["socialSecurityNumber"]) - Equal(?SELF_HOLDER_18Y["const_18y"], 1169909388) - Equal(?SELF_HOLDER_1Y["const_1y"], 1706367566) + SetNotContains(?sanctions["sanctionList"], ?gov["idNumber"]) + Lt(?gov["dateOfBirth"], ?SELF_HOLDER_18Y["const_18y"]) + Equal(?pay["startDate"], ?SELF_HOLDER_1Y["const_1y"]) + Equal(?gov["socialSecurityNumber"], ?pay["socialSecurityNumber"]) + Equal(?SELF_HOLDER_18Y["const_18y"], 1169909388) + Equal(?SELF_HOLDER_1Y["const_1y"], 1706367566) ) "#; @@ -412,13 +401,13 @@ mod tests { let wc_pay = wc("pay", 3); let wc_self_1y = wc("SELF_HOLDER_1Y", 4); - let id_num_key = k("idNumber"); - let dob_key = k("dateOfBirth"); - let const_18y_key = k("const_18y"); - let start_date_key = k("startDate"); - let const_1y_key = k("const_1y"); - let ssn_key = k("socialSecurityNumber"); - let sanction_list_key = k("sanctionList"); + let id_num_key = "idNumber"; + let dob_key = "dateOfBirth"; + let const_18y_key = "const_18y"; + let start_date_key = "startDate"; + let const_1y_key = "const_1y"; + let ssn_key = "socialSecurityNumber"; + let sanction_list_key = "sanctionList"; // Define the request templates using wildcards for constants let expected_templates = vec![ @@ -428,19 +417,19 @@ mod tests { args: vec![ sta_ak( (wc_sanctions.name.as_str(), wc_sanctions.index), - sanction_list_key.clone(), + sanction_list_key, ), - sta_ak((wc_gov.name.as_str(), wc_gov.index), id_num_key.clone()), + sta_ak((wc_gov.name.as_str(), wc_gov.index), id_num_key), ], }, // 2. Lt(?gov["dateOfBirth"], ?SELF_HOLDER_18Y["const_18y"]) StatementTmpl { pred: Predicate::Native(NativePredicate::Lt), args: vec![ - sta_ak((wc_gov.name.as_str(), wc_gov.index), dob_key.clone()), + sta_ak((wc_gov.name.as_str(), wc_gov.index), dob_key), sta_ak( (wc_self_18y.name.as_str(), wc_self_18y.index), - const_18y_key.clone(), + const_18y_key, ), ], }, @@ -448,19 +437,16 @@ mod tests { StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), args: vec![ - sta_ak((wc_pay.name.as_str(), wc_pay.index), start_date_key.clone()), - sta_ak( - (wc_self_1y.name.as_str(), wc_self_1y.index), - const_1y_key.clone(), - ), + sta_ak((wc_pay.name.as_str(), wc_pay.index), start_date_key), + sta_ak((wc_self_1y.name.as_str(), wc_self_1y.index), const_1y_key), ], }, // 4. Equal(?gov["socialSecurityNumber"], ?pay["socialSecurityNumber"]) StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), args: vec![ - sta_ak((wc_gov.name.as_str(), wc_gov.index), ssn_key.clone()), - sta_ak((wc_pay.name.as_str(), wc_pay.index), ssn_key.clone()), + sta_ak((wc_gov.name.as_str(), wc_gov.index), ssn_key), + sta_ak((wc_pay.name.as_str(), wc_pay.index), ssn_key), ], }, // 5. Equal(?SELF_HOLDER_18Y["const_18y"], 1169909388) @@ -469,7 +455,7 @@ mod tests { args: vec![ sta_ak( (wc_self_18y.name.as_str(), wc_self_18y.index), - const_18y_key.clone(), + const_18y_key, ), sta_lit(now_minus_18y_val.clone()), ], @@ -478,10 +464,7 @@ mod tests { StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), args: vec![ - sta_ak( - (wc_self_1y.name.as_str(), wc_self_1y.index), - const_1y_key.clone(), - ), + sta_ak((wc_self_1y.name.as_str(), wc_self_1y.index), const_1y_key), sta_lit(now_minus_1y_val.clone()), ], }, @@ -517,27 +500,26 @@ mod tests { }; let input = r#" - eth_friend(src_key, dst_key, private: attestation_pod) = AND( + eth_friend(src, dst, private: attestation_pod) = AND( Equal(?attestation_pod["_type"], 1) - Equal(?attestation_pod["_signer"], SELF[?src_key]) - Equal(?attestation_pod["attestation"], SELF[?dst_key]) + Equal(?attestation_pod["_signer"], ?src) + Equal(?attestation_pod["attestation"], ?dst) ) - eth_dos_distance_base(src_key, dst_key, distance_key) = AND( - Equal(SELF[?src_key], SELF[?dst_key]) - Equal(SELF[?distance_key], 0) + eth_dos_distance_base(src, dst, distance) = AND( + Equal(?src, ?dst) + Equal(?distance, 0) ) - eth_dos_distance_ind(src_key, dst_key, distance_key, private: one_key, shorter_distance_key, intermed_key) = AND( - eth_dos_distance(?src_key, ?dst_key, ?distance_key) - Equal(SELF[?one_key], 1) - SumOf(SELF[?distance_key], SELF[?shorter_distance_key], SELF[?one_key]) - eth_friend(?intermed_key, ?dst_key) + eth_dos_distance_ind(src, dst, distance, private: shorter_distance, intermed) = AND( + eth_dos_distance(?src, ?dst, ?distance) + SumOf(?distance, ?shorter_distance, 1) + eth_friend(?intermed, ?dst) ) - eth_dos_distance(src_key, dst_key, distance_key) = OR( - eth_dos_distance_base(?src_key, ?dst_key, ?distance_key) - eth_dos_distance_ind(?src_key, ?dst_key, ?distance_key) + eth_dos_distance(src, dst, distance) = OR( + eth_dos_distance_base(?src, ?dst, ?distance) + eth_dos_distance_ind(?src, ?dst, ?distance) ) "#; @@ -560,22 +542,22 @@ mod tests { StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), args: vec![ - sta_ak(("attestation_pod", 2), k("_type")), // Pub(0-1), Priv(2) + sta_ak(("attestation_pod", 2), "_type"), // Pub(0-1), Priv(2) sta_lit(PodType::MockSigned), ], }, StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), args: vec![ - sta_ak(("attestation_pod", 2), k("_signer")), - sta_ak_self(ko_wc("src_key", 0)), // Pub arg 0 + sta_ak(("attestation_pod", 2), "_signer"), + sta_wc_lit("src", 0), // Pub arg 0 ], }, StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), args: vec![ - sta_ak(("attestation_pod", 2), k("attestation")), - sta_ak_self(ko_wc("dst_key", 1)), // Pub arg 1 + sta_ak(("attestation_pod", 2), "attestation"), + sta_wc_lit("dst", 1), // Pub arg 1 ], }, ]; @@ -584,22 +566,19 @@ mod tests { "eth_friend".to_string(), true, // AND expected_friend_stmts, - 2, // public_args_len: src_key, dst_key - names(&["src_key", "dst_key", "attestation_pod"]), + 2, // public_args_len: src, dst + names(&["src", "dst", "attestation_pod"]), )?; // eth_dos_distance_base (Index 1) let expected_base_stmts = vec![ StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), - args: vec![ - sta_ak_self(ko_wc("src_key", 0)), - sta_ak_self(ko_wc("dst_key", 1)), - ], + args: vec![sta_wc_lit("src", 0), sta_wc_lit("dst", 1)], }, StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), - args: vec![sta_ak_self(ko_wc("distance_key", 2)), sta_lit(0i64)], + args: vec![sta_wc_lit("distance", 2), sta_lit(0i64)], }, ]; let expected_base_pred = CustomPredicate::new( @@ -608,40 +587,36 @@ mod tests { true, // AND expected_base_stmts, 3, // public_args_len - names(&["src_key", "dst_key", "distance_key"]), + names(&["src", "dst", "distance"]), )?; // eth_dos_distance_ind (Index 2) // Public args indices: 0-2 - // Private args indices: 3-5 (one_key, shorter_distance_key, intermed_key) + // Private args indices: 3-4 (shorter_distance, intermed) let expected_ind_stmts = vec![ StatementTmpl { pred: Predicate::BatchSelf(3), // Calls eth_dos_distance (index 3) args: vec![ // WildcardLiteral args - StatementTmplArg::WildcardLiteral(wc("src_key", 0)), - StatementTmplArg::WildcardLiteral(wc("dst_key", 1)), // private arg - StatementTmplArg::WildcardLiteral(wc("distance_key", 2)), // private arg + sta_wc_lit("src", 0), + sta_wc_lit("dst", 1), // private arg + sta_wc_lit("distance", 2), // private arg ], }, - StatementTmpl { - pred: Predicate::Native(NativePredicate::Equal), - args: vec![sta_ak_self(ko_wc("one_key", 3)), sta_lit(1i64)], // private arg - }, StatementTmpl { pred: Predicate::Native(NativePredicate::SumOf), args: vec![ - sta_ak_self(ko_wc("distance_key", 2)), // public arg - sta_ak_self(ko_wc("shorter_distance_key", 4)), // private arg - sta_ak_self(ko_wc("one_key", 3)), // private arg + sta_wc_lit("distance", 2), // public arg + sta_wc_lit("shorter_distance", 3), // private arg + sta_lit(1), ], }, StatementTmpl { pred: Predicate::BatchSelf(0), // Calls eth_friend (index 0) args: vec![ // WildcardLiteral args - StatementTmplArg::WildcardLiteral(wc("intermed_key", 5)), // private arg - StatementTmplArg::WildcardLiteral(wc("dst_key", 1)), // public arg + sta_wc_lit("intermed", 4), // private arg + sta_wc_lit("dst", 1), // public arg ], }, ]; @@ -651,14 +626,7 @@ mod tests { true, // AND expected_ind_stmts, 3, // public_args_len - names(&[ - "src_key", - "dst_key", - "distance_key", - "one_key", - "shorter_distance_key", - "intermed_key", - ]), + names(&["src", "dst", "distance", "shorter_distance", "intermed"]), )?; // eth_dos_distance (Index 3) @@ -667,18 +635,18 @@ mod tests { pred: Predicate::BatchSelf(1), // Calls eth_dos_distance_base (index 1) args: vec![ // WildcardLiteral args - StatementTmplArg::WildcardLiteral(wc("src_key", 0)), - StatementTmplArg::WildcardLiteral(wc("dst_key", 1)), - StatementTmplArg::WildcardLiteral(wc("distance_key", 2)), + sta_wc_lit("src", 0), + sta_wc_lit("dst", 1), + sta_wc_lit("distance", 2), ], }, StatementTmpl { pred: Predicate::BatchSelf(2), // Calls eth_dos_distance_ind (index 2) args: vec![ // WildcardLiteral args - StatementTmplArg::WildcardLiteral(wc("src_key", 0)), - StatementTmplArg::WildcardLiteral(wc("dst_key", 1)), - StatementTmplArg::WildcardLiteral(wc("distance_key", 2)), + sta_wc_lit("src", 0), + sta_wc_lit("dst", 1), + sta_wc_lit("distance", 2), ], }, ]; @@ -688,7 +656,7 @@ mod tests { false, // OR expected_dist_stmts, 3, // public_args_len - names(&["src_key", "dst_key", "distance_key"]), + names(&["src", "dst", "distance"]), )?; let expected_batch = CustomPredicateBatch::new( @@ -718,8 +686,8 @@ mod tests { let imported_pred_stmts = vec![StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), args: vec![ - sta_ak(("A", 0), k("foo")), // ?A["foo"] - sta_ak(("B", 1), k("bar")), // ?B["bar"] + sta_ak(("A", 0), "foo"), // ?A["foo"] + sta_ak(("B", 1), "bar"), // ?B["bar"] ], }]; let imported_predicate = CustomPredicate::and( @@ -760,8 +728,8 @@ mod tests { let expected_request_templates = vec![StatementTmpl { pred: Predicate::Custom(CustomPredicateRef::new(available_batch, 0)), args: vec![ - StatementTmplArg::WildcardLiteral(wc("Pod1", 0)), - StatementTmplArg::WildcardLiteral(wc("Pod2", 1)), + StatementTmplArg::Wildcard(wc("Pod1", 0)), + StatementTmplArg::Wildcard(wc("Pod2", 1)), ], }]; @@ -808,11 +776,11 @@ mod tests { let expected_templates = vec![ StatementTmpl { pred: Predicate::Custom(CustomPredicateRef::new(available_batch.clone(), 0)), - args: vec![StatementTmplArg::WildcardLiteral(wc("Pod1", 0))], + args: vec![StatementTmplArg::Wildcard(wc("Pod1", 0))], }, StatementTmpl { pred: Predicate::Custom(CustomPredicateRef::new(available_batch, 2)), - args: vec![StatementTmplArg::WildcardLiteral(wc("Pod2", 1))], + args: vec![StatementTmplArg::Wildcard(wc("Pod2", 1))], }, ]; @@ -828,7 +796,7 @@ mod tests { // 1. Create a batch with a predicate to be imported let imported_pred_stmts = vec![StatementTmpl { pred: Predicate::Native(NativePredicate::Equal), - args: vec![sta_ak(("A", 0), k("foo")), sta_ak(("B", 1), k("bar"))], + args: vec![sta_ak(("A", 0), "foo"), sta_ak(("B", 1), "bar")], }]; let imported_predicate = CustomPredicate::and( ¶ms, @@ -876,8 +844,8 @@ mod tests { let expected_statement = StatementTmpl { pred: Predicate::Custom(CustomPredicateRef::new(available_batch.clone(), 0)), args: vec![ - StatementTmplArg::WildcardLiteral(wc("X", 0)), - StatementTmplArg::WildcardLiteral(wc("Y", 1)), + StatementTmplArg::Wildcard(wc("X", 0)), + StatementTmplArg::Wildcard(wc("Y", 1)), ], }; diff --git a/src/lang/parser.rs b/src/lang/parser.rs index a648fe6..d191769 100644 --- a/src/lang/parser.rs +++ b/src/lang/parser.rs @@ -86,12 +86,10 @@ mod tests { #[test] fn test_parse_anchored_key() { assert_parses(Rule::anchored_key, "?PodVar[\"literal_key\"]"); - assert_parses(Rule::anchored_key, "?PodVar[?KeyVar]"); - assert_parses(Rule::anchored_key, "SELF[?KeyVar]"); - assert_parses(Rule::anchored_key, "SELF[\"literal_key\"]"); assert_fails(Rule::anchored_key, "PodVar[\"key\"]"); // Needs wildcard for pod assert_fails(Rule::anchored_key, "?PodVar[invalid_key]"); // Key must be literal string or wildcard assert_fails(Rule::anchored_key, "?PodVar[]"); // Key cannot be empty + assert_fails(Rule::anchored_key, "?PodVar[?key]"); // Key cannot be wildcard } #[test] @@ -179,7 +177,7 @@ mod tests { Rule::test_custom_predicate_def, // Trimmed leading/trailing whitespace r#"pred_with_private(X, private: TempKey) = OR( - Equal(?X[?TempKey], ?X["other"]) + Equal(?X["key"], 1234) )"#, ); assert_fails( diff --git a/src/lang/processor.rs b/src/lang/processor.rs index 9c5c7c3..d042800 100644 --- a/src/lang/processor.rs +++ b/src/lang/processor.rs @@ -8,15 +8,11 @@ use plonky2::field::types::Field; use super::error::ProcessorError; use crate::{ - frontend::{ - BuilderArg, CustomPredicateBatchBuilder, KeyOrWildcardStr, SelfOrWildcardStr, - StatementTmplBuilder, - }, + frontend::{BuilderArg, CustomPredicateBatchBuilder, StatementTmplBuilder}, lang::parser::Rule, middleware::{ - self, CustomPredicateBatch, CustomPredicateRef, Key, KeyOrWildcard, NativePredicate, - Params, Predicate, SelfOrWildcard as MiddlewareSelfOrWildcard, StatementTmpl, - StatementTmplArg, Value, Wildcard, F, VALUE_SIZE, + self, CustomPredicateBatch, CustomPredicateRef, Key, NativePredicate, Params, Predicate, + StatementTmpl, StatementTmplArg, Value, Wildcard, F, VALUE_SIZE, }, }; @@ -305,34 +301,11 @@ fn pest_pair_to_builder_arg(arg_content_pair: &Pair) -> Result { let mut inner_ak_pairs = arg_content_pair.clone().into_inner(); let pod_id_pair = inner_ak_pairs.next().unwrap(); - - let pod_self_or_wc_str = match pod_id_pair.as_rule() { - Rule::wildcard => { - let name = pod_id_pair.as_str().strip_prefix("?").unwrap(); - SelfOrWildcardStr::Wildcard(name.to_string()) - } - Rule::self_keyword => SelfOrWildcardStr::SELF, - _ => { - unreachable!("Unexpected rule: {:?}", pod_id_pair.as_rule()); - } - }; + let pod_id_wc_str = pod_id_pair.as_str().strip_prefix("?").unwrap(); let key_part_pair = inner_ak_pairs.next().unwrap(); - - let key_or_wildcard_str = match key_part_pair.as_rule() { - Rule::wildcard => { - let key_wildcard_name = key_part_pair.as_str().strip_prefix("?").unwrap(); - KeyOrWildcardStr::Wildcard(key_wildcard_name.to_string()) - } - Rule::literal_string => { - let key_str_literal = parse_pest_string_literal(&key_part_pair)?; - KeyOrWildcardStr::Key(key_str_literal) - } - _ => { - unreachable!("Unexpected rule: {:?}", key_part_pair.as_rule()); - } - }; - Ok(BuilderArg::Key(pod_self_or_wc_str, key_or_wildcard_str)) + let key_str = parse_pest_string_literal(&key_part_pair)?; + Ok(BuilderArg::Key(pod_id_wc_str.to_string(), key_str)) } _ => unreachable!("Unexpected rule: {:?}", arg_content_pair.as_rule()), } @@ -377,23 +350,6 @@ fn validate_and_build_statement_template( span: Some(stmt_name_span), }); } - - if expected_arity > 0 { - for (i, arg) in args.iter().enumerate() { - if !matches!(arg, BuilderArg::Key(..) | BuilderArg::Literal(..)) { - return Err(ProcessorError::TypeError { - expected: "Anchored Key".to_string(), - found: format!("{:?}", arg), - item: format!( - "argument {} of native predicate '{}'", - i + 1, - stmt_name_str - ), - span: Some(stmt_span), - }); - } - } - } } Predicate::Custom(custom_ref) => { let expected_arity = custom_ref.predicate().args_len; @@ -635,13 +591,8 @@ fn process_statement_template( for arg in &builder_args { match arg { BuilderArg::WildcardLiteral(name) => temp_stmt_wildcard_names.push(name.clone()), - BuilderArg::Key(pod_id_str, key_wc_str) => { - if let SelfOrWildcardStr::Wildcard(name) = pod_id_str { - temp_stmt_wildcard_names.push(name.clone()); - } - if let KeyOrWildcardStr::Wildcard(key_wc_name) = key_wc_str { - temp_stmt_wildcard_names.push(key_wc_name.clone()); - } + BuilderArg::Key(pod_id_wc_str, _key_str) => { + temp_stmt_wildcard_names.push(pod_id_wc_str.clone()); } _ => {} } @@ -873,19 +824,6 @@ fn resolve_wildcard( }) } -fn resolve_key_or_wildcard_str( - ordered_scope_wildcard_names: &[String], - kows: &KeyOrWildcardStr, -) -> Result { - match kows { - KeyOrWildcardStr::Key(k_str) => Ok(KeyOrWildcard::Key(Key::new(k_str.clone()))), - KeyOrWildcardStr::Wildcard(wc_name_str) => { - let resolved_wc = resolve_wildcard(ordered_scope_wildcard_names, wc_name_str)?; - Ok(KeyOrWildcard::Wildcard(resolved_wc)) - } - } -} - fn resolve_request_statement_builder( stb: StatementTmplBuilder, ordered_request_wildcard_names: &[String], @@ -897,20 +835,14 @@ fn resolve_request_statement_builder( for builder_arg in stb.args { let mw_arg = match builder_arg { BuilderArg::Literal(v) => StatementTmplArg::Literal(v), - BuilderArg::Key(pod_id_str, key_wc_str) => { - let pod_sowc = match pod_id_str { - SelfOrWildcardStr::SELF => MiddlewareSelfOrWildcard::SELF, - SelfOrWildcardStr::Wildcard(name) => MiddlewareSelfOrWildcard::Wildcard( - resolve_wildcard(ordered_request_wildcard_names, &name)?, - ), - }; - let key_or_wc = - resolve_key_or_wildcard_str(ordered_request_wildcard_names, &key_wc_str)?; - StatementTmplArg::AnchoredKey(pod_sowc, key_or_wc) + BuilderArg::Key(pod_id_wc_str, key_str) => { + let pod_id_wc = resolve_wildcard(ordered_request_wildcard_names, &pod_id_wc_str)?; + let key = Key::from(key_str); + StatementTmplArg::AnchoredKey(pod_id_wc, key) } BuilderArg::WildcardLiteral(wc_name) => { - let pod_wc = resolve_wildcard(ordered_request_wildcard_names, &wc_name)?; - StatementTmplArg::WildcardLiteral(pod_wc) + let wc = resolve_wildcard(ordered_request_wildcard_names, &wc_name)?; + StatementTmplArg::Wildcard(wc) } }; middleware_args.push(mw_arg); @@ -1183,7 +1115,7 @@ mod processor_tests { // Native predicate names are case-sensitive let input = r#" REQUEST( - EQUAL(?A[?B], ?C[?D]) + EQUAL(?A["b"], ?C["d"]) ) "#; let pairs = get_document_content_pairs(input)?; diff --git a/src/middleware/basetypes.rs b/src/middleware/basetypes.rs index 00b7acd..f54a413 100644 --- a/src/middleware/basetypes.rs +++ b/src/middleware/basetypes.rs @@ -206,6 +206,7 @@ impl Ord for Hash { } } +// TODO: In alternate mode, don't shorten the hash impl fmt::Display for Hash { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let v0 = self.0[0].to_canonical_u64(); diff --git a/src/middleware/custom.rs b/src/middleware/custom.rs index c587bd1..e7168f3 100644 --- a/src/middleware/custom.rs +++ b/src/middleware/custom.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use crate::middleware::{ hash_fields, Error, Hash, Key, NativePredicate, Params, Predicate, Result, ToFields, Value, - EMPTY_HASH, F, HASH_SIZE, VALUE_SIZE, + EMPTY_HASH, F, VALUE_SIZE, }; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)] @@ -37,75 +37,14 @@ impl ToFields for Wildcard { } } -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "type", content = "value")] -pub enum KeyOrWildcard { - Key(Key), - Wildcard(Wildcard), -} - -impl fmt::Display for KeyOrWildcard { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Key(k) => k.fmt(f), - Self::Wildcard(wc) => wc.fmt(f), - } - } -} - -impl ToFields for KeyOrWildcard { - // Encoding: - // - Key(k) => [[k]] - // - Wildcard(index) => [[index + 1], 0, 0, 0] - fn to_fields(&self, params: &Params) -> Vec { - match self { - KeyOrWildcard::Key(k) => k.hash().to_fields(params), - KeyOrWildcard::Wildcard(wc) => iter::once(F::from_canonical_u64(wc.index as u64 + 1)) - .chain(iter::repeat(F::ZERO)) - .take(HASH_SIZE) - .collect(), - } - } -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "type", content = "value")] -pub enum SelfOrWildcard { - SELF, - Wildcard(Wildcard), -} - -impl fmt::Display for SelfOrWildcard { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::SELF => write!(f, "SELF"), - Self::Wildcard(wc) => wc.fmt(f), - } - } -} - -impl ToFields for SelfOrWildcard { - // Encoding: - // - Self => [0] - // - Wildcard(index) => [index+1] - fn to_fields(&self, _params: &Params) -> Vec { - match self { - SelfOrWildcard::SELF => vec![F::ZERO], - SelfOrWildcard::Wildcard(wc) => vec![F::from_canonical_u64(wc.index as u64 + 1)], - } - } -} - #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)] #[serde(tag = "type", content = "value")] pub enum StatementTmplArg { None, Literal(Value), - // AnchoredKey - AnchoredKey(SelfOrWildcard, KeyOrWildcard), - // TODO: This naming is a bit confusing: a WildcardLiteral that contains a Wildcard... - // Could we merge WildcardValue and Value and allow wildcard value apart from pod_id and key? - WildcardLiteral(Wildcard), + // AnchoredKey where the origin is a wildcard + AnchoredKey(Wildcard, Key), + Wildcard(Wildcard), } #[derive(Clone, Copy)] @@ -154,7 +93,7 @@ impl ToFields for StatementTmplArg { .collect(); fields } - StatementTmplArg::WildcardLiteral(wc) => { + StatementTmplArg::Wildcard(wc) => { let fields: Vec = iter::once(F::from(StatementTmplArgPrefix::WildcardLiteral)) .chain(wc.to_fields(params)) .chain(iter::repeat(F::ZERO)) @@ -177,7 +116,7 @@ impl fmt::Display for StatementTmplArg { key.fmt(f)?; write!(f, "]") } - Self::WildcardLiteral(v) => v.fmt(f), + Self::Wildcard(v) => v.fmt(f), } } } @@ -208,7 +147,7 @@ impl fmt::Display for StatementTmpl { } arg.fmt(f)?; } - writeln!(f) + write!(f, ")") } } @@ -451,6 +390,15 @@ impl CustomPredicateBatch { pub fn predicates(&self) -> &[CustomPredicate] { &self.predicates } + pub fn predicate_ref_by_name( + self: &Arc, + name: &str, + ) -> Option { + self.predicates + .iter() + .enumerate() + .find_map(|(i, cp)| (cp.name == name).then(|| CustomPredicateRef::new(self.clone(), i))) + } } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)] @@ -473,26 +421,19 @@ impl CustomPredicateRef { #[cfg(test)] mod tests { - use std::array; - - use plonky2::field::goldilocks_field::GoldilocksField; - use super::*; use crate::middleware::{ - AnchoredKey, CustomPredicate, CustomPredicateBatch, CustomPredicateRef, Hash, - KeyOrWildcard, NativePredicate, Operation, Params, PodId, PodType, Predicate, Statement, - StatementTmpl, StatementTmplArg, WildcardValue, SELF, + AnchoredKey, CustomPredicate, CustomPredicateBatch, CustomPredicateRef, Key, + NativePredicate, Operation, Params, PodType, Predicate, Statement, StatementTmpl, + StatementTmplArg, SELF, }; fn st(p: Predicate, args: Vec) -> StatementTmpl { StatementTmpl { pred: p, args } } - fn kow_wc(i: usize) -> KOW { - KOW::Wildcard(wc(i)) - } - fn sow_wc(i: usize) -> SOW { - SOW::Wildcard(wc(i)) + fn key(name: &str) -> Key { + Key::from(name) } fn wc(i: usize) -> Wildcard { Wildcard { @@ -505,8 +446,6 @@ mod tests { } type STA = StatementTmplArg; - type KOW = KeyOrWildcard; - type SOW = SelfOrWildcard; type P = Predicate; type NP = NativePredicate; @@ -528,41 +467,35 @@ mod tests { vec![ st( P::Native(NP::Equal), - vec![ - STA::AnchoredKey(sow_wc(4), kow_wc(5)), - STA::Literal(2.into()), - ], + vec![STA::AnchoredKey(wc(1), key("c")), STA::Literal(2.into())], ), st( P::Native(NP::ProductOf), vec![ - STA::AnchoredKey(sow_wc(0), kow_wc(1)), - STA::AnchoredKey(sow_wc(4), kow_wc(5)), - STA::AnchoredKey(sow_wc(2), kow_wc(3)), + STA::AnchoredKey(wc(0), key("a")), + STA::AnchoredKey(wc(1), key("b")), + STA::Literal(Value::from(3)), ], ), ], - 2, - names(&["1", "2", "3", "4", "5"]), + 1, + names(&["0", "1", "2"]), )?], ); let custom_statement = Statement::Custom( CustomPredicateRef::new(cust_pred_batch.clone(), 0), - vec![ - WildcardValue::PodId(SELF), - WildcardValue::Key(Key::from("Some value")), - ], + vec![Value::from(SELF)], ); let custom_deduction = Operation::Custom( CustomPredicateRef::new(cust_pred_batch, 0), vec![ - Statement::equal(AnchoredKey::from((SELF, "Some constant")), 2), + Statement::equal(AnchoredKey::from((SELF, "c")), 2), Statement::product_of( - AnchoredKey::from((SELF, "Some value")), - AnchoredKey::from((SELF, "Some constant")), - AnchoredKey::from((SELF, "Some other value")), + AnchoredKey::from((SELF, "a")), + AnchoredKey::from((SELF, "b")), + Value::from(3), ), ], ); @@ -580,38 +513,38 @@ mod tests { ..Default::default() }; - let eth_friend_cp = CustomPredicate::and( + let eth_friend = CustomPredicate::and( ¶ms, - "eth_friend_cp".into(), + "eth_friend".into(), vec![ st( P::Native(NP::Equal), vec![ - STA::AnchoredKey(sow_wc(4), KeyOrWildcard::Key("type".into())), + STA::AnchoredKey(wc(2), Key::from("_type")), STA::Literal(PodType::Signed.into()), ], ), st( P::Native(NP::Equal), vec![ - STA::AnchoredKey(sow_wc(4), KeyOrWildcard::Key("signer".into())), - STA::AnchoredKey(sow_wc(0), kow_wc(1)), + STA::AnchoredKey(wc(2), Key::from("_signer")), + STA::Wildcard(wc(0)), ], ), st( P::Native(NP::Equal), vec![ - STA::AnchoredKey(sow_wc(4), KeyOrWildcard::Key("attestation".into())), - STA::AnchoredKey(sow_wc(2), kow_wc(3)), + STA::AnchoredKey(wc(2), Key::from("attestation")), + STA::Wildcard(wc(1)), ], ), ], - 4, - names(&["1", "2", "3", "4"]), + 2, + names(&["0", "1", "2"]), )?; let eth_friend_batch = - CustomPredicateBatch::new(¶ms, "eth_friend".to_string(), vec![eth_friend_cp]); + CustomPredicateBatch::new(¶ms, "eth_friend".to_string(), vec![eth_friend]); // 0 let eth_dos_base = CustomPredicate::and( @@ -620,21 +553,15 @@ mod tests { vec![ st( P::Native(NP::Equal), - vec![ - STA::AnchoredKey(sow_wc(0), kow_wc(1)), - STA::AnchoredKey(sow_wc(2), kow_wc(3)), - ], + vec![STA::Wildcard(wc(0)), STA::Wildcard(wc(1))], ), st( P::Native(NP::Equal), - vec![ - STA::AnchoredKey(sow_wc(4), kow_wc(5)), - STA::Literal(0.into()), - ], + vec![STA::Wildcard(wc(2)), STA::Literal(0.into())], ), ], - 6, - names(&["0", "1", "2", "3", "4", "5"]), + 3, + names(&["0", "1", "2"]), )?; // 1 @@ -645,98 +572,64 @@ mod tests { st( P::BatchSelf(2), vec![ - STA::WildcardLiteral(wc(0)), - STA::WildcardLiteral(wc(1)), - STA::WildcardLiteral(wc(10)), - STA::WildcardLiteral(wc(11)), - STA::WildcardLiteral(wc(8)), - STA::WildcardLiteral(wc(9)), - ], - ), - st( - P::Native(NP::Equal), - vec![ - STA::AnchoredKey(sow_wc(6), kow_wc(7)), - STA::Literal(1.into()), + STA::Wildcard(wc(0)), + STA::Wildcard(wc(4)), + STA::Wildcard(wc(3)), ], ), st( P::Native(NP::SumOf), vec![ - STA::AnchoredKey(sow_wc(4), kow_wc(5)), - STA::AnchoredKey(sow_wc(8), kow_wc(9)), - STA::AnchoredKey(sow_wc(6), kow_wc(7)), + STA::Wildcard(wc(2)), + STA::Wildcard(wc(3)), + STA::Literal(Value::from(1)), ], ), st( P::Custom(CustomPredicateRef::new(eth_friend_batch.clone(), 0)), - vec![ - STA::WildcardLiteral(wc(10)), - STA::WildcardLiteral(wc(11)), - STA::WildcardLiteral(wc(2)), - STA::WildcardLiteral(wc(3)), - ], + vec![STA::Wildcard(wc(4)), STA::Wildcard(wc(1))], ), ], - 6, - names(&["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]), + 3, + names(&["0", "1", "2", "3", "4"]), )?; // 2 - let eth_dos_distance_either = CustomPredicate::or( + let eth_dos = CustomPredicate::or( ¶ms, - "eth_dos_distance_either".into(), + "eth_dos".into(), vec![ st( P::BatchSelf(0), vec![ - STA::WildcardLiteral(wc(0)), - STA::WildcardLiteral(wc(1)), - STA::WildcardLiteral(wc(2)), - STA::WildcardLiteral(wc(3)), - STA::WildcardLiteral(wc(4)), - STA::WildcardLiteral(wc(5)), + STA::Wildcard(wc(0)), + STA::Wildcard(wc(1)), + STA::Wildcard(wc(2)), ], ), st( P::BatchSelf(1), vec![ - STA::WildcardLiteral(wc(0)), - STA::WildcardLiteral(wc(1)), - STA::WildcardLiteral(wc(2)), - STA::WildcardLiteral(wc(3)), - STA::WildcardLiteral(wc(4)), - STA::WildcardLiteral(wc(5)), + STA::Wildcard(wc(0)), + STA::Wildcard(wc(1)), + STA::Wildcard(wc(2)), ], ), ], - 6, - names(&["0", "1", "2", "3", "4", "5"]), + 3, + names(&["0", "1", "2"]), )?; let eth_dos_distance_batch = CustomPredicateBatch::new( ¶ms, "ETHDoS_distance".to_string(), - vec![eth_dos_base, eth_dos_ind, eth_dos_distance_either], + vec![eth_dos_base, eth_dos_ind, eth_dos], ); - // Some POD IDs - let pod_id1 = PodId(Hash(array::from_fn(|i| GoldilocksField(i as u64)))); - let pod_id2 = PodId(Hash(array::from_fn(|i| GoldilocksField((i * i) as u64)))); - let pod_id3 = PodId(Hash(array::from_fn(|i| GoldilocksField((2 * i) as u64)))); - let pod_id4 = PodId(Hash(array::from_fn(|i| GoldilocksField((2 * i) as u64)))); - // Example statement let ethdos_example = Statement::Custom( CustomPredicateRef::new(eth_dos_distance_batch.clone(), 2), - vec![ - WildcardValue::PodId(pod_id1), - WildcardValue::Key(Key::from("Alice")), - WildcardValue::PodId(pod_id2), - WildcardValue::Key(Key::from("Bob")), - WildcardValue::PodId(SELF), - WildcardValue::Key(Key::from("Seven")), - ], + vec![Value::from("Alice"), Value::from("Bob"), Value::from(7)], ); // Copies should work. @@ -745,14 +638,7 @@ mod tests { // This could arise as the inductive step. let ethdos_ind_example = Statement::Custom( CustomPredicateRef::new(eth_dos_distance_batch.clone(), 1), - vec![ - WildcardValue::PodId(pod_id1), - WildcardValue::Key(Key::from("Alice")), - WildcardValue::PodId(pod_id2), - WildcardValue::Key(Key::from("Bob")), - WildcardValue::PodId(SELF), - WildcardValue::Key(Key::from("Seven")), - ], + vec![Value::from("Alice"), Value::from("Bob"), Value::from(7)], ); assert!(Operation::Custom( @@ -767,29 +653,12 @@ mod tests { let ethdos_facts = vec![ Statement::Custom( CustomPredicateRef::new(eth_dos_distance_batch.clone(), 2), - vec![ - WildcardValue::PodId(pod_id1), - WildcardValue::Key(Key::from("Alice")), - WildcardValue::PodId(pod_id3), - WildcardValue::Key(Key::from("Charlie")), - WildcardValue::PodId(pod_id4), - WildcardValue::Key(Key::from("Six")), - ], - ), - Statement::equal(AnchoredKey::from((SELF, "One")), 1), - Statement::sum_of( - AnchoredKey::from((SELF, "Seven")), - AnchoredKey::from((pod_id4, "Six")), - AnchoredKey::from((SELF, "One")), + vec![Value::from("Alice"), Value::from("Charlie"), Value::from(6)], ), + Statement::sum_of(Value::from(7), Value::from(6), Value::from(1)), Statement::Custom( CustomPredicateRef::new(eth_friend_batch.clone(), 0), - vec![ - WildcardValue::PodId(pod_id3), - WildcardValue::Key(Key::from("Charlie")), - WildcardValue::PodId(pod_id2), - WildcardValue::Key(Key::from("Bob")), - ], + vec![Value::from("Charlie"), Value::from("Bob")], ), ]; diff --git a/src/middleware/mod.rs b/src/middleware/mod.rs index 3c17581..bc8e7f8 100644 --- a/src/middleware/mod.rs +++ b/src/middleware/mod.rs @@ -64,6 +64,7 @@ pub enum TypedValue { Raw(RawValue), // Public key variant PublicKey(PublicKey), + PodId(PodId), // UNTAGGED TYPES: #[serde(untagged)] Array(Array), @@ -109,6 +110,12 @@ impl From for TypedValue { } } +impl From for TypedValue { + fn from(id: PodId) -> Self { + TypedValue::PodId(id) + } +} + impl From for TypedValue { fn from(s: Set) -> Self { TypedValue::Set(s) @@ -174,6 +181,7 @@ impl fmt::Display for TypedValue { TypedValue::Array(a) => write!(f, "arr:{}", a.commitment()), TypedValue::Raw(v) => write!(f, "{}", v), TypedValue::PublicKey(p) => write!(f, "ecGFp5_pt:({},{})", p.x, p.u), + TypedValue::PodId(id) => write!(f, "pod_id:{}", id), } } } @@ -189,6 +197,7 @@ impl From<&TypedValue> for RawValue { TypedValue::Array(a) => RawValue::from(a.commitment()), TypedValue::Raw(v) => *v, TypedValue::PublicKey(p) => RawValue::from(hash_fields(&p.as_fields())), + TypedValue::PodId(id) => RawValue::from(id.0), } } } @@ -677,7 +686,7 @@ impl Default for Params { max_custom_predicate_verifications: 5, max_custom_predicate_arity: 5, max_custom_predicate_wildcards: 10, - max_custom_batch_size: 5, + max_custom_batch_size: 5, // TODO: Move down to 4? max_merkle_proofs_containers: 5, max_depth_mt_containers: 32, max_depth_mt_vds: 6, // up to 64 (2^6) different pod circuits diff --git a/src/middleware/operation.rs b/src/middleware/operation.rs index cde111e..942a109 100644 --- a/src/middleware/operation.rs +++ b/src/middleware/operation.rs @@ -7,9 +7,9 @@ use serde::{Deserialize, Serialize}; use crate::{ backends::plonky2::primitives::merkletree::MerkleProof, middleware::{ - custom::KeyOrWildcard, hash_values, AnchoredKey, CustomPredicate, CustomPredicateRef, - Error, NativePredicate, Params, Predicate, Result, SelfOrWildcard, Statement, StatementArg, - StatementTmplArg, ToFields, Value, ValueRef, Wildcard, WildcardValue, F, SELF, + hash_values, AnchoredKey, CustomPredicate, CustomPredicateRef, Error, NativePredicate, + Params, Predicate, Result, Statement, StatementArg, StatementTmplArg, ToFields, Value, + ValueRef, Wildcard, F, SELF, }, }; @@ -369,14 +369,10 @@ pub fn check_st_tmpl( st_tmpl_arg: &StatementTmplArg, st_arg: &StatementArg, // Map from wildcards to values that we have seen so far. - wildcard_map: &mut [Option], + wildcard_map: &mut [Option], ) -> bool { // Check that the value `v` at wildcard `wc` exists in the map or set it. - fn check_or_set( - v: WildcardValue, - wc: &Wildcard, - wildcard_map: &mut [Option], - ) -> bool { + fn check_or_set(v: Value, wc: &Wildcard, wildcard_map: &mut [Option]) -> bool { if let Some(prev) = &wildcard_map[wc.index] { if *prev != v { // TODO: Return nice error @@ -392,27 +388,19 @@ pub fn check_st_tmpl( (StatementTmplArg::None, StatementArg::None) => true, (StatementTmplArg::Literal(lhs), StatementArg::Literal(rhs)) if lhs == rhs => true, ( - StatementTmplArg::AnchoredKey(self_or_wc, key_or_wc), + StatementTmplArg::AnchoredKey(pod_id_wc, key_tmpl), StatementArg::Key(AnchoredKey { pod_id, key }), ) => { - let pod_id_ok = match self_or_wc { - SelfOrWildcard::SELF => SELF == *pod_id, - SelfOrWildcard::Wildcard(pod_id_wc) => { - check_or_set(WildcardValue::PodId(*pod_id), pod_id_wc, wildcard_map) - } - }; - let key_ok = match key_or_wc { - KeyOrWildcard::Key(tmpl_key) => tmpl_key == key, - KeyOrWildcard::Wildcard(key_wc) => { - check_or_set(WildcardValue::Key(key.clone()), key_wc, wildcard_map) - } - }; - pod_id_ok && key_ok + let pod_id_ok = check_or_set(Value::from(*pod_id), pod_id_wc, wildcard_map); + pod_id_ok && (key_tmpl == key) } - (StatementTmplArg::WildcardLiteral(wc), StatementArg::WildcardLiteral(v)) => { + (StatementTmplArg::Wildcard(wc), StatementArg::Literal(v)) => { check_or_set(v.clone(), wc, wildcard_map) } - _ => false, + _ => { + println!("DBG {:?} {:?}", st_tmpl_arg, st_arg); + false + } } } @@ -420,7 +408,7 @@ pub fn resolve_wildcard_values( params: &Params, pred: &CustomPredicate, args: &[Statement], -) -> Option> { +) -> Option> { // Check that all wildcard have consistent values as assigned in the statements while storing a // map of their values. // NOTE: We assume the statements have the same order as defined in the custom predicate. For @@ -444,7 +432,7 @@ pub fn resolve_wildcard_values( Some( wildcard_map .into_iter() - .map(|opt| opt.unwrap_or(WildcardValue::None)) + .map(|opt| opt.unwrap_or(Value::from(0))) .collect(), ) } @@ -453,7 +441,7 @@ fn check_custom_pred( params: &Params, custom_pred_ref: &CustomPredicateRef, args: &[Statement], - s_args: &[WildcardValue], + s_args: &[Value], ) -> Result { let pred = custom_pred_ref.predicate(); if pred.statements.len() != args.len() { diff --git a/src/middleware/statement.rs b/src/middleware/statement.rs index 894b4f7..551f323 100644 --- a/src/middleware/statement.rs +++ b/src/middleware/statement.rs @@ -6,8 +6,7 @@ use serde::{Deserialize, Serialize}; use strum_macros::FromRepr; use crate::middleware::{ - AnchoredKey, CustomPredicateRef, Error, Key, Params, PodId, RawValue, Result, ToFields, Value, - EMPTY_VALUE, F, VALUE_SIZE, + AnchoredKey, CustomPredicateRef, Error, Params, Result, ToFields, Value, F, VALUE_SIZE, }; // TODO: Maybe store KEY_SIGNER and KEY_TYPE as Key with lazy_static @@ -51,39 +50,6 @@ impl ToFields for NativePredicate { } } -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)] -pub enum WildcardValue { - None, - PodId(PodId), - Key(Key), -} - -impl WildcardValue { - pub fn raw(&self) -> RawValue { - match self { - WildcardValue::None => EMPTY_VALUE, - WildcardValue::PodId(pod_id) => RawValue::from(pod_id.0), - WildcardValue::Key(key) => key.raw(), - } - } -} - -impl fmt::Display for WildcardValue { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - WildcardValue::None => write!(f, "none"), - WildcardValue::PodId(pod_id) => pod_id.fmt(f), - WildcardValue::Key(key) => key.fmt(f), - } - } -} - -impl ToFields for WildcardValue { - fn to_fields(&self, params: &Params) -> Vec { - self.raw().to_fields(params) - } -} - #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)] #[serde(tag = "type", content = "value")] pub enum Predicate { @@ -181,7 +147,7 @@ pub enum Statement { ProductOf(ValueRef, ValueRef, ValueRef), MaxOf(ValueRef, ValueRef, ValueRef), HashOf(ValueRef, ValueRef, ValueRef), - Custom(CustomPredicateRef, Vec), + Custom(CustomPredicateRef, Vec), } macro_rules! statement_constructor { @@ -246,7 +212,7 @@ impl Statement { Self::ProductOf(ak1, ak2, ak3) => vec![ak1.into(), ak2.into(), ak3.into()], Self::MaxOf(ak1, ak2, ak3) => vec![ak1.into(), ak2.into(), ak3.into()], Self::HashOf(ak1, ak2, ak3) => vec![ak1.into(), ak2.into(), ak3.into()], - Self::Custom(_, args) => Vec::from_iter(args.into_iter().map(WildcardLiteral)), + Self::Custom(_, args) => Vec::from_iter(args.into_iter().map(Literal)), } } @@ -296,10 +262,10 @@ impl Statement { } (BatchSelf(_), _) => unreachable!(), (Custom(cpr), _) => { - let v_args: Result> = args + let v_args: Result> = args .iter() .map(|x| match x { - StatementArg::WildcardLiteral(v) => Ok(v.clone()), + StatementArg::Literal(v) => Ok(v.clone()), _ => Err(Error::incorrect_statements_args()), }) .collect(); @@ -338,7 +304,6 @@ pub enum StatementArg { None, Literal(Value), Key(AnchoredKey), - WildcardLiteral(WildcardValue), } impl fmt::Display for StatementArg { @@ -347,7 +312,6 @@ impl fmt::Display for StatementArg { StatementArg::None => write!(f, "none"), StatementArg::Literal(v) => v.fmt(f), StatementArg::Key(r) => r.fmt(f), - StatementArg::WildcardLiteral(v) => v.fmt(f), } } } @@ -398,12 +362,6 @@ impl ToFields for StatementArg { fields.extend(ak.key.to_fields(params)); fields } - StatementArg::WildcardLiteral(v) => v - .raw() - .0 - .into_iter() - .chain(iter::repeat(F::ZERO).take(STATEMENT_ARG_F_LEN - VALUE_SIZE)) - .collect(), }; assert_eq!(f.len(), STATEMENT_ARG_F_LEN); // sanity check f