mithril_aggregator/commands/
era_command.rs1use std::{collections::HashMap, fs::File, io::Write, path::PathBuf};
2
3use anyhow::Context;
4use clap::{Parser, Subcommand};
5use mithril_common::{
6 StdResult,
7 crypto_helper::{EraMarkersSigner, EraMarkersVerifierSecretKey},
8 entities::{Epoch, HexEncodedEraMarkersSecretKey},
9};
10use mithril_doc::StructDoc;
11use slog::{Logger, debug};
12
13use crate::{extract_all, 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(&self, root_logger: Logger) -> StdResult<()> {
25 self.era_subcommand.execute(root_logger).await
26 }
27
28 pub fn extract_config(command_path: String) -> HashMap<String, StructDoc> {
29 extract_all!(
30 command_path,
31 EraSubCommand,
32 List = { ListEraSubCommand },
33 GenerateTxDatum = { GenerateTxDatumEraSubCommand },
34 GenerateKeypair = { GenerateKeypairEraSubCommand },
35 )
36 }
37}
38
39#[derive(Debug, Clone, Subcommand)]
41pub enum EraSubCommand {
42 List(ListEraSubCommand),
44
45 GenerateTxDatum(GenerateTxDatumEraSubCommand),
47
48 GenerateKeypair(GenerateKeypairEraSubCommand),
50}
51
52impl EraSubCommand {
53 pub async fn execute(&self, root_logger: Logger) -> StdResult<()> {
54 match self {
55 Self::List(cmd) => cmd.execute(root_logger).await,
56 Self::GenerateTxDatum(cmd) => cmd.execute(root_logger).await,
57 Self::GenerateKeypair(cmd) => cmd.execute(root_logger).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(&self, root_logger: Logger) -> StdResult<()> {
72 debug!(root_logger, "LIST ERA command");
73 let era_tools = EraTools::new();
74 let eras = era_tools.get_supported_eras_list()?;
75
76 if self.json {
77 println!("{}", serde_json::to_string(&eras)?);
78 } else {
79 println!("Supported Eras:");
80 println!("{eras:#?}");
81 }
82
83 Ok(())
84 }
85
86 pub fn extract_config(_parent: String) -> HashMap<String, StructDoc> {
87 HashMap::new()
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(&self, root_logger: Logger) -> StdResult<()> {
113 debug!(root_logger, "GENERATETXDATUM ERA command");
114 let era_tools = EraTools::new();
115
116 let era_markers_secret_key =
117 EraMarkersVerifierSecretKey::from_json_hex(&self.era_markers_secret_key)
118 .with_context(|| "json hex decode of era markers secret key failure")?;
119 let era_markers_signer = EraMarkersSigner::from_secret_key(era_markers_secret_key);
120 let tx_datum = era_tools.generate_tx_datum(
121 Epoch(self.current_era_epoch),
122 self.next_era_epoch.map(Epoch),
123 &era_markers_signer,
124 )?;
125
126 let mut target_file = File::create(&self.target_path)?;
127 target_file.write_all(tx_datum.as_bytes())?;
128
129 Ok(())
130 }
131
132 pub fn extract_config(_parent: String) -> HashMap<String, StructDoc> {
133 HashMap::new()
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(&self, root_logger: Logger) -> StdResult<()> {
147 debug!(root_logger, "GENERATE KEYPAIR ERA command");
148 println!(
149 "Era generate keypair to {}",
150 self.target_path.to_string_lossy()
151 );
152
153 EraTools::create_and_save_era_keypair(&self.target_path)
154 .with_context(|| "era-tools: keypair generation error")?;
155
156 Ok(())
157 }
158
159 pub fn extract_config(_parent: String) -> HashMap<String, StructDoc> {
160 HashMap::new()
161 }
162}