mithril_aggregator/commands/
era_command.rs1use std::{fs::File, io::Write, path::PathBuf};
2
3use anyhow::Context;
4use clap::{Parser, Subcommand};
5use config::{builder::DefaultState, ConfigBuilder};
6use mithril_common::{
7 crypto_helper::{EraMarkersSigner, EraMarkersVerifierSecretKey},
8 entities::{Epoch, HexEncodedEraMarkersSecretKey},
9 StdResult,
10};
11use slog::{debug, Logger};
12
13use crate::tools::EraTools;
14
15#[derive(Parser, Debug, Clone)]
17pub struct EraCommand {
18 #[clap(subcommand)]
20 pub era_subcommand: EraSubCommand,
21}
22
23impl EraCommand {
24 pub async fn execute(
25 &self,
26 root_logger: Logger,
27 config_builder: ConfigBuilder<DefaultState>,
28 ) -> StdResult<()> {
29 self.era_subcommand
30 .execute(root_logger, config_builder)
31 .await
32 }
33}
34
35#[derive(Debug, Clone, Subcommand)]
37pub enum EraSubCommand {
38 List(ListEraSubCommand),
40
41 GenerateTxDatum(GenerateTxDatumEraSubCommand),
43
44 GenerateKeypair(GenerateKeypairEraSubCommand),
46}
47
48impl EraSubCommand {
49 pub async fn execute(
50 &self,
51 root_logger: Logger,
52 config_builder: ConfigBuilder<DefaultState>,
53 ) -> StdResult<()> {
54 match self {
55 Self::List(cmd) => cmd.execute(root_logger, config_builder).await,
56 Self::GenerateTxDatum(cmd) => cmd.execute(root_logger, config_builder).await,
57 Self::GenerateKeypair(cmd) => cmd.execute(root_logger, config_builder).await,
58 }
59 }
60}
61
62#[derive(Parser, Debug, Clone)]
64pub struct ListEraSubCommand {
65 #[clap(long)]
67 json: bool,
68}
69
70impl ListEraSubCommand {
71 pub async fn execute(
72 &self,
73 root_logger: Logger,
74 _config_builder: ConfigBuilder<DefaultState>,
75 ) -> StdResult<()> {
76 debug!(root_logger, "LIST ERA command");
77 let era_tools = EraTools::new();
78 let eras = era_tools.get_supported_eras_list()?;
79
80 if self.json {
81 println!("{}", serde_json::to_string(&eras)?);
82 } else {
83 println!("Supported Eras:");
84 println!("{eras:#?}");
85 }
86
87 Ok(())
88 }
89}
90
91#[derive(Parser, Debug, Clone)]
93pub struct GenerateTxDatumEraSubCommand {
94 #[clap(long, env = "CURRENT_ERA_EPOCH")]
96 current_era_epoch: u64,
97
98 #[clap(long, env = "NEXT_ERA_EPOCH")]
100 next_era_epoch: Option<u64>,
101
102 #[clap(long, env = "ERA_MARKERS_SECRET_KEY")]
104 era_markers_secret_key: HexEncodedEraMarkersSecretKey,
105
106 #[clap(long)]
108 target_path: PathBuf,
109}
110
111impl GenerateTxDatumEraSubCommand {
112 pub async fn execute(
113 &self,
114 root_logger: Logger,
115 _config_builder: ConfigBuilder<DefaultState>,
116 ) -> StdResult<()> {
117 debug!(root_logger, "GENERATETXDATUM ERA command");
118 let era_tools = EraTools::new();
119
120 let era_markers_secret_key =
121 EraMarkersVerifierSecretKey::from_json_hex(&self.era_markers_secret_key)
122 .with_context(|| "json hex decode of era markers secret key failure")?;
123 let era_markers_signer = EraMarkersSigner::from_secret_key(era_markers_secret_key);
124 let tx_datum = era_tools.generate_tx_datum(
125 Epoch(self.current_era_epoch),
126 self.next_era_epoch.map(Epoch),
127 &era_markers_signer,
128 )?;
129
130 let mut target_file = File::create(&self.target_path)?;
131 target_file.write_all(tx_datum.as_bytes())?;
132
133 Ok(())
134 }
135}
136
137#[derive(Parser, Debug, Clone)]
139pub struct GenerateKeypairEraSubCommand {
140 #[clap(long)]
142 target_path: PathBuf,
143}
144
145impl GenerateKeypairEraSubCommand {
146 pub async fn execute(
147 &self,
148 root_logger: Logger,
149 _config_builder: ConfigBuilder<DefaultState>,
150 ) -> StdResult<()> {
151 debug!(root_logger, "GENERATE KEYPAIR ERA command");
152 println!(
153 "Era generate keypair to {}",
154 self.target_path.to_string_lossy()
155 );
156
157 EraTools::create_and_save_era_keypair(&self.target_path)
158 .with_context(|| "era-tools: keypair generation error")?;
159
160 Ok(())
161 }
162}