Skip to content

Commit bae8c29

Browse files
committed
style(MMR): Use core, std, itertools more
Also: - adhere to trait-defined function order - remove various mutable variables - document various panic conditions - drop various type annotations
1 parent d498125 commit bae8c29

File tree

4 files changed

+113
-147
lines changed

4 files changed

+113
-147
lines changed

twenty-first/src/mock/mmr/mock_mmr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ impl Mmr for MockMmr {
136136
appended_leafs: &[Digest],
137137
leaf_mutations: Vec<LeafMutation>,
138138
) -> bool {
139-
let accumulator: MmrAccumulator = self.to_accumulator();
140-
accumulator.verify_batch_update(new_peaks, appended_leafs, leaf_mutations)
139+
self.to_accumulator()
140+
.verify_batch_update(new_peaks, appended_leafs, leaf_mutations)
141141
}
142142

143143
fn to_accumulator(&self) -> MmrAccumulator {

twenty-first/src/util_types/mmr/mmr_accumulator.rs

Lines changed: 67 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -94,96 +94,6 @@ impl Mmr for MmrAccumulator {
9494
)
9595
}
9696

97-
/// `true` if the `new_peaks` input matches the calculated new MMR peaks
98-
/// resulting from the provided appends and mutations. Can panic if initial
99-
/// state is not a valid MMR.
100-
fn verify_batch_update(
101-
&self,
102-
new_peaks: &[Digest],
103-
appended_leafs: &[Digest],
104-
mut leaf_mutations: Vec<LeafMutation>,
105-
) -> bool {
106-
// Verify that all leaf mutations operate on unique leafs
107-
let manipulated_leaf_indices: Vec<u64> =
108-
leaf_mutations.iter().map(|x| x.leaf_index).collect();
109-
if !manipulated_leaf_indices.iter().all_unique() {
110-
return false;
111-
}
112-
113-
// Disallow updating of out-of-bounds leafs
114-
if self.is_empty() && !manipulated_leaf_indices.is_empty()
115-
|| !manipulated_leaf_indices.is_empty()
116-
&& manipulated_leaf_indices.into_iter().max().unwrap() >= self.leaf_count
117-
{
118-
return false;
119-
}
120-
121-
// Reverse the leaf mutation vectors, since we want to apply them using `pop`
122-
leaf_mutations.reverse();
123-
let mut leaf_mutation_target_values: Vec<Digest> = leaf_mutations
124-
.iter()
125-
.map(|x| x.new_leaf.to_owned())
126-
.collect();
127-
let mut leaf_mutation_indices: Vec<u64> =
128-
leaf_mutations.iter().map(|x| x.leaf_index).collect();
129-
let mut updated_membership_proofs: Vec<MmrMembershipProof> = leaf_mutations
130-
.into_iter()
131-
.map(|x| x.membership_proof.to_owned())
132-
.collect();
133-
134-
// First we apply all the leaf mutations
135-
let mut running_peaks: Vec<Digest> = self.peaks.clone();
136-
while let Some(membership_proof) = updated_membership_proofs.pop() {
137-
// `new_leaf_value` and `leaf_index` are guaranteed to exist since all three
138-
// mutable lists have the same length.
139-
let new_leaf_value = leaf_mutation_target_values.pop().unwrap();
140-
let leaf_index_mutated_leaf = leaf_mutation_indices.pop().unwrap();
141-
142-
// TODO: Should we verify the membership proof here?
143-
144-
// Calculate the new peaks after mutating a leaf
145-
running_peaks = shared_basic::calculate_new_peaks_from_leaf_mutation(
146-
&running_peaks,
147-
self.leaf_count,
148-
new_leaf_value,
149-
leaf_index_mutated_leaf,
150-
&membership_proof,
151-
);
152-
153-
// TODO: Replace this with the new batch updater `batch_update_from_batch_leaf_mutation`
154-
// Update all remaining membership proofs with this leaf mutation
155-
let leaf_mutation =
156-
LeafMutation::new(leaf_index_mutated_leaf, new_leaf_value, membership_proof);
157-
MmrMembershipProof::batch_update_from_leaf_mutation(
158-
&mut updated_membership_proofs,
159-
&leaf_mutation_indices,
160-
leaf_mutation,
161-
);
162-
}
163-
164-
// Then apply all the leaf appends
165-
let mut new_leafs_cloned: Vec<Digest> = appended_leafs.to_vec();
166-
167-
// Reverse the new leafs to apply them in the same order as they were input,
168-
// using pop
169-
new_leafs_cloned.reverse();
170-
171-
// Apply all leaf appends
172-
let mut running_leaf_count = self.leaf_count;
173-
while let Some(new_leaf_for_append) = new_leafs_cloned.pop() {
174-
let (calculated_new_peaks, _new_membership_proof) =
175-
shared_basic::calculate_new_peaks_from_append(
176-
running_leaf_count,
177-
running_peaks,
178-
new_leaf_for_append,
179-
);
180-
running_peaks = calculated_new_peaks;
181-
running_leaf_count += 1;
182-
}
183-
184-
running_peaks == new_peaks
185-
}
186-
18797
/// Mutate multiple leafs in the MMR. Takes a list of membership proofs
18898
/// that will be updated accordingly. Meaning that the provided membership
18999
/// proofs will be valid for the new MMR, provided they were valid before
@@ -314,6 +224,73 @@ impl Mmr for MmrAccumulator {
314224
modified_membership_proof_indices
315225
}
316226

227+
/// `true` if the `new_peaks` input matches the calculated new MMR peaks
228+
/// resulting from the provided appends and mutations. Can panic if initial
229+
/// state is not a valid MMR.
230+
fn verify_batch_update(
231+
&self,
232+
new_peaks: &[Digest],
233+
appended_leafs: &[Digest],
234+
leaf_mutations: Vec<LeafMutation>,
235+
) -> bool {
236+
let mut manipulated_leaf_indices = leaf_mutations.iter().map(|x| x.leaf_index);
237+
if !manipulated_leaf_indices.clone().all_unique() {
238+
return false;
239+
}
240+
if manipulated_leaf_indices.any(|idx| idx >= self.leaf_count) {
241+
return false;
242+
}
243+
244+
// Reverse the leaf mutation vectors, since we want to apply them using `pop`
245+
let (
246+
mut leaf_mutation_indices,
247+
mut leaf_mutation_target_values,
248+
mut updated_membership_proofs,
249+
): (Vec<_>, Vec<_>, Vec<_>) = leaf_mutations
250+
.into_iter()
251+
.rev()
252+
.map(|m| (m.leaf_index, m.new_leaf, m.membership_proof))
253+
.multiunzip();
254+
255+
let mut running_peaks = self.peaks.clone();
256+
while let Some(membership_proof) = updated_membership_proofs.pop() {
257+
let new_leaf_value = leaf_mutation_target_values.pop().unwrap();
258+
let leaf_index_mutated_leaf = leaf_mutation_indices.pop().unwrap();
259+
260+
// TODO: Should we verify the membership proof here?
261+
262+
// Calculate the new peaks after mutating a leaf
263+
running_peaks = shared_basic::calculate_new_peaks_from_leaf_mutation(
264+
&running_peaks,
265+
self.leaf_count,
266+
new_leaf_value,
267+
leaf_index_mutated_leaf,
268+
&membership_proof,
269+
);
270+
271+
// TODO: Replace this with the new batch updater `batch_update_from_batch_leaf_mutation`
272+
// Update all remaining membership proofs with this leaf mutation
273+
let leaf_mutation =
274+
LeafMutation::new(leaf_index_mutated_leaf, new_leaf_value, membership_proof);
275+
MmrMembershipProof::batch_update_from_leaf_mutation(
276+
&mut updated_membership_proofs,
277+
&leaf_mutation_indices,
278+
leaf_mutation,
279+
);
280+
}
281+
282+
for (append_count, &leaf_to_append) in (0..).zip(appended_leafs) {
283+
let (calculated_new_peaks, _) = shared_basic::calculate_new_peaks_from_append(
284+
self.leaf_count + append_count,
285+
running_peaks,
286+
leaf_to_append,
287+
);
288+
running_peaks = calculated_new_peaks;
289+
}
290+
291+
running_peaks == new_peaks
292+
}
293+
317294
fn to_accumulator(&self) -> MmrAccumulator {
318295
self.to_owned()
319296
}

twenty-first/src/util_types/mmr/shared_advanced.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ pub fn leftmost_ancestor(node_index: u64) -> (u64, u32) {
99
if node_index.leading_zeros() == 0 {
1010
return (u64::MAX, 63);
1111
}
12-
let h = u64::BITS - node_index.leading_zeros() - 1;
13-
let ret = (1 << (h + 1)) - 1;
1412

15-
(ret, h)
13+
let height = node_index.ilog2();
14+
let index = (1 << (height + 1)) - 1;
15+
16+
(index, height)
1617
}
1718

1819
/// Traversing from this node upwards, count how many of the ancestor (including itself)
@@ -240,7 +241,6 @@ pub fn node_index_to_leaf_index(node_index: u64) -> Option<u64> {
240241
#[cfg(test)]
241242
mod mmr_test {
242243
use proptest::prop_assert_eq;
243-
use proptest_arbitrary_interop::arb;
244244
use rand::RngCore;
245245
use test_strategy::proptest;
246246

@@ -507,21 +507,17 @@ mod mmr_test {
507507
}
508508

509509
#[proptest]
510-
fn right_lineage_length_from_node_index_does_not_crash(
511-
#[strategy(arb::<u64>())] node_index: u64,
512-
) {
510+
fn right_lineage_length_from_node_index_does_not_crash(node_index: u64) {
513511
right_lineage_length_from_node_index(node_index);
514512
}
515513

516514
#[proptest]
517-
fn leftmost_ancestor_does_not_crash(#[strategy(arb::<u64>())] node_index: u64) {
515+
fn leftmost_ancestor_does_not_crash(node_index: u64) {
518516
leftmost_ancestor(node_index);
519517
}
520518

521519
#[proptest]
522-
fn right_lineage_length_and_own_height_does_not_crash(
523-
#[strategy(arb::<u64>())] node_index: u64,
524-
) {
520+
fn right_lineage_length_and_own_height_does_not_crash(node_index: u64) {
525521
right_lineage_length_and_own_height(node_index);
526522
}
527523
}

0 commit comments

Comments
 (0)