From 9c5c9eb979ad18a654fc538aff802cf0f65dbe14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20HUBERT=20/=20PALO-IT?= Date: Thu, 20 Apr 2023 17:55:16 +0200 Subject: [PATCH] [wip] certifier service --- mithril-aggregator/src/certifier_service.rs | 16 ++- mithril-aggregator/src/configuration.rs | 2 +- .../src/database/provider/open_message.rs | 19 +++ .../src/dependency_injection/builder.rs | 99 ++------------ .../http_server/routes/certificate_routes.rs | 4 +- mithril-aggregator/src/runtime/runner.rs | 127 +++++------------- .../src/runtime/state_machine.rs | 55 ++++---- mithril-aggregator/tests/certificate_chain.rs | 11 +- .../tests/create_certificate.rs | 10 +- mithril-aggregator/tests/era_checker.rs | 11 +- mithril-aggregator/tests/simple.rs | 10 +- .../tests/test_extensions/runtime_tester.rs | 10 +- .../tests/test_extensions/utilities.rs | 21 ++- mithril-common/src/sqlite/cursor.rs | 2 +- mithril-common/src/test_utils/fake_data.rs | 9 ++ 15 files changed, 173 insertions(+), 233 deletions(-) diff --git a/mithril-aggregator/src/certifier_service.rs b/mithril-aggregator/src/certifier_service.rs index accc9d99255..0c9285385d0 100644 --- a/mithril-aggregator/src/certifier_service.rs +++ b/mithril-aggregator/src/certifier_service.rs @@ -1,3 +1,9 @@ +//! ## Certifier Service +//! +//! This service is responsible of [OpenMessage] cycle of life. It creates open +//! messages and turn them into [CertificateRecord]. To do so, it registers +//! single signatures and deal with the multisigner for aggregate signature +//! creation. use std::sync::Arc; use async_trait::async_trait; @@ -269,7 +275,7 @@ impl CertifierService for MithrilCertifierService { .get_master_certificate_for_epoch(open_message.epoch) .await? .map(|cert| cert.hash) - .ok_or_else(|| CertifierServiceError::NoParentCertificateFound)?; + .ok_or_else(|| Box::new(CertifierServiceError::NoParentCertificateFound))?; let certificate = Certificate::new( parent_certificate_hash, @@ -296,10 +302,8 @@ impl CertifierService for MithrilCertifierService { #[cfg(test)] mod tests { - use std::sync::Mutex; - + /* use mithril_common::entities::Beacon; - use sqlite::Connection; use crate::{dependency_injection::DependenciesBuilder, Configuration}; @@ -310,12 +314,11 @@ mod tests { DependenciesBuilder::new(config) } - /* fn get_open_message(connection: Arc>, signed_entity_type: &SignedEntityType) -> StdResult> { let repository = OpenMessageRepository::new(connection); let open_message = repository.get_open_message(epoch, signed_entity_type) } - */ + #[tokio::test] async fn create_open_message() { let mut dependencies = setup_dependencies(); @@ -333,4 +336,5 @@ mod tests { let connection = dependencies.get_sqlite_connection().await.unwrap(); } + */ } diff --git a/mithril-aggregator/src/configuration.rs b/mithril-aggregator/src/configuration.rs index 328c036dfbb..57c9dd8afe4 100644 --- a/mithril-aggregator/src/configuration.rs +++ b/mithril-aggregator/src/configuration.rs @@ -146,7 +146,7 @@ impl Configuration { run_interval: 5000, db_directory: PathBuf::new(), snapshot_directory: PathBuf::new(), - data_stores_directory: PathBuf::new(), + data_stores_directory: PathBuf::from(":memory:"), genesis_verification_key: key_encode_hex(genesis_verification_key).unwrap(), reset_digests_cache: false, disable_digests_cache: false, diff --git a/mithril-aggregator/src/database/provider/open_message.rs b/mithril-aggregator/src/database/provider/open_message.rs index 9b964baf6cd..07f567c851f 100644 --- a/mithril-aggregator/src/database/provider/open_message.rs +++ b/mithril-aggregator/src/database/provider/open_message.rs @@ -45,6 +45,25 @@ pub struct OpenMessage { pub created_at: NaiveDateTime, } +impl OpenMessage { + #[cfg(test)] + /// Create a dumb OpenMessage instance mainly for test purposes + pub fn dummy() -> Self { + let beacon = mithril_common::test_utils::fake_data::beacon(); + let epoch = beacon.epoch; + let signed_entity_type = SignedEntityType::CardanoImmutableFilesFull(beacon); + + Self { + open_message_id: Uuid::parse_str("193d1442-e89b-43cf-9519-04d8db9a12ff").unwrap(), + epoch, + signed_entity_type, + protocol_message: ProtocolMessage::new(), + is_certified: false, + created_at: chrono::Local::now().naive_local(), + } + } +} + impl From for OpenMessage { fn from(value: OpenMessageWithSingleSignatures) -> Self { Self { diff --git a/mithril-aggregator/src/dependency_injection/builder.rs b/mithril-aggregator/src/dependency_injection/builder.rs index 30bcd4cc76d..a0d26b52561 100644 --- a/mithril-aggregator/src/dependency_injection/builder.rs +++ b/mithril-aggregator/src/dependency_injection/builder.rs @@ -11,10 +11,7 @@ use mithril_common::{ CardanoImmutableDigester, DumbImmutableFileObserver, ImmutableDigester, ImmutableFileObserver, ImmutableFileSystemObserver, }, - entities::{ - Beacon, Certificate, CertificatePending, Epoch, PartyId, ProtocolParameters, - SignerWithStake, SingleSignatures, - }, + entities::{Beacon, CertificatePending, Epoch, PartyId, SingleSignatures}, era::{ adapters::{EraReaderAdapterBuilder, EraReaderDummyAdapter}, EraChecker, EraMarker, EraReader, EraReaderAdapter, SupportedEra, @@ -228,7 +225,7 @@ impl DependenciesBuilder { ExecutionEnvironment::Production => { self.configuration.get_sqlite_dir().join(SQLITE_FILE) } - _ => ":memory:".into(), + _ => self.configuration.data_stores_directory.clone(), }; let connection = Connection::open(&path) .map(|c| Arc::new(Mutex::new(c))) @@ -290,27 +287,10 @@ impl DependenciesBuilder { } async fn build_snapshot_store(&mut self) -> Result> { - let adapter: Box< - dyn StoreAdapter, - > = match self.configuration.environment { - ExecutionEnvironment::Production => { - let adapter = SignedEntityStoreAdapter::new(self.get_sqlite_connection().await?); - - Box::new(adapter) - } - _ => { - let adapter = MemoryAdapter::new(None).map_err(|e| { - DependenciesBuilderError::Initialization { - message: "Cannot create Memory adapter for Snapshot Store.".to_string(), - error: Some(e.into()), - } - })?; - Box::new(adapter) - } - }; - Ok(Arc::new(LocalSnapshotStore::new( - adapter, + Box::new(SignedEntityStoreAdapter::new( + self.get_sqlite_connection().await?, + )), LIST_SNAPSHOTS_MAX_ITEMS, ))) } @@ -423,26 +403,9 @@ impl DependenciesBuilder { } async fn build_certificate_store(&mut self) -> Result> { - let adapter: Box> = - match self.configuration.environment { - ExecutionEnvironment::Production => { - let adapter = CertificateStoreAdapter::new(self.get_sqlite_connection().await?); - - Box::new(adapter) - } - _ => { - let adapter = MemoryAdapter::new(None).map_err(|e| { - DependenciesBuilderError::Initialization { - message: "Cannot create Memory adapter for Certificate Store." - .to_string(), - error: Some(e.into()), - } - })?; - Box::new(adapter) - } - }; - - Ok(Arc::new(CertificateStore::new(adapter))) + Ok(Arc::new(CertificateStore::new(Box::new( + CertificateStoreAdapter::new(self.get_sqlite_connection().await?), + )))) } /// Get a configured [CertificateStore]. @@ -455,29 +418,10 @@ impl DependenciesBuilder { } async fn build_verification_key_store(&mut self) -> Result> { - let adapter: Box< - dyn StoreAdapter>, - > = match self.configuration.environment { - ExecutionEnvironment::Production => { - let adapter = - SignerRegistrationStoreAdapter::new(self.get_sqlite_connection().await?); - - Box::new(adapter) - } - _ => { - let adapter = MemoryAdapter::new(None).map_err(|e| { - DependenciesBuilderError::Initialization { - message: "Cannot create Memory adapter for VerificationKeyStore." - .to_string(), - error: Some(e.into()), - } - })?; - Box::new(adapter) - } - }; - Ok(Arc::new(VerificationKeyStore::new( - adapter, + Box::new(SignerRegistrationStoreAdapter::new( + self.get_sqlite_connection().await?, + )), self.configuration.store_retention_limit, ))) } @@ -535,27 +479,8 @@ impl DependenciesBuilder { } async fn build_protocol_parameters_store(&mut self) -> Result> { - let adapter: Box> = - match self.configuration.environment { - ExecutionEnvironment::Production => { - let adapter = EpochSettingStore::new(self.get_sqlite_connection().await?); - - Box::new(adapter) - } - _ => { - let adapter = MemoryAdapter::new(None).map_err(|e| { - DependenciesBuilderError::Initialization { - message: "Cannot create Memory adapter for ProtocolParametersStore." - .to_string(), - error: Some(e.into()), - } - })?; - Box::new(adapter) - } - }; - Ok(Arc::new(ProtocolParametersStore::new( - adapter, + Box::new(EpochSettingStore::new(self.get_sqlite_connection().await?)), self.configuration.store_retention_limit, ))) } diff --git a/mithril-aggregator/src/http_server/routes/certificate_routes.rs b/mithril-aggregator/src/http_server/routes/certificate_routes.rs index cc8221bd36c..f5697af0fbc 100644 --- a/mithril-aggregator/src/http_server/routes/certificate_routes.rs +++ b/mithril-aggregator/src/http_server/routes/certificate_routes.rs @@ -183,7 +183,9 @@ mod tests { let (dependency_manager, _) = initialize_dependencies().await; dependency_manager .certificate_store - .save(fake_data::certificate("{certificate_hash}".to_string())) + .save(fake_data::genesis_certificate( + "{certificate_hash}".to_string(), + )) .await .expect("certificate store save should have succeeded"); diff --git a/mithril-aggregator/src/runtime/runner.rs b/mithril-aggregator/src/runtime/runner.rs index 9ddbb15d791..9b6bcf5c50a 100644 --- a/mithril-aggregator/src/runtime/runner.rs +++ b/mithril-aggregator/src/runtime/runner.rs @@ -1,9 +1,6 @@ use async_trait::async_trait; use chrono::Utc; -use mithril_common::crypto_helper::key_decode_hex; -use mithril_common::crypto_helper::ProtocolMultiSignature; use mithril_common::entities::Epoch; -use mithril_common::entities::PartyId; use mithril_common::entities::SignedEntityType; use mithril_common::store::StakeStorer; use slog_scope::{debug, warn}; @@ -19,12 +16,10 @@ use std::path::Path; use std::path::PathBuf; use std::sync::Arc; +use crate::database::provider::OpenMessage; use crate::runtime::WorkingCertificate; use crate::snapshot_uploaders::SnapshotLocation; use crate::snapshotter::OngoingSnapshot; -use crate::store::SingleSignatureStorer; -use crate::CertificateCreator; -use crate::MithrilCertificateCreator; use crate::RuntimeError; use crate::{DependencyManager, ProtocolError, SnapshotError}; @@ -112,7 +107,7 @@ pub trait AggregatorRunnerTrait: Sync + Send { async fn update_message_in_multisigner( &self, digest: String, - ) -> Result<(), Box>; + ) -> Result>; /// Return the actual pending certificate from the multisigner. async fn create_new_pending_certificate_from_multisigner( @@ -139,10 +134,10 @@ pub trait AggregatorRunnerTrait: Sync + Send { ) -> Result, Box>; /// Create multi-signature. - async fn create_multi_signature( + async fn create_certificate( &self, signed_entity_type: &SignedEntityType, - ) -> Result, Box>; + ) -> Result, Box>; /// Create an archive of the cardano node db directory naming it after the given beacon. /// @@ -160,13 +155,6 @@ pub trait AggregatorRunnerTrait: Sync + Send { ongoing_snapshot: &OngoingSnapshot, ) -> Result, Box>; - /// Create a signed certificate. - async fn create_and_save_certificate( - &self, - working_certificate: &WorkingCertificate, - multi_signature: ProtocolMultiSignature, - ) -> Result>; - /// Create a snapshot and save it to the given locations. async fn create_and_save_snapshot( &self, @@ -180,6 +168,13 @@ pub trait AggregatorRunnerTrait: Sync + Send { &self, beacon: &Beacon, ) -> Result<(), Box>; + + /// Create new open message + async fn create_open_message( + &self, + signed_entity_type: &SignedEntityType, + protocol_message: &ProtocolMessage, + ) -> Result>; } /// The runner responsibility is to expose a code API for the state machine. It @@ -414,7 +409,7 @@ impl AggregatorRunnerTrait for AggregatorRunner { async fn update_message_in_multisigner( &self, digest: String, - ) -> Result<(), Box> { + ) -> Result> { debug!("RUNNER: update message in multisigner"); let mut multi_signer = self.dependencies.multi_signer.write().await; let mut protocol_message = ProtocolMessage::new(); @@ -427,9 +422,10 @@ impl AggregatorRunnerTrait for AggregatorRunner { .unwrap_or_default(), ); multi_signer - .update_current_message(protocol_message) - .await - .map_err(|e| e.into()) + .update_current_message(protocol_message.clone()) + .await?; + + Ok(protocol_message) } async fn create_new_pending_certificate_from_multisigner( @@ -556,20 +552,16 @@ impl AggregatorRunnerTrait for AggregatorRunner { Ok(certificate_pending) } - async fn create_multi_signature( + async fn create_certificate( &self, signed_entity_type: &SignedEntityType, - ) -> Result, Box> { + ) -> Result, Box> { debug!("RUNNER: create multi-signature"); - let certificate = self - .dependencies + self.dependencies .certifier_service .create_certificate(signed_entity_type) - .await?; - - // TODO: Quickfix, this function should be renamed to create_certificate and retrun a Result - Ok(certificate.map(|c| key_decode_hex(&c.multi_signature).unwrap())) + .await } async fn create_snapshot_archive( @@ -635,41 +627,6 @@ impl AggregatorRunnerTrait for AggregatorRunner { Ok(vec![location]) } - async fn create_and_save_certificate( - &self, - working_certificate: &WorkingCertificate, - multi_signature: ProtocolMultiSignature, - ) -> Result> { - debug!("RUNNER: create and save certificate"); - let certificate_store = self.dependencies.certificate_store.clone(); - let signatures_party_ids: Vec = self - .dependencies - .single_signature_store - .get_single_signatures(&working_certificate.beacon) - .await? - .unwrap_or_default() - .into_keys() - .collect::>(); - - let certificate = MithrilCertificateCreator::create_certificate( - working_certificate, - &signatures_party_ids, - multi_signature, - )?; - - self.dependencies - .certificate_verifier - .verify_certificate( - &certificate, - certificate_store.clone(), - &self.dependencies.genesis_verifier, - ) - .await?; - let _ = certificate_store.save(certificate.clone()).await?; - - Ok(certificate) - } - async fn create_and_save_snapshot( &self, certificate: Certificate, @@ -731,6 +688,17 @@ impl AggregatorRunnerTrait for AggregatorRunner { Ok(()) } + + async fn create_open_message( + &self, + signed_entity_type: &SignedEntityType, + protocol_message: &ProtocolMessage, + ) -> Result> { + self.dependencies + .certifier_service + .create_open_message(signed_entity_type, protocol_message) + .await + } } #[cfg(test)] @@ -746,11 +714,10 @@ pub mod tests { use crate::{MithrilSignerRegisterer, ProtocolParametersStorer, SignerRegistrationRound}; use mithril_common::chain_observer::FakeObserver; use mithril_common::crypto_helper::{ - key_decode_hex, tests_setup::setup_certificate_chain, ProtocolMultiSignature, - }; + tests_setup::setup_certificate_chain, }; use mithril_common::digesters::DumbImmutableFileObserver; use mithril_common::entities::{ - Beacon, CertificatePending, HexEncodedKey, ProtocolMessage, SignedEntityType, + Beacon, CertificatePending, ProtocolMessage, SignedEntityType, StakeDistribution, }; use mithril_common::store::StakeStorer; @@ -1182,34 +1149,6 @@ pub mod tests { assert_eq!(None, maybe_saved_cert); } - #[tokio::test] - async fn test_create_and_save_certificate_ok() { - let (certificate_chain, _) = setup_certificate_chain(5, 1); - let first_certificate = certificate_chain[0].clone(); - let multi_signature: ProtocolMultiSignature = - key_decode_hex(&first_certificate.multi_signature as &HexEncodedKey).unwrap(); - let multi_signature_clone = multi_signature.clone(); - let working_certificate = WorkingCertificate { - beacon: first_certificate.beacon.clone(), - signers: first_certificate.metadata.signers.clone(), - aggregate_verification_key: first_certificate.aggregate_verification_key.clone(), - protocol_parameters: first_certificate.metadata.protocol_parameters.clone(), - previous_hash: certificate_chain[1].hash.clone(), - message: first_certificate.protocol_message.clone(), - ..WorkingCertificate::fake() - }; - let (mut deps, config) = initialize_dependencies().await; - let mock_multi_signer = MockMultiSigner::new(); - deps.multi_signer = Arc::new(RwLock::new(mock_multi_signer)); - deps.init_state_from_chain(&certificate_chain, vec![]).await; - let runner = AggregatorRunner::new(config, Arc::new(deps)); - - let certificate = runner - .create_and_save_certificate(&working_certificate, multi_signature_clone) - .await; - certificate.expect("a certificate should have been created and saved"); - } - #[tokio::test] async fn test_remove_snapshot_archive_after_upload() { let (deps, config) = initialize_dependencies().await; diff --git a/mithril-aggregator/src/runtime/state_machine.rs b/mithril-aggregator/src/runtime/state_machine.rs index 4d36ba81662..8a8f9fad2b1 100644 --- a/mithril-aggregator/src/runtime/state_machine.rs +++ b/mithril-aggregator/src/runtime/state_machine.rs @@ -268,17 +268,17 @@ impl AggregatorRuntime { state: SigningState, ) -> Result { trace!("launching transition from SIGNING to IDLE state"); - todo!() - /* - let certificate = - self.runner - .create_multi_signature() - .await? - .ok_or_else(|| RuntimeError::KeepState { - message: "not enough signature yet to aggregate a multi-signature, waiting…" - .to_string(), - nested_error: None, - })?; + // TODO: Temporary, we need to compute the signed entity type from the current open message + let signed_entity_type = + SignedEntityType::CardanoImmutableFilesFull(state.current_beacon.clone()); + let certificate = self + .runner + .create_certificate(&signed_entity_type) + .await? + .ok_or_else(|| RuntimeError::KeepState { + message: "not enough signature yet to create a certificate, waiting…".to_string(), + nested_error: None, + })?; self.runner.drop_pending_certificate().await?; let ongoing_snapshot = self @@ -289,10 +289,7 @@ impl AggregatorRuntime { .runner .upload_snapshot_archive(&ongoing_snapshot) .await?; - let certificate = self - .runner - .create_and_save_certificate(&state.working_certificate, multi_signature) - .await?; + let _ = self .runner .create_and_save_snapshot(certificate, &ongoing_snapshot, locations) @@ -300,7 +297,7 @@ impl AggregatorRuntime { Ok(IdleState { current_beacon: Some(state.current_beacon), - }) */ + }) } /// Perform a transition from `SIGNING` state to `IDLE` state when a new @@ -329,9 +326,14 @@ impl AggregatorRuntime { self.runner.update_beacon(&new_beacon).await?; let digester_result = self.runner.compute_digest(&new_beacon).await?; - self.runner + let protocol_message = self + .runner .update_message_in_multisigner(digester_result) .await?; + let _open_message = self + .runner + .create_open_message(&signed_entity_type, &protocol_message) + .await?; let certificate_pending = self .runner .create_new_pending_certificate_from_multisigner( @@ -357,16 +359,13 @@ impl AggregatorRuntime { #[cfg(test)] mod tests { - use std::path::Path; - use crate::snapshotter::OngoingSnapshot; + use crate::database::provider::OpenMessage; use super::super::runner::MockAggregatorRunner; use super::*; - use mithril_common::crypto_helper::tests_setup::setup_certificate_chain; - use mithril_common::crypto_helper::{key_decode_hex, ProtocolMultiSignature}; - use mithril_common::entities::HexEncodedKey; + use mithril_common::entities::ProtocolMessage; use mithril_common::era::UnsupportedEraError; use mithril_common::test_utils::fake_data; use mockall::predicate; @@ -586,7 +585,7 @@ mod tests { .expect_update_message_in_multisigner() .with(predicate::eq("whatever".to_string())) .once() - .returning(|_| Ok(())); + .returning(|_| Ok(ProtocolMessage::new())); runner .expect_create_new_pending_certificate_from_multisigner() //.with(predicate::eq(fake_data::beacon())) @@ -600,6 +599,10 @@ mod tests { .expect_save_pending_certificate() .once() .returning(|_| Ok(())); + runner + .expect_create_open_message() + .once() + .returning(|_, _| Ok(OpenMessage::dummy())); let mut runtime = init_runtime( Some(AggregatorState::Ready(ReadyState { @@ -650,7 +653,7 @@ mod tests { .once() .returning(|| Ok(fake_data::beacon())); runner - .expect_create_multi_signature() + .expect_create_certificate() .once() .returning(|_| Ok(None)); let state = SigningState { @@ -666,6 +669,7 @@ mod tests { assert_eq!("signing".to_string(), runtime.get_state()); } + /* TODO: create a fake certificate to test the certificate creation. #[tokio::test] async fn signing_multisig_is_created() { let (certificate_chain, _) = setup_certificate_chain(5, 1); @@ -678,7 +682,7 @@ mod tests { .once() .returning(|| Ok(fake_data::beacon())); runner - .expect_create_multi_signature() + .expect_create_certificate() .return_once(move |_| Ok(Some(multi_signature))); runner .expect_drop_pending_certificate() @@ -715,6 +719,7 @@ mod tests { assert_eq!("idle".to_string(), runtime.get_state()); } + */ #[tokio::test] pub async fn critical_error() { diff --git a/mithril-aggregator/tests/certificate_chain.rs b/mithril-aggregator/tests/certificate_chain.rs index b78c155bb2c..e8b62e2d9cd 100644 --- a/mithril-aggregator/tests/certificate_chain.rs +++ b/mithril-aggregator/tests/certificate_chain.rs @@ -1,10 +1,10 @@ mod test_extensions; -use mithril_aggregator::VerificationKeyStorer; +use mithril_aggregator::{Configuration, VerificationKeyStorer}; use mithril_common::{ chain_observer::ChainObserver, entities::ProtocolParameters, test_utils::MithrilFixtureBuilder, }; -use test_extensions::RuntimeTester; +use test_extensions::{utilities::get_test_dir, RuntimeTester}; #[tokio::test] async fn certificate_chain() { @@ -13,7 +13,12 @@ async fn certificate_chain() { m: 100, phi_f: 0.95, }; - let mut tester = RuntimeTester::build(protocol_parameters.clone()).await; + let configuration = Configuration { + protocol_parameters: protocol_parameters.clone(), + data_stores_directory: get_test_dir("certificate_chain").join("aggregator.sqlite3"), + ..Configuration::new_sample() + }; + let mut tester = RuntimeTester::build(configuration).await; comment!("Create signers & declare stake distribution"); let fixture = MithrilFixtureBuilder::default() diff --git a/mithril-aggregator/tests/create_certificate.rs b/mithril-aggregator/tests/create_certificate.rs index 6b602f45c63..609817804c7 100644 --- a/mithril-aggregator/tests/create_certificate.rs +++ b/mithril-aggregator/tests/create_certificate.rs @@ -2,11 +2,12 @@ mod test_extensions; use std::collections::BTreeSet; +use mithril_aggregator::Configuration; use mithril_common::{ entities::{ProtocolMessagePartKey, ProtocolParameters}, test_utils::MithrilFixtureBuilder, }; -use test_extensions::RuntimeTester; +use test_extensions::{utilities::get_test_dir, RuntimeTester}; #[tokio::test] async fn create_certificate() { @@ -15,7 +16,12 @@ async fn create_certificate() { m: 100, phi_f: 0.95, }; - let mut tester = RuntimeTester::build(protocol_parameters.clone()).await; + let configuration = Configuration { + protocol_parameters: protocol_parameters.clone(), + data_stores_directory: get_test_dir("create_certificate").join("aggregator.sqlite3"), + ..Configuration::new_sample() + }; + let mut tester = RuntimeTester::build(configuration).await; comment!("create signers & declare stake distribution"); let fixture = MithrilFixtureBuilder::default() diff --git a/mithril-aggregator/tests/era_checker.rs b/mithril-aggregator/tests/era_checker.rs index fc933bc5247..c98f6ea8c0e 100644 --- a/mithril-aggregator/tests/era_checker.rs +++ b/mithril-aggregator/tests/era_checker.rs @@ -1,5 +1,5 @@ mod test_extensions; -use mithril_aggregator::RuntimeError; +use mithril_aggregator::{Configuration, RuntimeError}; use mithril_common::{ chain_observer::ChainObserver, entities::{Epoch, ProtocolParameters}, @@ -7,7 +7,7 @@ use mithril_common::{ test_utils::MithrilFixtureBuilder, }; -use test_extensions::RuntimeTester; +use test_extensions::{utilities::get_test_dir, RuntimeTester}; // NOTE: Due to the shared nature of the Logger, there cannot be two methods in // the same test file. Because the logger is wiped of memory when the first @@ -19,7 +19,12 @@ async fn testing_eras() { m: 100, phi_f: 0.95, }; - let mut tester = RuntimeTester::build(protocol_parameters.clone()).await; + let configuration = Configuration { + protocol_parameters: protocol_parameters.clone(), + data_stores_directory: get_test_dir("testing_eras").join("aggregator.sqlite3"), + ..Configuration::new_sample() + }; + let mut tester = RuntimeTester::build(configuration).await; tester.era_reader_adapter.set_markers(vec![ EraMarker::new("unsupported", Some(Epoch(0))), EraMarker::new(&SupportedEra::dummy().to_string(), Some(Epoch(12))), diff --git a/mithril-aggregator/tests/simple.rs b/mithril-aggregator/tests/simple.rs index 4aaf6a9a75c..b79066f4b1a 100644 --- a/mithril-aggregator/tests/simple.rs +++ b/mithril-aggregator/tests/simple.rs @@ -1,10 +1,11 @@ mod test_extensions; +use mithril_aggregator::Configuration; use mithril_common::{ entities::{ProtocolParameters, SignerWithStake}, test_utils::MithrilFixtureBuilder, }; -use test_extensions::RuntimeTester; +use test_extensions::{utilities::get_test_dir, RuntimeTester}; #[tokio::test] async fn simple_scenario() { @@ -13,7 +14,12 @@ async fn simple_scenario() { m: 100, phi_f: 0.65, }; - let mut tester = RuntimeTester::build(protocol_parameters.clone()).await; + let configuration = Configuration { + protocol_parameters: protocol_parameters.clone(), + data_stores_directory: get_test_dir("simple_scenario").join("aggregator.sqlite3"), + ..Configuration::new_sample() + }; + let mut tester = RuntimeTester::build(configuration).await; comment!("Create signers & declare stake distribution"); let fixture = MithrilFixtureBuilder::default() diff --git a/mithril-aggregator/tests/test_extensions/runtime_tester.rs b/mithril-aggregator/tests/test_extensions/runtime_tester.rs index 74f54f8d58e..be63a9b4d27 100644 --- a/mithril-aggregator/tests/test_extensions/runtime_tester.rs +++ b/mithril-aggregator/tests/test_extensions/runtime_tester.rs @@ -17,8 +17,8 @@ use mithril_aggregator::{ use mithril_common::crypto_helper::{key_encode_hex, ProtocolClerk, ProtocolGenesisSigner}; use mithril_common::digesters::DumbImmutableFileObserver; use mithril_common::entities::{ - Certificate, Epoch, ImmutableFileNumber, ProtocolParameters, SignerWithStake, SingleSignatures, - Snapshot, StakeDistribution, + Certificate, Epoch, ImmutableFileNumber, SignerWithStake, SingleSignatures, Snapshot, + StakeDistribution, }; use mithril_common::{chain_observer::FakeObserver, digesters::DumbImmutableDigester}; @@ -56,7 +56,7 @@ pub struct RuntimeTester { } impl RuntimeTester { - pub async fn build(default_protocol_parameters: ProtocolParameters) -> Self { + pub async fn build(configuration: Configuration) -> Self { let snapshot_uploader = Arc::new(DumbSnapshotUploader::new()); let chain_observer = Arc::new(FakeObserver::default()); let immutable_file_observer = Arc::new(DumbImmutableFileObserver::default()); @@ -68,10 +68,6 @@ impl RuntimeTester { &SupportedEra::dummy().to_string(), Some(Epoch(0)), )])); - let configuration = Configuration { - protocol_parameters: default_protocol_parameters, - ..Configuration::new_sample() - }; let mut deps_builder = DependenciesBuilder::new(configuration); deps_builder.snapshot_uploader = Some(snapshot_uploader.clone()); deps_builder.chain_observer = Some(chain_observer.clone()); diff --git a/mithril-aggregator/tests/test_extensions/utilities.rs b/mithril-aggregator/tests/test_extensions/utilities.rs index 79a14c2b671..0f85108a42d 100644 --- a/mithril-aggregator/tests/test_extensions/utilities.rs +++ b/mithril-aggregator/tests/test_extensions/utilities.rs @@ -1,8 +1,27 @@ use slog_scope::debug; -use std::sync::atomic::{AtomicUsize, Ordering}; +use std::{ + path::PathBuf, + sync::atomic::{AtomicUsize, Ordering}, +}; pub static COMMENT_COUNT: AtomicUsize = AtomicUsize::new(0); +/// Create a directory to save test artefacts. This directory is cleaned if it +/// already exists, it is created if not. This directory is kept at the end to +/// allow debuging. +pub fn get_test_dir(subdir_name: &str) -> PathBuf { + let parent_dir = std::env::temp_dir().join("mithril_test").join(subdir_name); + + if parent_dir.exists() { + std::fs::remove_dir_all(&parent_dir) + .unwrap_or_else(|e| panic!("Could not remove dir {parent_dir:?}: {e}")); + } + std::fs::create_dir_all(&parent_dir) + .unwrap_or_else(|e| panic!("Could not create dir {parent_dir:?}: {e}")); + + parent_dir +} + pub fn comment(comment: String) { let old_count = COMMENT_COUNT.fetch_add(1, Ordering::SeqCst); debug!("COMMENT {:02} 💬 {}", old_count + 1, comment); diff --git a/mithril-common/src/sqlite/cursor.rs b/mithril-common/src/sqlite/cursor.rs index b2e9d2ea340..f412916f379 100644 --- a/mithril-common/src/sqlite/cursor.rs +++ b/mithril-common/src/sqlite/cursor.rs @@ -33,6 +33,6 @@ where fn next(&mut self) -> Option { self.cursor .next() - .map(|res| T::hydrate(res.unwrap()).unwrap()) + .map(|res| T::hydrate(res.map_err(|e| panic!("{e}")).unwrap()).unwrap()) } } diff --git a/mithril-common/src/test_utils/fake_data.rs b/mithril-common/src/test_utils/fake_data.rs index 53dc2fe44f7..5c815a7f925 100644 --- a/mithril-common/src/test_utils/fake_data.rs +++ b/mithril-common/src/test_utils/fake_data.rs @@ -77,6 +77,15 @@ pub fn certificate_pending() -> entities::CertificatePending { ) } +/// Fake Genesis Certificate +pub fn genesis_certificate(certificate_hash: String) -> entities::Certificate { + let mut certificate = certificate(certificate_hash); + certificate.genesis_signature = certificate.multi_signature; + certificate.multi_signature = "".to_string(); + + certificate +} + /// Fake Certificate pub fn certificate(certificate_hash: String) -> entities::Certificate { // Beacon