Skip to content

Commit e93d680

Browse files
committed
feature: Add a subcommand generate_keypair on eracommand
1 parent b4ad474 commit e93d680

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

mithril-aggregator/src/commands/era_command.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ pub enum EraSubCommand {
4040

4141
/// Era tx datum generate command.
4242
GenerateTxDatum(GenerateTxDatumEraSubCommand),
43+
44+
/// Era keypair generation command.
45+
GenerateKeypair(GenerateKeypairEraSubCommand),
4346
}
4447

4548
impl EraSubCommand {
@@ -51,6 +54,7 @@ impl EraSubCommand {
5154
match self {
5255
Self::List(cmd) => cmd.execute(root_logger, config_builder).await,
5356
Self::GenerateTxDatum(cmd) => cmd.execute(root_logger, config_builder).await,
57+
Self::GenerateKeypair(cmd) => cmd.execute(root_logger, config_builder).await,
5458
}
5559
}
5660
}
@@ -129,3 +133,30 @@ impl GenerateTxDatumEraSubCommand {
129133
Ok(())
130134
}
131135
}
136+
137+
/// Era keypair generation command.
138+
#[derive(Parser, Debug, Clone)]
139+
pub struct GenerateKeypairEraSubCommand {
140+
/// Target path for the generated keypair
141+
#[clap(long)]
142+
target_path: PathBuf,
143+
}
144+
145+
impl 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+
}

mithril-aggregator/src/tools/era.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::path::{Path, PathBuf};
2+
13
use anyhow::anyhow;
24
use mithril_common::{
35
chain_observer::{TxDatumBuilder, TxDatumFieldValue},
@@ -56,16 +58,41 @@ impl EraTools {
5658
.build()?;
5759
Ok(tx_datum.0)
5860
}
61+
62+
/// Export the era keypair to a folder and returns the paths to the files (secret key, verification_key)
63+
pub fn create_and_save_era_keypair(keypair_path: &Path) -> StdResult<(PathBuf, PathBuf)> {
64+
let era_signer = EraMarkersSigner::create_non_deterministic_signer();
65+
let era_secret_key_path = keypair_path.join("era.sk");
66+
era_signer
67+
.secret_key()
68+
.write_json_hex_to_file(&era_secret_key_path)?;
69+
let era_verification_key_path = keypair_path.join("era.vk");
70+
era_signer
71+
.verification_key()
72+
.write_json_hex_to_file(&era_verification_key_path)?;
73+
74+
Ok((era_secret_key_path, era_verification_key_path))
75+
}
5976
}
6077

6178
#[cfg(test)]
6279
mod tests {
80+
use mithril_common::{
81+
crypto_helper::{EraMarkersVerifierSecretKey, EraMarkersVerifierVerificationKey},
82+
test_utils::TempDir,
83+
};
84+
use std::fs::read_to_string;
85+
6386
use super::*;
6487

6588
fn build_tools() -> EraTools {
6689
EraTools {}
6790
}
6891

92+
fn get_temp_dir(dir_name: &str) -> PathBuf {
93+
TempDir::create("era", dir_name)
94+
}
95+
6996
#[test]
7097
fn get_supported_eras_list() {
7198
let era_tools = build_tools();
@@ -92,4 +119,25 @@ mod tests {
92119
.generate_tx_datum(Epoch(3), Some(Epoch(2)), &era_markers_signer)
93120
.expect_err("generate_tx_datum should have failed");
94121
}
122+
123+
#[test]
124+
fn test_create_and_save_era_keypair() {
125+
let temp_dir = get_temp_dir("test_create_and_save_era_keypair");
126+
let (era_secret_key_path, era_verification_key_path) =
127+
EraTools::create_and_save_era_keypair(&temp_dir)
128+
.expect("Failed to create and save era keypair");
129+
let era_secret_key = EraMarkersVerifierSecretKey::from_json_hex(
130+
&read_to_string(&era_secret_key_path).expect("Failed to read era secret key file"),
131+
)
132+
.expect("Failed to parse era secret key");
133+
let era_verification_key = EraMarkersVerifierVerificationKey::from_json_hex(
134+
&read_to_string(&era_verification_key_path)
135+
.expect("Failed to read era verification key file"),
136+
)
137+
.expect("Failed to parse era verification key");
138+
let era_verifier = EraMarkersSigner::from_secret_key(era_secret_key).create_verifier();
139+
140+
let expected_era_verification_key = era_verifier.to_verification_key();
141+
assert_eq!(expected_era_verification_key, era_verification_key);
142+
}
95143
}

mithril-common/src/crypto_helper/era.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ impl EraMarkersSigner {
5454
Self::create_test_signer(rng)
5555
}
5656

57+
/// Get the [EraMarkersVerifierSecretKey]
58+
pub fn secret_key(&self) -> EraMarkersVerifierSecretKey {
59+
self.secret_key.clone()
60+
}
61+
62+
/// Get the [EraMarkersVerifierVerificationKey]
63+
pub fn verification_key(&self) -> EraMarkersVerifierVerificationKey {
64+
self.secret_key.verifying_key().into()
65+
}
66+
5767
/// [EraMarkersSigner] from [EraMarkersVerifierSecretKey]
5868
pub fn from_secret_key(secret_key: EraMarkersVerifierSecretKey) -> Self {
5969
Self { secret_key }

0 commit comments

Comments
 (0)