@@ -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 }
0 commit comments