tx_indexer/
progress_tracker.rs1use std::sync::{atomic::AtomicUsize, Arc};
2
3use anyhow::anyhow;
4use chrono::{DateTime, Duration, Utc};
5use oura::utils::ChainWellKnownInfo;
6use tx_bakery::chain_query::{EraParameters, EraSummary, EraTime};
7
8use crate::from_oura::OuraParseError;
9
10#[derive(Clone, Debug)]
13pub struct ProgressTracker {
14 pub system_start: DateTime<Utc>,
15 pub era_summaries: Vec<EraSummary>,
16 pub since_slot: u64,
17 pub sync_progress: Arc<AtomicUsize>,
18}
19
20impl ProgressTracker {
21 pub fn new(since_slot: u64, chain_info: &ChainWellKnownInfo) -> Result<Self, anyhow::Error> {
22 let system_start = DateTime::from_timestamp(chain_info.byron_known_time as i64, 0).ok_or(
23 anyhow!("Unable to convert shelley_known_time to to DateTime"),
24 )?;
25
26 Ok(ProgressTracker {
27 system_start,
28 era_summaries: chain_info_to_era_summaries(&system_start, chain_info)?,
29 since_slot,
30 sync_progress: Arc::new(AtomicUsize::new(0)),
31 })
32 }
33
34 pub fn get_percentage(&self, slot: u64) -> Result<f32, OuraParseError> {
35 let current_time = Utc::now();
36 let current_slot =
37 tx_bakery::time::time_into_slot(&self.era_summaries, &self.system_start, current_time)
38 .map_err(OuraParseError::TimeConversionError)?;
39
40 let synced = slot - self.since_slot;
41 let to_be_synced = current_slot - self.since_slot;
42
43 Ok(synced as f32 * 100.0 / to_be_synced as f32)
44 }
45}
46
47fn chain_info_to_era_summaries(
51 system_start_time: &DateTime<Utc>,
52 chain_info: &ChainWellKnownInfo,
53) -> Result<Vec<EraSummary>, anyhow::Error> {
54 let byron_start = EraTime {
55 time: Duration::zero(),
56 slot: 0,
57 epoch: 0,
58 };
59
60 let shelley_start = EraTime {
61 time: DateTime::from_timestamp(chain_info.shelley_known_time as i64, 0).ok_or(anyhow!(
62 "Unable to convert shelley_known_time to to DateTime"
63 ))? - system_start_time,
64 slot: chain_info.shelley_known_slot,
65 epoch: chain_info.shelley_known_slot / chain_info.byron_epoch_length as u64,
66 };
67
68 Ok(vec![
69 EraSummary {
70 start: byron_start,
71 end: Some(shelley_start.clone()),
72 parameters: EraParameters {
73 epoch_length: chain_info.byron_epoch_length as u64,
74 slot_length: chain_info.byron_slot_length as u64 * 1000,
75 safe_zone: Some(4320),
76 },
77 },
78 EraSummary {
79 start: shelley_start,
80 end: None,
81 parameters: EraParameters {
82 epoch_length: chain_info.shelley_epoch_length as u64,
83 slot_length: chain_info.shelley_slot_length as u64 * 1000,
84 safe_zone: Some(4320),
85 },
86 },
87 ])
88}