@@ -37,6 +37,8 @@ pub struct ConcurrentMerkleTree<
37
37
pub next_index : u64 ,
38
38
/// History of roots.
39
39
pub roots : [ [ u8 ; 32 ] ; MAX_ROOTS ] ,
40
+ /// Number of successful operations on the tree.
41
+ pub sequence_number : u64 ,
40
42
/// History of Merkle proofs.
41
43
pub changelog : [ ChangelogEntry < HEIGHT > ; MAX_CHANGELOG ] ,
42
44
/// Index of the newest changelog.
61
63
changelog : [ ChangelogEntry :: default ( ) ; MAX_CHANGELOG ] ,
62
64
current_changelog_index : 0 ,
63
65
roots : [ [ 0u8 ; 32 ] ; MAX_ROOTS ] ,
66
+ sequence_number : 0 ,
64
67
current_root_index : 0 ,
65
68
rightmost_proof : [ [ 0u8 ; 32 ] ; HEIGHT ] ,
66
69
next_index : 0 ,
@@ -254,7 +257,7 @@ where
254
257
new_leaf : & [ u8 ; 32 ] ,
255
258
leaf_index : usize ,
256
259
proof : & [ [ u8 ; 32 ] ; HEIGHT ] ,
257
- ) -> Result < ( ) , HasherError > {
260
+ ) -> Result < ChangelogEntry < HEIGHT > , HasherError > {
258
261
let mut node = * new_leaf;
259
262
let mut changelog_path = [ [ 0u8 ; 32 ] ; HEIGHT ] ;
260
263
@@ -301,7 +304,7 @@ where
301
304
}
302
305
}
303
306
304
- Ok ( ( ) )
307
+ Ok ( changelog_entry )
305
308
}
306
309
307
310
/// Replaces the `old_leaf` under the `leaf_index` with a `new_leaf`, using
@@ -314,7 +317,7 @@ where
314
317
new_leaf : & [ u8 ; 32 ] ,
315
318
leaf_index : usize ,
316
319
proof : & [ [ u8 ; 32 ] ; HEIGHT ] ,
317
- ) -> Result < ( ) , HasherError > {
320
+ ) -> Result < ChangelogEntry < HEIGHT > , HasherError > {
318
321
let updated_proof = if self . next_index > 0 && MAX_CHANGELOG > 0 {
319
322
match self . update_proof_or_leaf ( changelog_index, leaf_index, proof) {
320
323
Some ( proof) => proof,
@@ -337,8 +340,13 @@ where
337
340
self . update_leaf_in_tree ( new_leaf, leaf_index, & updated_proof)
338
341
}
339
342
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 > {
342
350
if self . next_index >= 1 << HEIGHT {
343
351
return Err ( HasherError :: TreeFull ) ;
344
352
}
@@ -397,13 +405,16 @@ where
397
405
}
398
406
}
399
407
408
+ changelog_entry. root = current_node;
409
+ changelog_entry. path = changelog_path;
410
+ changelog_entry. index = self . next_index ;
411
+
400
412
self . inc_current_changelog_index ( ) ;
401
413
if let Some ( changelog_element) = self
402
414
. changelog
403
415
. get_mut ( self . current_changelog_index as usize )
404
416
{
405
- * changelog_element =
406
- ChangelogEntry :: new ( current_node, changelog_path, self . next_index as usize )
417
+ * changelog_element = * changelog_entry;
407
418
}
408
419
self . inc_current_root_index ( ) ;
409
420
* self
@@ -412,21 +423,32 @@ where
412
423
. ok_or ( HasherError :: RootsZero ) ? = current_node;
413
424
}
414
425
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 ) ;
416
428
self . rightmost_leaf = * leaf;
417
429
418
430
Ok ( ( ) )
419
431
}
420
432
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 > (
423
442
& 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)
431
453
}
432
454
}
0 commit comments