Skip to content

Commit b797355

Browse files
authored
Merge pull request #2274 from input-output-hk/sfa/2271/add_command_to_create_keypair
Add an `era` subcommand to create keypair
2 parents b4ad474 + 257cb8f commit b797355

File tree

7 files changed

+101
-5
lines changed

7 files changed

+101
-5
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/website/root/manual/develop/nodes/mithril-aggregator.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ Usage: mithril-aggregator era <COMMAND>
259259
Commands:
260260
list Era list command
261261
generate-tx-datum Era tx datum generate command
262+
generate-keypair Era keypair generation command
262263
help Print this message or the help of the given subcommand(s)
263264

264265
Options:
@@ -401,6 +402,7 @@ Here are the available subcommands:
401402
| **genesis generate-keypair** | Generates a genesis keypair |
402403
| **era list** | Lists the supported eras |
403404
| **era generate-tx-datum** | Generates the era markers transaction datum to be stored on-chain |
405+
| **era generate-keypair** | Generates an era keypair |
404406
| **tools recompute-certificates-hash** | Loads all certificates in the database, recomputing their hash, and updating all related entities |
405407

406408
## Configuration parameters
@@ -506,4 +508,10 @@ Here is a list of the available parameters:
506508
| `era_markers_secret_key` | `--era-markers-secret-key` | - | `ERA_MARKERS_SECRET_KEY` | Era markers secret key that is used to verify the authenticity of the era markers on the chain. | - | - | :heavy_check_mark: |
507509
| `target_path` | `--target-path` | - | - | Path of the file to export the payload to. | - | - | - |
508510

511+
`era generate-keypair` command:
512+
513+
| Parameter | Command line (long) | Command line (short) | Environment variable | Description | Default value | Example | Mandatory |
514+
| ------------- | ------------------- | :------------------: | -------------------- | ------------------------------------- | ------------- | ------- | :----------------: |
515+
| `target_path` | `--target-path` | - | - | Target path for the generated keypair | - | - | :heavy_check_mark: |
516+
509517
The `tools recompute-certificates-hash` command has no dedicated parameters.

mithril-aggregator/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mithril-aggregator"
3-
version = "0.6.26"
3+
version = "0.6.27"
44
description = "A Mithril Aggregator server"
55
authors = { workspace = true }
66
edition = { workspace = true }

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/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mithril-common"
3-
version = "0.4.112"
3+
version = "0.4.113"
44
description = "Common types, interfaces, and utilities for Mithril nodes."
55
authors = { workspace = true }
66
edition = { workspace = true }

mithril-common/src/crypto_helper/era.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,22 @@ impl EraMarkersSigner {
4747
Self::create_test_signer(rng)
4848
}
4949

50-
#[cfg(test)]
5150
/// [EraMarkersSigner] non deterministic
5251
pub fn create_non_deterministic_signer() -> Self {
5352
let rng = rand_core::OsRng;
5453
Self::create_test_signer(rng)
5554
}
5655

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

0 commit comments

Comments
 (0)