cleaned up key loading

This commit is contained in:
Jędrzej Stuczyński
2024-01-05 14:10:41 +00:00
parent 858fafb1a5
commit 89315f0c2a
5 changed files with 88 additions and 49 deletions
-1
View File
@@ -16,7 +16,6 @@ use nym_dkg::Threshold;
use nym_validator_client::nyxd::cosmwasm_client::logs::{find_attribute, NODE_INDEX};
use nym_validator_client::nyxd::cosmwasm_client::types::ExecuteResult;
use nym_validator_client::nyxd::AccountId;
use std::time::Duration;
pub(crate) struct DkgClient {
inner: Box<dyn Client + Send + Sync>,
@@ -0,0 +1,45 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::support::config;
use anyhow::Context;
use nym_dkg::bte::keys::KeyPair as DkgKeyPair;
use rand::{CryptoRng, RngCore};
pub(crate) fn init_bte_keypair<R: RngCore + CryptoRng>(
rng: &mut R,
config: &config::CoconutSigner,
) -> anyhow::Result<()> {
let dkg_params = nym_dkg::bte::setup();
let kp = DkgKeyPair::new(&dkg_params, rng);
nym_pemstore::store_keypair(
&kp,
&nym_pemstore::KeyPairPath::new(
&config.storage_paths.decryption_key_path,
&config.storage_paths.public_key_with_proof_path,
),
)?;
Ok(())
}
pub(crate) fn load_bte_keypair(config: &config::CoconutSigner) -> anyhow::Result<DkgKeyPair> {
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
&config.storage_paths.decryption_key_path,
&config.storage_paths.public_key_with_proof_path,
))
.context("bte keypair load failure")
}
pub(crate) fn load_coconut_keypair_if_exists(
config: &config::CoconutSigner,
) -> anyhow::Result<Option<nym_coconut_interface::KeyPair>> {
if !config.storage_paths.secret_key_path.exists() {
return Ok(None);
}
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
&config.storage_paths.secret_key_path,
&config.storage_paths.verification_key_path,
))
.context("coconut keypair load failure")
.map(Some)
}
@@ -18,25 +18,12 @@ use nym_coconut_dkg_common::types::EpochState;
use nym_crypto::asymmetric::identity;
use nym_dkg::bte::keys::KeyPair as DkgKeyPair;
use nym_task::{TaskClient, TaskManager};
use rand::rngs::OsRng;
use rand::{CryptoRng, RngCore};
use std::path::PathBuf;
use std::time::{Duration, SystemTime};
use tokio::time::interval;
pub(crate) fn init_keypair(config: &config::CoconutSigner) -> Result<()> {
let mut rng = OsRng;
let dkg_params = nym_dkg::bte::setup();
let kp = DkgKeyPair::new(&dkg_params, &mut rng);
nym_pemstore::store_keypair(
&kp,
&nym_pemstore::KeyPairPath::new(
&config.storage_paths.decryption_key_path,
&config.storage_paths.public_key_with_proof_path,
),
)?;
Ok(())
}
pub(crate) mod keys;
pub(crate) struct DkgController<R> {
dkg_client: DkgClient,
@@ -48,10 +35,11 @@ pub(crate) struct DkgController<R> {
}
impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
pub(crate) async fn new(
pub(crate) fn new(
config: &config::CoconutSigner,
nyxd_client: nyxd::Client,
coconut_keypair: CoconutKeyPair,
dkg_keypair: DkgKeyPair,
identity_key: identity::PublicKey,
rng: R,
) -> Result<Self> {
@@ -59,18 +47,6 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
bail!("can't start a DKG controller without specifying an announce address!")
};
let dkg_keypair = nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
&config.storage_paths.decryption_key_path,
&config.storage_paths.public_key_with_proof_path,
))?;
if let Ok(coconut_keypair_value) =
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
&config.storage_paths.secret_key_path,
&config.storage_paths.verification_key_path,
))
{
coconut_keypair.set(Some(coconut_keypair_value)).await;
}
let persistent_state =
PersistentState::load_from_file(&config.storage_paths.dkg_persistent_state_path)
.unwrap_or_default();
@@ -92,12 +68,12 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
})
}
async fn dump_persistent_state(&self) {
if !self.state.coconut_keypair_is_some().await {
// Delete the files just in case the process is killed before the new keys are generated
std::fs::remove_file(&self.secret_key_path).ok();
std::fs::remove_file(&self.verification_key_path).ok();
}
fn persist_state(&self) {
// if !self.state.coconut_keypair_is_some().await {
// // Delete the files just in case the process is killed before the new keys are generated
// std::fs::remove_file(&self.secret_key_path).ok();
// std::fs::remove_file(&self.verification_key_path).ok();
// }
let persistent_state = PersistentState::from(&self.state);
if let Err(err) = persistent_state.save_to_file(self.state.persistent_state_path()) {
warn!("Could not backup the state for this iteration: {err}");
@@ -170,7 +146,7 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
self.state.set_was_in_progress();
// We're dumping state here so that we don't do it uselessly during the
// long InProgress state
self.dump_persistent_state().await;
self.persist_state();
Ok(())
}
};
@@ -179,7 +155,7 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
} else if epoch.state != EpochState::InProgress
&& epoch.state != EpochState::WaitingInitialisation
{
self.dump_persistent_state().await;
self.persist_state();
}
if let Ok(current_timestamp) = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
@@ -205,12 +181,11 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
}
}
// TODO: can we make it non-async? it seems we'd have to modify `coconut_keypair.set(coconut_keypair_value)` in new
// could we do it?
pub(crate) async fn start(
pub(crate) fn start(
config: &config::CoconutSigner,
nyxd_client: nyxd::Client,
coconut_keypair: CoconutKeyPair,
dkg_bte_keypair: DkgKeyPair,
identity_key: identity::PublicKey,
rng: R,
shutdown: &TaskManager,
@@ -219,8 +194,14 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
R: Sync + Send + 'static,
{
let shutdown_listener = shutdown.subscribe();
let dkg_controller =
DkgController::new(config, nyxd_client, coconut_keypair, identity_key, rng).await?;
let dkg_controller = DkgController::new(
config,
nyxd_client,
coconut_keypair,
dkg_bte_keypair,
identity_key,
rng,
)?;
tokio::spawn(async move { dkg_controller.run(shutdown_listener).await });
Ok(())
}
+14 -5
View File
@@ -4,6 +4,7 @@
#[macro_use]
extern crate rocket;
use crate::coconut::dkg::controller::keys::{load_bte_keypair, load_coconut_keypair_if_exists};
use crate::epoch_operations::RewardedSetUpdater;
use crate::network::models::NetworkDetails;
use crate::node_describe_cache::DescribedNodes;
@@ -68,7 +69,13 @@ async fn start_nym_api_tasks(config: Config) -> anyhow::Result<ShutdownHandles>
let nym_network_details = NymNetworkDetails::new_from_env();
let network_details = NetworkDetails::new(connected_nyxd.to_string(), nym_network_details);
let coconut_keypair = coconut::keypair::KeyPair::new();
let coconut_keypair_wrapper = coconut::keypair::KeyPair::new();
// if the keypair doesnt exist (because say this API is running in the caching mode), nothing will happen
if let Some(loaded_keys) = load_coconut_keypair_if_exists(&config.coconut_signer)? {
coconut_keypair_wrapper.set(Some(loaded_keys)).await
}
let identity_keypair = config.base.storage_paths.load_identity()?;
let identity_public_key = *identity_keypair.public_key();
@@ -78,7 +85,7 @@ async fn start_nym_api_tasks(config: Config) -> anyhow::Result<ShutdownHandles>
network_details,
nyxd_client.clone(),
identity_keypair,
coconut_keypair.clone(),
coconut_keypair_wrapper.clone(),
)
.await?;
@@ -134,15 +141,17 @@ async fn start_nym_api_tasks(config: Config) -> anyhow::Result<ShutdownHandles>
// start dkg task
if config.coconut_signer.enabled {
let dkg_bte_keypair = load_bte_keypair(&config.coconut_signer)?;
DkgController::start(
&config.coconut_signer,
nyxd_client.clone(),
coconut_keypair,
coconut_keypair_wrapper,
dkg_bte_keypair,
identity_public_key,
OsRng,
&shutdown,
)
.await?;
)?;
}
// and then only start the uptime updater (and the monitor itself, duh)
+8 -3
View File
@@ -1,22 +1,26 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::coconut::dkg::controller::keys::init_bte_keypair;
use crate::support::config;
use crate::support::config::{
default_config_directory, default_data_directory, upgrade_helpers, Config,
};
use anyhow::{Context, Result};
use nym_crypto::asymmetric::identity;
use rand_07::rngs::OsRng;
use rand::rngs::OsRng;
use rand_07::rngs::OsRng as OsRng07;
use std::{fs, io};
// TODO: once we upgrade ed25519 library, we could use the same rand library and use proper
// <R: RngCore + CryptoRng> bound
fn init_identity_keys(config: &config::NymApiPaths) -> Result<()> {
let keypaths = nym_pemstore::KeyPairPath::new(
&config.private_identity_key_file,
&config.public_identity_key_file,
);
let mut rng = OsRng;
let mut rng = OsRng07;
let keypair = identity::KeyPair::new(&mut rng);
nym_pemstore::store_keypair(&keypair, &keypaths)
.context("failed to store identity keys of the nym api")?;
@@ -38,7 +42,8 @@ pub(crate) fn initialise_new(id: &str) -> Result<Config> {
init_identity_keys(&config.base.storage_paths)?;
// create DKG BTE keys
crate::coconut::dkg::controller::init_keypair(&config.coconut_signer)?;
let mut rng = OsRng;
init_bte_keypair(&mut rng, &config.coconut_signer)?;
Ok(config)
}