Allow literals in statement templates (#287)
This PR is a continuation of the work done in #276 - Fix PodType in MainPod (we were using `MockMain` instead of `Main`) - Update anchored keys in statement template arguments to only support wildcards in the origin and literal keys as the key. - Update the pest grammar accordingly - Update the parser accordingly - Rewrite the eth_dos example in a recursive manner so that we use one recursive pod for every distance increment of 1. - I've also used the podlang to define the eth_dos custom predicates. Currently all predicates are in a single batch (previously `eth_friend` was in a different batch). With #286 we could define `eth_friend` in a different batch again. - I was feeling a bit creative and used a format macro to pass `Value`s from rust to the podlang code. - The eth_dos is now written using literals. This resolves https://github.com/0xPARC/pod2/issues/255 - Remove `StatementArg::WildcardValue` in favor of `StatementArg::Literal`. The `WildcardValue` was just a way to have some kind of typing for values that would be used as arguments in custom predicates. Now that we can have literals in any statement this value can be anything, so I just removed the `WildcardValue` and use `Literal` instead. On the backend it was already the case that both cases were treated the same way (after all, `WildcardValue` and `Literal` were 4 fields in the backend). - Added a new type for Value: `PodId` so that we can use it for custom predicates that take a pod id to be used in a wildcard - Add a mock vd_set that is empty for tests that don't use plonky2; this allows running those tests individually without paying for the expensive work of calculating the vd for various circuits. - rename StatementTmplArg::WildcardValue to StatementTmplArg::Wildcard
This commit is contained in:
parent
7d0d3ad769
commit
3c6930dfe6
20 changed files with 659 additions and 1111 deletions
|
|
@ -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::<F, D>::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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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<WildcardValue>,
|
||||
pub args: Vec<Value>,
|
||||
pub op_args: Vec<mainpod::Statement>,
|
||||
}
|
||||
|
||||
|
|
@ -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<Statement>,
|
||||
args: Vec<WildcardValue>,
|
||||
args: Vec<Value>,
|
||||
expected_st: Option<Statement>,
|
||||
) -> 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,
|
||||
|
|
|
|||
|
|
@ -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<dyn Any>)
|
||||
.downcast::<MainPod>()
|
||||
.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))?;
|
||||
|
|
|
|||
|
|
@ -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<Statement> for middleware::Statement {
|
|||
)))?,
|
||||
},
|
||||
Predicate::Custom(cpr) => {
|
||||
let vs: Vec<WildcardValue> = proper_args
|
||||
let vs: Vec<Value> = proper_args
|
||||
.into_iter()
|
||||
.filter_map(|arg| match arg {
|
||||
SA::None => None,
|
||||
SA::WildcardLiteral(v) => Some(v),
|
||||
SA::Literal(v) => Some(v),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
.collect();
|
||||
|
|
|
|||
|
|
@ -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<Key, Value>) -> Result<MockSignedPod> {
|
||||
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())?;
|
||||
|
|
|
|||
|
|
@ -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<Arc<CustomPredicateBatch>> {
|
||||
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<Arc<CustomPredicateBatch>> {
|
||||
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<Arc<CustomPredicateBatch>> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<VDSet> = 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<MainPodBuilder> {
|
||||
// Will need ETH friend and ETH DoS custom predicate batches.
|
||||
let eth_friend = CustomPredicateRef::new(eth_friend_batch(params, mock)?, 0);
|
||||
eth_friend: CustomPredicateRef,
|
||||
eth_dos_base: CustomPredicateRef,
|
||||
eth_dos_ind: CustomPredicateRef,
|
||||
eth_dos: CustomPredicateRef,
|
||||
src: Value,
|
||||
}
|
||||
|
||||
impl EthDosHelper {
|
||||
pub fn new(params: &Params, vd_set: &VDSet, mock: bool, src: Value) -> Result<Self> {
|
||||
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);
|
||||
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,
|
||||
})
|
||||
}
|
||||
|
||||
// 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);
|
||||
pub fn dist_1(&self, src_attestation: &SignedPod) -> Result<MainPodBuilder> {
|
||||
assert_eq!(
|
||||
&self.src,
|
||||
src_attestation.get(KEY_SIGNER).expect("get KEY_SIGNER")
|
||||
);
|
||||
|
||||
// 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();
|
||||
let mut pod = MainPodBuilder::new(&self.params, &self.vd_set);
|
||||
pod.add_signed_pod(src_attestation);
|
||||
|
||||
// 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)))?;
|
||||
|
||||
// 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!(
|
||||
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,
|
||||
eth_dos_base.clone(),
|
||||
alice_equals_alice,
|
||||
zero.clone()
|
||||
self.eth_dos_base.clone(),
|
||||
src_eq_src,
|
||||
distance_eq_zero
|
||||
))?;
|
||||
let ethdos_alice_alice_is_zero = alice_bob_ethdos.priv_op(op!(
|
||||
let eth_dos_src_to_src = pod.priv_op(op!(
|
||||
custom,
|
||||
eth_dos.clone(),
|
||||
ethdos_alice_alice_is_zero_base,
|
||||
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!(
|
||||
// eth_dos src->dst dist=1
|
||||
self.n_plus_1(&mut pod, eth_dos_src_to_src, src_attestation, 0)?;
|
||||
|
||||
Ok(pod)
|
||||
}
|
||||
|
||||
pub fn dist_n_plus_1(
|
||||
&self,
|
||||
eth_dos_src_to_int_pod: &MainPod,
|
||||
int_attestation: &SignedPod, // int signs dst
|
||||
) -> Result<MainPodBuilder> {
|
||||
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")
|
||||
);
|
||||
|
||||
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());
|
||||
|
||||
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,
|
||||
eth_friend.clone(),
|
||||
self.eth_friend.clone(),
|
||||
attestation_is_signed_pod,
|
||||
attestation_signed_by_alice,
|
||||
alice_attests_to_charlie
|
||||
attestation_signed_by_int,
|
||||
int_attests_to_dst
|
||||
))?;
|
||||
|
||||
// ...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!(
|
||||
// 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,
|
||||
eth_friend.clone(),
|
||||
attestation_is_signed_pod,
|
||||
attestation_signed_by_charlie,
|
||||
charlie_attests_to_bob
|
||||
))?;
|
||||
|
||||
// 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(),
|
||||
self.eth_dos_ind.clone(),
|
||||
eth_dos_int_to_dst,
|
||||
ethdos_sum,
|
||||
ethfriends_alice_charlie
|
||||
ethfriends_int_dst
|
||||
))?;
|
||||
let ethdos_alice_charlie_is_one = alice_bob_ethdos.priv_op(op!(
|
||||
let _eth_dos_src_dst = pod.pub_op(op!(
|
||||
custom,
|
||||
eth_dos.clone(),
|
||||
self.eth_dos.clone(),
|
||||
Statement::None,
|
||||
ethdos_alice_charlie_is_one_ind
|
||||
eth_dos_src_to_dst_ind
|
||||
))?;
|
||||
|
||||
// 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
|
||||
))?;
|
||||
|
||||
Ok(alice_bob_ethdos)
|
||||
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<MainPodBuilder> {
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -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<Value> = [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!(
|
||||
|
|
|
|||
|
|
@ -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<T, E = Error> = core::result::Result<T, E>;
|
||||
|
||||
fn display_wc_map(wc_map: &[Option<Value>]) -> 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<Option<Value>>),
|
||||
#[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<Option<Value>>,
|
||||
) -> Self {
|
||||
new!(StatementsDontMatch(s0, s1, wc_map))
|
||||
}
|
||||
pub(crate) fn max_length(obj: String, found: usize, expect: usize) -> Self {
|
||||
new!(MaxLength(obj, found, expect))
|
||||
|
|
|
|||
|
|
@ -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<S: PodSigner>(&self, signer: &mut S) -> Result<SignedPod> {
|
||||
// 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<Key, Value> = 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"));
|
||||
|
|
|
|||
|
|
@ -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<MainPod> {
|
||||
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<MainPod> {
|
||||
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(),
|
||||
)?
|
||||
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]
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
226
src/lang/mod.rs
226
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<Value>) -> 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,14 +166,14 @@ 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_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)),
|
||||
],
|
||||
}];
|
||||
|
||||
|
|
@ -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"),
|
||||
],
|
||||
},
|
||||
];
|
||||
|
|
@ -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)),
|
||||
],
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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<Rule>) -> Result<BuilderArg,
|
|||
Rule::anchored_key => {
|
||||
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<KeyOrWildcard, ProcessorError> {
|
||||
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)?;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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<F> {
|
||||
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<F> {
|
||||
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<F> = 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<CustomPredicateBatch>,
|
||||
name: &str,
|
||||
) -> Option<CustomPredicateRef> {
|
||||
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<StatementTmplArg>) -> 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")],
|
||||
),
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -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<PublicKey> for TypedValue {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<PodId> for TypedValue {
|
||||
fn from(id: PodId) -> Self {
|
||||
TypedValue::PodId(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Set> 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
|
||||
|
|
|
|||
|
|
@ -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<WildcardValue>],
|
||||
wildcard_map: &mut [Option<Value>],
|
||||
) -> 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<WildcardValue>],
|
||||
) -> bool {
|
||||
fn check_or_set(v: Value, wc: &Wildcard, wildcard_map: &mut [Option<Value>]) -> 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 pod_id_ok = check_or_set(Value::from(*pod_id), pod_id_wc, wildcard_map);
|
||||
pod_id_ok && (key_tmpl == key)
|
||||
}
|
||||
};
|
||||
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
|
||||
}
|
||||
(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<Vec<WildcardValue>> {
|
||||
) -> Option<Vec<Value>> {
|
||||
// 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<bool> {
|
||||
let pred = custom_pred_ref.predicate();
|
||||
if pred.statements.len() != args.len() {
|
||||
|
|
|
|||
|
|
@ -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<F> {
|
||||
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<WildcardValue>),
|
||||
Custom(CustomPredicateRef, Vec<Value>),
|
||||
}
|
||||
|
||||
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<Vec<WildcardValue>> = args
|
||||
let v_args: Result<Vec<Value>> = 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue