@@ -4,7 +4,7 @@ use std::sync::Arc;
4
4
use async_trait:: async_trait;
5
5
use slog:: { debug, Logger } ;
6
6
7
- use mithril_common:: cardano_block_scanner:: BlockScanner ;
7
+ use mithril_common:: cardano_block_scanner:: { BlockScanner , ScannedBlock } ;
8
8
use mithril_common:: crypto_helper:: MKTreeNode ;
9
9
use mithril_common:: entities:: { BlockRange , CardanoTransaction , ImmutableFileNumber } ;
10
10
use mithril_common:: signable_builder:: TransactionsImporter ;
@@ -87,6 +87,8 @@ impl CardanoTransactionsImporter {
87
87
// todo: temp algorithm, should be optimized to avoid loading all blocks & transactions
88
88
// at once in memory (probably using iterators)
89
89
let scanned_blocks = self . block_scanner . scan ( & self . dirpath , from, until) . await ?;
90
+ let block_ranges = Self :: compute_block_ranges ( & scanned_blocks) . await ?;
91
+
90
92
let parsed_transactions: Vec < CardanoTransaction > = scanned_blocks
91
93
. into_iter ( )
92
94
. flat_map ( |b| b. into_transactions ( ) )
@@ -101,8 +103,40 @@ impl CardanoTransactionsImporter {
101
103
self . transaction_store
102
104
. store_transactions ( parsed_transactions)
103
105
. await ?;
106
+ self . transaction_store
107
+ . store_block_ranges ( block_ranges)
108
+ . await ?;
104
109
Ok ( ( ) )
105
110
}
111
+
112
+ async fn compute_block_ranges (
113
+ scanned_blocks : & [ ScannedBlock ] ,
114
+ ) -> StdResult < Vec < ( BlockRange , MKTreeNode ) > > {
115
+ let mut block_ranges_with_merkle_root: Vec < ( BlockRange , MKTreeNode ) > = vec ! [ ] ;
116
+ if scanned_blocks. is_empty ( ) {
117
+ return Ok ( block_ranges_with_merkle_root) ;
118
+ }
119
+
120
+ let start = scanned_blocks[ 0 ] . block_number ;
121
+ let start_block_range = BlockRange :: from_block_number ( start) ;
122
+
123
+ let chunk = if start == start_block_range. start {
124
+ scanned_blocks. chunks_exact ( BlockRange :: LENGTH as usize )
125
+ } else {
126
+ scanned_blocks[ ( ( start_block_range. end - start) as usize ) ..scanned_blocks. len ( ) ]
127
+ . chunks_exact ( BlockRange :: LENGTH as usize )
128
+ } ;
129
+
130
+ block_ranges_with_merkle_root = chunk
131
+ . map ( |c| {
132
+ let start = c[ 0 ] . block_number ;
133
+
134
+ ( BlockRange :: from_block_number ( start) , "" . into ( ) )
135
+ } )
136
+ . collect ( ) ;
137
+
138
+ Ok ( block_ranges_with_merkle_root)
139
+ }
106
140
}
107
141
108
142
#[ async_trait]
@@ -369,4 +403,99 @@ mod tests {
369
403
// If sub overflow it should be 0
370
404
assert_eq ! ( Some ( 0 ) , from) ;
371
405
}
406
+
407
+ fn build_blocks (
408
+ start_block_number : BlockNumber ,
409
+ number_of_consecutive_block : BlockNumber ,
410
+ ) -> Vec < ScannedBlock > {
411
+ ( start_block_number..( start_block_number + number_of_consecutive_block) )
412
+ . map ( |block_number| {
413
+ ScannedBlock :: new (
414
+ format ! ( "block_hash-{}" , block_number) ,
415
+ block_number,
416
+ block_number * 100 ,
417
+ block_number * 10 ,
418
+ vec ! [ format!( "tx_hash-{}" , block_number) ] ,
419
+ )
420
+ } )
421
+ . collect ( )
422
+ }
423
+
424
+ /// ---- Commence à block number qui est un début de block range:
425
+ // J'ai 15 blocks consécutifs (soit BlockRange::Length) ce qui donne 1 block ranges
426
+ // j'ai 14 blocks consécutifs (soit BlockRange::Length - 1) ce qui donne 0 block range
427
+ // j'ai 16 blocks consécutifs (soit BlockRange::Length + 1) ce qui donne 1 seul block range
428
+ /// ---- Commence à block number qui n'est pas un début de block range:
429
+ // J'ai 15 blocks consécutifs (soit BlockRange::Length) ce qui donne 0 block ranges
430
+ #[ tokio:: test]
431
+ async fn vvv_less_than_a_block_range_length_of_consecutive_blocks_starting_from_block_number_0_give_0_block_range (
432
+ ) {
433
+ let blocks = build_blocks ( 0 , BlockRange :: LENGTH - 1 ) ;
434
+
435
+ let block_ranges = CardanoTransactionsImporter :: compute_block_ranges ( & blocks)
436
+ . await
437
+ . unwrap ( ) ;
438
+
439
+ assert_eq ! ( Vec :: <( BlockRange , MKTreeNode ) >:: new( ) , block_ranges) ;
440
+ }
441
+
442
+ #[ tokio:: test]
443
+ async fn vvv_exactly_a_block_range_length_of_consecutive_blocks_starting_from_block_number_0_give_1_block_range (
444
+ ) {
445
+ let blocks = build_blocks ( 0 , BlockRange :: LENGTH ) ;
446
+ let expected = vec ! [ BlockRange :: from_block_number( 0 ) ] ;
447
+
448
+ let block_ranges = CardanoTransactionsImporter :: compute_block_ranges ( & blocks)
449
+ . await
450
+ . unwrap ( ) ;
451
+
452
+ assert_eq ! (
453
+ expected,
454
+ block_ranges. into_iter( ) . map( |( r, _) | r) . collect:: <Vec <_>>( )
455
+ ) ;
456
+ }
457
+
458
+ #[ tokio:: test]
459
+ async fn vvv_more_than_a_block_range_length_of_consecutive_blocks_starting_from_block_number_0_give_1_block_range (
460
+ ) {
461
+ let blocks = build_blocks ( 0 , BlockRange :: LENGTH + 1 ) ;
462
+ let expected = vec ! [ BlockRange :: from_block_number( 0 ) ] ;
463
+
464
+ let block_ranges = CardanoTransactionsImporter :: compute_block_ranges ( & blocks)
465
+ . await
466
+ . unwrap ( ) ;
467
+
468
+ assert_eq ! (
469
+ expected,
470
+ block_ranges. into_iter( ) . map( |( r, _) | r) . collect:: <Vec <_>>( )
471
+ ) ;
472
+ }
473
+
474
+ #[ tokio:: test]
475
+ async fn vvv_exactly_a_block_range_length_of_consecutive_blocks_starting_from_block_number_4_give_0_block_range (
476
+ ) {
477
+ let blocks = build_blocks ( 4 , BlockRange :: LENGTH ) ;
478
+
479
+ let block_ranges = CardanoTransactionsImporter :: compute_block_ranges ( & blocks)
480
+ . await
481
+ . unwrap ( ) ;
482
+
483
+ assert_eq ! ( Vec :: <( BlockRange , MKTreeNode ) >:: new( ) , block_ranges) ;
484
+ }
485
+
486
+ #[ tokio:: test]
487
+ async fn vvv_exactly_two_block_range_length_of_consecutive_blocks_starting_from_block_number_14_give_1_block_range (
488
+ ) {
489
+ let blocks = build_blocks ( BlockRange :: LENGTH - 1 , BlockRange :: LENGTH * 2 ) ;
490
+ let expected = vec ! [ BlockRange :: from_block_number( BlockRange :: LENGTH ) ] ;
491
+
492
+ let block_ranges = CardanoTransactionsImporter :: compute_block_ranges ( & blocks)
493
+ . await
494
+ . unwrap ( ) ;
495
+
496
+ assert_eq ! (
497
+ expected,
498
+ block_ranges. into_iter( ) . map( |( r, _) | r) . collect:: <Vec <_>>( )
499
+ ) ;
500
+ }
372
501
}
0 commit comments