Skip to content

Commit 61c817f

Browse files
committed
Compute block range list to compute from the scanned blocks
1 parent 0c72a96 commit 61c817f

File tree

1 file changed

+130
-1
lines changed

1 file changed

+130
-1
lines changed

mithril-signer/src/cardano_transactions_importer.rs

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::sync::Arc;
44
use async_trait::async_trait;
55
use slog::{debug, Logger};
66

7-
use mithril_common::cardano_block_scanner::BlockScanner;
7+
use mithril_common::cardano_block_scanner::{BlockScanner, ScannedBlock};
88
use mithril_common::crypto_helper::MKTreeNode;
99
use mithril_common::entities::{BlockRange, CardanoTransaction, ImmutableFileNumber};
1010
use mithril_common::signable_builder::TransactionsImporter;
@@ -87,6 +87,8 @@ impl CardanoTransactionsImporter {
8787
// todo: temp algorithm, should be optimized to avoid loading all blocks & transactions
8888
// at once in memory (probably using iterators)
8989
let scanned_blocks = self.block_scanner.scan(&self.dirpath, from, until).await?;
90+
let block_ranges = Self::compute_block_ranges(&scanned_blocks).await?;
91+
9092
let parsed_transactions: Vec<CardanoTransaction> = scanned_blocks
9193
.into_iter()
9294
.flat_map(|b| b.into_transactions())
@@ -101,8 +103,40 @@ impl CardanoTransactionsImporter {
101103
self.transaction_store
102104
.store_transactions(parsed_transactions)
103105
.await?;
106+
self.transaction_store
107+
.store_block_ranges(block_ranges)
108+
.await?;
104109
Ok(())
105110
}
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+
}
106140
}
107141

108142
#[async_trait]
@@ -369,4 +403,99 @@ mod tests {
369403
// If sub overflow it should be 0
370404
assert_eq!(Some(0), from);
371405
}
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+
}
372501
}

0 commit comments

Comments
 (0)