Skip to content

Commit 813a86c

Browse files
authored
Remove max_depth in native MerkleTree (#442)
This simplifies the MerkleTree (and container) API. Defer the max depth check when assigning the witness (merkle proof siblings) to the merkle tree circuit. In this implementation the native Merkle Tree branches grow as much as they needed. There are no checks of max depth in the merkle tree. All keys are 256 bits (I added a debug_assert for this); so in the worst case a path will have depth 256. It can't have a longer depth because the `insert` method calls `prove_nonexistence` which errors if the key already exists; another one may exist which must be different and thus require a path <= 256 depth. Resolve #436
1 parent 32dc854 commit 813a86c

File tree

18 files changed

+269
-465
lines changed

18 files changed

+269
-465
lines changed

examples/main_pod_points.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
3535
let mock_prover = MockProver {};
3636
let real_prover = Prover {};
3737
let (vd_set, prover): (_, &dyn MainPodProver) = if mock {
38-
(&VDSet::new(8, &[])?, &mock_prover)
38+
(&VDSet::new(&[]), &mock_prover)
3939
} else {
4040
println!("Prebuilding circuits to calculate vd_set...");
4141
let vd_set = &*DEFAULT_VD_SET;

examples/signed_dict.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
3030
.into_iter()
3131
.map(Value::from)
3232
.collect();
33-
builder.insert(
34-
"friends",
35-
Set::new(params.max_merkle_proofs_containers, friends_set)?,
36-
);
33+
builder.insert("friends", Set::new(friends_set));
3734

3835
// Sign the dict and verify it
3936
let signed_dict = builder.sign(&signer)?;

src/backends/plonky2/basetypes.rs

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,8 @@ pub static DEFAULT_VD_LIST: LazyLock<Vec<VerifierOnlyCircuitData>> = LazyLock::n
6565
});
6666

6767
pub static DEFAULT_VD_SET: LazyLock<VDSet> = LazyLock::new(|| {
68-
let params = Params::default();
6968
let vds = &*DEFAULT_VD_LIST;
70-
VDSet::new(params.max_depth_mt_vds, vds).unwrap()
69+
VDSet::new(vds)
7170
});
7271

7372
/// VDSet is the set of the allowed verifier_data hashes. When proving a
@@ -84,35 +83,29 @@ pub struct VDSet {
8483
#[serde(skip)]
8584
#[schemars(skip)]
8685
proofs_map: HashMap<Hash, MerkleClaimAndProof>,
87-
tree_depth: usize,
8886
vds_hashes: Vec<Hash>,
8987
}
9088

9189
impl PartialEq for VDSet {
9290
fn eq(&self, other: &Self) -> bool {
93-
self.root == other.root
94-
&& self.tree_depth == other.tree_depth
95-
&& self.vds_hashes == other.vds_hashes
91+
self.root == other.root && self.vds_hashes == other.vds_hashes
9692
}
9793
}
9894
impl Eq for VDSet {}
9995

10096
impl VDSet {
101-
fn new_from_vds_hashes(tree_depth: usize, mut vds_hashes: Vec<Hash>) -> Result<Self> {
97+
fn new_from_vds_hashes(mut vds_hashes: Vec<Hash>) -> Self {
10298
// before using the hash values, sort them, so that each set of
10399
// verifier_datas gets the same VDSet root
104100
vds_hashes.sort();
105101

106-
let array = Array::new(
107-
tree_depth,
108-
vds_hashes.iter().map(|vd| Value::from(*vd)).collect(),
109-
)?;
102+
let array = Array::new(vds_hashes.iter().map(|vd| Value::from(*vd)).collect());
110103

111104
let root = array.commitment();
112105
let mut proofs_map = HashMap::<Hash, MerkleClaimAndProof>::new();
113106

114107
for (i, vd) in vds_hashes.iter().enumerate() {
115-
let (value, proof) = array.prove(i)?;
108+
let (value, proof) = array.prove(i).expect("exists");
116109
let p = MerkleClaimAndProof {
117110
root,
118111
key: RawValue::from(i as i64),
@@ -121,15 +114,14 @@ impl VDSet {
121114
};
122115
proofs_map.insert(*vd, p);
123116
}
124-
Ok(Self {
117+
Self {
125118
root,
126119
proofs_map,
127-
tree_depth,
128120
vds_hashes,
129-
})
121+
}
130122
}
131123
/// builds the verifier_datas tree, and returns the root and the proofs
132-
pub fn new(tree_depth: usize, vds: &[VerifierOnlyCircuitData]) -> Result<Self> {
124+
pub fn new(vds: &[VerifierOnlyCircuitData]) -> Self {
133125
// compute the verifier_data's hashes
134126
let vds_hashes: Vec<HashOut> = vds
135127
.iter()
@@ -141,7 +133,7 @@ impl VDSet {
141133
.map(|h| Hash(h.elements))
142134
.collect::<Vec<_>>();
143135

144-
Self::new_from_vds_hashes(tree_depth, vds_hashes)
136+
Self::new_from_vds_hashes(vds_hashes)
145137
}
146138
pub fn root(&self) -> Hash {
147139
self.root
@@ -172,10 +164,9 @@ impl<'de> Deserialize<'de> for VDSet {
172164
{
173165
#[derive(Deserialize)]
174166
struct Aux {
175-
tree_depth: usize,
176167
vds_hashes: Vec<Hash>,
177168
}
178169
let aux = Aux::deserialize(deserializer)?;
179-
VDSet::new_from_vds_hashes(aux.tree_depth, aux.vds_hashes).map_err(serde::de::Error::custom)
170+
Ok(VDSet::new_from_vds_hashes(aux.vds_hashes))
180171
}
181172
}

src/backends/plonky2/circuits/mainpod.rs

Lines changed: 31 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2329,8 +2329,8 @@ mod tests {
23292329

23302330
#[test]
23312331
fn test_operation_verify_eq() -> Result<()> {
2332-
let dict1 = dict!(32, {"hello" => 55})?;
2333-
let dict2 = dict!(32, {"world" => 55})?;
2332+
let dict1 = dict!({"hello" => 55});
2333+
let dict2 = dict!({"world" => 55});
23342334
let st1: mainpod::Statement = Statement::contains(dict1.clone(), "hello", 55).into();
23352335
let st2: mainpod::Statement = Statement::contains(dict2.clone(), "world", 55).into();
23362336
let st: mainpod::Statement = Statement::equal(
@@ -2349,8 +2349,8 @@ mod tests {
23492349

23502350
#[test]
23512351
fn test_operation_verify_neq() -> Result<()> {
2352-
let dict1 = dict!(32, {"hello" => 55})?;
2353-
let dict2 = dict!(32, {"world" => 75})?;
2352+
let dict1 = dict!({"hello" => 55});
2353+
let dict2 = dict!({"world" => 75});
23542354
let st1: mainpod::Statement = Statement::contains(dict1.clone(), "hello", 55).into();
23552355
let st2: mainpod::Statement = Statement::contains(dict2.clone(), "world", 75).into();
23562356
let st: mainpod::Statement = Statement::not_equal(
@@ -2369,8 +2369,8 @@ mod tests {
23692369

23702370
#[test]
23712371
fn test_operation_verify_lt() -> Result<()> {
2372-
let dict1 = dict!(32, {"hello" => 55})?;
2373-
let dict2 = dict!(32, {"hello" => 56})?;
2372+
let dict1 = dict!({"hello" => 55});
2373+
let dict2 = dict!({"hello" => 56});
23742374
let st1: mainpod::Statement = Statement::contains(dict1.clone(), "hello", 55).into();
23752375
let st2: mainpod::Statement = Statement::contains(dict2.clone(), "hello", 56).into();
23762376
let st: mainpod::Statement = Statement::lt(
@@ -2387,8 +2387,8 @@ mod tests {
23872387
operation_verify(st, op, prev_statements, Aux::default())?;
23882388

23892389
// Also check negative < negative
2390-
let dict3 = dict!(32, {"hola" => -56})?;
2391-
let dict4 = dict!(32, {"mundo" => -55})?;
2390+
let dict3 = dict!({"hola" => -56});
2391+
let dict4 = dict!({"mundo" => -55});
23922392
let st3: mainpod::Statement = Statement::contains(dict3.clone(), "hola", -56).into();
23932393
let st4: mainpod::Statement = Statement::contains(dict4.clone(), "mundo", -55).into();
23942394
let st: mainpod::Statement = Statement::lt(
@@ -2421,12 +2421,12 @@ mod tests {
24212421

24222422
#[test]
24232423
fn test_operation_verify_lteq() -> Result<()> {
2424-
let local = dict!(32, {
2424+
let local = dict!({
24252425
"n55" => 55,
24262426
"n56" => 56,
24272427
"n_56" => -56,
24282428
"n_55" => -55,
2429-
})?;
2429+
});
24302430
let st1: mainpod::Statement = Statement::contains(local.clone(), "n55", 55).into();
24312431
let st2: mainpod::Statement = Statement::contains(local.clone(), "n56", 56).into();
24322432
let st: mainpod::Statement = Statement::lt_eq(
@@ -2511,11 +2511,11 @@ mod tests {
25112511
let v1 = hash_values(&input_values);
25122512
let [v2, v3] = input_values;
25132513

2514-
let local = dict!(32, {
2514+
let local = dict!({
25152515
"hola" => v1,
25162516
"mundo" => v2.clone(),
25172517
"!" => v3.clone(),
2518-
})?;
2518+
});
25192519

25202520
let st1: mainpod::Statement = Statement::contains(local.clone(), "hola", v1).into();
25212521
let st2: mainpod::Statement = Statement::contains(local.clone(), "mundo", v2).into();
@@ -2549,11 +2549,11 @@ mod tests {
25492549
overflow.not().then_some((a, b, sum))
25502550
})
25512551
.try_for_each(|(a, b, sum)| {
2552-
let local = dict!(32, {
2552+
let local = dict!({
25532553
"sum" => sum,
25542554
"a" => a,
25552555
"b" => b,
2556-
})?;
2556+
});
25572557

25582558
let st1: mainpod::Statement = Statement::contains(local.clone(), "sum", sum).into();
25592559
let st2: mainpod::Statement = Statement::contains(local.clone(), "a", a).into();
@@ -2588,11 +2588,11 @@ mod tests {
25882588
overflow.not().then_some((a, b, prod))
25892589
})
25902590
.try_for_each(|(a, b, prod)| {
2591-
let local = dict!(32, {
2591+
let local = dict!({
25922592
"prod" => prod,
25932593
"a" => a,
25942594
"b" => b,
2595-
})?;
2595+
});
25962596

25972597
let st1: mainpod::Statement =
25982598
Statement::contains(local.clone(), "prod", prod).into();
@@ -2623,11 +2623,11 @@ mod tests {
26232623
fn test_operation_verify_maxof() -> Result<()> {
26242624
I64_TEST_PAIRS.into_iter().try_for_each(|(a, b)| {
26252625
let max = i64::max(a, b);
2626-
let local = dict!(32, {
2626+
let local = dict!({
26272627
"max" => max,
26282628
"a" => a,
26292629
"b" => b,
2630-
})?;
2630+
});
26312631

26322632
let st1: mainpod::Statement = Statement::contains(local.clone(), "max", max).into();
26332633
let st2: mainpod::Statement = Statement::contains(local.clone(), "a", a).into();
@@ -2689,10 +2689,10 @@ mod tests {
26892689

26902690
#[test]
26912691
fn test_operation_verify_lt_to_neq() -> Result<()> {
2692-
let local = dict!(32,{
2692+
let local = dict!({
26932693
"a" => 10,
26942694
"b" => 20,
2695-
})?;
2695+
});
26962696
let st: mainpod::Statement = Statement::not_equal(
26972697
AnchoredKey::from((&local, "a")),
26982698
AnchoredKey::from((&local, "b")),
@@ -2714,11 +2714,11 @@ mod tests {
27142714

27152715
#[test]
27162716
fn test_operation_verify_transitive_eq() -> Result<()> {
2717-
let local = dict!(32,{
2717+
let local = dict!({
27182718
"a" => 10,
27192719
"b" => 10,
27202720
"c" => 10,
2721-
})?;
2721+
});
27222722
let st: mainpod::Statement = Statement::equal(
27232723
AnchoredKey::from((&local, "a")),
27242724
AnchoredKey::from((&local, "c")),
@@ -2745,23 +2745,21 @@ mod tests {
27452745

27462746
#[test]
27472747
fn test_operation_verify_sintains() -> Result<()> {
2748-
let params = Params::default();
2749-
27502748
let kvs = [
27512749
(1.into(), 55.into()),
27522750
(2.into(), 88.into()),
27532751
(175.into(), 0.into()),
27542752
]
27552753
.into_iter()
27562754
.collect();
2757-
let mt = MerkleTree::new(params.max_depth_mt_containers, &kvs)?;
2755+
let mt = MerkleTree::new(&kvs);
27582756

27592757
let root = mt.root();
27602758
let key = Value::from(5);
2761-
let local = dict!(32,{
2759+
let local = dict!({
27622760
"merkle_root" => root,
27632761
"key" => key.clone(),
2764-
})?;
2762+
});
27652763
let root_ak = AnchoredKey::from((&local, "merkle_root"));
27662764
let key_ak = AnchoredKey::from((&local, "key"));
27672765

@@ -2785,25 +2783,23 @@ mod tests {
27852783

27862784
#[test]
27872785
fn test_operation_verify_contains() -> Result<()> {
2788-
let params = Params::default();
2789-
27902786
let kvs = [
27912787
(1.into(), 55.into()),
27922788
(2.into(), 88.into()),
27932789
(175.into(), 0.into()),
27942790
]
27952791
.into_iter()
27962792
.collect();
2797-
let mt = MerkleTree::new(params.max_depth_mt_containers, &kvs)?;
2793+
let mt = MerkleTree::new(&kvs);
27982794

27992795
let root = mt.root();
28002796
let key = Value::from(175);
28012797
let (value, key_pf) = mt.prove(&key.raw())?;
2802-
let local = dict!(32,{
2798+
let local = dict!({
28032799
"merkle_root" => root,
28042800
"key" => key.clone(),
28052801
"value" => value,
2806-
})?;
2802+
});
28072803
let root_ak = AnchoredKey::from((&local, "merkle_root"));
28082804
let key_ak = AnchoredKey::from((&local, "key"));
28092805
let value_ak = AnchoredKey::from((&local, "value"));
@@ -2833,9 +2829,7 @@ mod tests {
28332829

28342830
#[test]
28352831
fn test_operation_verify_merkle_insert() -> Result<()> {
2836-
let params = Params::default();
2837-
2838-
let mut tree = MerkleTree::new(params.max_depth_mt_containers, &[].into())?;
2832+
let mut tree = MerkleTree::new(&[].into());
28392833

28402834
let key = Value::from(175);
28412835
let value = Value::from(0);
@@ -2862,12 +2856,7 @@ mod tests {
28622856

28632857
#[test]
28642858
fn test_operation_verify_merkle_update() -> Result<()> {
2865-
let params = Params::default();
2866-
2867-
let mut tree = MerkleTree::new(
2868-
params.max_depth_mt_containers,
2869-
&[(175.into(), 55.into())].into(),
2870-
)?;
2859+
let mut tree = MerkleTree::new(&[(175.into(), 55.into())].into());
28712860

28722861
let key = Value::from(175);
28732862
let value = Value::from(0);
@@ -2894,12 +2883,7 @@ mod tests {
28942883

28952884
#[test]
28962885
fn test_operation_verify_merkle_delete() -> Result<()> {
2897-
let params = Params::default();
2898-
2899-
let mut tree = MerkleTree::new(
2900-
params.max_depth_mt_containers,
2901-
&[(175.into(), 55.into())].into(),
2902-
)?;
2886+
let mut tree = MerkleTree::new(&[(175.into(), 55.into())].into());
29032887

29042888
let key = Value::from(175);
29052889
let state_transition_proof = tree.delete(&key.raw())?;

src/backends/plonky2/emptypod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ pub mod tests {
260260
fn test_empty_pod() {
261261
let params = Params::default();
262262

263-
let empty_pod = EmptyPod::new_boxed(&params, VDSet::new(8, &[]).unwrap());
263+
let empty_pod = EmptyPod::new_boxed(&params, VDSet::new(&[]));
264264
empty_pod.verify().unwrap();
265265
}
266266
}

0 commit comments

Comments
 (0)