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