more completed key finalization

This commit is contained in:
Jędrzej Stuczyński
2024-01-24 10:34:42 +00:00
parent 75cc310fc8
commit 6d9bc302ff
8 changed files with 391 additions and 350 deletions
+2 -1
View File
@@ -1,6 +1,7 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::coconut::dkg::key_finalization::KeyFinalizationError;
use crate::coconut::error::CoconutError;
use std::path::PathBuf;
use thiserror::Error;
@@ -56,7 +57,7 @@ pub enum DkgError {
#[error("failed to finalize verification keys in the DKG contract: {source}")]
VerificationKeyFinalizationFailure {
#[source]
source: CoconutError,
source: KeyFinalizationError,
},
#[error("failed to advance the DKG state: {source}")]
+1 -1
View File
@@ -172,7 +172,7 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
) -> Result<(), DkgError> {
debug!("DKG: verification key finalization (resharing: {resharing})");
self.verification_key_finalization(epoch_id, resharing)
self.verification_key_finalization(epoch_id)
.await
.map_err(|source| DkgError::VerificationKeyFinalizationFailure { source })
}
+4 -323
View File
@@ -484,6 +484,7 @@ impl<R: RngCore + CryptoRng> DkgController<R> {
// check if we have already generated the new keys and submitted verification proposal
if key_generation_state.completed() {
// TODO: ASSERT: we have a VALID key
// TODO: ASSERT we have a valid proposal id
// the only way this could be a false positive is if the chain forked and blocks got reverted,
// but I don't think we have to worry about that
@@ -505,6 +506,7 @@ impl<R: RngCore + CryptoRng> DkgController<R> {
.await?;
if maybe_share.is_some() {
todo!("finalize, we're done")
// TODO: recover proposal id with some weird queries
}
// ASSUMPTION:
@@ -527,7 +529,8 @@ impl<R: RngCore + CryptoRng> DkgController<R> {
todo!()
}
let proposal_id = self.submit_partial_verification_key(coconut_keypair.keys.verification_key(), resharing)
let proposal_id = self
.submit_partial_verification_key(coconut_keypair.keys.verification_key(), resharing)
.await?;
self.state.set_coconut_keypair(coconut_keypair).await;
@@ -1009,326 +1012,4 @@ pub(crate) mod tests {
Ok(())
}
#[tokio::test]
#[ignore] // expensive test
async fn reshare_preserves_keys() {
todo!()
// let db = MockContractDb::new();
// let mut clients_and_states = prepare_clients_and_states_with_finalization(&db).await;
// for controller in clients_and_states.iter_mut() {
// controller.state.set_was_in_progress();
// }
//
// let mut vks = vec![];
// let mut indices = vec![];
// for controller in clients_and_states.iter() {
// let vk = controller
// .state
// .coconut_keypair()
// .await
// .as_ref()
// .unwrap()
// .keys
// .verification_key()
// .clone();
// let index = controller.state.node_index().unwrap();
// vks.push(vk);
// indices.push(index);
// }
// let initial_master_vk = aggregate_verification_keys(&vks, Some(&indices)).unwrap();
//
// let new_dkg_client = DkgClient::new(
// DummyClient::new(
// AccountId::from_str("n1sqkxzh7nl6kgndr4ew9795t2nkwmd8tpql67q7").unwrap(),
// )
// .with_dealer_details(&db.dealer_details_db)
// .with_dealings(&db.dealings_db)
// .with_proposal_db(&db.proposal_db)
// .with_verification_share(&db.verification_share_db)
// .with_threshold(&db.threshold_db)
// .with_initial_dealers_db(&db.initial_dealers_db),
// );
// let keypair = DkgKeyPair::new(dkg::params(), OsRng);
// let identity_keypair = identity::KeyPair::new(&mut thread_rng());
// let state = State::new(
// PathBuf::default(),
// PersistentState::default(),
// Url::parse("localhost:8000").unwrap(),
// keypair,
// *identity_keypair.public_key(),
// KeyPair::new(),
// );
//
// for (_, active) in db.dealer_details_db.write().unwrap().values_mut() {
// *active = false;
// }
//
// *db.dealings_db.write().unwrap() = Default::default();
// *db.verification_share_db.write().unwrap() = Default::default();
// let mut initial_dealers = vec![];
// for controller in clients_and_states.iter() {
// let client_address =
// Addr::unchecked(controller.dkg_client.get_address().await.as_ref());
// initial_dealers.push(client_address);
// }
// *db.initial_dealers_db.write().unwrap() = Some(InitialReplacementData {
// initial_dealers,
// initial_height: 1,
// });
// *clients_and_states.first_mut().unwrap() = DkgController::test_mock(new_dkg_client, state);
//
// for controller in clients_and_states.iter_mut() {
// controller.public_key_submission(0, true).await.unwrap();
// controller.dealing_exchange(0, true).await.unwrap();
// }
//
// for controller in clients_and_states.iter_mut() {
// let random_file: usize = OsRng.gen();
// let keypath = temp_dir().join(format!("coconut{}.pem", random_file));
// verification_key_submission(
// &controller.dkg_client,
// &mut controller.state,
// 0,
// &keypath,
// true,
// )
// .await
// .unwrap();
// std::fs::remove_file(keypath).unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// verification_key_validation(&controller.dkg_client, &mut controller.state, true)
// .await
// .unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// verification_key_finalization(&controller.dkg_client, &mut controller.state, true)
// .await
// .unwrap();
// }
// assert!(db
// .proposal_db
// .read()
// .unwrap()
// .values()
// .all(|proposal| { proposal.status == Status::Executed }));
//
// let mut vks = vec![];
// let mut indices = vec![];
// for controller in clients_and_states.iter() {
// let vk = controller
// .state
// .coconut_keypair()
// .await
// .as_ref()
// .unwrap()
// .keys
// .verification_key()
// .clone();
// let index = controller.state.node_index().unwrap();
// vks.push(vk);
// indices.push(index);
// }
// let reshared_master_vk = aggregate_verification_keys(&vks, Some(&indices)).unwrap();
// assert_eq!(initial_master_vk, reshared_master_vk);
}
#[tokio::test]
#[ignore] // expensive test
async fn reshare_after_reset() {
todo!()
// let db = MockContractDb::new();
// let mut clients_and_states = prepare_clients_and_states_with_finalization(&db).await;
// for controller in clients_and_states.iter_mut() {
// controller.state.set_was_in_progress();
// }
//
// let new_dkg_client = DkgClient::new(
// DummyClient::new(
// AccountId::from_str("n1vxkywf9g4cg0k2dehanzwzz64jw782qm0kuynf").unwrap(),
// )
// .with_dealer_details(&db.dealer_details_db)
// .with_dealings(&db.dealings_db)
// .with_proposal_db(&db.proposal_db)
// .with_verification_share(&db.verification_share_db)
// .with_threshold(&db.threshold_db)
// .with_initial_dealers_db(&db.initial_dealers_db),
// );
// let keypair = DkgKeyPair::new(dkg::params(), OsRng);
// let identity_keypair = identity::KeyPair::new(&mut thread_rng());
// let state = State::new(
// PathBuf::default(),
// PersistentState::default(),
// Url::parse("localhost:8000").unwrap(),
// keypair,
// *identity_keypair.public_key(),
// KeyPair::new(),
// );
// let new_dkg_client2 = DkgClient::new(
// DummyClient::new(
// AccountId::from_str("n1sqkxzh7nl6kgndr4ew9795t2nkwmd8tpql67q7").unwrap(),
// )
// .with_dealer_details(&db.dealer_details_db)
// .with_dealings(&db.dealings_db)
// .with_proposal_db(&db.proposal_db)
// .with_verification_share(&db.verification_share_db)
// .with_threshold(&db.threshold_db)
// .with_initial_dealers_db(&db.initial_dealers_db),
// );
// let keypair = DkgKeyPair::new(dkg::params(), OsRng);
// let identity_keypair = identity::KeyPair::new(&mut thread_rng());
// let state2 = State::new(
// PathBuf::default(),
// PersistentState::default(),
// Url::parse("localhost:8000").unwrap(),
// keypair,
// *identity_keypair.public_key(),
// KeyPair::new(),
// );
//
// for (_, active) in db.dealer_details_db.write().unwrap().values_mut() {
// *active = false;
// }
//
// *db.dealings_db.write().unwrap() = Default::default();
// *db.verification_share_db.write().unwrap() = Default::default();
// clients_and_states.pop().unwrap();
// let controller2 = clients_and_states.pop().unwrap();
// clients_and_states.push(DkgController::test_mock(new_dkg_client, state));
// clients_and_states.push(DkgController::test_mock(new_dkg_client2, state2));
//
// // DKG in reset mode
// for controller in clients_and_states.iter_mut() {
// controller.public_key_submission(0, false).await.unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// controller.dealing_exchange(0, false).await.unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// let random_file: usize = OsRng.gen();
// let keypath = temp_dir().join(format!("coconut{}.pem", random_file));
// verification_key_submission(
// &controller.dkg_client,
// &mut controller.state,
// 0,
// &keypath,
// false,
// )
// .await
// .unwrap();
// std::fs::remove_file(keypath).unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// verification_key_validation(&controller.dkg_client, &mut controller.state, false)
// .await
// .unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// verification_key_finalization(&controller.dkg_client, &mut controller.state, false)
// .await
// .unwrap();
// }
// assert!(db
// .proposal_db
// .read()
// .unwrap()
// .values()
// .all(|proposal| { proposal.status == Status::Executed }));
// for controller in clients_and_states.iter_mut() {
// controller.state.set_was_in_progress();
// }
//
// // DKG in reshare mode
// let mut vks = vec![];
// let mut indices = vec![];
// for controller in clients_and_states.iter() {
// let vk = controller
// .state
// .coconut_keypair()
// .await
// .as_ref()
// .unwrap()
// .keys
// .verification_key()
// .clone();
// let index = controller.state.node_index().unwrap();
// vks.push(vk);
// indices.push(index);
// }
// let initial_master_vk = aggregate_verification_keys(&vks, Some(&indices)).unwrap();
//
// for (_, active) in db.dealer_details_db.write().unwrap().values_mut() {
// *active = false;
// }
// *db.dealings_db.write().unwrap() = Default::default();
// *db.verification_share_db.write().unwrap() = Default::default();
// let mut initial_dealers = vec![];
// for controller in clients_and_states.iter() {
// let client_address =
// Addr::unchecked(controller.dkg_client.get_address().await.as_ref());
// initial_dealers.push(client_address);
// }
// *db.initial_dealers_db.write().unwrap() = Some(InitialReplacementData {
// initial_dealers,
// initial_height: 1,
// });
// *clients_and_states.last_mut().unwrap() = controller2;
//
// for controller in clients_and_states.iter_mut() {
// controller.public_key_submission(0, true).await.unwrap();
// controller.dealing_exchange(0, true).await.unwrap();
// }
//
// for controller in clients_and_states.iter_mut() {
// let random_file: usize = OsRng.gen();
// let keypath = temp_dir().join(format!("coconut{}.pem", random_file));
// verification_key_submission(
// &controller.dkg_client,
// &mut controller.state,
// 0,
// &keypath,
// true,
// )
// .await
// .unwrap();
// std::fs::remove_file(keypath).unwrap();
// }
//
// for controller in clients_and_states.iter_mut() {
// verification_key_validation(&controller.dkg_client, &mut controller.state, true)
// .await
// .unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// verification_key_finalization(&controller.dkg_client, &mut controller.state, true)
// .await
// .unwrap();
// }
// // assert!(db
// // .proposal_db
// // .read()
// // .unwrap()
// // .values()
// // .all(|proposal| { proposal.status == Status::Executed }));
//
// let mut vks = vec![];
// let mut indices = vec![];
// for controller in clients_and_states.iter() {
// let vk = controller
// .state
// .coconut_keypair()
// .await
// .as_ref()
// .unwrap()
// .keys
// .verification_key()
// .clone();
// let index = controller.state.node_index().unwrap();
// vks.push(vk);
// indices.push(index);
// }
// let reshared_master_vk = aggregate_verification_keys(&vks, Some(&indices)).unwrap();
// assert_eq!(initial_master_vk, reshared_master_vk);
}
}
+35 -10
View File
@@ -1,20 +1,33 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::coconut::dkg::client::DkgClient;
use crate::coconut::dkg::controller::DkgController;
use crate::coconut::dkg::state::{ConsistentState, State};
use crate::coconut::error::CoconutError;
use cw3::Status;
use nym_coconut_dkg_common::types::EpochId;
use rand::{CryptoRng, RngCore};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum KeyFinalizationError {
#[error(transparent)]
CoconutError(#[from] CoconutError),
#[error("our proposal for key verification is still open (or is pending) (proposal id: {proposal_id}) ")]
UnresolvedProposal { proposal_id: u64 },
#[error("our proposal for key verification has been rejected (proposal id: {proposal_id})")]
RejectedProposal { proposal_id: u64 },
#[error("can't complete key finalization without key validation")]
IncompleteKeyValidation,
}
impl<R: RngCore + CryptoRng> DkgController<R> {
pub(crate) async fn verification_key_finalization(
&mut self,
epoch_id: EpochId,
_resharing: bool,
) -> Result<(), CoconutError> {
) -> Result<(), KeyFinalizationError> {
let key_finalization_state = self.state.key_finalization_state(epoch_id)?;
// check if we have already executed our own proposal
@@ -25,6 +38,10 @@ impl<R: RngCore + CryptoRng> DkgController<R> {
return Ok(());
}
if !self.state.key_validation_state(epoch_id)?.completed {
return Err(KeyFinalizationError::IncompleteKeyValidation);
}
let proposal_id = self.state.proposal_id(epoch_id)?;
// check whether our key has already been verified with executed proposal,
@@ -32,34 +49,42 @@ impl<R: RngCore + CryptoRng> DkgController<R> {
// or by another party
let status = self.dkg_client.get_proposal_status(proposal_id).await?;
match status {
// if the proposal hasn't been resolved, there's not much we can do but wait and pray
Status::Pending | Status::Open => {
// 'theoretically' it's possible that more votes are going to come in, but it's very unlikely
warn!("our proposal ({proposal_id}) still hasn't received enough votes to get accepted");
todo!();
return Err(KeyFinalizationError::UnresolvedProposal { proposal_id });
}
// if the proposal has been rejected, there's nothing we can do, we failed the DKG
Status::Rejected => {
// TODO: technically there's nothing enforcing this...
// technically there's nothing enforcing this, so as long as our keys have been properly generated
// (even though they've been rejected by other parties), they could still issue [cryptographically] valid credentials
error!("our key verification proposal ({proposal_id}) has been rejected - we can't use our derived keys!");
todo!()
self.state.key_finalization_state_mut(epoch_id)?.completed = true;
return Err(KeyFinalizationError::RejectedProposal { proposal_id });
}
// if the proposal has passed, execute it to finalize our key
Status::Passed => {
self.dkg_client
.execute_verification_key_share(proposal_id)
.await?;
}
// if they proposal has already been executed, we're done!
Status::Executed => {
// generally each dealer is responsible for executing its own proposals,
// but technically there's nothing preventing other dealers from executing them
debug!("our dkg proposal has already been executed");
}
}
self.state.key_finalization_state_mut(epoch_id)?.completed = true;
self.state.validate_coconut_keypair();
info!("DKG: Finalized own verification key on chain");
Ok(())
}
}
// each dealer is responsible for executing its own proposals
#[cfg(test)]
mod tests {
use super::*;
@@ -84,7 +109,7 @@ mod tests {
validate_keys(&mut controllers, false).await;
for controller in controllers.iter_mut() {
let res = controller.verification_key_finalization(epoch, false).await;
let res = controller.verification_key_finalization(epoch).await;
assert!(res.is_ok());
assert!(controller.state.key_finalization_state(epoch)?.completed);
+330 -3
View File
@@ -1,4 +1,4 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use std::sync::OnceLock;
@@ -13,7 +13,334 @@ pub(crate) mod complaints;
pub(crate) mod controller;
pub(crate) mod dealing;
pub(crate) mod key_derivation;
mod key_finalization;
mod key_validation;
pub(crate) mod key_finalization;
pub(crate) mod key_validation;
pub(crate) mod public_key;
pub(crate) mod state;
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
#[ignore] // expensive test
async fn reshare_preserves_keys() {
todo!()
// let db = MockContractDb::new();
// let mut clients_and_states = prepare_clients_and_states_with_finalization(&db).await;
// for controller in clients_and_states.iter_mut() {
// controller.state.set_was_in_progress();
// }
//
// let mut vks = vec![];
// let mut indices = vec![];
// for controller in clients_and_states.iter() {
// let vk = controller
// .state
// .coconut_keypair()
// .await
// .as_ref()
// .unwrap()
// .keys
// .verification_key()
// .clone();
// let index = controller.state.node_index().unwrap();
// vks.push(vk);
// indices.push(index);
// }
// let initial_master_vk = aggregate_verification_keys(&vks, Some(&indices)).unwrap();
//
// let new_dkg_client = DkgClient::new(
// DummyClient::new(
// AccountId::from_str("n1sqkxzh7nl6kgndr4ew9795t2nkwmd8tpql67q7").unwrap(),
// )
// .with_dealer_details(&db.dealer_details_db)
// .with_dealings(&db.dealings_db)
// .with_proposal_db(&db.proposal_db)
// .with_verification_share(&db.verification_share_db)
// .with_threshold(&db.threshold_db)
// .with_initial_dealers_db(&db.initial_dealers_db),
// );
// let keypair = DkgKeyPair::new(dkg::params(), OsRng);
// let identity_keypair = identity::KeyPair::new(&mut thread_rng());
// let state = State::new(
// PathBuf::default(),
// PersistentState::default(),
// Url::parse("localhost:8000").unwrap(),
// keypair,
// *identity_keypair.public_key(),
// KeyPair::new(),
// );
//
// for (_, active) in db.dealer_details_db.write().unwrap().values_mut() {
// *active = false;
// }
//
// *db.dealings_db.write().unwrap() = Default::default();
// *db.verification_share_db.write().unwrap() = Default::default();
// let mut initial_dealers = vec![];
// for controller in clients_and_states.iter() {
// let client_address =
// Addr::unchecked(controller.dkg_client.get_address().await.as_ref());
// initial_dealers.push(client_address);
// }
// *db.initial_dealers_db.write().unwrap() = Some(InitialReplacementData {
// initial_dealers,
// initial_height: 1,
// });
// *clients_and_states.first_mut().unwrap() = DkgController::test_mock(new_dkg_client, state);
//
// for controller in clients_and_states.iter_mut() {
// controller.public_key_submission(0, true).await.unwrap();
// controller.dealing_exchange(0, true).await.unwrap();
// }
//
// for controller in clients_and_states.iter_mut() {
// let random_file: usize = OsRng.gen();
// let keypath = temp_dir().join(format!("coconut{}.pem", random_file));
// verification_key_submission(
// &controller.dkg_client,
// &mut controller.state,
// 0,
// &keypath,
// true,
// )
// .await
// .unwrap();
// std::fs::remove_file(keypath).unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// verification_key_validation(&controller.dkg_client, &mut controller.state, true)
// .await
// .unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// verification_key_finalization(&controller.dkg_client, &mut controller.state, true)
// .await
// .unwrap();
// }
// assert!(db
// .proposal_db
// .read()
// .unwrap()
// .values()
// .all(|proposal| { proposal.status == Status::Executed }));
//
// let mut vks = vec![];
// let mut indices = vec![];
// for controller in clients_and_states.iter() {
// let vk = controller
// .state
// .coconut_keypair()
// .await
// .as_ref()
// .unwrap()
// .keys
// .verification_key()
// .clone();
// let index = controller.state.node_index().unwrap();
// vks.push(vk);
// indices.push(index);
// }
// let reshared_master_vk = aggregate_verification_keys(&vks, Some(&indices)).unwrap();
// assert_eq!(initial_master_vk, reshared_master_vk);
}
#[tokio::test]
#[ignore] // expensive test
async fn reshare_after_reset() {
todo!()
// let db = MockContractDb::new();
// let mut clients_and_states = prepare_clients_and_states_with_finalization(&db).await;
// for controller in clients_and_states.iter_mut() {
// controller.state.set_was_in_progress();
// }
//
// let new_dkg_client = DkgClient::new(
// DummyClient::new(
// AccountId::from_str("n1vxkywf9g4cg0k2dehanzwzz64jw782qm0kuynf").unwrap(),
// )
// .with_dealer_details(&db.dealer_details_db)
// .with_dealings(&db.dealings_db)
// .with_proposal_db(&db.proposal_db)
// .with_verification_share(&db.verification_share_db)
// .with_threshold(&db.threshold_db)
// .with_initial_dealers_db(&db.initial_dealers_db),
// );
// let keypair = DkgKeyPair::new(dkg::params(), OsRng);
// let identity_keypair = identity::KeyPair::new(&mut thread_rng());
// let state = State::new(
// PathBuf::default(),
// PersistentState::default(),
// Url::parse("localhost:8000").unwrap(),
// keypair,
// *identity_keypair.public_key(),
// KeyPair::new(),
// );
// let new_dkg_client2 = DkgClient::new(
// DummyClient::new(
// AccountId::from_str("n1sqkxzh7nl6kgndr4ew9795t2nkwmd8tpql67q7").unwrap(),
// )
// .with_dealer_details(&db.dealer_details_db)
// .with_dealings(&db.dealings_db)
// .with_proposal_db(&db.proposal_db)
// .with_verification_share(&db.verification_share_db)
// .with_threshold(&db.threshold_db)
// .with_initial_dealers_db(&db.initial_dealers_db),
// );
// let keypair = DkgKeyPair::new(dkg::params(), OsRng);
// let identity_keypair = identity::KeyPair::new(&mut thread_rng());
// let state2 = State::new(
// PathBuf::default(),
// PersistentState::default(),
// Url::parse("localhost:8000").unwrap(),
// keypair,
// *identity_keypair.public_key(),
// KeyPair::new(),
// );
//
// for (_, active) in db.dealer_details_db.write().unwrap().values_mut() {
// *active = false;
// }
//
// *db.dealings_db.write().unwrap() = Default::default();
// *db.verification_share_db.write().unwrap() = Default::default();
// clients_and_states.pop().unwrap();
// let controller2 = clients_and_states.pop().unwrap();
// clients_and_states.push(DkgController::test_mock(new_dkg_client, state));
// clients_and_states.push(DkgController::test_mock(new_dkg_client2, state2));
//
// // DKG in reset mode
// for controller in clients_and_states.iter_mut() {
// controller.public_key_submission(0, false).await.unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// controller.dealing_exchange(0, false).await.unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// let random_file: usize = OsRng.gen();
// let keypath = temp_dir().join(format!("coconut{}.pem", random_file));
// verification_key_submission(
// &controller.dkg_client,
// &mut controller.state,
// 0,
// &keypath,
// false,
// )
// .await
// .unwrap();
// std::fs::remove_file(keypath).unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// verification_key_validation(&controller.dkg_client, &mut controller.state, false)
// .await
// .unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// verification_key_finalization(&controller.dkg_client, &mut controller.state, false)
// .await
// .unwrap();
// }
// assert!(db
// .proposal_db
// .read()
// .unwrap()
// .values()
// .all(|proposal| { proposal.status == Status::Executed }));
// for controller in clients_and_states.iter_mut() {
// controller.state.set_was_in_progress();
// }
//
// // DKG in reshare mode
// let mut vks = vec![];
// let mut indices = vec![];
// for controller in clients_and_states.iter() {
// let vk = controller
// .state
// .coconut_keypair()
// .await
// .as_ref()
// .unwrap()
// .keys
// .verification_key()
// .clone();
// let index = controller.state.node_index().unwrap();
// vks.push(vk);
// indices.push(index);
// }
// let initial_master_vk = aggregate_verification_keys(&vks, Some(&indices)).unwrap();
//
// for (_, active) in db.dealer_details_db.write().unwrap().values_mut() {
// *active = false;
// }
// *db.dealings_db.write().unwrap() = Default::default();
// *db.verification_share_db.write().unwrap() = Default::default();
// let mut initial_dealers = vec![];
// for controller in clients_and_states.iter() {
// let client_address =
// Addr::unchecked(controller.dkg_client.get_address().await.as_ref());
// initial_dealers.push(client_address);
// }
// *db.initial_dealers_db.write().unwrap() = Some(InitialReplacementData {
// initial_dealers,
// initial_height: 1,
// });
// *clients_and_states.last_mut().unwrap() = controller2;
//
// for controller in clients_and_states.iter_mut() {
// controller.public_key_submission(0, true).await.unwrap();
// controller.dealing_exchange(0, true).await.unwrap();
// }
//
// for controller in clients_and_states.iter_mut() {
// let random_file: usize = OsRng.gen();
// let keypath = temp_dir().join(format!("coconut{}.pem", random_file));
// verification_key_submission(
// &controller.dkg_client,
// &mut controller.state,
// 0,
// &keypath,
// true,
// )
// .await
// .unwrap();
// std::fs::remove_file(keypath).unwrap();
// }
//
// for controller in clients_and_states.iter_mut() {
// verification_key_validation(&controller.dkg_client, &mut controller.state, true)
// .await
// .unwrap();
// }
// for controller in clients_and_states.iter_mut() {
// verification_key_finalization(&controller.dkg_client, &mut controller.state, true)
// .await
// .unwrap();
// }
// // assert!(db
// // .proposal_db
// // .read()
// // .unwrap()
// // .values()
// // .all(|proposal| { proposal.status == Status::Executed }));
//
// let mut vks = vec![];
// let mut indices = vec![];
// for controller in clients_and_states.iter() {
// let vk = controller
// .state
// .coconut_keypair()
// .await
// .as_ref()
// .unwrap()
// .keys
// .verification_key()
// .clone();
// let index = controller.state.node_index().unwrap();
// vks.push(vk);
// indices.push(index);
// }
// let reshared_master_vk = aggregate_verification_keys(&vks, Some(&indices)).unwrap();
// assert_eq!(initial_master_vk, reshared_master_vk);
}
}
+16 -9
View File
@@ -5,6 +5,8 @@ use crate::coconut::dkg::complaints::ComplaintReason;
use crate::coconut::dkg::controller::keys::archive_coconut_keypair;
use crate::coconut::dkg::state::dealing_exchange::DealingExchangeState;
use crate::coconut::dkg::state::key_derivation::KeyDerivationState;
use crate::coconut::dkg::state::key_finalization::FinalizationState;
use crate::coconut::dkg::state::key_validation::ValidationState;
use crate::coconut::dkg::state::registration::RegistrationState;
use crate::coconut::error::CoconutError;
use crate::coconut::keys::{KeyPair as CoconutKeyPair, KeyPairWithEpoch};
@@ -26,8 +28,6 @@ use std::path::{Path, PathBuf};
use time::OffsetDateTime;
use tokio::sync::RwLockReadGuard;
use url::Url;
use crate::coconut::dkg::state::key_finalization::FinalizationState;
use crate::coconut::dkg::state::key_validation::ValidationState;
mod dealing_exchange;
mod key_derivation;
@@ -246,13 +246,13 @@ impl PersistentState {
#[derive(Default)]
pub(crate) struct DkgState {
pub(crate) registration: RegistrationState,
pub(crate) dealing_exchange: DealingExchangeState,
pub(crate) key_generation: KeyDerivationState,
pub(crate) key_validation: ValidationState,
pub(crate) key_finalization: FinalizationState,
}
@@ -267,7 +267,8 @@ impl DkgState {
dkg_participant.address
)
}
self.dealing_exchange.dealers
self.dealing_exchange
.dealers
.insert(dkg_participant.assigned_index, dkg_participant);
}
}
@@ -524,9 +525,11 @@ impl State {
.receiver_index
.ok_or(CoconutError::UnavailableReceiverIndex { epoch_id })
}
pub fn proposal_id(&self, epoch_id: EpochId) -> Result<u64, CoconutError> {
self.key_derivation_state(epoch_id)?.proposal_id.ok_or(CoconutError::UnavailableProposalId {epoch_id})
pub fn proposal_id(&self, epoch_id: EpochId) -> Result<u64, CoconutError> {
self.key_derivation_state(epoch_id)?
.proposal_id
.ok_or(CoconutError::UnavailableProposalId { epoch_id })
}
pub fn persistent_state_path(&self) -> &Path {
@@ -557,6 +560,10 @@ impl State {
self.coconut_keypair.invalidate()
}
pub fn validate_coconut_keypair(&self) {
self.coconut_keypair.validate()
}
pub fn get_dealing(&self, epoch_id: EpochId, dealing_index: DealingIndex) -> Option<&Dealing> {
self.generated_dealings
.get(&epoch_id)
+1 -1
View File
@@ -67,7 +67,7 @@ impl KeyPair {
self.valid.load(Ordering::SeqCst)
}
pub fn enable(&self) {
pub fn validate(&self) {
self.valid.store(true, Ordering::SeqCst);
}
+2 -2
View File
@@ -125,7 +125,7 @@ pub(crate) async fn validate_keys(controllers: &mut [TestingDkgController], resh
guard.dkg_epoch.state = EpochState::VerificationKeyFinalization { resharing }
}
pub(crate) async fn finalize(controllers: &mut [TestingDkgController], resharing: bool) {
pub(crate) async fn finalize(controllers: &mut [TestingDkgController]) {
let epoch = controllers[0]
.chain_state
.lock()
@@ -135,7 +135,7 @@ pub(crate) async fn finalize(controllers: &mut [TestingDkgController], resharing
for controller in controllers.iter_mut() {
controller
.verification_key_finalization(epoch, resharing)
.verification_key_finalization(epoch)
.await
.unwrap();
}