Skip to content

Commit 254b9b1

Browse files
committed
Handle multiple signed entity types in aggregator runtime
1 parent e2fe5e7 commit 254b9b1

File tree

4 files changed

+75
-87
lines changed

4 files changed

+75
-87
lines changed

mithril-aggregator/src/certifier_service.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,18 @@ impl CertifierService for MithrilCertifierService {
227227
debug!("CertifierService::create_open_message(signed_entity_type: {signed_entity_type:?}, protocol_message: {protocol_message:?})");
228228
let current_epoch = self.current_epoch.read().await;
229229

230-
let open_message = self
230+
let open_message = match self
231231
.open_message_repository
232-
.create_open_message(*current_epoch, signed_entity_type, protocol_message)
233-
.await?;
232+
.get_open_message(signed_entity_type)
233+
.await?
234+
{
235+
Some(open_message) => open_message,
236+
None => {
237+
self.open_message_repository
238+
.create_open_message(*current_epoch, signed_entity_type, protocol_message)
239+
.await?
240+
}
241+
};
234242
info!("CertifierService::create_open_message: created open message for {signed_entity_type:?}");
235243
debug!(
236244
"CertifierService::create_open_message: created open message ID='{}'",

mithril-aggregator/src/entities/open_message.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::database::provider::{OpenMessageRecord, OpenMessageWithSingleSignatur
1010
/// An open message is a message open for signatures. Every signer may send a
1111
/// single signature for this message from which a multi signature will be
1212
/// generated if possible.
13-
#[derive(Debug, Clone, PartialEq)]
13+
#[derive(Debug, Clone, PartialEq, Eq)]
1414
pub struct OpenMessage {
1515
/// Epoch
1616
pub epoch: Epoch,

mithril-aggregator/src/runtime/runner.rs

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,10 @@ pub trait AggregatorRunnerTrait: Sync + Send {
5555
/// Return the current beacon from the chain
5656
async fn get_beacon_from_chain(&self) -> Result<Beacon, Box<dyn StdError + Sync + Send>>;
5757

58-
/// Check if a certificate already have been issued for a given beacon.
59-
async fn does_certificate_exist_for_beacon(
58+
/// Retrieves the ucrrent non certified open message.
59+
async fn get_current_non_certified_open_message(
6060
&self,
61-
beacon: &Beacon,
62-
) -> Result<bool, Box<dyn StdError + Sync + Send>>;
61+
) -> Result<Option<OpenMessage>, Box<dyn StdError + Sync + Send>>;
6362

6463
/// Check if a certificate chain is valid.
6564
async fn is_certificate_chain_valid(&self) -> Result<bool, Box<dyn StdError + Sync + Send>>;
@@ -176,18 +175,32 @@ impl AggregatorRunnerTrait for AggregatorRunner {
176175
Ok(beacon)
177176
}
178177

179-
async fn does_certificate_exist_for_beacon(
178+
async fn get_current_non_certified_open_message(
180179
&self,
181-
beacon: &Beacon,
182-
) -> Result<bool, Box<dyn StdError + Sync + Send>> {
183-
debug!("RUNNER: does_certificate_exist_for_beacon");
184-
let certificate_exist = self
185-
.dependencies
186-
.certificate_store
187-
.get_from_beacon(beacon)
188-
.await?
189-
.is_some();
190-
Ok(certificate_exist)
180+
) -> Result<Option<OpenMessage>, Box<dyn StdError + Sync + Send>> {
181+
let signed_entity_types = vec![
182+
SignedEntityType::MithrilStakeDistribution(
183+
self.dependencies.ticker_service.get_current_epoch().await?,
184+
),
185+
SignedEntityType::CardanoImmutableFilesFull(
186+
self.dependencies
187+
.ticker_service
188+
.get_current_immutable_beacon()
189+
.await?,
190+
),
191+
];
192+
193+
for signed_entity_type in signed_entity_types {
194+
let protocol_message = self.compute_protocol_message(&signed_entity_type).await?;
195+
let open_message = self
196+
.create_open_message(&signed_entity_type, &protocol_message)
197+
.await?;
198+
if !open_message.is_certified {
199+
return Ok(Some(open_message));
200+
}
201+
}
202+
203+
Ok(None)
191204
}
192205

193206
async fn is_certificate_chain_valid(&self) -> Result<bool, Box<dyn StdError + Sync + Send>> {
@@ -547,27 +560,6 @@ pub mod tests {
547560
assert_eq!(expected_beacon, res.unwrap());
548561
}
549562

550-
#[tokio::test]
551-
async fn test_does_certificate_exist_for_beacon() {
552-
let dependencies = initialize_dependencies().await;
553-
let certificate_store = dependencies.certificate_store.clone();
554-
let runner = AggregatorRunner::new(Arc::new(dependencies));
555-
556-
let beacon = fake_data::beacon();
557-
let mut certificate = fake_data::genesis_certificate("certificate_hash".to_string());
558-
certificate.beacon = beacon.clone();
559-
560-
assert!(!runner
561-
.does_certificate_exist_for_beacon(&beacon)
562-
.await
563-
.unwrap());
564-
certificate_store.save(certificate).await.unwrap();
565-
assert!(runner
566-
.does_certificate_exist_for_beacon(&beacon)
567-
.await
568-
.unwrap());
569-
}
570-
571563
#[tokio::test]
572564
async fn test_update_beacon() {
573565
let deps = initialize_dependencies().await;

mithril-aggregator/src/runtime/state_machine.rs

Lines changed: 35 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
use crate::runtime::{AggregatorRunnerTrait, RuntimeError};
1+
use crate::{
2+
entities::OpenMessage,
3+
runtime::{AggregatorRunnerTrait, RuntimeError},
4+
};
25

3-
use mithril_common::entities::{Beacon, ProtocolMessage, SignedEntityType};
6+
use mithril_common::entities::Beacon;
47
use slog_scope::{crit, info, trace, warn};
58
use std::fmt::Display;
69
use std::sync::Arc;
@@ -19,8 +22,7 @@ pub struct ReadyState {
1922
#[derive(Clone, Debug, PartialEq)]
2023
pub struct SigningState {
2124
current_beacon: Beacon,
22-
signed_entity_type: SignedEntityType,
23-
protocol_message: ProtocolMessage,
25+
open_message: OpenMessage,
2426
}
2527

2628
#[derive(Clone, Debug, PartialEq)]
@@ -179,11 +181,18 @@ impl AggregatorRuntime {
179181
self.state = AggregatorState::Idle(IdleState {
180182
current_beacon: Some(state.current_beacon),
181183
});
182-
} else if self
184+
} else if let Some(open_message) = self
183185
.runner
184-
.does_certificate_exist_for_beacon(&state.current_beacon)
186+
.get_current_non_certified_open_message()
185187
.await?
186-
{
188+
{
189+
// transition READY > SIGNING
190+
info!("→ transitioning to SIGNING");
191+
let new_state = self
192+
.transition_from_ready_to_signing(state.current_beacon, open_message)
193+
.await?;
194+
self.state = AggregatorState::Signing(new_state);
195+
}else{
187196
// READY > READY
188197
info!(
189198
" ⋅ a certificate already exists for this beacon, waiting…";
@@ -192,13 +201,6 @@ impl AggregatorRuntime {
192201
self.state = AggregatorState::Ready(ReadyState {
193202
current_beacon: chain_beacon,
194203
});
195-
} else {
196-
// transition READY > SIGNING
197-
info!("→ transitioning to SIGNING");
198-
let new_state = self
199-
.transition_from_ready_to_signing(state.current_beacon)
200-
.await?;
201-
self.state = AggregatorState::Signing(new_state);
202204
}
203205
}
204206
AggregatorState::Signing(state) => {
@@ -274,7 +276,7 @@ impl AggregatorRuntime {
274276
trace!("launching transition from SIGNING to IDLE state");
275277
let certificate = self
276278
.runner
277-
.create_certificate(&state.signed_entity_type)
279+
.create_certificate(&state.open_message.signed_entity_type)
278280
.await?
279281
.ok_or_else(|| RuntimeError::KeepState {
280282
message: "not enough signature yet to create a certificate, waiting…".to_string(),
@@ -283,7 +285,7 @@ impl AggregatorRuntime {
283285

284286
self.runner.drop_pending_certificate().await?;
285287
self.runner
286-
.create_artifact(&state.signed_entity_type, &certificate)
288+
.create_artifact(&state.open_message.signed_entity_type, &certificate)
287289
.await?;
288290

289291
Ok(IdleState {
@@ -310,33 +312,24 @@ impl AggregatorRuntime {
310312
async fn transition_from_ready_to_signing(
311313
&mut self,
312314
new_beacon: Beacon,
315+
open_message: OpenMessage,
313316
) -> Result<SigningState, RuntimeError> {
314317
trace!("launching transition from READY to SIGNING state");
315-
// TODO: Temporary, we need to compute the signed entity type for other types than Cardano immutable files
316-
let signed_entity_type = SignedEntityType::CardanoImmutableFilesFull(new_beacon.clone());
317318
self.runner.update_beacon(&new_beacon).await?;
318319

319-
let protocol_message = self
320-
.runner
321-
.compute_protocol_message(&signed_entity_type)
322-
.await?;
323-
self.runner
324-
.create_open_message(&signed_entity_type, &protocol_message)
325-
.await?;
326320
let certificate_pending = self
327321
.runner
328322
.create_new_pending_certificate_from_multisigner(
329323
new_beacon.clone(),
330-
&signed_entity_type,
324+
&open_message.signed_entity_type,
331325
)
332326
.await?;
333327
self.runner
334328
.save_pending_certificate(certificate_pending.clone())
335329
.await?;
336330
let state = SigningState {
337331
current_beacon: new_beacon,
338-
signed_entity_type,
339-
protocol_message,
332+
open_message,
340333
};
341334

342335
Ok(state)
@@ -522,7 +515,7 @@ mod tests {
522515
}
523516

524517
#[tokio::test]
525-
pub async fn ready_certificate_already_exist_for_beacon() {
518+
pub async fn ready_open_message_not_exist() {
526519
let mut runner = MockAggregatorRunner::new();
527520
let beacon = fake_data::beacon();
528521
let next_beacon = Beacon {
@@ -535,9 +528,9 @@ mod tests {
535528
.once()
536529
.returning(move || Ok(next_beacon.clone()));
537530
runner
538-
.expect_does_certificate_exist_for_beacon()
531+
.expect_get_current_non_certified_open_message()
539532
.once()
540-
.returning(|_| Ok(true));
533+
.returning(|| Ok(None));
541534
let mut runtime = init_runtime(
542535
Some(AggregatorState::Ready(ReadyState {
543536
current_beacon: beacon.clone(),
@@ -564,18 +557,20 @@ mod tests {
564557
.once()
565558
.returning(|| Ok(fake_data::beacon()));
566559
runner
567-
.expect_does_certificate_exist_for_beacon()
560+
.expect_get_current_non_certified_open_message()
568561
.once()
569-
.returning(|_| Ok(false));
562+
.returning(|| {
563+
let open_message = OpenMessage {
564+
is_certified: false,
565+
..OpenMessage::dummy()
566+
};
567+
Ok(Some(open_message))
568+
});
570569
runner
571570
.expect_update_beacon()
572571
.with(predicate::eq(fake_data::beacon()))
573572
.once()
574573
.returning(|_| Ok(()));
575-
runner
576-
.expect_compute_protocol_message()
577-
.once()
578-
.returning(|_| Ok(ProtocolMessage::new()));
579574
runner
580575
.expect_create_new_pending_certificate_from_multisigner()
581576
.once()
@@ -584,10 +579,6 @@ mod tests {
584579
.expect_save_pending_certificate()
585580
.once()
586581
.returning(|_| Ok(()));
587-
runner
588-
.expect_create_open_message()
589-
.once()
590-
.returning(|_, _| Ok(OpenMessage::dummy()));
591582

592583
let mut runtime = init_runtime(
593584
Some(AggregatorState::Ready(ReadyState {
@@ -622,8 +613,7 @@ mod tests {
622613

623614
beacon
624615
},
625-
signed_entity_type: SignedEntityType::dummy(),
626-
protocol_message: ProtocolMessage::default(),
616+
open_message: OpenMessage::dummy(),
627617
};
628618
let mut runtime = init_runtime(Some(AggregatorState::Signing(state)), runner).await;
629619
runtime.cycle().await.unwrap();
@@ -644,8 +634,7 @@ mod tests {
644634
.returning(|_| Ok(None));
645635
let state = SigningState {
646636
current_beacon: fake_data::beacon(),
647-
signed_entity_type: SignedEntityType::dummy(),
648-
protocol_message: ProtocolMessage::default(),
637+
open_message: OpenMessage::dummy(),
649638
};
650639
let mut runtime = init_runtime(Some(AggregatorState::Signing(state)), runner).await;
651640
runtime
@@ -677,8 +666,7 @@ mod tests {
677666

678667
let state = SigningState {
679668
current_beacon: fake_data::beacon(),
680-
signed_entity_type: SignedEntityType::dummy(),
681-
protocol_message: ProtocolMessage::default(),
669+
open_message: OpenMessage::dummy(),
682670
};
683671
let mut runtime = init_runtime(Some(AggregatorState::Signing(state)), runner).await;
684672
runtime.cycle().await.unwrap();

0 commit comments

Comments
 (0)