Skip to content

Commit

Permalink
fix(aggregator): avoid epoch service failure when a aggregator start …
Browse files Browse the repository at this point in the history
…for the first time

Epoch settings for the first "working" epoch were not available at start
since they use the 'signer retrieval offset' of -1 and we handled
discrepencies only starting the current epoch.

Also `handle_discrepancies_at_startup` is modified to register data over
four epochs instead of 3 to take in account the case when between its
call and epoch service 'inform epoch' there's an epoch change.
  • Loading branch information
Alenar committed Feb 12, 2025
1 parent 2360c25 commit 2321d95
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ impl DependenciesBuilder {
message: "cannot build aggregator runner: no epoch returned.".to_string(),
error: None,
})?;
let retrieval_epoch = current_epoch
.offset_to_signer_retrieval_epoch()
.map_err(|e| DependenciesBuilderError::Initialization {
message: format!("cannot create aggregator runner: failed to offset current epoch '{current_epoch}' to signer retrieval epoch."),
error: Some(e.into()),
})?;

{
// Temporary fix, should be removed
Expand All @@ -136,11 +142,11 @@ impl DependenciesBuilder {
let epoch_settings_configuration = self.configuration.get_epoch_settings_configuration();
debug!(
logger,
"Handle discrepancies at startup of epoch settings store, will record epoch settings from the configuration for epoch {current_epoch}";
"Handle discrepancies at startup of epoch settings store, will record epoch settings from the configuration for epoch {retrieval_epoch}";
"epoch_settings_configuration" => ?epoch_settings_configuration,
);
epoch_settings_store
.handle_discrepancies_at_startup(current_epoch, &epoch_settings_configuration)
.handle_discrepancies_at_startup(retrieval_epoch, &epoch_settings_configuration)
.await
.map_err(|e| DependenciesBuilderError::Initialization {
message: "can not create aggregator runner".to_string(),
Expand Down
14 changes: 11 additions & 3 deletions mithril-aggregator/src/store/epoch_settings_storer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,20 @@ pub trait EpochSettingsStorer: EpochPruningTask + Sync + Send {
async fn get_epoch_settings(&self, epoch: Epoch) -> StdResult<Option<AggregatorEpochSettings>>;

/// Handle discrepancies at startup in the epoch settings store.
///
/// In case an aggregator has been launched after some epochs of not being up or at initial startup,
/// the discrepancies in the epoch settings store needs to be fixed.
/// The epoch settings needs to be recorded for the working epoch and the next 2 epochs.
///
/// The epoch settings needs to be recorded for the working epoch and the next 3 epochs.
/// We need data over four epochs because the epoch service use epoch settings over a window of
/// three epochs, and there may be an epoch change between this `handle_discrepancies_at_startup`
/// call and the epoch service call.
async fn handle_discrepancies_at_startup(
&self,
current_epoch: Epoch,
epoch_settings_configuration: &AggregatorEpochSettings,
) -> StdResult<()> {
for epoch_offset in 0..=2 {
for epoch_offset in 0..=3 {
let epoch = current_epoch + epoch_offset;
if self.get_epoch_settings(epoch).await?.is_none() {
self.save_epoch_settings(epoch, epoch_settings_configuration.clone())
Expand Down Expand Up @@ -158,7 +163,7 @@ mod tests {
}

#[tokio::test]
async fn test_handle_discrepancies_at_startup_should_complete_at_least_two_epochs() {
async fn test_handle_discrepancies_at_startup_should_complete_at_least_four_epochs() {
let epoch_settings = AggregatorEpochSettings::dummy();
let epoch_settings_new = AggregatorEpochSettings {
protocol_parameters: ProtocolParameters {
Expand Down Expand Up @@ -191,6 +196,9 @@ mod tests {
assert_eq!(Some(epoch_settings_new.clone()), epoch_settings_stored);

let epoch_settings_stored = store.get_epoch_settings(epoch + 3).await.unwrap();
assert_eq!(Some(epoch_settings_new.clone()), epoch_settings_stored);

let epoch_settings_stored = store.get_epoch_settings(epoch + 4).await.unwrap();
assert!(epoch_settings_stored.is_none());
}
}

0 comments on commit 2321d95

Please sign in to comment.