mithril_client_cli/commands/cardano_db/
list.rs

1use clap::Parser;
2use cli_table::{Cell, Table, format::Justify, print_stdout};
3
4use mithril_client::common::{EpochSpecifier, SignedEntityTypeDiscriminants};
5use mithril_client::{Client, MithrilResult, RequiredAggregatorCapabilities};
6
7use crate::{
8    CommandContext,
9    commands::{
10        cardano_db::{
11            CardanoDbCommandsBackend, warn_deprecated_v1_backend,
12            warn_unused_parameter_with_v1_backend,
13        },
14        client_builder_with_fallback_genesis_key,
15    },
16    utils::CardanoDbUtils,
17};
18
19/// Clap command to list existing Cardano dbs
20#[derive(Parser, Debug, Clone)]
21pub struct CardanoDbListCommand {
22    ///Backend to use, either: `v1` (default, full database restoration only) or `v2` (full or partial database restoration)
23    #[arg(short, long, value_enum, default_value_t)]
24    backend: CardanoDbCommandsBackend,
25
26    /// [backend `v2` only] Epoch of the Cardano db snapshots to list, or `latest` for the latest artifact, or `latest-X` for the artifact of the latest epoch minus X.
27    #[clap(long)]
28    epoch: Option<String>,
29}
30
31impl CardanoDbListCommand {
32    /// Main command execution
33    pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> {
34        match self.backend {
35            CardanoDbCommandsBackend::V1 => {
36                let client = client_builder_with_fallback_genesis_key(context.config_parameters())?
37                    .with_capabilities(RequiredAggregatorCapabilities::And(vec![
38                        RequiredAggregatorCapabilities::SignedEntityType(
39                            SignedEntityTypeDiscriminants::CardanoImmutableFilesFull,
40                        ),
41                    ]))
42                    .with_logger(context.logger().clone())
43                    .build()?;
44                self.print_v1(client, context).await?;
45            }
46            CardanoDbCommandsBackend::V2 => {
47                let client = client_builder_with_fallback_genesis_key(context.config_parameters())?
48                    .with_capabilities(RequiredAggregatorCapabilities::And(vec![
49                        RequiredAggregatorCapabilities::SignedEntityType(
50                            SignedEntityTypeDiscriminants::CardanoDatabase,
51                        ),
52                    ]))
53                    .with_logger(context.logger().clone())
54                    .build()?;
55                self.print_v2(client, context).await?;
56            }
57        }
58
59        Ok(())
60    }
61
62    #[allow(deprecated)]
63    async fn print_v1(&self, client: Client, context: CommandContext) -> MithrilResult<()> {
64        warn_deprecated_v1_backend(&context);
65        if self.epoch.is_some() {
66            warn_unused_parameter_with_v1_backend(&context, ["--epoch"]);
67        }
68
69        let items = client.cardano_database().list().await?;
70
71        if context.is_json_output_enabled() {
72            println!("{}", serde_json::to_string(&items)?);
73        } else {
74            let items = items
75                .into_iter()
76                .map(|item| {
77                    vec![
78                        format!("{}", item.beacon.epoch).cell(),
79                        format!("{}", item.beacon.immutable_file_number).cell(),
80                        item.network.cell(),
81                        item.digest.cell(),
82                        CardanoDbUtils::format_bytes_to_gigabytes(item.size).cell(),
83                        format!("{}", item.locations.len()).cell(),
84                        item.created_at.to_string().cell(),
85                    ]
86                })
87                .collect::<Vec<_>>()
88                .table()
89                .title(vec![
90                    "Epoch".cell(),
91                    "Immutable".cell(),
92                    "Network".cell(),
93                    "Digest".cell(),
94                    "Size".cell().justify(Justify::Right),
95                    "Locations".cell().justify(Justify::Right),
96                    "Created".cell().justify(Justify::Right),
97                ]);
98            print_stdout(items)?;
99        }
100        Ok(())
101    }
102
103    async fn print_v2(&self, client: Client, context: CommandContext) -> MithrilResult<()> {
104        let cdb_v2_client = client.cardano_database_v2();
105        let items = match &self.epoch {
106            None => cdb_v2_client.list().await?,
107            Some(epoch_str) => match EpochSpecifier::parse(epoch_str)? {
108                EpochSpecifier::Number(epoch) => cdb_v2_client.list_by_epoch(epoch).await?,
109                EpochSpecifier::Latest => cdb_v2_client.list_for_latest_epoch().await?,
110                EpochSpecifier::LatestMinusOffset(offset) => {
111                    cdb_v2_client.list_for_latest_epoch_with_offset(offset).await?
112                }
113            },
114        };
115
116        if context.is_json_output_enabled() {
117            println!("{}", serde_json::to_string(&items)?);
118        } else {
119            let items = items
120                .into_iter()
121                .map(|item| {
122                    vec![
123                        format!("{}", item.beacon.epoch).cell(),
124                        format!("{}", item.beacon.immutable_file_number).cell(),
125                        item.hash.cell(),
126                        item.merkle_root.cell(),
127                        CardanoDbUtils::format_bytes_to_gigabytes(item.total_db_size_uncompressed)
128                            .cell(),
129                        item.cardano_node_version.cell(),
130                        item.created_at.to_string().cell(),
131                    ]
132                })
133                .collect::<Vec<_>>()
134                .table()
135                .title(vec![
136                    "Epoch".cell(),
137                    "Immutable".cell(),
138                    "Hash".cell(),
139                    "Merkle root".cell(),
140                    "Database size".cell().justify(Justify::Right),
141                    "Cardano node".cell(),
142                    "Created".cell().justify(Justify::Right),
143                ]);
144            print_stdout(items)?;
145        }
146
147        Ok(())
148    }
149}