mithril_cardano_node_chain/chain_scanner/
block_scanner.rs1use std::sync::Arc;
2use std::time::Duration;
3
4use async_trait::async_trait;
5use slog::Logger;
6use tokio::sync::Mutex;
7
8use mithril_common::StdResult;
9use mithril_common::entities::BlockNumber;
10
11use crate::chain_reader::ChainBlockReader;
12use crate::chain_scanner::block_streamer_with_throttling::BlockStreamerWithThrottling;
13use crate::chain_scanner::{BlockScanner, BlockStreamer};
14use crate::entities::RawCardanoPoint;
15
16use super::ChainReaderBlockStreamer;
17
18pub struct CardanoBlockScanner {
22 chain_reader: Arc<Mutex<dyn ChainBlockReader>>,
23 max_roll_forwards_per_poll: usize,
24 throttling_interval: Option<Duration>,
25 logger: Logger,
26}
27
28impl CardanoBlockScanner {
29 pub fn new(
31 chain_reader: Arc<Mutex<dyn ChainBlockReader>>,
32 max_roll_forwards_per_poll: usize,
33 logger: Logger,
34 ) -> Self {
35 Self {
36 chain_reader,
37 max_roll_forwards_per_poll,
38 throttling_interval: None,
39 logger,
40 }
41 }
42
43 pub fn set_throttling_interval(mut self, interval: Option<Duration>) -> Self {
48 if interval.is_none_or(|i| i.is_zero()) {
49 self.throttling_interval = None;
50 } else {
51 self.throttling_interval = interval;
52 }
53 self
54 }
55}
56
57#[async_trait]
58impl BlockScanner for CardanoBlockScanner {
59 async fn scan(
60 &self,
61 from: Option<RawCardanoPoint>,
62 until: BlockNumber,
63 ) -> StdResult<Box<dyn BlockStreamer>> {
64 let streamer = Box::new(
65 ChainReaderBlockStreamer::try_new(
66 self.chain_reader.clone(),
67 from,
68 until,
69 self.max_roll_forwards_per_poll,
70 self.logger.clone(),
71 )
72 .await?,
73 );
74
75 match self.throttling_interval {
76 Some(interval) => Ok(Box::new(BlockStreamerWithThrottling::new(
77 streamer, interval,
78 ))),
79 None => Ok(streamer),
80 }
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use crate::test::TestLogger;
87 use crate::test::double::FakeChainReader;
88
89 use super::*;
90
91 #[test]
92 fn setting_interval_of_zero_is_same_as_setting_it_to_none() {
93 let scanner = CardanoBlockScanner::new(
94 Arc::new(Mutex::new(FakeChainReader::new(vec![]))),
95 100,
96 TestLogger::stdout(),
97 );
98
99 assert!(scanner.throttling_interval.is_none());
100
101 let scanner = scanner.set_throttling_interval(Some(Duration::from_secs(0)));
102 assert!(scanner.throttling_interval.is_none());
103 }
104}