Skip to content

Commit 7b93834

Browse files
authored
Add test for merkle statements, and some debug prints to verify() (#140)
1 parent 3853aa2 commit 7b93834

File tree

4 files changed

+110
-6
lines changed

4 files changed

+110
-6
lines changed

src/backends/plonky2/mock_main/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ impl Pod for MockMainPod {
430430
self.operations[i]
431431
.deref(&self.statements[..input_statement_offset + i])
432432
.unwrap()
433-
.check(&self.params, &s.clone().try_into().unwrap())
433+
.check_and_print(&self.params, &s.clone().try_into().unwrap())
434434
})
435435
.collect::<Result<Vec<_>>>()
436436
.unwrap();

src/backends/plonky2/primitives/merkletree.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use crate::middleware::{keypath, kv_hash};
1313
/// https://0xparc.github.io/pod2/merkletree.html
1414
#[derive(Clone, Debug)]
1515
pub struct MerkleTree {
16-
max_depth: usize,
17-
root: Node,
16+
pub max_depth: usize,
17+
pub root: Node,
1818
}
1919

2020
impl MerkleTree {
@@ -248,7 +248,7 @@ impl MerkleProof {
248248
}
249249

250250
#[derive(Clone, Debug)]
251-
enum Node {
251+
pub enum Node {
252252
None,
253253
Leaf(Leaf),
254254
Intermediate(Intermediate),
@@ -285,7 +285,7 @@ impl fmt::Display for Node {
285285
}
286286

287287
impl Node {
288-
fn is_empty(&self) -> bool {
288+
pub fn is_empty(&self) -> bool {
289289
match self {
290290
Self::None => true,
291291
Self::Leaf(_l) => false,
@@ -299,14 +299,38 @@ impl Node {
299299
Self::Intermediate(n) => n.compute_hash(),
300300
}
301301
}
302-
fn hash(&self) -> Hash {
302+
pub fn hash(&self) -> Hash {
303303
match self {
304304
Self::None => NULL,
305305
Self::Leaf(l) => l.hash(),
306306
Self::Intermediate(n) => n.hash(),
307307
}
308308
}
309309

310+
pub fn left(&self) -> Option<&Box<Node>> {
311+
match self {
312+
Self::None => None,
313+
Self::Leaf(_l) => None,
314+
Self::Intermediate(Intermediate {
315+
hash: _h,
316+
left: l,
317+
right: _r
318+
}) => Some(l),
319+
}
320+
}
321+
322+
pub fn right(&self) -> Option<&Box<Node>> {
323+
match self {
324+
Self::None => None,
325+
Self::Leaf(_l) => None,
326+
Self::Intermediate(Intermediate {
327+
hash: _h,
328+
left: _l,
329+
right: r
330+
}) => Some(r),
331+
}
332+
}
333+
310334
/// Goes down from the current node until it encounters a terminal node,
311335
/// viz. a leaf or empty node, or until it reaches the maximum depth. The
312336
/// `siblings` parameter is used to store the siblings while going down to

src/frontend/mod.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,7 @@ pub mod tests {
953953
use super::*;
954954
use crate::backends::plonky2::mock_main::MockProver;
955955
use crate::backends::plonky2::mock_signed::MockSigner;
956+
use crate::backends::plonky2::primitives::merkletree::MerkleTree;
956957
use crate::examples::{
957958
eth_dos_pod_builder, eth_friend_signed_pod_builder, great_boy_pod_full_flow,
958959
tickets_pod_full_flow, zu_kyc_pod_builder, zu_kyc_sign_pod_builders,
@@ -1165,4 +1166,74 @@ pub mod tests {
11651166
println!("{}", builder);
11661167
println!("{}", false_pod);
11671168
}
1169+
1170+
#[test]
1171+
fn test_merkle_proofs() -> Result<()> {
1172+
let mut kvs = HashMap::new();
1173+
for i in 0..8 {
1174+
if i == 1 {
1175+
continue;
1176+
}
1177+
kvs.insert(middleware::Value::from(i), middleware::Value::from(1000 + i));
1178+
}
1179+
let key = middleware::Value::from(13);
1180+
let value = middleware::Value::from(1013);
1181+
kvs.insert(key, value);
1182+
1183+
let tree = MerkleTree::new(32, &kvs)?;
1184+
// when printing the tree, it should print the same tree as in
1185+
// https://0xparc.github.io/pod2/merkletree.html#example-2
1186+
println!("{}", tree);
1187+
1188+
println!("{}", tree.root());
1189+
1190+
let root: Hash = tree.root();
1191+
let left: Hash = (*tree.root.left().unwrap().clone()).hash();
1192+
let right: Hash = (*tree.root.right().unwrap().clone()).hash();
1193+
1194+
let params = Params::default();
1195+
let mut signed_builder = SignedPodBuilder::new(&params);
1196+
1197+
let mut builder = MainPodBuilder::new(&params);
1198+
let introduce_root_op = Operation(
1199+
OperationType::Native(NativeOperation::NewEntry),
1200+
vec![
1201+
OperationArg::Entry("root".into(), Value::Raw(middleware::Value::from(root))),
1202+
]
1203+
);
1204+
let introduce_left_op = Operation(
1205+
OperationType::Native(NativeOperation::NewEntry),
1206+
vec![
1207+
OperationArg::Entry("left".into(), Value::Raw(middleware::Value::from(left))),
1208+
]
1209+
);
1210+
let introduce_right_op = Operation(
1211+
OperationType::Native(NativeOperation::NewEntry),
1212+
vec![
1213+
OperationArg::Entry("right".into(), Value::Raw(middleware::Value::from(right))),
1214+
]
1215+
);
1216+
let st1 = builder.op(false, introduce_root_op).unwrap();
1217+
let st2 = builder.op(false, introduce_left_op).unwrap();
1218+
let st3 = builder.op(false, introduce_right_op).unwrap();
1219+
1220+
// verify Branches statement
1221+
let branches_op = Operation(
1222+
OperationType::Native(NativeOperation::BranchesFromEntries),
1223+
vec![
1224+
OperationArg::Statement(st1),
1225+
OperationArg::Statement(st2),
1226+
OperationArg::Statement(st3),
1227+
]
1228+
);
1229+
1230+
let _branches_st = builder.op(true, branches_op).unwrap();
1231+
1232+
let mut prover = MockProver {};
1233+
let pod = builder.prove(&mut prover, &params).unwrap();
1234+
print!("{}", pod);
1235+
assert_eq!(pod.pod.verify(), true);
1236+
1237+
Ok(())
1238+
}
11681239
}

src/middleware/operation.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,15 @@ impl Operation {
347347
.map(|(pred, st_args)| Statement::from_args(pred, st_args));
348348
x.transpose()
349349
}
350+
/// Checks the given operation against a statement, and prints information if the check does not pass
351+
pub fn check_and_print(&self, params: &Params, output_statement: &Statement) -> Result<bool> {
352+
let valid: bool = self.check(params, output_statement)?;
353+
if !valid {
354+
println!("Check failed on the following statement");
355+
println!("{}", output_statement);
356+
}
357+
Ok(valid)
358+
}
350359
/// Checks the given operation against a statement.
351360
pub fn check(&self, _params: &Params, output_statement: &Statement) -> Result<bool> {
352361
use Statement::*;

0 commit comments

Comments
 (0)