Skip to main content

ethl_cli/commands/
repair.rs

1use anyhow::Result;
2use clap::Parser;
3use ethl::storage::store::{EventStore, directory::IntegrityStatus};
4use tracing::info;
5
6use crate::commands::full_signatures_to_events;
7
8#[derive(Parser, Debug)]
9pub struct RepairArgs {
10    /// Full event signatures to filter and parse against (e.g. "event Transfer(address from,address to,uint256 amount)")
11    #[arg(long, required = true)]
12    events: Vec<String>,
13
14    /// The archived events location (eg: file:///tmp/events or s3://my-bucket/events)
15    #[arg(long, required = true)]
16    archive_path: String,
17
18    /// Dry run - show what would be repaired and which errors
19    #[arg(long, default_value_t = false)]
20    dry_run: bool,
21}
22
23pub async fn run_repair_command(args: RepairArgs) -> Result<()> {
24    let events = full_signatures_to_events(&args.events)?;
25
26    for event in &events {
27        let store = EventStore::from_uri(&args.archive_path, &event.try_into()?)?;
28        let integrity = store.list().await?.integrity_report();
29
30        match integrity.status() {
31            IntegrityStatus::Intact => {
32                info!("Event {}: Archive is valid, no repairs needed", &event.name);
33                continue;
34            }
35            IntegrityStatus::Unrepairable => {
36                info!(
37                    "Event {}: Archive is unrepairable: {}",
38                    &event.name, integrity
39                );
40                continue;
41            }
42            IntegrityStatus::Repairable => {
43                info!(
44                    "Event {}: Archive has integrity issues, attempting repair: {}",
45                    &event.name, integrity
46                );
47
48                if !args.dry_run {
49                    store.repair().await?;
50                }
51            }
52        }
53    }
54
55    Ok(())
56}