@@ -37,6 +37,8 @@ pub struct ConcurrentMerkleTree<
3737 pub next_index : u64 ,
3838 /// History of roots.
3939 pub roots : [ [ u8 ; 32 ] ; MAX_ROOTS ] ,
40+ /// Number of successful operations on the tree.
41+ pub sequence_number : u64 ,
4042 /// History of Merkle proofs.
4143 pub changelog : [ ChangelogEntry < HEIGHT > ; MAX_CHANGELOG ] ,
4244 /// Index of the newest changelog.
6163 changelog : [ ChangelogEntry :: default ( ) ; MAX_CHANGELOG ] ,
6264 current_changelog_index : 0 ,
6365 roots : [ [ 0u8 ; 32 ] ; MAX_ROOTS ] ,
66+ sequence_number : 0 ,
6467 current_root_index : 0 ,
6568 rightmost_proof : [ [ 0u8 ; 32 ] ; HEIGHT ] ,
6669 next_index : 0 ,
@@ -254,7 +257,7 @@ where
254257 new_leaf : & [ u8 ; 32 ] ,
255258 leaf_index : usize ,
256259 proof : & [ [ u8 ; 32 ] ; HEIGHT ] ,
257- ) -> Result < ( ) , HasherError > {
260+ ) -> Result < ChangelogEntry < HEIGHT > , HasherError > {
258261 let mut node = * new_leaf;
259262 let mut changelog_path = [ [ 0u8 ; 32 ] ; HEIGHT ] ;
260263
@@ -301,7 +304,7 @@ where
301304 }
302305 }
303306
304- Ok ( ( ) )
307+ Ok ( changelog_entry )
305308 }
306309
307310 /// Replaces the `old_leaf` under the `leaf_index` with a `new_leaf`, using
@@ -314,7 +317,7 @@ where
314317 new_leaf : & [ u8 ; 32 ] ,
315318 leaf_index : usize ,
316319 proof : & [ [ u8 ; 32 ] ; HEIGHT ] ,
317- ) -> Result < ( ) , HasherError > {
320+ ) -> Result < ChangelogEntry < HEIGHT > , HasherError > {
318321 let updated_proof = if self . next_index > 0 && MAX_CHANGELOG > 0 {
319322 match self . update_proof_or_leaf ( changelog_index, leaf_index, proof) {
320323 Some ( proof) => proof,
@@ -337,8 +340,13 @@ where
337340 self . update_leaf_in_tree ( new_leaf, leaf_index, & updated_proof)
338341 }
339342
340- /// Appends a new leaf to the tree.
341- pub fn append ( & mut self , leaf : & [ u8 ; 32 ] ) -> Result < ( ) , HasherError > {
343+ /// Appends a new leaf to the tree with the given `changelog_entry` to save
344+ /// the Merkle path in.
345+ fn append_with_changelog_entry (
346+ & mut self ,
347+ leaf : & [ u8 ; 32 ] ,
348+ changelog_entry : & mut ChangelogEntry < HEIGHT > ,
349+ ) -> Result < ( ) , HasherError > {
342350 if self . next_index >= 1 << HEIGHT {
343351 return Err ( HasherError :: TreeFull ) ;
344352 }
@@ -397,13 +405,16 @@ where
397405 }
398406 }
399407
408+ changelog_entry. root = current_node;
409+ changelog_entry. path = changelog_path;
410+ changelog_entry. index = self . next_index ;
411+
400412 self . inc_current_changelog_index ( ) ;
401413 if let Some ( changelog_element) = self
402414 . changelog
403415 . get_mut ( self . current_changelog_index as usize )
404416 {
405- * changelog_element =
406- ChangelogEntry :: new ( current_node, changelog_path, self . next_index as usize )
417+ * changelog_element = * changelog_entry;
407418 }
408419 self . inc_current_root_index ( ) ;
409420 * self
@@ -412,21 +423,32 @@ where
412423 . ok_or ( HasherError :: RootsZero ) ? = current_node;
413424 }
414425
415- self . next_index += 1 ;
426+ self . sequence_number = self . sequence_number . saturating_add ( 1 ) ;
427+ self . next_index = self . next_index . saturating_add ( 1 ) ;
416428 self . rightmost_leaf = * leaf;
417429
418430 Ok ( ( ) )
419431 }
420432
421- /// Appends a new pair of leaves to the tree.
422- pub fn append_two (
433+ /// Appends a new leaf to the tree.
434+ pub fn append ( & mut self , leaf : & [ u8 ; 32 ] ) -> Result < ChangelogEntry < HEIGHT > , HasherError > {
435+ let mut changelog_entry = ChangelogEntry :: default ( ) ;
436+ self . append_with_changelog_entry ( leaf, & mut changelog_entry) ?;
437+ Ok ( changelog_entry)
438+ }
439+
440+ /// Appends a new batch of leaves to the tree.
441+ pub fn append_batch < const N : usize > (
423442 & mut self ,
424- leaf_left : & [ u8 ; 32 ] ,
425- leaf_right : & [ u8 ; 32 ] ,
426- ) -> Result < ( ) , HasherError > {
427- // TODO(vadorovsky): Instead of this naive double append, implement an
428- // optimized insertion of two leaves.
429- self . append ( leaf_left) ?;
430- self . append ( leaf_right)
443+ leaves : & [ & [ u8 ; 32 ] ; N ] ,
444+ ) -> Result < [ Box < ChangelogEntry < HEIGHT > > ; N ] , HasherError > {
445+ let mut changelog_entries: [ Box < ChangelogEntry < HEIGHT > > ; N ] =
446+ std:: array:: from_fn ( |_| Box :: < ChangelogEntry < HEIGHT > > :: default ( ) ) ;
447+
448+ for ( leaf, changelog_entry) in leaves. iter ( ) . zip ( changelog_entries. iter_mut ( ) ) {
449+ self . append_with_changelog_entry ( leaf, changelog_entry) ?;
450+ }
451+
452+ Ok ( changelog_entries)
431453 }
432454}
0 commit comments