Skip to content

Commit 7584085

Browse files
committed
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
1 parent 74d2982 commit 7584085

File tree

11 files changed

+130
-70
lines changed

11 files changed

+130
-70
lines changed

mithril-signer/src/dependency_injection/builder.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ impl<'a> DependenciesBuilder<'a> {
513513

514514
let services = SignerDependencyContainer {
515515
ticker_service,
516-
certificate_handler: aggregator_client,
516+
certificate_handler: aggregator_client.clone(),
517517
chain_observer,
518518
digester,
519519
single_signer,
@@ -529,6 +529,7 @@ impl<'a> DependenciesBuilder<'a> {
529529
upkeep_service,
530530
epoch_service,
531531
certifier,
532+
signer_registration_publisher: aggregator_client,
532533
kes_signer,
533534
network_configuration_service,
534535
};

mithril-signer/src/dependency_injection/containers.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ use mithril_ticker::TickerService;
1616

1717
use crate::MetricsService;
1818
use crate::services::{
19-
AggregatorClient, CertifierService, EpochService, SingleSigner, UpkeepService,
19+
AggregatorClient, CertifierService, EpochService, SignerRegistrationPublisher, SingleSigner,
20+
UpkeepService,
2021
};
2122
use crate::store::ProtocolInitializerStorer;
2223

@@ -85,6 +86,9 @@ pub struct SignerDependencyContainer {
8586
/// Certifier service
8687
pub certifier: Arc<dyn CertifierService>,
8788

89+
/// Signer registration publisher
90+
pub signer_registration_publisher: Arc<dyn SignerRegistrationPublisher>,
91+
8892
/// Kes signer service
8993
pub kes_signer: Option<Arc<dyn KesSigner>>,
9094

mithril-signer/src/runtime/runner.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ impl Runner for SignerRunner {
233233
kes_period,
234234
);
235235
self.services
236-
.certificate_handler
236+
.signer_registration_publisher
237237
.register_signer(epoch_offset_to_recording_epoch, &signer)
238238
.await?;
239239

@@ -417,6 +417,7 @@ mod tests {
417417
CardanoTransactionsImporter, DumbAggregatorClient, MithrilEpochService,
418418
MithrilSingleSigner, MockTransactionStore, MockUpkeepService, SignaturePublisherNoop,
419419
SignerCertifierService, SignerSignableSeedBuilder, SignerSignedEntityConfigProvider,
420+
SpySignerRegistrationPublisher,
420421
};
421422
use crate::test_tools::TestLogger;
422423

@@ -585,6 +586,7 @@ mod tests {
585586
upkeep_service,
586587
epoch_service,
587588
certifier,
589+
signer_registration_publisher: Arc::new(SpySignerRegistrationPublisher::default()),
588590
kes_signer,
589591
network_configuration_service,
590592
}
@@ -659,8 +661,8 @@ mod tests {
659661
async fn test_register_signer_to_aggregator() {
660662
let mut services = init_services().await;
661663
let fixture = MithrilFixtureBuilder::default().with_signers(5).build();
662-
let certificate_handler = Arc::new(DumbAggregatorClient::default());
663-
services.certificate_handler = certificate_handler.clone();
664+
let registration_publisher_spy = Arc::new(SpySignerRegistrationPublisher::default());
665+
services.signer_registration_publisher = registration_publisher_spy.clone();
664666
let protocol_initializer_store = services.protocol_initializer_store.clone();
665667
let current_epoch = services.ticker_service.get_current_epoch().await.unwrap();
666668

@@ -699,7 +701,7 @@ mod tests {
699701
.expect("registering a signer to the aggregator should not fail");
700702

701703
let last_registered_signer_first_registration =
702-
certificate_handler.get_last_registered_signer().await.unwrap();
704+
registration_publisher_spy.get_last_registered_signer().await.unwrap();
703705
let maybe_protocol_initializer_first_registration = protocol_initializer_store
704706
.get_protocol_initializer(current_epoch.offset_to_recording_epoch())
705707
.await
@@ -709,7 +711,8 @@ mod tests {
709711
"A protocol initializer should have been registered at the 'Recording' epoch"
710712
);
711713

712-
let total_registered_signers = certificate_handler.get_total_registered_signers().await;
714+
let total_registered_signers =
715+
registration_publisher_spy.get_total_registered_signers().await;
713716
assert_eq!(1, total_registered_signers);
714717

715718
runner
@@ -718,7 +721,7 @@ mod tests {
718721
.expect("registering a signer to the aggregator should not fail");
719722

720723
let last_registered_signer_second_registration =
721-
certificate_handler.get_last_registered_signer().await.unwrap();
724+
registration_publisher_spy.get_last_registered_signer().await.unwrap();
722725
let maybe_protocol_initializer_second_registration = protocol_initializer_store
723726
.get_protocol_initializer(current_epoch.offset_to_recording_epoch())
724727
.await
@@ -733,7 +736,8 @@ mod tests {
733736
"The signer registration should be the same and should have been registered twice"
734737
);
735738

736-
let total_registered_signers = certificate_handler.get_total_registered_signers().await;
739+
let total_registered_signers =
740+
registration_publisher_spy.get_total_registered_signers().await;
737741
assert_eq!(1, total_registered_signers);
738742
}
739743

mithril-signer/src/services/aggregator_client.rs

Lines changed: 3 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
use async_trait::async_trait;
22

33
use mithril_aggregator_client::AggregatorHttpClient;
4-
use mithril_aggregator_client::query::{
5-
GetAggregatorFeaturesQuery, GetEpochSettingsQuery, PostRegisterSignerQuery,
6-
};
4+
use mithril_aggregator_client::query::{GetAggregatorFeaturesQuery, GetEpochSettingsQuery};
75
use mithril_common::{
86
StdResult,
9-
entities::{Epoch, Signer},
10-
messages::{AggregatorFeaturesMessage, TryFromMessageAdapter, TryToMessageAdapter},
7+
messages::{AggregatorFeaturesMessage, TryFromMessageAdapter},
118
};
129

1310
use crate::entities::SignerEpochSettings;
14-
use crate::message_adapters::{FromEpochSettingsAdapter, ToRegisterSignerMessageAdapter};
11+
use crate::message_adapters::FromEpochSettingsAdapter;
1512

1613
/// Trait for mocking and testing a `AggregatorClient`
1714
#[cfg_attr(test, mockall::automock)]
@@ -20,9 +17,6 @@ pub trait AggregatorClient: Sync + Send {
2017
/// Retrieves epoch settings from the aggregator
2118
async fn retrieve_epoch_settings(&self) -> StdResult<Option<SignerEpochSettings>>;
2219

23-
/// Registers signer with the aggregator.
24-
async fn register_signer(&self, epoch: Epoch, signer: &Signer) -> StdResult<()>;
25-
2620
/// Retrieves aggregator features message from the aggregator
2721
async fn retrieve_aggregator_features(&self) -> StdResult<AggregatorFeaturesMessage>;
2822
}
@@ -36,16 +30,6 @@ impl AggregatorClient for AggregatorHttpClient {
3630
Ok(Some(epoch_settings))
3731
}
3832

39-
async fn register_signer(&self, epoch: Epoch, signer: &Signer) -> StdResult<()> {
40-
let register_signer_message =
41-
ToRegisterSignerMessageAdapter::try_adapt((epoch, signer.to_owned()))?;
42-
43-
self.send(PostRegisterSignerQuery::new(register_signer_message))
44-
.await?;
45-
46-
Ok(())
47-
}
48-
4933
async fn retrieve_aggregator_features(&self) -> StdResult<AggregatorFeaturesMessage> {
5034
let aggregator_features = self.send(GetAggregatorFeaturesQuery::current()).await?;
5135
Ok(aggregator_features)
@@ -64,30 +48,14 @@ pub(crate) mod dumb {
6448
/// It is driven by a Tester that controls the data it can return, and it can return its internal state for testing.
6549
pub struct DumbAggregatorClient {
6650
epoch_settings: RwLock<Option<SignerEpochSettings>>,
67-
last_registered_signer: RwLock<Option<Signer>>,
6851
aggregator_features: RwLock<AggregatorFeaturesMessage>,
69-
total_registered_signers: RwLock<u32>,
70-
}
71-
72-
impl DumbAggregatorClient {
73-
/// Return the last signer that called with the `register` method.
74-
pub async fn get_last_registered_signer(&self) -> Option<Signer> {
75-
self.last_registered_signer.read().await.clone()
76-
}
77-
78-
/// Return the total number of signers that called with the `register` method.
79-
pub async fn get_total_registered_signers(&self) -> u32 {
80-
*self.total_registered_signers.read().await
81-
}
8252
}
8353

8454
impl Default for DumbAggregatorClient {
8555
fn default() -> Self {
8656
Self {
8757
epoch_settings: RwLock::new(Some(SignerEpochSettings::dummy())),
88-
last_registered_signer: RwLock::new(None),
8958
aggregator_features: RwLock::new(AggregatorFeaturesMessage::dummy()),
90-
total_registered_signers: RwLock::new(0),
9159
}
9260
}
9361
}
@@ -100,18 +68,6 @@ pub(crate) mod dumb {
10068
Ok(epoch_settings)
10169
}
10270

103-
/// Registers signer with the aggregator
104-
async fn register_signer(&self, _epoch: Epoch, signer: &Signer) -> StdResult<()> {
105-
let mut last_registered_signer = self.last_registered_signer.write().await;
106-
let signer = signer.clone();
107-
*last_registered_signer = Some(signer);
108-
109-
let mut total_registered_signers = self.total_registered_signers.write().await;
110-
*total_registered_signers += 1;
111-
112-
Ok(())
113-
}
114-
11571
async fn retrieve_aggregator_features(&self) -> StdResult<AggregatorFeaturesMessage> {
11672
let aggregator_features = self.aggregator_features.read().await;
11773
Ok(aggregator_features.clone())

mithril-signer/src/services/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ mod certifier;
1515
mod epoch_service;
1616
mod signable_builder;
1717
mod signature_publisher;
18+
mod signer_registration;
1819
mod single_signer;
1920
mod upkeep_service;
2021

@@ -26,5 +27,6 @@ pub use certifier::*;
2627
pub use epoch_service::*;
2728
pub use signable_builder::*;
2829
pub use signature_publisher::*;
30+
pub use signer_registration::*;
2931
pub use single_signer::*;
3032
pub use upkeep_service::*;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use anyhow::Context;
2+
3+
use mithril_aggregator_client::{AggregatorHttpClient, query::PostRegisterSignerQuery};
4+
use mithril_common::{
5+
StdResult,
6+
entities::{Epoch, Signer},
7+
messages::TryToMessageAdapter,
8+
};
9+
10+
use crate::ToRegisterSignerMessageAdapter;
11+
use crate::services::SignerRegistrationPublisher;
12+
13+
#[async_trait::async_trait]
14+
impl SignerRegistrationPublisher for AggregatorHttpClient {
15+
async fn register_signer(&self, epoch: Epoch, signer: &Signer) -> StdResult<()> {
16+
let register_signer_message =
17+
ToRegisterSignerMessageAdapter::try_adapt((epoch, signer.to_owned()))
18+
.with_context(|| "Failed to adapt message to register signer message")?;
19+
20+
self.send(PostRegisterSignerQuery::new(register_signer_message))
21+
.await?;
22+
23+
Ok(())
24+
}
25+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use mithril_common::StdResult;
2+
use mithril_common::entities::{Epoch, Signer};
3+
4+
/// Publishes a signer registration to a third party.
5+
#[cfg_attr(test, mockall::automock)]
6+
#[async_trait::async_trait]
7+
pub trait SignerRegistrationPublisher: Send + Sync {
8+
/// Registers signer with the aggregator.
9+
async fn register_signer(&self, epoch: Epoch, signer: &Signer) -> StdResult<()>;
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
mod http;
2+
mod interface;
3+
#[cfg(test)]
4+
mod spy;
5+
6+
pub use interface::*;
7+
#[cfg(test)]
8+
pub use spy::*;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use tokio::sync::RwLock;
2+
3+
use mithril_common::StdResult;
4+
use mithril_common::entities::{Epoch, Signer};
5+
6+
use crate::services::SignerRegistrationPublisher;
7+
8+
/// A spy implementation of the `SignerRegistrationPublisher` trait for testing
9+
pub struct SpySignerRegistrationPublisher {
10+
last_registered_signer: RwLock<Option<Signer>>,
11+
total_registered_signers: RwLock<u32>,
12+
}
13+
14+
impl SpySignerRegistrationPublisher {
15+
/// Return the last signer that called with the `register` method.
16+
pub async fn get_last_registered_signer(&self) -> Option<Signer> {
17+
self.last_registered_signer.read().await.clone()
18+
}
19+
20+
/// Return the total number of signers that called with the `register` method.
21+
pub async fn get_total_registered_signers(&self) -> u32 {
22+
*self.total_registered_signers.read().await
23+
}
24+
}
25+
26+
impl Default for SpySignerRegistrationPublisher {
27+
fn default() -> Self {
28+
Self {
29+
last_registered_signer: RwLock::new(None),
30+
total_registered_signers: RwLock::new(0),
31+
}
32+
}
33+
}
34+
35+
#[async_trait::async_trait]
36+
impl SignerRegistrationPublisher for SpySignerRegistrationPublisher {
37+
async fn register_signer(&self, _epoch: Epoch, signer: &Signer) -> StdResult<()> {
38+
let mut last_registered_signer = self.last_registered_signer.write().await;
39+
let signer = signer.clone();
40+
*last_registered_signer = Some(signer);
41+
42+
let mut total_registered_signers = self.total_registered_signers.write().await;
43+
*total_registered_signers += 1;
44+
45+
Ok(())
46+
}
47+
}

mithril-signer/tests/test_extensions/certificate_handler.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use mithril_common::{
1414
};
1515
use mithril_ticker::{MithrilTickerService, TickerService};
1616

17-
use mithril_signer::services::SignaturePublisher;
17+
use mithril_signer::services::{SignaturePublisher, SignerRegistrationPublisher};
1818
use mithril_signer::{entities::SignerEpochSettings, services::AggregatorClient};
1919

2020
pub struct FakeAggregator {
@@ -93,6 +93,18 @@ impl SignaturePublisher for FakeAggregator {
9393
}
9494
}
9595

96+
#[async_trait]
97+
impl SignerRegistrationPublisher for FakeAggregator {
98+
async fn register_signer(&self, epoch: Epoch, signer: &Signer) -> StdResult<()> {
99+
let mut store = self.registered_signers.write().await;
100+
let mut signers = store.get(&epoch).cloned().unwrap_or_default();
101+
signers.push(signer.clone());
102+
let _ = store.insert(epoch, signers);
103+
104+
Ok(())
105+
}
106+
}
107+
96108
#[async_trait]
97109
impl AggregatorClient for FakeAggregator {
98110
async fn retrieve_epoch_settings(&self) -> StdResult<Option<SignerEpochSettings>> {
@@ -112,16 +124,6 @@ impl AggregatorClient for FakeAggregator {
112124
}
113125
}
114126

115-
/// Registers signer with the aggregator
116-
async fn register_signer(&self, epoch: Epoch, signer: &Signer) -> StdResult<()> {
117-
let mut store = self.registered_signers.write().await;
118-
let mut signers = store.get(&epoch).cloned().unwrap_or_default();
119-
signers.push(signer.clone());
120-
let _ = store.insert(epoch, signers);
121-
122-
Ok(())
123-
}
124-
125127
async fn retrieve_aggregator_features(&self) -> StdResult<AggregatorFeaturesMessage> {
126128
let signed_entity_config = self.signed_entity_config.read().await;
127129

0 commit comments

Comments
 (0)