Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1dcd1776b5 | |||
| e3169c95c6 |
@@ -14,13 +14,14 @@ use crate::coconut::keypair::KeyPair as CoconutKeyPair;
|
|||||||
use crate::nyxd;
|
use crate::nyxd;
|
||||||
use crate::support::config;
|
use crate::support::config;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use nym_coconut_dkg_common::types::EpochState;
|
use nym_coconut_dkg_common::types::{Epoch, EpochState};
|
||||||
use nym_dkg::bte::keys::KeyPair as DkgKeyPair;
|
use nym_dkg::bte::keys::KeyPair as DkgKeyPair;
|
||||||
use nym_task::{TaskClient, TaskManager};
|
use nym_task::{TaskClient, TaskManager};
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::Duration;
|
||||||
|
use time::OffsetDateTime;
|
||||||
use tokio::time::interval;
|
use tokio::time::interval;
|
||||||
|
|
||||||
pub(crate) fn init_keypair(config: &config::CoconutSigner) -> Result<()> {
|
pub(crate) fn init_keypair(config: &config::CoconutSigner) -> Result<()> {
|
||||||
@@ -97,99 +98,121 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn handle_epoch_state(&mut self) {
|
async fn maybe_advance_dkg_state(&self, epoch: Epoch) {
|
||||||
match self.dkg_client.get_current_epoch().await {
|
let end =
|
||||||
Err(err) => warn!("Could not get current epoch state {err}"),
|
OffsetDateTime::from_unix_timestamp(epoch.finish_timestamp.seconds() as i64).unwrap();
|
||||||
Ok(epoch) => {
|
|
||||||
if self
|
let remaining = end - OffsetDateTime::now_utc();
|
||||||
.dkg_client
|
|
||||||
.group_member()
|
// TODO: after debugging is finished, change that to `debug!`
|
||||||
.await
|
info!(
|
||||||
.map(|resp| resp.weight.is_none())
|
"there are {} seconds until the current DKG epoch [stage] end",
|
||||||
.unwrap_or(true)
|
remaining.whole_seconds()
|
||||||
{
|
);
|
||||||
debug!("Not a member of the group, DKG won't be run");
|
|
||||||
return;
|
if remaining.is_negative() {
|
||||||
}
|
// We try advancing the epoch state, on a best-effort basis
|
||||||
if let Err(err) = self.state.is_consistent(epoch.state).await {
|
info!("DKG: Trying to advance the epoch");
|
||||||
debug!("Epoch state is corrupted - {err}. Awaiting for a DKG restart.");
|
if let Err(err) = self.dkg_client.advance_epoch_state().await {
|
||||||
} else {
|
error!("failed to advance DKG epoch: {err}")
|
||||||
let ret = match epoch.state {
|
|
||||||
EpochState::PublicKeySubmission { resharing } => {
|
|
||||||
public_key_submission(&self.dkg_client, &mut self.state, resharing)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
EpochState::DealingExchange { resharing } => {
|
|
||||||
dealing_exchange(
|
|
||||||
&self.dkg_client,
|
|
||||||
&mut self.state,
|
|
||||||
self.rng.clone(),
|
|
||||||
resharing,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
EpochState::VerificationKeySubmission { resharing } => {
|
|
||||||
let keypair_path = nym_pemstore::KeyPairPath::new(
|
|
||||||
self.secret_key_path.clone(),
|
|
||||||
self.verification_key_path.clone(),
|
|
||||||
);
|
|
||||||
verification_key_submission(
|
|
||||||
&self.dkg_client,
|
|
||||||
&mut self.state,
|
|
||||||
&keypair_path,
|
|
||||||
resharing,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
EpochState::VerificationKeyValidation { resharing } => {
|
|
||||||
verification_key_validation(
|
|
||||||
&self.dkg_client,
|
|
||||||
&mut self.state,
|
|
||||||
resharing,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
EpochState::VerificationKeyFinalization { resharing } => {
|
|
||||||
verification_key_finalization(
|
|
||||||
&self.dkg_client,
|
|
||||||
&mut self.state,
|
|
||||||
resharing,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
// Just wait, in case we need to redo dkg at some point
|
|
||||||
EpochState::InProgress => {
|
|
||||||
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;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Err(err) = ret {
|
|
||||||
warn!("Could not handle this iteration for the epoch state: {err}");
|
|
||||||
} else if epoch.state != EpochState::InProgress {
|
|
||||||
self.dump_persistent_state().await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Ok(current_timestamp) =
|
|
||||||
SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)
|
|
||||||
{
|
|
||||||
if current_timestamp.as_secs() >= epoch.finish_timestamp.seconds() {
|
|
||||||
// We try advancing the epoch state, on a best-effort basis
|
|
||||||
info!("DKG: Trying to advance the epoch");
|
|
||||||
self.dkg_client.advance_epoch_state().await.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn handle_epoch_state(&mut self) {
|
||||||
|
let epoch = match self.dkg_client.get_current_epoch().await {
|
||||||
|
Ok(epoch) => epoch,
|
||||||
|
Err(err) => {
|
||||||
|
warn!("Could not get current epoch state: {err}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if self
|
||||||
|
.dkg_client
|
||||||
|
.group_member()
|
||||||
|
.await
|
||||||
|
.map(|resp| resp.weight.is_none())
|
||||||
|
.unwrap_or(true)
|
||||||
|
{
|
||||||
|
debug!("Not a member of the group, DKG won't be run");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(err) = self.state.is_consistent(epoch.state).await {
|
||||||
|
warn!("Epoch state is corrupted - {err}. Awaiting for a DKG restart.");
|
||||||
|
self.maybe_advance_dkg_state(epoch).await;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ret = match epoch.state {
|
||||||
|
EpochState::PublicKeySubmission { resharing } => {
|
||||||
|
info!("attempting to perform DKG key submission");
|
||||||
|
public_key_submission(&self.dkg_client, &mut self.state, resharing).await
|
||||||
|
}
|
||||||
|
EpochState::DealingExchange { resharing } => {
|
||||||
|
info!("attempting to perform DKG dealing exchange");
|
||||||
|
dealing_exchange(
|
||||||
|
&self.dkg_client,
|
||||||
|
&mut self.state,
|
||||||
|
self.rng.clone(),
|
||||||
|
resharing,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
EpochState::VerificationKeySubmission { resharing } => {
|
||||||
|
info!("attempting to perform DKG verification key submission");
|
||||||
|
let keypair_path = nym_pemstore::KeyPairPath::new(
|
||||||
|
self.secret_key_path.clone(),
|
||||||
|
self.verification_key_path.clone(),
|
||||||
|
);
|
||||||
|
verification_key_submission(
|
||||||
|
&self.dkg_client,
|
||||||
|
&mut self.state,
|
||||||
|
&keypair_path,
|
||||||
|
resharing,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
EpochState::VerificationKeyValidation { resharing } => {
|
||||||
|
info!("attempting to perform DKG verification key validation");
|
||||||
|
verification_key_validation(&self.dkg_client, &mut self.state, resharing).await
|
||||||
|
}
|
||||||
|
EpochState::VerificationKeyFinalization { resharing } => {
|
||||||
|
info!("attempting to perform DKG verification key finalization");
|
||||||
|
verification_key_finalization(&self.dkg_client, &mut self.state, resharing).await
|
||||||
|
}
|
||||||
|
// Just wait, in case we need to redo dkg at some point
|
||||||
|
EpochState::InProgress => {
|
||||||
|
info!(
|
||||||
|
"DKG epoch is in progress - dumping the persistent state to {}",
|
||||||
|
self.state.persistent_state_path().display()
|
||||||
|
);
|
||||||
|
|
||||||
|
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;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Err(err) = ret {
|
||||||
|
warn!("Could not handle this iteration for the epoch state: {err}");
|
||||||
|
} else if epoch.state != EpochState::InProgress {
|
||||||
|
self.dump_persistent_state().await;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.maybe_advance_dkg_state(epoch).await
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) async fn run(mut self, mut shutdown: TaskClient) {
|
pub(crate) async fn run(mut self, mut shutdown: TaskClient) {
|
||||||
let mut interval = interval(self.polling_rate);
|
let mut interval = interval(self.polling_rate);
|
||||||
while !shutdown.is_shutdown() {
|
while !shutdown.is_shutdown() {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = interval.tick() => self.handle_epoch_state().await,
|
_ = interval.tick() => {
|
||||||
|
info!("DkgController tick (this should be happening every {:?}", self.polling_rate);
|
||||||
|
self.handle_epoch_state().await
|
||||||
|
}
|
||||||
_ = shutdown.recv() => {
|
_ = shutdown.recv() => {
|
||||||
trace!("DkgController: Received shutdown");
|
trace!("DkgController: Received shutdown");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user