From ba1dc9eb3fedb35921c5a55d6c117e82a5b3c74e Mon Sep 17 00:00:00 2001 From: DJO <790521+Alenar@users.noreply.github.com> Date: Mon, 10 Nov 2025 17:52:20 +0100 Subject: [PATCH 1/7] refactor(signer): impl `SignaturePublisher` directly on `AggregatorHttpClient` Instead of implementing the publisher on the signer `AggregatorClient`, removing an intermediate layer --- mithril-signer/src/runtime/runner.rs | 6 +-- .../src/services/aggregator_client.rs | 51 ++----------------- .../src/services/signature_publisher/http.rs | 28 +++++++--- .../test_extensions/certificate_handler.rs | 23 +++++---- 4 files changed, 42 insertions(+), 66 deletions(-) diff --git a/mithril-signer/src/runtime/runner.rs b/mithril-signer/src/runtime/runner.rs index a3390e9332e..ca5974bc9bf 100644 --- a/mithril-signer/src/runtime/runner.rs +++ b/mithril-signer/src/runtime/runner.rs @@ -415,8 +415,8 @@ mod tests { use crate::metrics::MetricsService; use crate::services::{ CardanoTransactionsImporter, DumbAggregatorClient, MithrilEpochService, - MithrilSingleSigner, MockTransactionStore, MockUpkeepService, SignerCertifierService, - SignerSignableSeedBuilder, SignerSignedEntityConfigProvider, + MithrilSingleSigner, MockTransactionStore, MockUpkeepService, SignaturePublisherNoop, + SignerCertifierService, SignerSignableSeedBuilder, SignerSignedEntityConfigProvider, }; use crate::test_tools::TestLogger; @@ -552,7 +552,7 @@ mod tests { Arc::new(SignerSignedEntityConfigProvider::new(epoch_service.clone())), signed_entity_type_lock.clone(), single_signer.clone(), - aggregator_client.clone(), + Arc::new(SignaturePublisherNoop), logger.clone(), )); let kes_signer = None; diff --git a/mithril-signer/src/services/aggregator_client.rs b/mithril-signer/src/services/aggregator_client.rs index 01578642511..40035bba3a3 100644 --- a/mithril-signer/src/services/aggregator_client.rs +++ b/mithril-signer/src/services/aggregator_client.rs @@ -1,21 +1,17 @@ -use anyhow::anyhow; use async_trait::async_trait; +use mithril_aggregator_client::AggregatorHttpClient; use mithril_aggregator_client::query::{ - GetAggregatorFeaturesQuery, GetEpochSettingsQuery, PostRegisterSignatureQuery, - PostRegisterSignerQuery, + GetAggregatorFeaturesQuery, GetEpochSettingsQuery, PostRegisterSignerQuery, }; -use mithril_aggregator_client::{AggregatorHttpClient, AggregatorHttpClientError}; use mithril_common::{ StdResult, - entities::{Epoch, ProtocolMessage, SignedEntityType, Signer, SingleSignature}, + entities::{Epoch, Signer}, messages::{AggregatorFeaturesMessage, TryFromMessageAdapter, TryToMessageAdapter}, }; use crate::entities::SignerEpochSettings; -use crate::message_adapters::{ - FromEpochSettingsAdapter, ToRegisterSignatureMessageAdapter, ToRegisterSignerMessageAdapter, -}; +use crate::message_adapters::{FromEpochSettingsAdapter, ToRegisterSignerMessageAdapter}; /// Trait for mocking and testing a `AggregatorClient` #[cfg_attr(test, mockall::automock)] @@ -27,14 +23,6 @@ pub trait AggregatorClient: Sync + Send { /// Registers signer with the aggregator. async fn register_signer(&self, epoch: Epoch, signer: &Signer) -> StdResult<()>; - /// Registers single signature with the aggregator. - async fn register_signature( - &self, - signed_entity_type: &SignedEntityType, - signature: &SingleSignature, - protocol_message: &ProtocolMessage, - ) -> StdResult<()>; - /// Retrieves aggregator features message from the aggregator async fn retrieve_aggregator_features(&self) -> StdResult; } @@ -58,27 +46,6 @@ impl AggregatorClient for AggregatorHttpClient { Ok(()) } - async fn register_signature( - &self, - signed_entity_type: &SignedEntityType, - signature: &SingleSignature, - protocol_message: &ProtocolMessage, - ) -> StdResult<()> { - let register_single_signature_message = ToRegisterSignatureMessageAdapter::try_adapt(( - signed_entity_type.to_owned(), - signature.to_owned(), - protocol_message, - )) - .map_err(|e| AggregatorHttpClientError::JsonParseFailed(anyhow!(e)))?; - - self.send(PostRegisterSignatureQuery::new( - register_single_signature_message, - )) - .await?; - - Ok(()) - } - async fn retrieve_aggregator_features(&self) -> StdResult { let aggregator_features = self.send(GetAggregatorFeaturesQuery::current()).await?; Ok(aggregator_features) @@ -145,16 +112,6 @@ pub(crate) mod dumb { Ok(()) } - /// Registers single signature with the aggregator - async fn register_signature( - &self, - _signed_entity_type: &SignedEntityType, - _signature: &SingleSignature, - _protocol_message: &ProtocolMessage, - ) -> StdResult<()> { - Ok(()) - } - async fn retrieve_aggregator_features(&self) -> StdResult { let aggregator_features = self.aggregator_features.read().await; Ok(aggregator_features.clone()) diff --git a/mithril-signer/src/services/signature_publisher/http.rs b/mithril-signer/src/services/signature_publisher/http.rs index f9ef912efe3..e66766bc734 100644 --- a/mithril-signer/src/services/signature_publisher/http.rs +++ b/mithril-signer/src/services/signature_publisher/http.rs @@ -1,21 +1,37 @@ +use anyhow::Context; use async_trait::async_trait; -use mithril_common::StdResult; -use mithril_common::entities::{ProtocolMessage, SignedEntityType, SingleSignature}; -use crate::services::AggregatorClient; +use mithril_aggregator_client::{AggregatorHttpClient, query::PostRegisterSignatureQuery}; +use mithril_common::{ + StdResult, + entities::{ProtocolMessage, SignedEntityType, SingleSignature}, + messages::TryToMessageAdapter, +}; + +use crate::message_adapters::ToRegisterSignatureMessageAdapter; use super::SignaturePublisher; #[async_trait] -impl SignaturePublisher for T { +impl SignaturePublisher for AggregatorHttpClient { async fn publish( &self, signed_entity_type: &SignedEntityType, signature: &SingleSignature, protocol_message: &ProtocolMessage, ) -> StdResult<()> { - self.register_signature(signed_entity_type, signature, protocol_message) - .await?; + let register_single_signature_message = ToRegisterSignatureMessageAdapter::try_adapt(( + signed_entity_type.to_owned(), + signature.to_owned(), + protocol_message, + )) + .with_context(|| "Failed to adapt message to register single signature message")?; + + self.send(PostRegisterSignatureQuery::new( + register_single_signature_message, + )) + .await?; + Ok(()) } } diff --git a/mithril-signer/tests/test_extensions/certificate_handler.rs b/mithril-signer/tests/test_extensions/certificate_handler.rs index 394346231fb..d78fab61da0 100644 --- a/mithril-signer/tests/test_extensions/certificate_handler.rs +++ b/mithril-signer/tests/test_extensions/certificate_handler.rs @@ -14,6 +14,7 @@ use mithril_common::{ }; use mithril_ticker::{MithrilTickerService, TickerService}; +use mithril_signer::services::SignaturePublisher; use mithril_signer::{entities::SignerEpochSettings, services::AggregatorClient}; pub struct FakeAggregator { @@ -80,6 +81,18 @@ impl FakeAggregator { } } +#[async_trait] +impl SignaturePublisher for FakeAggregator { + async fn publish( + &self, + _signed_entity_type: &SignedEntityType, + _signature: &SingleSignature, + _protocol_message: &ProtocolMessage, + ) -> StdResult<()> { + Ok(()) + } +} + #[async_trait] impl AggregatorClient for FakeAggregator { async fn retrieve_epoch_settings(&self) -> StdResult> { @@ -109,16 +122,6 @@ impl AggregatorClient for FakeAggregator { Ok(()) } - /// Registers single signatures with the aggregator - async fn register_signature( - &self, - _signed_entity_type: &SignedEntityType, - _signature: &SingleSignature, - _protocol_message: &ProtocolMessage, - ) -> StdResult<()> { - Ok(()) - } - async fn retrieve_aggregator_features(&self) -> StdResult { let signed_entity_config = self.signed_entity_config.read().await; From a700a034f7c94bd397ec559d3d24165c4356a118 Mon Sep 17 00:00:00 2001 From: DJO <790521+Alenar@users.noreply.github.com> Date: Mon, 10 Nov 2025 18:21:19 +0100 Subject: [PATCH 2/7] refactor(signer): move `AggregatorClient::register_signer` to a new `SignerRegistrationPublisher` trait - Based on the same architecture than the `SignaturePublisher` - with an http implementation directly on the shared `AggregatorHttpClient` - add a spy implementation for the tests needs --- .../src/dependency_injection/builder.rs | 3 +- .../src/dependency_injection/containers.rs | 6 ++- mithril-signer/src/runtime/runner.rs | 18 ++++--- .../src/services/aggregator_client.rs | 50 ++----------------- mithril-signer/src/services/mod.rs | 2 + .../src/services/signer_registration/http.rs | 25 ++++++++++ .../services/signer_registration/interface.rs | 10 ++++ .../src/services/signer_registration/mod.rs | 8 +++ .../src/services/signer_registration/spy.rs | 47 +++++++++++++++++ .../test_extensions/certificate_handler.rs | 24 +++++---- .../test_extensions/state_machine_tester.rs | 7 +-- 11 files changed, 130 insertions(+), 70 deletions(-) create mode 100644 mithril-signer/src/services/signer_registration/http.rs create mode 100644 mithril-signer/src/services/signer_registration/interface.rs create mode 100644 mithril-signer/src/services/signer_registration/mod.rs create mode 100644 mithril-signer/src/services/signer_registration/spy.rs diff --git a/mithril-signer/src/dependency_injection/builder.rs b/mithril-signer/src/dependency_injection/builder.rs index ebc9080deda..8c8751c270f 100644 --- a/mithril-signer/src/dependency_injection/builder.rs +++ b/mithril-signer/src/dependency_injection/builder.rs @@ -513,7 +513,7 @@ impl<'a> DependenciesBuilder<'a> { let services = SignerDependencyContainer { ticker_service, - certificate_handler: aggregator_client, + certificate_handler: aggregator_client.clone(), chain_observer, digester, single_signer, @@ -529,6 +529,7 @@ impl<'a> DependenciesBuilder<'a> { upkeep_service, epoch_service, certifier, + signer_registration_publisher: aggregator_client, kes_signer, network_configuration_service, }; diff --git a/mithril-signer/src/dependency_injection/containers.rs b/mithril-signer/src/dependency_injection/containers.rs index ce74c456a38..007f08586fc 100644 --- a/mithril-signer/src/dependency_injection/containers.rs +++ b/mithril-signer/src/dependency_injection/containers.rs @@ -16,7 +16,8 @@ use mithril_ticker::TickerService; use crate::MetricsService; use crate::services::{ - AggregatorClient, CertifierService, EpochService, SingleSigner, UpkeepService, + AggregatorClient, CertifierService, EpochService, SignerRegistrationPublisher, SingleSigner, + UpkeepService, }; use crate::store::ProtocolInitializerStorer; @@ -85,6 +86,9 @@ pub struct SignerDependencyContainer { /// Certifier service pub certifier: Arc, + /// Signer registration publisher + pub signer_registration_publisher: Arc, + /// Kes signer service pub kes_signer: Option>, diff --git a/mithril-signer/src/runtime/runner.rs b/mithril-signer/src/runtime/runner.rs index ca5974bc9bf..cfaf5b0d618 100644 --- a/mithril-signer/src/runtime/runner.rs +++ b/mithril-signer/src/runtime/runner.rs @@ -233,7 +233,7 @@ impl Runner for SignerRunner { kes_period, ); self.services - .certificate_handler + .signer_registration_publisher .register_signer(epoch_offset_to_recording_epoch, &signer) .await?; @@ -417,6 +417,7 @@ mod tests { CardanoTransactionsImporter, DumbAggregatorClient, MithrilEpochService, MithrilSingleSigner, MockTransactionStore, MockUpkeepService, SignaturePublisherNoop, SignerCertifierService, SignerSignableSeedBuilder, SignerSignedEntityConfigProvider, + SpySignerRegistrationPublisher, }; use crate::test_tools::TestLogger; @@ -585,6 +586,7 @@ mod tests { upkeep_service, epoch_service, certifier, + signer_registration_publisher: Arc::new(SpySignerRegistrationPublisher::default()), kes_signer, network_configuration_service, } @@ -659,8 +661,8 @@ mod tests { async fn test_register_signer_to_aggregator() { let mut services = init_services().await; let fixture = MithrilFixtureBuilder::default().with_signers(5).build(); - let certificate_handler = Arc::new(DumbAggregatorClient::default()); - services.certificate_handler = certificate_handler.clone(); + let registration_publisher_spy = Arc::new(SpySignerRegistrationPublisher::default()); + services.signer_registration_publisher = registration_publisher_spy.clone(); let protocol_initializer_store = services.protocol_initializer_store.clone(); let current_epoch = services.ticker_service.get_current_epoch().await.unwrap(); @@ -699,7 +701,7 @@ mod tests { .expect("registering a signer to the aggregator should not fail"); let last_registered_signer_first_registration = - certificate_handler.get_last_registered_signer().await.unwrap(); + registration_publisher_spy.get_last_registered_signer().await.unwrap(); let maybe_protocol_initializer_first_registration = protocol_initializer_store .get_protocol_initializer(current_epoch.offset_to_recording_epoch()) .await @@ -709,7 +711,8 @@ mod tests { "A protocol initializer should have been registered at the 'Recording' epoch" ); - let total_registered_signers = certificate_handler.get_total_registered_signers().await; + let total_registered_signers = + registration_publisher_spy.get_total_registered_signers().await; assert_eq!(1, total_registered_signers); runner @@ -718,7 +721,7 @@ mod tests { .expect("registering a signer to the aggregator should not fail"); let last_registered_signer_second_registration = - certificate_handler.get_last_registered_signer().await.unwrap(); + registration_publisher_spy.get_last_registered_signer().await.unwrap(); let maybe_protocol_initializer_second_registration = protocol_initializer_store .get_protocol_initializer(current_epoch.offset_to_recording_epoch()) .await @@ -733,7 +736,8 @@ mod tests { "The signer registration should be the same and should have been registered twice" ); - let total_registered_signers = certificate_handler.get_total_registered_signers().await; + let total_registered_signers = + registration_publisher_spy.get_total_registered_signers().await; assert_eq!(1, total_registered_signers); } diff --git a/mithril-signer/src/services/aggregator_client.rs b/mithril-signer/src/services/aggregator_client.rs index 40035bba3a3..8c8f2028e36 100644 --- a/mithril-signer/src/services/aggregator_client.rs +++ b/mithril-signer/src/services/aggregator_client.rs @@ -1,17 +1,14 @@ use async_trait::async_trait; use mithril_aggregator_client::AggregatorHttpClient; -use mithril_aggregator_client::query::{ - GetAggregatorFeaturesQuery, GetEpochSettingsQuery, PostRegisterSignerQuery, -}; +use mithril_aggregator_client::query::{GetAggregatorFeaturesQuery, GetEpochSettingsQuery}; use mithril_common::{ StdResult, - entities::{Epoch, Signer}, - messages::{AggregatorFeaturesMessage, TryFromMessageAdapter, TryToMessageAdapter}, + messages::{AggregatorFeaturesMessage, TryFromMessageAdapter}, }; use crate::entities::SignerEpochSettings; -use crate::message_adapters::{FromEpochSettingsAdapter, ToRegisterSignerMessageAdapter}; +use crate::message_adapters::FromEpochSettingsAdapter; /// Trait for mocking and testing a `AggregatorClient` #[cfg_attr(test, mockall::automock)] @@ -20,9 +17,6 @@ pub trait AggregatorClient: Sync + Send { /// Retrieves epoch settings from the aggregator async fn retrieve_epoch_settings(&self) -> StdResult>; - /// Registers signer with the aggregator. - async fn register_signer(&self, epoch: Epoch, signer: &Signer) -> StdResult<()>; - /// Retrieves aggregator features message from the aggregator async fn retrieve_aggregator_features(&self) -> StdResult; } @@ -36,16 +30,6 @@ impl AggregatorClient for AggregatorHttpClient { Ok(Some(epoch_settings)) } - async fn register_signer(&self, epoch: Epoch, signer: &Signer) -> StdResult<()> { - let register_signer_message = - ToRegisterSignerMessageAdapter::try_adapt((epoch, signer.to_owned()))?; - - self.send(PostRegisterSignerQuery::new(register_signer_message)) - .await?; - - Ok(()) - } - async fn retrieve_aggregator_features(&self) -> StdResult { let aggregator_features = self.send(GetAggregatorFeaturesQuery::current()).await?; Ok(aggregator_features) @@ -64,30 +48,14 @@ pub(crate) mod dumb { /// It is driven by a Tester that controls the data it can return, and it can return its internal state for testing. pub struct DumbAggregatorClient { epoch_settings: RwLock>, - last_registered_signer: RwLock>, aggregator_features: RwLock, - total_registered_signers: RwLock, - } - - impl DumbAggregatorClient { - /// Return the last signer that called with the `register` method. - pub async fn get_last_registered_signer(&self) -> Option { - self.last_registered_signer.read().await.clone() - } - - /// Return the total number of signers that called with the `register` method. - pub async fn get_total_registered_signers(&self) -> u32 { - *self.total_registered_signers.read().await - } } impl Default for DumbAggregatorClient { fn default() -> Self { Self { epoch_settings: RwLock::new(Some(SignerEpochSettings::dummy())), - last_registered_signer: RwLock::new(None), aggregator_features: RwLock::new(AggregatorFeaturesMessage::dummy()), - total_registered_signers: RwLock::new(0), } } } @@ -100,18 +68,6 @@ pub(crate) mod dumb { Ok(epoch_settings) } - /// Registers signer with the aggregator - async fn register_signer(&self, _epoch: Epoch, signer: &Signer) -> StdResult<()> { - let mut last_registered_signer = self.last_registered_signer.write().await; - let signer = signer.clone(); - *last_registered_signer = Some(signer); - - let mut total_registered_signers = self.total_registered_signers.write().await; - *total_registered_signers += 1; - - Ok(()) - } - async fn retrieve_aggregator_features(&self) -> StdResult { let aggregator_features = self.aggregator_features.read().await; Ok(aggregator_features.clone()) diff --git a/mithril-signer/src/services/mod.rs b/mithril-signer/src/services/mod.rs index 823f1054b0c..553e7a49d63 100644 --- a/mithril-signer/src/services/mod.rs +++ b/mithril-signer/src/services/mod.rs @@ -15,6 +15,7 @@ mod certifier; mod epoch_service; mod signable_builder; mod signature_publisher; +mod signer_registration; mod single_signer; mod upkeep_service; @@ -26,5 +27,6 @@ pub use certifier::*; pub use epoch_service::*; pub use signable_builder::*; pub use signature_publisher::*; +pub use signer_registration::*; pub use single_signer::*; pub use upkeep_service::*; diff --git a/mithril-signer/src/services/signer_registration/http.rs b/mithril-signer/src/services/signer_registration/http.rs new file mode 100644 index 00000000000..1d3d4f093c2 --- /dev/null +++ b/mithril-signer/src/services/signer_registration/http.rs @@ -0,0 +1,25 @@ +use anyhow::Context; + +use mithril_aggregator_client::{AggregatorHttpClient, query::PostRegisterSignerQuery}; +use mithril_common::{ + StdResult, + entities::{Epoch, Signer}, + messages::TryToMessageAdapter, +}; + +use crate::ToRegisterSignerMessageAdapter; +use crate::services::SignerRegistrationPublisher; + +#[async_trait::async_trait] +impl SignerRegistrationPublisher for AggregatorHttpClient { + async fn register_signer(&self, epoch: Epoch, signer: &Signer) -> StdResult<()> { + let register_signer_message = + ToRegisterSignerMessageAdapter::try_adapt((epoch, signer.to_owned())) + .with_context(|| "Failed to adapt message to register signer message")?; + + self.send(PostRegisterSignerQuery::new(register_signer_message)) + .await?; + + Ok(()) + } +} diff --git a/mithril-signer/src/services/signer_registration/interface.rs b/mithril-signer/src/services/signer_registration/interface.rs new file mode 100644 index 00000000000..86471ea596e --- /dev/null +++ b/mithril-signer/src/services/signer_registration/interface.rs @@ -0,0 +1,10 @@ +use mithril_common::StdResult; +use mithril_common::entities::{Epoch, Signer}; + +/// Publishes a signer registration to a third party. +#[cfg_attr(test, mockall::automock)] +#[async_trait::async_trait] +pub trait SignerRegistrationPublisher: Send + Sync { + /// Registers signer with the aggregator. + async fn register_signer(&self, epoch: Epoch, signer: &Signer) -> StdResult<()>; +} diff --git a/mithril-signer/src/services/signer_registration/mod.rs b/mithril-signer/src/services/signer_registration/mod.rs new file mode 100644 index 00000000000..de9d4b8e73d --- /dev/null +++ b/mithril-signer/src/services/signer_registration/mod.rs @@ -0,0 +1,8 @@ +mod http; +mod interface; +#[cfg(test)] +mod spy; + +pub use interface::*; +#[cfg(test)] +pub use spy::*; diff --git a/mithril-signer/src/services/signer_registration/spy.rs b/mithril-signer/src/services/signer_registration/spy.rs new file mode 100644 index 00000000000..f2b77292e9a --- /dev/null +++ b/mithril-signer/src/services/signer_registration/spy.rs @@ -0,0 +1,47 @@ +use tokio::sync::RwLock; + +use mithril_common::StdResult; +use mithril_common::entities::{Epoch, Signer}; + +use crate::services::SignerRegistrationPublisher; + +/// A spy implementation of the `SignerRegistrationPublisher` trait for testing +pub struct SpySignerRegistrationPublisher { + last_registered_signer: RwLock>, + total_registered_signers: RwLock, +} + +impl SpySignerRegistrationPublisher { + /// Return the last signer that called with the `register` method. + pub async fn get_last_registered_signer(&self) -> Option { + self.last_registered_signer.read().await.clone() + } + + /// Return the total number of signers that called with the `register` method. + pub async fn get_total_registered_signers(&self) -> u32 { + *self.total_registered_signers.read().await + } +} + +impl Default for SpySignerRegistrationPublisher { + fn default() -> Self { + Self { + last_registered_signer: RwLock::new(None), + total_registered_signers: RwLock::new(0), + } + } +} + +#[async_trait::async_trait] +impl SignerRegistrationPublisher for SpySignerRegistrationPublisher { + async fn register_signer(&self, _epoch: Epoch, signer: &Signer) -> StdResult<()> { + let mut last_registered_signer = self.last_registered_signer.write().await; + let signer = signer.clone(); + *last_registered_signer = Some(signer); + + let mut total_registered_signers = self.total_registered_signers.write().await; + *total_registered_signers += 1; + + Ok(()) + } +} diff --git a/mithril-signer/tests/test_extensions/certificate_handler.rs b/mithril-signer/tests/test_extensions/certificate_handler.rs index d78fab61da0..ca3fe650074 100644 --- a/mithril-signer/tests/test_extensions/certificate_handler.rs +++ b/mithril-signer/tests/test_extensions/certificate_handler.rs @@ -14,7 +14,7 @@ use mithril_common::{ }; use mithril_ticker::{MithrilTickerService, TickerService}; -use mithril_signer::services::SignaturePublisher; +use mithril_signer::services::{SignaturePublisher, SignerRegistrationPublisher}; use mithril_signer::{entities::SignerEpochSettings, services::AggregatorClient}; pub struct FakeAggregator { @@ -93,6 +93,18 @@ impl SignaturePublisher for FakeAggregator { } } +#[async_trait] +impl SignerRegistrationPublisher for FakeAggregator { + async fn register_signer(&self, epoch: Epoch, signer: &Signer) -> StdResult<()> { + let mut store = self.registered_signers.write().await; + let mut signers = store.get(&epoch).cloned().unwrap_or_default(); + signers.push(signer.clone()); + let _ = store.insert(epoch, signers); + + Ok(()) + } +} + #[async_trait] impl AggregatorClient for FakeAggregator { async fn retrieve_epoch_settings(&self) -> StdResult> { @@ -112,16 +124,6 @@ impl AggregatorClient for FakeAggregator { } } - /// Registers signer with the aggregator - async fn register_signer(&self, epoch: Epoch, signer: &Signer) -> StdResult<()> { - let mut store = self.registered_signers.write().await; - let mut signers = store.get(&epoch).cloned().unwrap_or_default(); - signers.push(signer.clone()); - let _ = store.insert(epoch, signers); - - Ok(()) - } - async fn retrieve_aggregator_features(&self) -> StdResult { let signed_entity_config = self.signed_entity_config.read().await; diff --git a/mithril-signer/tests/test_extensions/state_machine_tester.rs b/mithril-signer/tests/test_extensions/state_machine_tester.rs index bcaa1220f71..415d225ad5d 100644 --- a/mithril-signer/tests/test_extensions/state_machine_tester.rs +++ b/mithril-signer/tests/test_extensions/state_machine_tester.rs @@ -61,9 +61,9 @@ use mithril_signer::{ database::repository::{ProtocolInitializerRepository, SignedBeaconRepository, StakePoolStore}, dependency_injection::{DependenciesBuilder, SignerDependencyContainer}, services::{ - AggregatorClient, CardanoTransactionsImporter, MithrilEpochService, MithrilSingleSigner, - SignerCertifierService, SignerSignableSeedBuilder, SignerSignedEntityConfigProvider, - SignerUpkeepService, + CardanoTransactionsImporter, MithrilEpochService, MithrilSingleSigner, + SignerCertifierService, SignerRegistrationPublisher, SignerSignableSeedBuilder, + SignerSignedEntityConfigProvider, SignerUpkeepService, }, store::{MKTreeStoreSqlite, ProtocolInitializerStorer}, }; @@ -339,6 +339,7 @@ impl StateMachineTester { upkeep_service, epoch_service, certifier, + signer_registration_publisher: certificate_handler.clone(), kes_signer, network_configuration_service: network_configuration_service.clone(), }; From 1822051e904f31a94987f5d55b25185160582f5c Mon Sep 17 00:00:00 2001 From: DJO <790521+Alenar@users.noreply.github.com> Date: Mon, 10 Nov 2025 18:29:43 +0100 Subject: [PATCH 3/7] refactor(signer): Remove `AggregatorClient::retrieve_aggregator_features` As it was supersed by the mithril network configuration and have now no usage even in tests. --- .../src/services/aggregator_client.rs | 22 +----- .../test_extensions/certificate_handler.rs | 68 +------------------ .../test_extensions/state_machine_tester.rs | 13 +--- 3 files changed, 8 insertions(+), 95 deletions(-) diff --git a/mithril-signer/src/services/aggregator_client.rs b/mithril-signer/src/services/aggregator_client.rs index 8c8f2028e36..d29be1c1ccf 100644 --- a/mithril-signer/src/services/aggregator_client.rs +++ b/mithril-signer/src/services/aggregator_client.rs @@ -1,11 +1,8 @@ use async_trait::async_trait; use mithril_aggregator_client::AggregatorHttpClient; -use mithril_aggregator_client::query::{GetAggregatorFeaturesQuery, GetEpochSettingsQuery}; -use mithril_common::{ - StdResult, - messages::{AggregatorFeaturesMessage, TryFromMessageAdapter}, -}; +use mithril_aggregator_client::query::GetEpochSettingsQuery; +use mithril_common::{StdResult, messages::TryFromMessageAdapter}; use crate::entities::SignerEpochSettings; use crate::message_adapters::FromEpochSettingsAdapter; @@ -16,9 +13,6 @@ use crate::message_adapters::FromEpochSettingsAdapter; pub trait AggregatorClient: Sync + Send { /// Retrieves epoch settings from the aggregator async fn retrieve_epoch_settings(&self) -> StdResult>; - - /// Retrieves aggregator features message from the aggregator - async fn retrieve_aggregator_features(&self) -> StdResult; } #[async_trait] @@ -29,11 +23,6 @@ impl AggregatorClient for AggregatorHttpClient { Ok(Some(epoch_settings)) } - - async fn retrieve_aggregator_features(&self) -> StdResult { - let aggregator_features = self.send(GetAggregatorFeaturesQuery::current()).await?; - Ok(aggregator_features) - } } #[cfg(test)] @@ -48,14 +37,12 @@ pub(crate) mod dumb { /// It is driven by a Tester that controls the data it can return, and it can return its internal state for testing. pub struct DumbAggregatorClient { epoch_settings: RwLock>, - aggregator_features: RwLock, } impl Default for DumbAggregatorClient { fn default() -> Self { Self { epoch_settings: RwLock::new(Some(SignerEpochSettings::dummy())), - aggregator_features: RwLock::new(AggregatorFeaturesMessage::dummy()), } } } @@ -67,10 +54,5 @@ pub(crate) mod dumb { Ok(epoch_settings) } - - async fn retrieve_aggregator_features(&self) -> StdResult { - let aggregator_features = self.aggregator_features.read().await; - Ok(aggregator_features.clone()) - } } } diff --git a/mithril-signer/tests/test_extensions/certificate_handler.rs b/mithril-signer/tests/test_extensions/certificate_handler.rs index ca3fe650074..5d2215d197b 100644 --- a/mithril-signer/tests/test_extensions/certificate_handler.rs +++ b/mithril-signer/tests/test_extensions/certificate_handler.rs @@ -1,15 +1,10 @@ use async_trait::async_trait; -use std::collections::BTreeSet; use std::{collections::HashMap, sync::Arc}; use tokio::sync::RwLock; use mithril_common::{ StdResult, - entities::{ - CardanoTransactionsSigningConfig, Epoch, ProtocolMessage, SignedEntityConfig, - SignedEntityType, SignedEntityTypeDiscriminants, Signer, SingleSignature, TimePoint, - }, - messages::AggregatorFeaturesMessage, + entities::{Epoch, ProtocolMessage, SignedEntityType, Signer, SingleSignature, TimePoint}, test::double::Dummy, }; use mithril_ticker::{MithrilTickerService, TickerService}; @@ -18,19 +13,14 @@ use mithril_signer::services::{SignaturePublisher, SignerRegistrationPublisher}; use mithril_signer::{entities::SignerEpochSettings, services::AggregatorClient}; pub struct FakeAggregator { - signed_entity_config: RwLock, registered_signers: RwLock>>, ticker_service: Arc, withhold_epoch_settings: RwLock, } impl FakeAggregator { - pub fn new( - signed_entity_config: SignedEntityConfig, - ticker_service: Arc, - ) -> Self { + pub fn new(ticker_service: Arc) -> Self { Self { - signed_entity_config: RwLock::new(signed_entity_config), registered_signers: RwLock::new(HashMap::new()), ticker_service, withhold_epoch_settings: RwLock::new(true), @@ -47,14 +37,6 @@ impl FakeAggregator { *settings = false; } - pub async fn change_allowed_discriminants( - &self, - discriminants: &BTreeSet, - ) { - let mut signed_entity_config = self.signed_entity_config.write().await; - signed_entity_config.allowed_discriminants = discriminants.clone(); - } - async fn get_time_point(&self) -> StdResult { let time_point = self.ticker_service.get_current_time_point().await?; Ok(time_point) @@ -123,16 +105,6 @@ impl AggregatorClient for FakeAggregator { })) } } - - async fn retrieve_aggregator_features(&self) -> StdResult { - let signed_entity_config = self.signed_entity_config.read().await; - - let mut message = AggregatorFeaturesMessage::dummy(); - message.capabilities.signed_entity_types = - signed_entity_config.allowed_discriminants.clone(); - - Ok(message) - } } #[cfg(test)] @@ -158,10 +130,7 @@ mod tests { immutable_observer.clone(), )); - ( - chain_observer, - FakeAggregator::new(SignedEntityConfig::dummy(), ticker_service), - ) + (chain_observer, FakeAggregator::new(ticker_service)) } #[tokio::test] @@ -249,35 +218,4 @@ mod tests { assert_eq!(2, epoch_settings.current_signers.len()); assert_eq!(1, epoch_settings.next_signers.len()); } - - #[tokio::test] - async fn retrieve_aggregator_features() { - let (_chain_observer, fake_aggregator) = init().await; - - { - let mut signing_config = fake_aggregator.signed_entity_config.write().await; - signing_config.allowed_discriminants = SignedEntityTypeDiscriminants::all(); - signing_config.cardano_transactions_signing_config = - CardanoTransactionsSigningConfig::dummy(); - } - - let features = fake_aggregator.retrieve_aggregator_features().await.unwrap(); - assert_eq!( - &SignedEntityTypeDiscriminants::all(), - &features.capabilities.signed_entity_types, - ); - - let new_discriminants = BTreeSet::from([ - SignedEntityTypeDiscriminants::CardanoTransactions, - SignedEntityTypeDiscriminants::CardanoImmutableFilesFull, - ]); - - fake_aggregator.change_allowed_discriminants(&new_discriminants).await; - - let updated_features = fake_aggregator.retrieve_aggregator_features().await.unwrap(); - assert_eq!( - &new_discriminants, - &updated_features.capabilities.signed_entity_types, - ); - } } diff --git a/mithril-signer/tests/test_extensions/state_machine_tester.rs b/mithril-signer/tests/test_extensions/state_machine_tester.rs index 415d225ad5d..06f0cfe56d2 100644 --- a/mithril-signer/tests/test_extensions/state_machine_tester.rs +++ b/mithril-signer/tests/test_extensions/state_machine_tester.rs @@ -34,9 +34,8 @@ use mithril_common::{ api_version::APIVersionProvider, crypto_helper::{KesSigner, KesSignerStandard}, entities::{ - BlockNumber, CardanoTransactionsSigningConfig, ChainPoint, Epoch, SignedEntityConfig, - SignedEntityType, SignedEntityTypeDiscriminants, SignerWithStake, SlotNumber, SupportedEra, - TimePoint, + BlockNumber, CardanoTransactionsSigningConfig, ChainPoint, Epoch, SignedEntityType, + SignedEntityTypeDiscriminants, SignerWithStake, SlotNumber, SupportedEra, TimePoint, }, signable_builder::{ CardanoStakeDistributionSignableBuilder, CardanoTransactionsSignableBuilder, @@ -167,13 +166,7 @@ impl StateMachineTester { security_parameter: BlockNumber(0), step: BlockNumber(30), }; - let certificate_handler = Arc::new(FakeAggregator::new( - SignedEntityConfig { - allowed_discriminants: SignedEntityTypeDiscriminants::all(), - cardano_transactions_signing_config: cardano_transactions_signing_config.clone(), - }, - ticker_service.clone(), - )); + let certificate_handler = Arc::new(FakeAggregator::new(ticker_service.clone())); let configuration_for_aggregation = MithrilNetworkConfigurationForEpoch { signed_entity_types_config: SignedEntityTypeConfiguration { From 6db767b362454831ef61c4c82444242b054ba903 Mon Sep 17 00:00:00 2001 From: DJO <790521+Alenar@users.noreply.github.com> Date: Mon, 10 Nov 2025 18:37:19 +0100 Subject: [PATCH 4/7] refactor(signer): rename `AggregatorClient::retrieve_epoch_settings` to `retrieve_all_signer_registrations` And `SignerEpochSettings` to `RegisteredSigners` --- mithril-signer/src/entities/mod.rs | 4 ++-- ...ner_epoch_settings.rs => registered_signers.rs} | 14 +++++++------- mithril-signer/src/lib.rs | 2 +- .../src/message_adapters/from_epoch_settings.rs | 10 +++++----- mithril-signer/src/runtime/runner.rs | 11 +++++++---- mithril-signer/src/runtime/state_machine.rs | 10 +++++----- mithril-signer/src/services/aggregator_client.rs | 12 ++++++------ .../tests/test_extensions/certificate_handler.rs | 12 ++++++------ 8 files changed, 39 insertions(+), 36 deletions(-) rename mithril-signer/src/entities/{signer_epoch_settings.rs => registered_signers.rs} (68%) diff --git a/mithril-signer/src/entities/mod.rs b/mithril-signer/src/entities/mod.rs index d873f48c1d8..75c86ce4807 100644 --- a/mithril-signer/src/entities/mod.rs +++ b/mithril-signer/src/entities/mod.rs @@ -3,7 +3,7 @@ //! This module provide domain entities for the services & state machine. mod beacon_to_sign; -mod signer_epoch_settings; +mod registered_signers; pub use beacon_to_sign::*; -pub use signer_epoch_settings::*; +pub use registered_signers::*; diff --git a/mithril-signer/src/entities/signer_epoch_settings.rs b/mithril-signer/src/entities/registered_signers.rs similarity index 68% rename from mithril-signer/src/entities/signer_epoch_settings.rs rename to mithril-signer/src/entities/registered_signers.rs index a193a8282b6..979114323a7 100644 --- a/mithril-signer/src/entities/signer_epoch_settings.rs +++ b/mithril-signer/src/entities/registered_signers.rs @@ -1,9 +1,9 @@ use mithril_common::entities::{Epoch, Signer}; -/// SignerEpochSettings represents the settings of an epoch +/// `RegisteredSigners` represents the registered signers of an epoch #[derive(Clone, Debug, PartialEq)] -pub struct SignerEpochSettings { - /// Current Epoch +pub struct RegisteredSigners { + /// Epoch for which those registrations are active. pub epoch: Epoch, /// Current Signers @@ -14,9 +14,9 @@ pub struct SignerEpochSettings { } #[cfg(test)] -impl mithril_common::test::double::Dummy for SignerEpochSettings { - /// Create a dummy `SignerEpochSettings` - fn dummy() -> SignerEpochSettings { +impl mithril_common::test::double::Dummy for RegisteredSigners { + /// Create a dummy `RegisteredSigners` + fn dummy() -> RegisteredSigners { use mithril_common::test::double::fake_data; // Beacon @@ -28,7 +28,7 @@ impl mithril_common::test::double::Dummy for SignerEpochSettings { let next_signers = signers[2..5].to_vec(); // Signer Epoch settings - SignerEpochSettings { + RegisteredSigners { epoch: beacon.epoch, current_signers, next_signers, diff --git a/mithril-signer/src/lib.rs b/mithril-signer/src/lib.rs index 3631aaf5e16..734ad170b92 100644 --- a/mithril-signer/src/lib.rs +++ b/mithril-signer/src/lib.rs @@ -19,7 +19,7 @@ pub mod store; pub use commands::*; pub use configuration::{Configuration, DefaultConfiguration}; -pub use entities::SignerEpochSettings; +pub use entities::RegisteredSigners; pub use message_adapters::{FromEpochSettingsAdapter, ToRegisterSignerMessageAdapter}; pub use metrics::*; pub use runtime::*; diff --git a/mithril-signer/src/message_adapters/from_epoch_settings.rs b/mithril-signer/src/message_adapters/from_epoch_settings.rs index 9e3b0b3567d..44798d7db7a 100644 --- a/mithril-signer/src/message_adapters/from_epoch_settings.rs +++ b/mithril-signer/src/message_adapters/from_epoch_settings.rs @@ -4,15 +4,15 @@ use mithril_common::{ messages::{EpochSettingsMessage, SignerMessagePart, TryFromMessageAdapter}, }; -use crate::entities::SignerEpochSettings; +use crate::entities::RegisteredSigners; -/// Adapter to convert [EpochSettingsMessage] to [SignerEpochSettings]. +/// Adapter to convert [EpochSettingsMessage] to [RegisteredSigners]. pub struct FromEpochSettingsAdapter; -impl TryFromMessageAdapter for FromEpochSettingsAdapter { +impl TryFromMessageAdapter for FromEpochSettingsAdapter { /// Method to convert. - fn try_adapt(message: EpochSettingsMessage) -> StdResult { - let epoch_settings = SignerEpochSettings { + fn try_adapt(message: EpochSettingsMessage) -> StdResult { + let epoch_settings = RegisteredSigners { epoch: message.epoch, current_signers: SignerMessagePart::try_into_signers(message.current_signers) .with_context(|| "'FromMessageAdapter' can not convert the current signers")?, diff --git a/mithril-signer/src/runtime/runner.rs b/mithril-signer/src/runtime/runner.rs index cfaf5b0d618..34a3736a195 100644 --- a/mithril-signer/src/runtime/runner.rs +++ b/mithril-signer/src/runtime/runner.rs @@ -14,7 +14,7 @@ use mithril_protocol_config::model::MithrilNetworkConfiguration; use crate::Configuration; use crate::dependency_injection::SignerDependencyContainer; -use crate::entities::{BeaconToSign, SignerEpochSettings}; +use crate::entities::{BeaconToSign, RegisteredSigners}; use crate::services::{EpochService, MithrilProtocolInitializerBuilder}; /// This trait is mainly intended for mocking. @@ -29,7 +29,7 @@ pub trait Runner: Send + Sync { /// Fetch the current epoch settings if any. async fn get_signer_registrations_from_aggregator( &self, - ) -> StdResult>; + ) -> StdResult>; /// Fetch the beacon to sign if any. async fn get_beacon_to_sign(&self, time_point: TimePoint) -> StdResult>; @@ -131,10 +131,13 @@ impl Runner for SignerRunner { async fn get_signer_registrations_from_aggregator( &self, - ) -> StdResult> { + ) -> StdResult> { debug!(self.logger, ">> get_epoch_settings"); - self.services.certificate_handler.retrieve_epoch_settings().await + self.services + .certificate_handler + .retrieve_all_signer_registrations() + .await } async fn get_beacon_to_sign(&self, time_point: TimePoint) -> StdResult> { diff --git a/mithril-signer/src/runtime/state_machine.rs b/mithril-signer/src/runtime/state_machine.rs index a800f298523..9109eeb90b6 100644 --- a/mithril-signer/src/runtime/state_machine.rs +++ b/mithril-signer/src/runtime/state_machine.rs @@ -496,7 +496,7 @@ mod tests { use mithril_common::entities::{ChainPoint, Epoch, ProtocolMessage, SignedEntityType}; use mithril_common::test::double::Dummy; - use crate::SignerEpochSettings; + use crate::RegisteredSigners; use crate::runtime::runner::MockSignerRunner; use crate::test_tools::TestLogger; @@ -547,7 +547,7 @@ mod tests { #[tokio::test] async fn unregistered_epoch_settings_behind_known_epoch() { let mut runner = MockSignerRunner::new(); - let epoch_settings = SignerEpochSettings { + let epoch_settings = RegisteredSigners { epoch: Epoch(3), current_signers: vec![], next_signers: vec![], @@ -594,7 +594,7 @@ mod tests { runner .expect_get_signer_registrations_from_aggregator() .once() - .returning(|| Ok(Some(SignerEpochSettings::dummy()))); + .returning(|| Ok(Some(RegisteredSigners::dummy()))); runner .expect_get_mithril_network_configuration() @@ -646,7 +646,7 @@ mod tests { runner .expect_get_signer_registrations_from_aggregator() .once() - .returning(|| Ok(Some(SignerEpochSettings::dummy()))); + .returning(|| Ok(Some(RegisteredSigners::dummy()))); runner .expect_get_mithril_network_configuration() @@ -702,7 +702,7 @@ mod tests { runner .expect_get_signer_registrations_from_aggregator() .once() - .returning(|| Ok(Some(SignerEpochSettings::dummy()))); + .returning(|| Ok(Some(RegisteredSigners::dummy()))); runner .expect_get_mithril_network_configuration() diff --git a/mithril-signer/src/services/aggregator_client.rs b/mithril-signer/src/services/aggregator_client.rs index d29be1c1ccf..395102279ef 100644 --- a/mithril-signer/src/services/aggregator_client.rs +++ b/mithril-signer/src/services/aggregator_client.rs @@ -4,7 +4,7 @@ use mithril_aggregator_client::AggregatorHttpClient; use mithril_aggregator_client::query::GetEpochSettingsQuery; use mithril_common::{StdResult, messages::TryFromMessageAdapter}; -use crate::entities::SignerEpochSettings; +use crate::entities::RegisteredSigners; use crate::message_adapters::FromEpochSettingsAdapter; /// Trait for mocking and testing a `AggregatorClient` @@ -12,12 +12,12 @@ use crate::message_adapters::FromEpochSettingsAdapter; #[async_trait] pub trait AggregatorClient: Sync + Send { /// Retrieves epoch settings from the aggregator - async fn retrieve_epoch_settings(&self) -> StdResult>; + async fn retrieve_all_signer_registrations(&self) -> StdResult>; } #[async_trait] impl AggregatorClient for AggregatorHttpClient { - async fn retrieve_epoch_settings(&self) -> StdResult> { + async fn retrieve_all_signer_registrations(&self) -> StdResult> { let message = self.send(GetEpochSettingsQuery::current()).await?; let epoch_settings = FromEpochSettingsAdapter::try_adapt(message)?; @@ -36,20 +36,20 @@ pub(crate) mod dumb { /// It actually does not communicate with an aggregator host but mimics this behavior. /// It is driven by a Tester that controls the data it can return, and it can return its internal state for testing. pub struct DumbAggregatorClient { - epoch_settings: RwLock>, + epoch_settings: RwLock>, } impl Default for DumbAggregatorClient { fn default() -> Self { Self { - epoch_settings: RwLock::new(Some(SignerEpochSettings::dummy())), + epoch_settings: RwLock::new(Some(RegisteredSigners::dummy())), } } } #[async_trait] impl AggregatorClient for DumbAggregatorClient { - async fn retrieve_epoch_settings(&self) -> StdResult> { + async fn retrieve_all_signer_registrations(&self) -> StdResult> { let epoch_settings = self.epoch_settings.read().await.clone(); Ok(epoch_settings) diff --git a/mithril-signer/tests/test_extensions/certificate_handler.rs b/mithril-signer/tests/test_extensions/certificate_handler.rs index 5d2215d197b..50b57dfd0c5 100644 --- a/mithril-signer/tests/test_extensions/certificate_handler.rs +++ b/mithril-signer/tests/test_extensions/certificate_handler.rs @@ -10,7 +10,7 @@ use mithril_common::{ use mithril_ticker::{MithrilTickerService, TickerService}; use mithril_signer::services::{SignaturePublisher, SignerRegistrationPublisher}; -use mithril_signer::{entities::SignerEpochSettings, services::AggregatorClient}; +use mithril_signer::{entities::RegisteredSigners, services::AggregatorClient}; pub struct FakeAggregator { registered_signers: RwLock>>, @@ -89,7 +89,7 @@ impl SignerRegistrationPublisher for FakeAggregator { #[async_trait] impl AggregatorClient for FakeAggregator { - async fn retrieve_epoch_settings(&self) -> StdResult> { + async fn retrieve_all_signer_registrations(&self) -> StdResult> { if *self.withhold_epoch_settings.read().await { Ok(None) } else { @@ -98,7 +98,7 @@ impl AggregatorClient for FakeAggregator { let current_signers = self.get_current_signers(&store).await?; let next_signers = self.get_next_signers(&store).await?; - Ok(Some(SignerEpochSettings { + Ok(Some(RegisteredSigners { epoch: time_point.epoch, current_signers, next_signers, @@ -183,7 +183,7 @@ mod tests { .await .expect("aggregator client should not fail while registering a user"); let epoch_settings = fake_aggregator - .retrieve_epoch_settings() + .retrieve_all_signer_registrations() .await .expect("we should have a result, None found!") .expect("we should have an EpochSettings, None found!"); @@ -196,7 +196,7 @@ mod tests { .await .expect("aggregator client should not fail while registering a user"); let epoch_settings = fake_aggregator - .retrieve_epoch_settings() + .retrieve_all_signer_registrations() .await .expect("we should have a result, None found!") .expect("we should have an EpochSettings, None found!"); @@ -210,7 +210,7 @@ mod tests { .await .expect("aggregator client should not fail while registering a user"); let epoch_settings = fake_aggregator - .retrieve_epoch_settings() + .retrieve_all_signer_registrations() .await .expect("we should have a result, None found!") .expect("we should have an EpochSettings, None found!"); From 9f1bb724d801ddaf25b841c887f19b67c71975d4 Mon Sep 17 00:00:00 2001 From: DJO <790521+Alenar@users.noreply.github.com> Date: Mon, 10 Nov 2025 18:48:16 +0100 Subject: [PATCH 5/7] refactor(signer): rename `AggregatorClient` to `SignersRegistrationRetriever` --- .../src/dependency_injection/builder.rs | 4 ++-- .../src/dependency_injection/containers.rs | 11 +++++------ mithril-signer/src/runtime/runner.rs | 12 ++++-------- mithril-signer/src/services/mod.rs | 8 ++++---- ...nt.rs => signers_registration_retriever.rs} | 18 ++++++++---------- .../test_extensions/certificate_handler.rs | 4 ++-- .../test_extensions/state_machine_tester.rs | 2 +- 7 files changed, 26 insertions(+), 33 deletions(-) rename mithril-signer/src/services/{aggregator_client.rs => signers_registration_retriever.rs} (68%) diff --git a/mithril-signer/src/dependency_injection/builder.rs b/mithril-signer/src/dependency_injection/builder.rs index 8c8751c270f..fb9458fe61e 100644 --- a/mithril-signer/src/dependency_injection/builder.rs +++ b/mithril-signer/src/dependency_injection/builder.rs @@ -513,7 +513,6 @@ impl<'a> DependenciesBuilder<'a> { let services = SignerDependencyContainer { ticker_service, - certificate_handler: aggregator_client.clone(), chain_observer, digester, single_signer, @@ -529,7 +528,8 @@ impl<'a> DependenciesBuilder<'a> { upkeep_service, epoch_service, certifier, - signer_registration_publisher: aggregator_client, + signer_registration_publisher: aggregator_client.clone(), + signers_registration_retriever: aggregator_client, kes_signer, network_configuration_service, }; diff --git a/mithril-signer/src/dependency_injection/containers.rs b/mithril-signer/src/dependency_injection/containers.rs index 007f08586fc..7baba8cddaa 100644 --- a/mithril-signer/src/dependency_injection/containers.rs +++ b/mithril-signer/src/dependency_injection/containers.rs @@ -16,13 +16,12 @@ use mithril_ticker::TickerService; use crate::MetricsService; use crate::services::{ - AggregatorClient, CertifierService, EpochService, SignerRegistrationPublisher, SingleSigner, - UpkeepService, + CertifierService, EpochService, SignerRegistrationPublisher, SignersRegistrationRetriever, + SingleSigner, UpkeepService, }; use crate::store::ProtocolInitializerStorer; type StakeStoreService = Arc; -type CertificateHandlerService = Arc; type ChainObserverService = Arc; type DigesterService = Arc; type SingleSignerService = Arc; @@ -41,9 +40,6 @@ pub struct SignerDependencyContainer { /// Stake store service pub stake_store: StakeStoreService, - /// Certificate handler service - pub certificate_handler: CertificateHandlerService, - /// Chain Observer service pub chain_observer: ChainObserverService, @@ -89,6 +85,9 @@ pub struct SignerDependencyContainer { /// Signer registration publisher pub signer_registration_publisher: Arc, + /// Signers registration retriever + pub signers_registration_retriever: Arc, + /// Kes signer service pub kes_signer: Option>, diff --git a/mithril-signer/src/runtime/runner.rs b/mithril-signer/src/runtime/runner.rs index 34a3736a195..234b0d4fca9 100644 --- a/mithril-signer/src/runtime/runner.rs +++ b/mithril-signer/src/runtime/runner.rs @@ -135,7 +135,7 @@ impl Runner for SignerRunner { debug!(self.logger, ">> get_epoch_settings"); self.services - .certificate_handler + .signers_registration_retriever .retrieve_all_signer_registrations() .await } @@ -417,7 +417,7 @@ mod tests { use crate::database::test_helper::main_db_connection; use crate::metrics::MetricsService; use crate::services::{ - CardanoTransactionsImporter, DumbAggregatorClient, MithrilEpochService, + CardanoTransactionsImporter, DumbSignersRegistrationRetriever, MithrilEpochService, MithrilSingleSigner, MockTransactionStore, MockUpkeepService, SignaturePublisherNoop, SignerCertifierService, SignerSignableSeedBuilder, SignerSignedEntityConfigProvider, SpySignerRegistrationPublisher, @@ -550,7 +550,6 @@ mod tests { Arc::new(CardanoTransactionsPreloaderActivation::new(true)), )); let upkeep_service = Arc::new(MockUpkeepService::new()); - let aggregator_client = Arc::new(DumbAggregatorClient::default()); let certifier = Arc::new(SignerCertifierService::new( Arc::new(SignedBeaconRepository::new(sqlite_connection.clone(), None)), Arc::new(SignerSignedEntityConfigProvider::new(epoch_service.clone())), @@ -573,7 +572,6 @@ mod tests { SignerDependencyContainer { stake_store, - certificate_handler: aggregator_client, chain_observer, digester, single_signer, @@ -590,6 +588,7 @@ mod tests { epoch_service, certifier, signer_registration_publisher: Arc::new(SpySignerRegistrationPublisher::default()), + signers_registration_retriever: Arc::new(DumbSignersRegistrationRetriever::default()), kes_signer, network_configuration_service, } @@ -776,10 +775,7 @@ mod tests { #[tokio::test] async fn test_inform_epoch_setting_pass_available_signed_entity_types_to_epoch_service() { - let mut services = init_services().await; - let certificate_handler = Arc::new(DumbAggregatorClient::default()); - - services.certificate_handler = certificate_handler; + let services = init_services().await; let runner = init_runner(Some(services), None).await; let epoch = Epoch(1); diff --git a/mithril-signer/src/services/mod.rs b/mithril-signer/src/services/mod.rs index 553e7a49d63..50a0544d7e4 100644 --- a/mithril-signer/src/services/mod.rs +++ b/mithril-signer/src/services/mod.rs @@ -9,24 +9,24 @@ //! //! Each service is defined by a public API (a trait) that is used in the controllers (runtimes). -mod aggregator_client; mod cardano_transactions; mod certifier; mod epoch_service; mod signable_builder; mod signature_publisher; mod signer_registration; +mod signers_registration_retriever; mod single_signer; mod upkeep_service; -#[cfg(test)] -pub(crate) use aggregator_client::dumb::DumbAggregatorClient; -pub use aggregator_client::*; pub use cardano_transactions::*; pub use certifier::*; pub use epoch_service::*; pub use signable_builder::*; pub use signature_publisher::*; pub use signer_registration::*; +#[cfg(test)] +pub(crate) use signers_registration_retriever::dumb::DumbSignersRegistrationRetriever; +pub use signers_registration_retriever::*; pub use single_signer::*; pub use upkeep_service::*; diff --git a/mithril-signer/src/services/aggregator_client.rs b/mithril-signer/src/services/signers_registration_retriever.rs similarity index 68% rename from mithril-signer/src/services/aggregator_client.rs rename to mithril-signer/src/services/signers_registration_retriever.rs index 395102279ef..872f41097ad 100644 --- a/mithril-signer/src/services/aggregator_client.rs +++ b/mithril-signer/src/services/signers_registration_retriever.rs @@ -7,16 +7,16 @@ use mithril_common::{StdResult, messages::TryFromMessageAdapter}; use crate::entities::RegisteredSigners; use crate::message_adapters::FromEpochSettingsAdapter; -/// Trait for mocking and testing a `AggregatorClient` +/// Service responsible for retrieving the signer's registration from the mithril network #[cfg_attr(test, mockall::automock)] #[async_trait] -pub trait AggregatorClient: Sync + Send { - /// Retrieves epoch settings from the aggregator +pub trait SignersRegistrationRetriever: Sync + Send { + /// Retrieves signer's registration from the mithril network async fn retrieve_all_signer_registrations(&self) -> StdResult>; } #[async_trait] -impl AggregatorClient for AggregatorHttpClient { +impl SignersRegistrationRetriever for AggregatorHttpClient { async fn retrieve_all_signer_registrations(&self) -> StdResult> { let message = self.send(GetEpochSettingsQuery::current()).await?; let epoch_settings = FromEpochSettingsAdapter::try_adapt(message)?; @@ -32,14 +32,12 @@ pub(crate) mod dumb { use super::*; - /// This aggregator client is intended to be used by test services. - /// It actually does not communicate with an aggregator host but mimics this behavior. - /// It is driven by a Tester that controls the data it can return, and it can return its internal state for testing. - pub struct DumbAggregatorClient { + /// Dumb `SignersRegistrationRetriever` implementation for testing + pub struct DumbSignersRegistrationRetriever { epoch_settings: RwLock>, } - impl Default for DumbAggregatorClient { + impl Default for DumbSignersRegistrationRetriever { fn default() -> Self { Self { epoch_settings: RwLock::new(Some(RegisteredSigners::dummy())), @@ -48,7 +46,7 @@ pub(crate) mod dumb { } #[async_trait] - impl AggregatorClient for DumbAggregatorClient { + impl SignersRegistrationRetriever for DumbSignersRegistrationRetriever { async fn retrieve_all_signer_registrations(&self) -> StdResult> { let epoch_settings = self.epoch_settings.read().await.clone(); diff --git a/mithril-signer/tests/test_extensions/certificate_handler.rs b/mithril-signer/tests/test_extensions/certificate_handler.rs index 50b57dfd0c5..9d4d3b21870 100644 --- a/mithril-signer/tests/test_extensions/certificate_handler.rs +++ b/mithril-signer/tests/test_extensions/certificate_handler.rs @@ -10,7 +10,7 @@ use mithril_common::{ use mithril_ticker::{MithrilTickerService, TickerService}; use mithril_signer::services::{SignaturePublisher, SignerRegistrationPublisher}; -use mithril_signer::{entities::RegisteredSigners, services::AggregatorClient}; +use mithril_signer::{entities::RegisteredSigners, services::SignersRegistrationRetriever}; pub struct FakeAggregator { registered_signers: RwLock>>, @@ -88,7 +88,7 @@ impl SignerRegistrationPublisher for FakeAggregator { } #[async_trait] -impl AggregatorClient for FakeAggregator { +impl SignersRegistrationRetriever for FakeAggregator { async fn retrieve_all_signer_registrations(&self) -> StdResult> { if *self.withhold_epoch_settings.read().await { Ok(None) diff --git a/mithril-signer/tests/test_extensions/state_machine_tester.rs b/mithril-signer/tests/test_extensions/state_machine_tester.rs index 06f0cfe56d2..6994e3ba52e 100644 --- a/mithril-signer/tests/test_extensions/state_machine_tester.rs +++ b/mithril-signer/tests/test_extensions/state_machine_tester.rs @@ -315,7 +315,7 @@ impl StateMachineTester { )) as Arc); let services = SignerDependencyContainer { - certificate_handler: certificate_handler.clone(), + signers_registration_retriever: certificate_handler.clone(), ticker_service: ticker_service.clone(), chain_observer: chain_observer.clone(), digester: digester.clone(), From 756eed62eadc91b108fb7e5a8b6978868557335e Mon Sep 17 00:00:00 2001 From: DJO <790521+Alenar@users.noreply.github.com> Date: Mon, 10 Nov 2025 18:50:01 +0100 Subject: [PATCH 6/7] test(signer): rename `certificate_handler` mod to `fake_aggregator` Since the former have been supersed with multiple traits which are implemented on the `FakeAggregator` test utils. --- ...certificate_handler.rs => fake_aggregator.rs} | 0 mithril-signer/tests/test_extensions/mod.rs | 4 ++-- .../test_extensions/state_machine_tester.rs | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) rename mithril-signer/tests/test_extensions/{certificate_handler.rs => fake_aggregator.rs} (100%) diff --git a/mithril-signer/tests/test_extensions/certificate_handler.rs b/mithril-signer/tests/test_extensions/fake_aggregator.rs similarity index 100% rename from mithril-signer/tests/test_extensions/certificate_handler.rs rename to mithril-signer/tests/test_extensions/fake_aggregator.rs diff --git a/mithril-signer/tests/test_extensions/mod.rs b/mithril-signer/tests/test_extensions/mod.rs index 9c6187923f7..edb4124b5fd 100644 --- a/mithril-signer/tests/test_extensions/mod.rs +++ b/mithril-signer/tests/test_extensions/mod.rs @@ -1,5 +1,5 @@ -mod certificate_handler; +mod fake_aggregator; mod state_machine_tester; -pub use certificate_handler::FakeAggregator; +pub use fake_aggregator::FakeAggregator; pub use state_machine_tester::StateMachineTester; diff --git a/mithril-signer/tests/test_extensions/state_machine_tester.rs b/mithril-signer/tests/test_extensions/state_machine_tester.rs index 6994e3ba52e..14822173cdd 100644 --- a/mithril-signer/tests/test_extensions/state_machine_tester.rs +++ b/mithril-signer/tests/test_extensions/state_machine_tester.rs @@ -91,7 +91,7 @@ pub struct StateMachineTester { state_machine: StateMachine, immutable_observer: Arc, chain_observer: Arc, - certificate_handler: Arc, + fake_aggregator: Arc, network_configuration_service: Arc, protocol_initializer_store: Arc, stake_store: Arc, @@ -166,7 +166,7 @@ impl StateMachineTester { security_parameter: BlockNumber(0), step: BlockNumber(30), }; - let certificate_handler = Arc::new(FakeAggregator::new(ticker_service.clone())); + let fake_aggregator = Arc::new(FakeAggregator::new(ticker_service.clone())); let configuration_for_aggregation = MithrilNetworkConfigurationForEpoch { signed_entity_types_config: SignedEntityTypeConfiguration { @@ -306,7 +306,7 @@ impl StateMachineTester { Arc::new(SignerSignedEntityConfigProvider::new(epoch_service.clone())), signed_entity_type_lock.clone(), single_signer.clone(), - certificate_handler.clone(), + fake_aggregator.clone(), logger.clone(), )); let kes_signer = Some(Arc::new(KesSignerStandard::new( @@ -315,7 +315,7 @@ impl StateMachineTester { )) as Arc); let services = SignerDependencyContainer { - signers_registration_retriever: certificate_handler.clone(), + signers_registration_retriever: fake_aggregator.clone(), ticker_service: ticker_service.clone(), chain_observer: chain_observer.clone(), digester: digester.clone(), @@ -332,7 +332,7 @@ impl StateMachineTester { upkeep_service, epoch_service, certifier, - signer_registration_publisher: certificate_handler.clone(), + signer_registration_publisher: fake_aggregator.clone(), kes_signer, network_configuration_service: network_configuration_service.clone(), }; @@ -353,7 +353,7 @@ impl StateMachineTester { state_machine, immutable_observer, chain_observer, - certificate_handler, + fake_aggregator, network_configuration_service, protocol_initializer_store, stake_store, @@ -471,7 +471,7 @@ impl StateMachineTester { /// make the aggregator send the epoch settings from now on pub async fn aggregator_send_epoch_settings(&mut self) -> &mut Self { - self.certificate_handler.release_epoch_settings().await; + self.fake_aggregator.release_epoch_settings().await; self } @@ -687,7 +687,7 @@ impl StateMachineTester { .unwrap() .epoch; for signer_with_stake in signers_with_stake { - self.certificate_handler + self.fake_aggregator .register_signer(epoch, &signer_with_stake.to_owned().into()) .await .map_err(TestError::SubsystemError)?; From 1501736ae5cb7a2996a9b752fecbd1070905ee82 Mon Sep 17 00:00:00 2001 From: DJO <790521+Alenar@users.noreply.github.com> Date: Mon, 10 Nov 2025 18:55:53 +0100 Subject: [PATCH 7/7] refactor(signer): unify signers registration publisher and retriever in the same parent module and split the retriever in several modules like the publisher --- mithril-signer/src/services/mod.rs | 4 -- .../src/services/signer_registration/mod.rs | 11 ++-- .../{ => publisher}/http.rs | 0 .../{ => publisher}/interface.rs | 0 .../signer_registration/publisher/mod.rs | 8 +++ .../{ => publisher}/spy.rs | 0 .../signer_registration/retriever/dumb.rs | 29 ++++++++++ .../signer_registration/retriever/http.rs | 15 +++++ .../retriever/interface.rs | 11 ++++ .../signer_registration/retriever/mod.rs | 8 +++ .../signers_registration_retriever.rs | 56 ------------------- 11 files changed, 75 insertions(+), 67 deletions(-) rename mithril-signer/src/services/signer_registration/{ => publisher}/http.rs (100%) rename mithril-signer/src/services/signer_registration/{ => publisher}/interface.rs (100%) create mode 100644 mithril-signer/src/services/signer_registration/publisher/mod.rs rename mithril-signer/src/services/signer_registration/{ => publisher}/spy.rs (100%) create mode 100644 mithril-signer/src/services/signer_registration/retriever/dumb.rs create mode 100644 mithril-signer/src/services/signer_registration/retriever/http.rs create mode 100644 mithril-signer/src/services/signer_registration/retriever/interface.rs create mode 100644 mithril-signer/src/services/signer_registration/retriever/mod.rs delete mode 100644 mithril-signer/src/services/signers_registration_retriever.rs diff --git a/mithril-signer/src/services/mod.rs b/mithril-signer/src/services/mod.rs index 50a0544d7e4..1e49466d2e2 100644 --- a/mithril-signer/src/services/mod.rs +++ b/mithril-signer/src/services/mod.rs @@ -15,7 +15,6 @@ mod epoch_service; mod signable_builder; mod signature_publisher; mod signer_registration; -mod signers_registration_retriever; mod single_signer; mod upkeep_service; @@ -25,8 +24,5 @@ pub use epoch_service::*; pub use signable_builder::*; pub use signature_publisher::*; pub use signer_registration::*; -#[cfg(test)] -pub(crate) use signers_registration_retriever::dumb::DumbSignersRegistrationRetriever; -pub use signers_registration_retriever::*; pub use single_signer::*; pub use upkeep_service::*; diff --git a/mithril-signer/src/services/signer_registration/mod.rs b/mithril-signer/src/services/signer_registration/mod.rs index de9d4b8e73d..49302ca86cc 100644 --- a/mithril-signer/src/services/signer_registration/mod.rs +++ b/mithril-signer/src/services/signer_registration/mod.rs @@ -1,8 +1,5 @@ -mod http; -mod interface; -#[cfg(test)] -mod spy; +mod publisher; +mod retriever; -pub use interface::*; -#[cfg(test)] -pub use spy::*; +pub use publisher::*; +pub use retriever::*; diff --git a/mithril-signer/src/services/signer_registration/http.rs b/mithril-signer/src/services/signer_registration/publisher/http.rs similarity index 100% rename from mithril-signer/src/services/signer_registration/http.rs rename to mithril-signer/src/services/signer_registration/publisher/http.rs diff --git a/mithril-signer/src/services/signer_registration/interface.rs b/mithril-signer/src/services/signer_registration/publisher/interface.rs similarity index 100% rename from mithril-signer/src/services/signer_registration/interface.rs rename to mithril-signer/src/services/signer_registration/publisher/interface.rs diff --git a/mithril-signer/src/services/signer_registration/publisher/mod.rs b/mithril-signer/src/services/signer_registration/publisher/mod.rs new file mode 100644 index 00000000000..de9d4b8e73d --- /dev/null +++ b/mithril-signer/src/services/signer_registration/publisher/mod.rs @@ -0,0 +1,8 @@ +mod http; +mod interface; +#[cfg(test)] +mod spy; + +pub use interface::*; +#[cfg(test)] +pub use spy::*; diff --git a/mithril-signer/src/services/signer_registration/spy.rs b/mithril-signer/src/services/signer_registration/publisher/spy.rs similarity index 100% rename from mithril-signer/src/services/signer_registration/spy.rs rename to mithril-signer/src/services/signer_registration/publisher/spy.rs diff --git a/mithril-signer/src/services/signer_registration/retriever/dumb.rs b/mithril-signer/src/services/signer_registration/retriever/dumb.rs new file mode 100644 index 00000000000..8fc5bea0d5c --- /dev/null +++ b/mithril-signer/src/services/signer_registration/retriever/dumb.rs @@ -0,0 +1,29 @@ +use tokio::sync::RwLock; + +use mithril_common::StdResult; +use mithril_common::test::double::Dummy; + +use crate::RegisteredSigners; +use crate::services::signer_registration::retriever::interface::SignersRegistrationRetriever; + +/// Dumb `SignersRegistrationRetriever` implementation for testing +pub struct DumbSignersRegistrationRetriever { + epoch_settings: RwLock>, +} + +impl Default for DumbSignersRegistrationRetriever { + fn default() -> Self { + Self { + epoch_settings: RwLock::new(Some(RegisteredSigners::dummy())), + } + } +} + +#[async_trait::async_trait] +impl SignersRegistrationRetriever for DumbSignersRegistrationRetriever { + async fn retrieve_all_signer_registrations(&self) -> StdResult> { + let epoch_settings = self.epoch_settings.read().await.clone(); + + Ok(epoch_settings) + } +} diff --git a/mithril-signer/src/services/signer_registration/retriever/http.rs b/mithril-signer/src/services/signer_registration/retriever/http.rs new file mode 100644 index 00000000000..8c3d4150ed8 --- /dev/null +++ b/mithril-signer/src/services/signer_registration/retriever/http.rs @@ -0,0 +1,15 @@ +use mithril_aggregator_client::{AggregatorHttpClient, query::GetEpochSettingsQuery}; +use mithril_common::{StdResult, messages::TryFromMessageAdapter}; + +use crate::services::SignersRegistrationRetriever; +use crate::{FromEpochSettingsAdapter, RegisteredSigners}; + +#[async_trait::async_trait] +impl SignersRegistrationRetriever for AggregatorHttpClient { + async fn retrieve_all_signer_registrations(&self) -> StdResult> { + let message = self.send(GetEpochSettingsQuery::current()).await?; + let epoch_settings = FromEpochSettingsAdapter::try_adapt(message)?; + + Ok(Some(epoch_settings)) + } +} diff --git a/mithril-signer/src/services/signer_registration/retriever/interface.rs b/mithril-signer/src/services/signer_registration/retriever/interface.rs new file mode 100644 index 00000000000..bcd26140156 --- /dev/null +++ b/mithril-signer/src/services/signer_registration/retriever/interface.rs @@ -0,0 +1,11 @@ +use mithril_common::StdResult; + +use crate::RegisteredSigners; + +/// Service responsible for retrieving the signer's registration from the mithril network +#[cfg_attr(test, mockall::automock)] +#[async_trait::async_trait] +pub trait SignersRegistrationRetriever: Sync + Send { + /// Retrieves signer's registration from the mithril network + async fn retrieve_all_signer_registrations(&self) -> StdResult>; +} diff --git a/mithril-signer/src/services/signer_registration/retriever/mod.rs b/mithril-signer/src/services/signer_registration/retriever/mod.rs new file mode 100644 index 00000000000..195d1398ff8 --- /dev/null +++ b/mithril-signer/src/services/signer_registration/retriever/mod.rs @@ -0,0 +1,8 @@ +#[cfg(test)] +mod dumb; +mod http; +mod interface; + +#[cfg(test)] +pub use dumb::*; +pub use interface::*; diff --git a/mithril-signer/src/services/signers_registration_retriever.rs b/mithril-signer/src/services/signers_registration_retriever.rs deleted file mode 100644 index 872f41097ad..00000000000 --- a/mithril-signer/src/services/signers_registration_retriever.rs +++ /dev/null @@ -1,56 +0,0 @@ -use async_trait::async_trait; - -use mithril_aggregator_client::AggregatorHttpClient; -use mithril_aggregator_client::query::GetEpochSettingsQuery; -use mithril_common::{StdResult, messages::TryFromMessageAdapter}; - -use crate::entities::RegisteredSigners; -use crate::message_adapters::FromEpochSettingsAdapter; - -/// Service responsible for retrieving the signer's registration from the mithril network -#[cfg_attr(test, mockall::automock)] -#[async_trait] -pub trait SignersRegistrationRetriever: Sync + Send { - /// Retrieves signer's registration from the mithril network - async fn retrieve_all_signer_registrations(&self) -> StdResult>; -} - -#[async_trait] -impl SignersRegistrationRetriever for AggregatorHttpClient { - async fn retrieve_all_signer_registrations(&self) -> StdResult> { - let message = self.send(GetEpochSettingsQuery::current()).await?; - let epoch_settings = FromEpochSettingsAdapter::try_adapt(message)?; - - Ok(Some(epoch_settings)) - } -} - -#[cfg(test)] -pub(crate) mod dumb { - use mithril_common::test::double::Dummy; - use tokio::sync::RwLock; - - use super::*; - - /// Dumb `SignersRegistrationRetriever` implementation for testing - pub struct DumbSignersRegistrationRetriever { - epoch_settings: RwLock>, - } - - impl Default for DumbSignersRegistrationRetriever { - fn default() -> Self { - Self { - epoch_settings: RwLock::new(Some(RegisteredSigners::dummy())), - } - } - } - - #[async_trait] - impl SignersRegistrationRetriever for DumbSignersRegistrationRetriever { - async fn retrieve_all_signer_registrations(&self) -> StdResult> { - let epoch_settings = self.epoch_settings.read().await.clone(); - - Ok(epoch_settings) - } - } -}