From 70043beecdf55689598d0f70a86f1d180d8fa096 Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Wed, 6 Nov 2024 16:17:27 +0100 Subject: [PATCH 1/7] feat: store the current Cardano era in the Epoch service --- .../src/dependency_injection/builder.rs | 2 + .../src/services/epoch_service.rs | 72 ++++++++++++++++--- .../src/chain_observer/fake_observer.rs | 33 ++++++++- 3 files changed, 97 insertions(+), 10 deletions(-) diff --git a/mithril-aggregator/src/dependency_injection/builder.rs b/mithril-aggregator/src/dependency_injection/builder.rs index 721522e761a..500752c1c73 100644 --- a/mithril-aggregator/src/dependency_injection/builder.rs +++ b/mithril-aggregator/src/dependency_injection/builder.rs @@ -1259,6 +1259,7 @@ impl DependenciesBuilder { async fn build_epoch_service(&mut self) -> Result { let verification_key_store = self.get_verification_key_store().await?; let epoch_settings_storer = self.get_epoch_settings_storer().await?; + let chain_observer = self.get_chain_observer().await?; let epoch_settings = self.get_epoch_settings_configuration()?; let network = self.configuration.get_network()?; let allowed_discriminants = self.get_allowed_signed_entity_types_discriminants()?; @@ -1267,6 +1268,7 @@ impl DependenciesBuilder { epoch_settings, epoch_settings_storer, verification_key_store, + chain_observer, network, allowed_discriminants, self.root_logger(), diff --git a/mithril-aggregator/src/services/epoch_service.rs b/mithril-aggregator/src/services/epoch_service.rs index f5c4f8d1423..46c0bcdad3a 100644 --- a/mithril-aggregator/src/services/epoch_service.rs +++ b/mithril-aggregator/src/services/epoch_service.rs @@ -1,5 +1,6 @@ -use anyhow::Context; +use anyhow::{anyhow, Context}; use async_trait::async_trait; +use mithril_common::chain_observer::ChainObserver; use slog::{debug, Logger}; use std::collections::BTreeSet; use std::sync::Arc; @@ -52,6 +53,9 @@ pub trait EpochService: Sync + Send { /// Note: must be called after `inform_epoch`. async fn precompute_epoch_data(&mut self) -> StdResult<()>; + /// Get the current Cardano era. + fn cardano_era(&self) -> StdResult; + /// Get the current epoch for which the data stored in this service are computed. fn epoch_of_current_data(&self) -> StdResult; @@ -103,6 +107,7 @@ pub trait EpochService: Sync + Send { } struct EpochData { + cardano_era: String, epoch: Epoch, current_epoch_settings: AggregatorEpochSettings, next_epoch_settings: AggregatorEpochSettings, @@ -129,6 +134,7 @@ pub struct MithrilEpochService { computed_epoch_data: Option, epoch_settings_storer: Arc, verification_key_store: Arc, + chain_observer: Arc, network: CardanoNetwork, allowed_signed_entity_discriminants: BTreeSet, logger: Logger, @@ -140,6 +146,7 @@ impl MithrilEpochService { future_epoch_settings: AggregatorEpochSettings, epoch_settings_storer: Arc, verification_key_store: Arc, + chain_observer: Arc, network: CardanoNetwork, allowed_discriminants: BTreeSet, logger: Logger, @@ -150,12 +157,23 @@ impl MithrilEpochService { computed_epoch_data: None, epoch_settings_storer, verification_key_store, + chain_observer, network, allowed_signed_entity_discriminants: allowed_discriminants, logger: logger.new_with_component_name::(), } } + async fn get_cardano_era(&self) -> StdResult { + let cardano_era = self + .chain_observer + .get_current_era() + .await? + .ok_or_else(|| anyhow!("No Cardano era returned by the chain observer".to_string()))?; + + Ok(cardano_era) + } + async fn get_signers_with_stake_at_epoch( &self, signer_retrieval_epoch: Epoch, @@ -222,6 +240,8 @@ impl EpochService for MithrilEpochService { async fn inform_epoch(&mut self, epoch: Epoch) -> StdResult<()> { debug!(self.logger, ">> inform_epoch(epoch: {epoch:?})"); + let cardano_era = self.get_cardano_era().await?; + let signer_retrieval_epoch = epoch.offset_to_signer_retrieval_epoch().with_context(|| { format!("EpochService could not compute signer retrieval epoch from epoch: {epoch}") @@ -261,6 +281,7 @@ impl EpochService for MithrilEpochService { }; self.epoch_data = Some(EpochData { + cardano_era, epoch, current_epoch_settings, next_epoch_settings, @@ -318,6 +339,10 @@ impl EpochService for MithrilEpochService { Ok(()) } + fn cardano_era(&self) -> StdResult { + Ok(self.unwrap_data()?.cardano_era.clone()) + } + fn epoch_of_current_data(&self) -> StdResult { Ok(self.unwrap_data()?.epoch) } @@ -406,6 +431,7 @@ pub struct FakeEpochService { #[cfg(test)] pub struct FakeEpochServiceBuilder { + pub cardano_era: String, pub epoch: Epoch, pub current_epoch_settings: AggregatorEpochSettings, pub next_epoch_settings: AggregatorEpochSettings, @@ -422,6 +448,7 @@ impl FakeEpochServiceBuilder { let signers = fake_data::signers_with_stakes(3); Self { + cardano_era: "DummyEra".to_string(), epoch, current_epoch_settings: AggregatorEpochSettings::dummy(), next_epoch_settings: AggregatorEpochSettings::dummy(), @@ -453,6 +480,7 @@ impl FakeEpochServiceBuilder { FakeEpochService { epoch_data: Some(EpochData { + cardano_era: self.cardano_era, epoch: self.epoch, current_epoch_settings: self.current_epoch_settings, next_epoch_settings: self.next_epoch_settings, @@ -572,6 +600,10 @@ impl EpochService for FakeEpochService { Ok(()) } + fn cardano_era(&self) -> StdResult { + Ok(self.unwrap_data()?.cardano_era.clone()) + } + fn epoch_of_current_data(&self) -> StdResult { Ok(self.unwrap_data()?.epoch) } @@ -651,6 +683,7 @@ impl EpochService for FakeEpochService { #[cfg(test)] mod tests { + use mithril_common::chain_observer::FakeObserver; use mithril_common::entities::{BlockNumber, CardanoTransactionsSigningConfig, PartyId}; use mithril_common::test_utils::{fake_data, MithrilFixture, MithrilFixtureBuilder}; use mithril_persistence::store::adapter::MemoryAdapter; @@ -664,6 +697,7 @@ mod tests { #[derive(Debug, Clone, PartialEq)] struct ExpectedEpochData { + cardano_era: String, epoch: Epoch, protocol_parameters: ProtocolParameters, next_protocol_parameters: ProtocolParameters, @@ -686,6 +720,7 @@ mod tests { impl ExpectedEpochData { async fn from_service(service: &MithrilEpochService) -> StdResult { Ok(Self { + cardano_era: service.cardano_era()?, epoch: service.epoch_of_current_data()?, protocol_parameters: service.current_protocol_parameters()?.clone(), next_protocol_parameters: service.next_protocol_parameters()?.clone(), @@ -739,6 +774,7 @@ mod tests { future_protocol_parameters: ProtocolParameters, network: CardanoNetwork, allowed_discriminants: BTreeSet, + cardano_era: String, current_epoch: Epoch, signers_with_stake: Vec, next_signers_with_stake: Vec, @@ -754,6 +790,7 @@ mod tests { future_protocol_parameters: epoch_fixture.protocol_parameters(), network: CardanoNetwork::TestNet(0), allowed_discriminants: BTreeSet::new(), + cardano_era: String::new(), current_epoch: epoch, signers_with_stake: epoch_fixture.signers_with_stake(), next_signers_with_stake: epoch_fixture.signers_with_stake(), @@ -772,7 +809,7 @@ mod tests { } } - fn build(self) -> MithrilEpochService { + async fn build(self) -> MithrilEpochService { let signer_retrieval_epoch = self .current_epoch .offset_to_signer_retrieval_epoch() @@ -804,6 +841,9 @@ mod tests { ])) .unwrap(), )); + let chain_observer = FakeObserver::default(); + chain_observer.set_current_era(self.cardano_era).await; + MithrilEpochService::new( AggregatorEpochSettings { protocol_parameters: self.future_protocol_parameters, @@ -811,6 +851,7 @@ mod tests { }, Arc::new(epoch_settings_storer), Arc::new(vkey_store), + Arc::new(chain_observer), self.network, self.allowed_discriminants, TestLogger::stdout(), @@ -840,10 +881,11 @@ mod tests { }, network: SignedEntityConfig::dummy().network, allowed_discriminants: SignedEntityConfig::dummy().allowed_discriminants, + cardano_era: "CardanoEra".to_string(), ..EpochServiceBuilder::new(epoch, current_epoch_fixture.clone()) }; - let mut service = builder.build(); + let mut service = builder.build().await; service .inform_epoch(epoch) @@ -857,6 +899,7 @@ mod tests { assert_eq!( data.clone(), ExpectedEpochData { + cardano_era: "CardanoEra".to_string(), epoch, protocol_parameters: current_epoch_fixture.protocol_parameters(), next_protocol_parameters: next_epoch_fixture.protocol_parameters(), @@ -899,7 +942,8 @@ mod tests { }, ..EpochServiceBuilder::new(epoch, MithrilFixtureBuilder::default().build()) } - .build(); + .build() + .await; service .inform_epoch(epoch) @@ -937,7 +981,8 @@ mod tests { next_signers_with_stake: next_epoch_fixture.signers_with_stake().clone(), ..EpochServiceBuilder::new(epoch, current_epoch_fixture.clone()) } - .build(); + .build() + .await; service .inform_epoch(epoch) @@ -966,7 +1011,9 @@ mod tests { let fixture = MithrilFixtureBuilder::default().with_signers(3).build(); let avk = fixture.compute_avk(); let epoch = Epoch(4); - let mut service = EpochServiceBuilder::new(epoch, fixture.clone()).build(); + let mut service = EpochServiceBuilder::new(epoch, fixture.clone()) + .build() + .await; let signer_builder = SignerBuilder::new( &fixture.signers_with_stake(), &fixture.protocol_parameters(), @@ -995,7 +1042,8 @@ mod tests { future_protocol_parameters: future_protocol_parameters.clone(), ..EpochServiceBuilder::new(epoch, MithrilFixtureBuilder::default().build()) } - .build(); + .build() + .await; service .inform_epoch(epoch) @@ -1027,9 +1075,12 @@ mod tests { #[tokio::test] async fn cant_get_data_if_inform_epoch_has_not_been_called() { let fixture = MithrilFixtureBuilder::default().with_signers(3).build(); - let service = EpochServiceBuilder::new(Epoch(4), fixture.clone()).build(); + let service = EpochServiceBuilder::new(Epoch(4), fixture.clone()) + .build() + .await; for (name, res) in [ + ("cardano_era", service.cardano_era().err()), ( "epoch_of_current_data", service.epoch_of_current_data().err(), @@ -1096,9 +1147,12 @@ mod tests { async fn can_only_get_non_computed_data_if_inform_epoch_has_been_called_but_not_precompute_epoch_data( ) { let fixture = MithrilFixtureBuilder::default().with_signers(3).build(); - let mut service = EpochServiceBuilder::new(Epoch(4), fixture.clone()).build(); + let mut service = EpochServiceBuilder::new(Epoch(4), fixture.clone()) + .build() + .await; service.inform_epoch(Epoch(4)).await.unwrap(); + assert!(service.cardano_era().is_ok()); assert!(service.epoch_of_current_data().is_ok()); assert!(service.current_protocol_parameters().is_ok()); assert!(service.next_protocol_parameters().is_ok()); diff --git a/mithril-common/src/chain_observer/fake_observer.rs b/mithril-common/src/chain_observer/fake_observer.rs index 3910d347da9..766a1fe9d8e 100644 --- a/mithril-common/src/chain_observer/fake_observer.rs +++ b/mithril-common/src/chain_observer/fake_observer.rs @@ -22,6 +22,11 @@ pub struct FakeObserver { /// /// [get_current_datums]: ChainObserver::get_current_datums pub datums: RwLock>, + + /// A Cardano era, used by [get_current_era] + /// + /// [get_current_era]: ChainObserver::get_current_era + pub current_era: RwLock, } impl FakeObserver { @@ -31,6 +36,7 @@ impl FakeObserver { signers: RwLock::new(vec![]), current_time_point: RwLock::new(current_time_point.clone()), datums: RwLock::new(vec![]), + current_era: RwLock::new(String::new()), } } @@ -130,6 +136,13 @@ impl FakeObserver { let mut datums = self.datums.write().await; *datums = new_datums; } + + /// Set the current Era + /// [get_current_era][ChainObserver::get_current_era]. + pub async fn set_current_era(&self, new_current_era: String) { + let mut current_era = self.current_era.write().await; + *current_era = new_current_era; + } } impl Default for FakeObserver { @@ -152,7 +165,7 @@ impl ChainObserver for FakeObserver { } async fn get_current_era(&self) -> Result, ChainObserverError> { - Ok(Some(String::new())) + Ok(Some(self.current_era.read().await.clone())) } async fn get_current_epoch(&self) -> Result, ChainObserverError> { @@ -343,4 +356,22 @@ mod tests { "get current chain point should not fail" ); } + + #[tokio::test] + async fn test_get_current_era() { + let fake_observer = FakeObserver::new(None); + + let current_era = fake_observer + .get_current_era() + .await + .expect("get_current_era should not fail"); + assert_ne!(Some("Conway".to_string()), current_era); + + fake_observer.set_current_era("Conway".to_string()).await; + let current_era = fake_observer + .get_current_era() + .await + .expect("get_current_era should not fail"); + assert_eq!(Some("Conway".to_string()), current_era); + } } From e17a25812e4c27e5dd6dde71a042c15dccfdedeb Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Wed, 6 Nov 2024 17:39:44 +0100 Subject: [PATCH 2/7] refactor: introduce `EpochServiceDependencies` struct to group the requirements of `MithrilEpochService` --- .../src/dependency_injection/builder.rs | 17 ++++---- .../src/services/epoch_service.rs | 40 ++++++++++++++----- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/mithril-aggregator/src/dependency_injection/builder.rs b/mithril-aggregator/src/dependency_injection/builder.rs index 500752c1c73..81ac67c4e95 100644 --- a/mithril-aggregator/src/dependency_injection/builder.rs +++ b/mithril-aggregator/src/dependency_injection/builder.rs @@ -63,14 +63,11 @@ use crate::{ }, entities::AggregatorEpochSettings, event_store::{EventMessage, EventStore, TransmitterService}, - http_server::routes::{ - router, - router::{RouterConfig, RouterState}, - }, + http_server::routes::router::{self, RouterConfig, RouterState}, services::{ AggregatorSignableSeedBuilder, AggregatorUpkeepService, BufferedCertifierService, - CardanoTransactionsImporter, CertifierService, MessageService, MithrilCertifierService, - MithrilEpochService, MithrilMessageService, MithrilProverService, + CardanoTransactionsImporter, CertifierService, EpochServiceDependencies, MessageService, + MithrilCertifierService, MithrilEpochService, MithrilMessageService, MithrilProverService, MithrilSignedEntityService, MithrilStakeDistributionService, ProverService, SignedEntityService, StakeDistributionService, UpkeepService, UsageReporter, }, @@ -1266,9 +1263,11 @@ impl DependenciesBuilder { let epoch_service = Arc::new(RwLock::new(MithrilEpochService::new( epoch_settings, - epoch_settings_storer, - verification_key_store, - chain_observer, + EpochServiceDependencies::new( + epoch_settings_storer, + verification_key_store, + chain_observer, + ), network, allowed_discriminants, self.root_logger(), diff --git a/mithril-aggregator/src/services/epoch_service.rs b/mithril-aggregator/src/services/epoch_service.rs index 46c0bcdad3a..f3256e055ac 100644 --- a/mithril-aggregator/src/services/epoch_service.rs +++ b/mithril-aggregator/src/services/epoch_service.rs @@ -126,6 +126,28 @@ struct ComputedEpochData { next_protocol_multi_signer: ProtocolMultiSigner, } +/// Dependencies required by the [MithrilEpochService]. +pub struct EpochServiceDependencies { + epoch_settings_storer: Arc, + verification_key_store: Arc, + chain_observer: Arc, +} + +impl EpochServiceDependencies { + /// Create a new instance of [EpochServiceDependencies]. + pub fn new( + epoch_settings_storer: Arc, + verification_key_store: Arc, + chain_observer: Arc, + ) -> Self { + Self { + epoch_settings_storer, + verification_key_store, + chain_observer, + } + } +} + /// Implementation of the [epoch service][EpochService]. pub struct MithrilEpochService { /// Epoch settings that will be inserted when inform_epoch is called @@ -144,9 +166,7 @@ impl MithrilEpochService { /// Create a new service instance pub fn new( future_epoch_settings: AggregatorEpochSettings, - epoch_settings_storer: Arc, - verification_key_store: Arc, - chain_observer: Arc, + dependencies: EpochServiceDependencies, network: CardanoNetwork, allowed_discriminants: BTreeSet, logger: Logger, @@ -155,9 +175,9 @@ impl MithrilEpochService { future_epoch_settings, epoch_data: None, computed_epoch_data: None, - epoch_settings_storer, - verification_key_store, - chain_observer, + epoch_settings_storer: dependencies.epoch_settings_storer, + verification_key_store: dependencies.verification_key_store, + chain_observer: dependencies.chain_observer, network, allowed_signed_entity_discriminants: allowed_discriminants, logger: logger.new_with_component_name::(), @@ -849,9 +869,11 @@ mod tests { protocol_parameters: self.future_protocol_parameters, cardano_transactions_signing_config: self.cardano_transactions_signing_config, }, - Arc::new(epoch_settings_storer), - Arc::new(vkey_store), - Arc::new(chain_observer), + EpochServiceDependencies::new( + Arc::new(epoch_settings_storer), + Arc::new(vkey_store), + Arc::new(chain_observer), + ), self.network, self.allowed_discriminants, TestLogger::stdout(), From 50b017b79f9644e721c2b5080bc42b9e209b56bb Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:28:56 +0100 Subject: [PATCH 3/7] feat: store the current Mithril era in the Epoch service --- .../src/dependency_injection/builder.rs | 2 ++ .../src/services/epoch_service.rs | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/mithril-aggregator/src/dependency_injection/builder.rs b/mithril-aggregator/src/dependency_injection/builder.rs index 81ac67c4e95..510364c6778 100644 --- a/mithril-aggregator/src/dependency_injection/builder.rs +++ b/mithril-aggregator/src/dependency_injection/builder.rs @@ -1257,6 +1257,7 @@ impl DependenciesBuilder { let verification_key_store = self.get_verification_key_store().await?; let epoch_settings_storer = self.get_epoch_settings_storer().await?; let chain_observer = self.get_chain_observer().await?; + let era_checker = self.get_era_checker().await?; let epoch_settings = self.get_epoch_settings_configuration()?; let network = self.configuration.get_network()?; let allowed_discriminants = self.get_allowed_signed_entity_types_discriminants()?; @@ -1267,6 +1268,7 @@ impl DependenciesBuilder { epoch_settings_storer, verification_key_store, chain_observer, + era_checker, ), network, allowed_discriminants, diff --git a/mithril-aggregator/src/services/epoch_service.rs b/mithril-aggregator/src/services/epoch_service.rs index f3256e055ac..4d3d7e6054a 100644 --- a/mithril-aggregator/src/services/epoch_service.rs +++ b/mithril-aggregator/src/services/epoch_service.rs @@ -1,6 +1,7 @@ use anyhow::{anyhow, Context}; use async_trait::async_trait; use mithril_common::chain_observer::ChainObserver; +use mithril_common::era::{EraChecker, SupportedEra}; use slog::{debug, Logger}; use std::collections::BTreeSet; use std::sync::Arc; @@ -56,6 +57,9 @@ pub trait EpochService: Sync + Send { /// Get the current Cardano era. fn cardano_era(&self) -> StdResult; + /// Get the current Mithril era. + fn mithril_era(&self) -> StdResult; + /// Get the current epoch for which the data stored in this service are computed. fn epoch_of_current_data(&self) -> StdResult; @@ -108,6 +112,7 @@ pub trait EpochService: Sync + Send { struct EpochData { cardano_era: String, + mithril_era: SupportedEra, epoch: Epoch, current_epoch_settings: AggregatorEpochSettings, next_epoch_settings: AggregatorEpochSettings, @@ -131,6 +136,7 @@ pub struct EpochServiceDependencies { epoch_settings_storer: Arc, verification_key_store: Arc, chain_observer: Arc, + era_checker: Arc, } impl EpochServiceDependencies { @@ -139,11 +145,13 @@ impl EpochServiceDependencies { epoch_settings_storer: Arc, verification_key_store: Arc, chain_observer: Arc, + era_checker: Arc, ) -> Self { Self { epoch_settings_storer, verification_key_store, chain_observer, + era_checker, } } } @@ -157,6 +165,7 @@ pub struct MithrilEpochService { epoch_settings_storer: Arc, verification_key_store: Arc, chain_observer: Arc, + era_checker: Arc, network: CardanoNetwork, allowed_signed_entity_discriminants: BTreeSet, logger: Logger, @@ -178,6 +187,7 @@ impl MithrilEpochService { epoch_settings_storer: dependencies.epoch_settings_storer, verification_key_store: dependencies.verification_key_store, chain_observer: dependencies.chain_observer, + era_checker: dependencies.era_checker, network, allowed_signed_entity_discriminants: allowed_discriminants, logger: logger.new_with_component_name::(), @@ -262,6 +272,8 @@ impl EpochService for MithrilEpochService { let cardano_era = self.get_cardano_era().await?; + let mithril_era = self.era_checker.current_era(); + let signer_retrieval_epoch = epoch.offset_to_signer_retrieval_epoch().with_context(|| { format!("EpochService could not compute signer retrieval epoch from epoch: {epoch}") @@ -302,6 +314,7 @@ impl EpochService for MithrilEpochService { self.epoch_data = Some(EpochData { cardano_era, + mithril_era, epoch, current_epoch_settings, next_epoch_settings, @@ -363,6 +376,10 @@ impl EpochService for MithrilEpochService { Ok(self.unwrap_data()?.cardano_era.clone()) } + fn mithril_era(&self) -> StdResult { + Ok(self.unwrap_data()?.mithril_era) + } + fn epoch_of_current_data(&self) -> StdResult { Ok(self.unwrap_data()?.epoch) } @@ -452,6 +469,7 @@ pub struct FakeEpochService { #[cfg(test)] pub struct FakeEpochServiceBuilder { pub cardano_era: String, + pub mithril_era: SupportedEra, pub epoch: Epoch, pub current_epoch_settings: AggregatorEpochSettings, pub next_epoch_settings: AggregatorEpochSettings, @@ -469,6 +487,7 @@ impl FakeEpochServiceBuilder { Self { cardano_era: "DummyEra".to_string(), + mithril_era: SupportedEra::dummy(), epoch, current_epoch_settings: AggregatorEpochSettings::dummy(), next_epoch_settings: AggregatorEpochSettings::dummy(), @@ -501,6 +520,7 @@ impl FakeEpochServiceBuilder { FakeEpochService { epoch_data: Some(EpochData { cardano_era: self.cardano_era, + mithril_era: self.mithril_era, epoch: self.epoch, current_epoch_settings: self.current_epoch_settings, next_epoch_settings: self.next_epoch_settings, @@ -624,6 +644,10 @@ impl EpochService for FakeEpochService { Ok(self.unwrap_data()?.cardano_era.clone()) } + fn mithril_era(&self) -> StdResult { + Ok(self.unwrap_data()?.mithril_era) + } + fn epoch_of_current_data(&self) -> StdResult { Ok(self.unwrap_data()?.epoch) } @@ -705,6 +729,7 @@ impl EpochService for FakeEpochService { mod tests { use mithril_common::chain_observer::FakeObserver; use mithril_common::entities::{BlockNumber, CardanoTransactionsSigningConfig, PartyId}; + use mithril_common::era::SupportedEra; use mithril_common::test_utils::{fake_data, MithrilFixture, MithrilFixtureBuilder}; use mithril_persistence::store::adapter::MemoryAdapter; use std::collections::{BTreeSet, HashMap}; @@ -718,6 +743,7 @@ mod tests { #[derive(Debug, Clone, PartialEq)] struct ExpectedEpochData { cardano_era: String, + mithril_era: SupportedEra, epoch: Epoch, protocol_parameters: ProtocolParameters, next_protocol_parameters: ProtocolParameters, @@ -741,6 +767,7 @@ mod tests { async fn from_service(service: &MithrilEpochService) -> StdResult { Ok(Self { cardano_era: service.cardano_era()?, + mithril_era: service.mithril_era()?, epoch: service.epoch_of_current_data()?, protocol_parameters: service.current_protocol_parameters()?.clone(), next_protocol_parameters: service.next_protocol_parameters()?.clone(), @@ -795,6 +822,7 @@ mod tests { network: CardanoNetwork, allowed_discriminants: BTreeSet, cardano_era: String, + mithril_era: SupportedEra, current_epoch: Epoch, signers_with_stake: Vec, next_signers_with_stake: Vec, @@ -811,6 +839,7 @@ mod tests { network: CardanoNetwork::TestNet(0), allowed_discriminants: BTreeSet::new(), cardano_era: String::new(), + mithril_era: SupportedEra::dummy(), current_epoch: epoch, signers_with_stake: epoch_fixture.signers_with_stake(), next_signers_with_stake: epoch_fixture.signers_with_stake(), @@ -863,6 +892,7 @@ mod tests { )); let chain_observer = FakeObserver::default(); chain_observer.set_current_era(self.cardano_era).await; + let era_checker = EraChecker::new(self.mithril_era, Epoch::default()); MithrilEpochService::new( AggregatorEpochSettings { @@ -873,6 +903,7 @@ mod tests { Arc::new(epoch_settings_storer), Arc::new(vkey_store), Arc::new(chain_observer), + Arc::new(era_checker), ), self.network, self.allowed_discriminants, @@ -904,6 +935,7 @@ mod tests { network: SignedEntityConfig::dummy().network, allowed_discriminants: SignedEntityConfig::dummy().allowed_discriminants, cardano_era: "CardanoEra".to_string(), + mithril_era: SupportedEra::eras()[1], ..EpochServiceBuilder::new(epoch, current_epoch_fixture.clone()) }; @@ -922,6 +954,7 @@ mod tests { data.clone(), ExpectedEpochData { cardano_era: "CardanoEra".to_string(), + mithril_era: SupportedEra::eras()[1], epoch, protocol_parameters: current_epoch_fixture.protocol_parameters(), next_protocol_parameters: next_epoch_fixture.protocol_parameters(), @@ -1103,6 +1136,7 @@ mod tests { for (name, res) in [ ("cardano_era", service.cardano_era().err()), + ("mithril_era", service.mithril_era().err()), ( "epoch_of_current_data", service.epoch_of_current_data().err(), @@ -1175,6 +1209,7 @@ mod tests { service.inform_epoch(Epoch(4)).await.unwrap(); assert!(service.cardano_era().is_ok()); + assert!(service.mithril_era().is_ok()); assert!(service.epoch_of_current_data().is_ok()); assert!(service.current_protocol_parameters().is_ok()); assert!(service.next_protocol_parameters().is_ok()); From 897eadca4ecc66aa1baf4a5ad473c78d83169875 Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:45:38 +0100 Subject: [PATCH 4/7] feat: compute and store the total number of SPOs in the Epoch service Run `update_stake_distribution` before `inform_epoch`, as it's now needed to record the total number of SPOs and total stake in the Epoch service. --- .../src/dependency_injection/builder.rs | 2 + .../src/runtime/state_machine.rs | 2 +- .../src/services/epoch_service.rs | 70 ++++++++++++++++++- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/mithril-aggregator/src/dependency_injection/builder.rs b/mithril-aggregator/src/dependency_injection/builder.rs index 510364c6778..462f114f497 100644 --- a/mithril-aggregator/src/dependency_injection/builder.rs +++ b/mithril-aggregator/src/dependency_injection/builder.rs @@ -1258,6 +1258,7 @@ impl DependenciesBuilder { let epoch_settings_storer = self.get_epoch_settings_storer().await?; let chain_observer = self.get_chain_observer().await?; let era_checker = self.get_era_checker().await?; + let stake_distribution_service = self.get_stake_distribution_service().await?; let epoch_settings = self.get_epoch_settings_configuration()?; let network = self.configuration.get_network()?; let allowed_discriminants = self.get_allowed_signed_entity_types_discriminants()?; @@ -1269,6 +1270,7 @@ impl DependenciesBuilder { verification_key_store, chain_observer, era_checker, + stake_distribution_service, ), network, allowed_discriminants, diff --git a/mithril-aggregator/src/runtime/state_machine.rs b/mithril-aggregator/src/runtime/state_machine.rs index 8042b73439b..1b6cd87a6c4 100644 --- a/mithril-aggregator/src/runtime/state_machine.rs +++ b/mithril-aggregator/src/runtime/state_machine.rs @@ -252,10 +252,10 @@ impl AggregatorRuntime { .update_era_checker(new_time_point.epoch) .await .map_err(|e| RuntimeError::critical("transiting IDLE → READY", Some(e)))?; - self.runner.inform_new_epoch(new_time_point.epoch).await?; self.runner .update_stake_distribution(&new_time_point) .await?; + self.runner.inform_new_epoch(new_time_point.epoch).await?; self.runner.upkeep().await?; self.runner .open_signer_registration_round(&new_time_point) diff --git a/mithril-aggregator/src/services/epoch_service.rs b/mithril-aggregator/src/services/epoch_service.rs index 4d3d7e6054a..f6135c727ad 100644 --- a/mithril-aggregator/src/services/epoch_service.rs +++ b/mithril-aggregator/src/services/epoch_service.rs @@ -16,8 +16,10 @@ use mithril_common::logging::LoggerExtensions; use mithril_common::protocol::{MultiSigner as ProtocolMultiSigner, SignerBuilder}; use mithril_common::{CardanoNetwork, StdResult}; -use crate::entities::AggregatorEpochSettings; -use crate::{EpochSettingsStorer, VerificationKeyStorer}; +use crate::{ + entities::AggregatorEpochSettings, services::StakeDistributionService, EpochSettingsStorer, + VerificationKeyStorer, +}; /// Errors dedicated to the CertifierService. #[derive(Debug, Error)] @@ -108,6 +110,9 @@ pub trait EpochService: Sync + Send { /// Get the [SignedEntityConfig] for the current epoch. fn signed_entity_config(&self) -> StdResult<&SignedEntityConfig>; + + /// Get the total number of SPOs for the current epoch. + fn total_spo(&self) -> StdResult<&u32>; } struct EpochData { @@ -122,6 +127,7 @@ struct EpochData { current_signers: Vec, next_signers: Vec, signed_entity_config: SignedEntityConfig, + total_spo: u32, } struct ComputedEpochData { @@ -137,6 +143,7 @@ pub struct EpochServiceDependencies { verification_key_store: Arc, chain_observer: Arc, era_checker: Arc, + stake_distribution_service: Arc, } impl EpochServiceDependencies { @@ -146,12 +153,14 @@ impl EpochServiceDependencies { verification_key_store: Arc, chain_observer: Arc, era_checker: Arc, + stake_distribution_service: Arc, ) -> Self { Self { epoch_settings_storer, verification_key_store, chain_observer, era_checker, + stake_distribution_service, } } } @@ -166,6 +175,7 @@ pub struct MithrilEpochService { verification_key_store: Arc, chain_observer: Arc, era_checker: Arc, + stake_distribution_service: Arc, network: CardanoNetwork, allowed_signed_entity_discriminants: BTreeSet, logger: Logger, @@ -188,6 +198,7 @@ impl MithrilEpochService { verification_key_store: dependencies.verification_key_store, chain_observer: dependencies.chain_observer, era_checker: dependencies.era_checker, + stake_distribution_service: dependencies.stake_distribution_service, network, allowed_signed_entity_discriminants: allowed_discriminants, logger: logger.new_with_component_name::(), @@ -204,6 +215,18 @@ impl MithrilEpochService { Ok(cardano_era) } + async fn get_total_spo(&self, epoch: Epoch) -> StdResult { + let stake_distribution = self + .stake_distribution_service + .get_stake_distribution(epoch) + .await + .with_context(|| { + format!("Epoch service failed to obtain the stake distribution for epoch: {epoch}") + })?; + + Ok(stake_distribution.len() as u32) + } + async fn get_signers_with_stake_at_epoch( &self, signer_retrieval_epoch: Epoch, @@ -312,6 +335,8 @@ impl EpochService for MithrilEpochService { .clone(), }; + let total_spo = self.get_total_spo(epoch).await?; + self.epoch_data = Some(EpochData { cardano_era, mithril_era, @@ -324,6 +349,7 @@ impl EpochService for MithrilEpochService { current_signers, next_signers, signed_entity_config, + total_spo, }); self.computed_epoch_data = None; @@ -455,6 +481,10 @@ impl EpochService for MithrilEpochService { fn signed_entity_config(&self) -> StdResult<&SignedEntityConfig> { Ok(&self.unwrap_data()?.signed_entity_config) } + + fn total_spo(&self) -> StdResult<&u32> { + Ok(&self.unwrap_data()?.total_spo) + } } #[cfg(test)] @@ -477,6 +507,7 @@ pub struct FakeEpochServiceBuilder { pub current_signers_with_stake: Vec, pub next_signers_with_stake: Vec, pub signed_entity_config: SignedEntityConfig, + pub total_spo: u32, } #[cfg(test)] @@ -495,6 +526,7 @@ impl FakeEpochServiceBuilder { current_signers_with_stake: signers.clone(), next_signers_with_stake: signers, signed_entity_config: SignedEntityConfig::dummy(), + total_spo: 0, } } @@ -530,6 +562,7 @@ impl FakeEpochServiceBuilder { current_signers, next_signers, signed_entity_config: self.signed_entity_config, + total_spo: self.total_spo, }), computed_epoch_data: Some(ComputedEpochData { aggregate_verification_key: protocol_multi_signer @@ -723,23 +756,39 @@ impl EpochService for FakeEpochService { fn signed_entity_config(&self) -> StdResult<&SignedEntityConfig> { Ok(&self.unwrap_data()?.signed_entity_config) } + + fn total_spo(&self) -> StdResult<&u32> { + Ok(&self.unwrap_data()?.total_spo) + } } #[cfg(test)] mod tests { use mithril_common::chain_observer::FakeObserver; - use mithril_common::entities::{BlockNumber, CardanoTransactionsSigningConfig, PartyId}; + use mithril_common::entities::{ + BlockNumber, CardanoTransactionsSigningConfig, PartyId, StakeDistribution, + }; use mithril_common::era::SupportedEra; use mithril_common::test_utils::{fake_data, MithrilFixture, MithrilFixtureBuilder}; use mithril_persistence::store::adapter::MemoryAdapter; use std::collections::{BTreeSet, HashMap}; + use crate::services::MockStakeDistributionService; use crate::store::FakeEpochSettingsStorer; use crate::test_tools::TestLogger; use crate::VerificationKeyStore; use super::*; + fn stake_distribution_with_given_number_of_spo(total_spo: u32) -> StakeDistribution { + let mut stake_distribution: StakeDistribution = StakeDistribution::new(); + for i in 0..total_spo { + let party_id = format!("party-id-{i}"); + stake_distribution.insert(party_id.clone(), 0); + } + stake_distribution + } + #[derive(Debug, Clone, PartialEq)] struct ExpectedEpochData { cardano_era: String, @@ -755,6 +804,7 @@ mod tests { current_signers: BTreeSet, next_signers: BTreeSet, signed_entity_config: SignedEntityConfig, + total_spo: u32, } #[derive(Debug, Clone, PartialEq)] @@ -793,6 +843,7 @@ mod tests { current_signers: service.current_signers()?.clone().into_iter().collect(), next_signers: service.next_signers()?.clone().into_iter().collect(), signed_entity_config: service.signed_entity_config()?.clone(), + total_spo: *service.total_spo()?, }) } } @@ -829,6 +880,7 @@ mod tests { stored_current_epoch_settings: AggregatorEpochSettings, stored_next_epoch_settings: AggregatorEpochSettings, stored_signer_registration_epoch_settings: AggregatorEpochSettings, + total_spo: u32, } impl EpochServiceBuilder { @@ -855,6 +907,7 @@ mod tests { protocol_parameters: epoch_fixture.protocol_parameters(), cardano_transactions_signing_config: CardanoTransactionsSigningConfig::dummy(), }, + total_spo: 0, } } @@ -894,6 +947,12 @@ mod tests { chain_observer.set_current_era(self.cardano_era).await; let era_checker = EraChecker::new(self.mithril_era, Epoch::default()); + let stake_distribution = stake_distribution_with_given_number_of_spo(self.total_spo); + let mut stake_distribution_service = MockStakeDistributionService::new(); + stake_distribution_service + .expect_get_stake_distribution() + .returning(move |_| Ok(stake_distribution.clone())); + MithrilEpochService::new( AggregatorEpochSettings { protocol_parameters: self.future_protocol_parameters, @@ -904,6 +963,7 @@ mod tests { Arc::new(vkey_store), Arc::new(chain_observer), Arc::new(era_checker), + Arc::new(stake_distribution_service), ), self.network, self.allowed_discriminants, @@ -936,6 +996,7 @@ mod tests { allowed_discriminants: SignedEntityConfig::dummy().allowed_discriminants, cardano_era: "CardanoEra".to_string(), mithril_era: SupportedEra::eras()[1], + total_spo: 37, ..EpochServiceBuilder::new(epoch, current_epoch_fixture.clone()) }; @@ -972,6 +1033,7 @@ mod tests { current_signers: current_epoch_fixture.signers().into_iter().collect(), next_signers: next_epoch_fixture.signers().into_iter().collect(), signed_entity_config: SignedEntityConfig::dummy(), + total_spo: 37, } ); } @@ -1188,6 +1250,7 @@ mod tests { service.next_protocol_multi_signer().err(), ), ("signed_entity_config", service.signed_entity_config().err()), + ("total_spo", service.total_spo().err()), ] { let error = res.unwrap_or_else(|| panic!("getting {name} should have returned an error")); @@ -1223,6 +1286,7 @@ mod tests { assert!(service.current_signers().is_ok()); assert!(service.next_signers().is_ok()); assert!(service.signed_entity_config().is_ok()); + assert!(service.total_spo().is_ok()); for (name, res) in [ ( From 57e4b22b7d6513dd7db53a0726f4913745e6f801 Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:54:16 +0100 Subject: [PATCH 5/7] feat: compute and store the total stake in the Epoch service --- .../src/services/epoch_service.rs | 79 ++++++++++++++----- 1 file changed, 60 insertions(+), 19 deletions(-) diff --git a/mithril-aggregator/src/services/epoch_service.rs b/mithril-aggregator/src/services/epoch_service.rs index f6135c727ad..3a6eff85b9f 100644 --- a/mithril-aggregator/src/services/epoch_service.rs +++ b/mithril-aggregator/src/services/epoch_service.rs @@ -113,6 +113,9 @@ pub trait EpochService: Sync + Send { /// Get the total number of SPOs for the current epoch. fn total_spo(&self) -> StdResult<&u32>; + + /// Get the total stake for the current epoch. + fn total_stake(&self) -> StdResult<&u64>; } struct EpochData { @@ -128,6 +131,7 @@ struct EpochData { next_signers: Vec, signed_entity_config: SignedEntityConfig, total_spo: u32, + total_stake: u64, } struct ComputedEpochData { @@ -215,7 +219,7 @@ impl MithrilEpochService { Ok(cardano_era) } - async fn get_total_spo(&self, epoch: Epoch) -> StdResult { + async fn get_total_spo_and_total_stake(&self, epoch: Epoch) -> StdResult<(u32, u64)> { let stake_distribution = self .stake_distribution_service .get_stake_distribution(epoch) @@ -224,7 +228,10 @@ impl MithrilEpochService { format!("Epoch service failed to obtain the stake distribution for epoch: {epoch}") })?; - Ok(stake_distribution.len() as u32) + Ok(( + stake_distribution.len() as u32, + stake_distribution.values().sum(), + )) } async fn get_signers_with_stake_at_epoch( @@ -335,7 +342,7 @@ impl EpochService for MithrilEpochService { .clone(), }; - let total_spo = self.get_total_spo(epoch).await?; + let (total_spo, total_stake) = self.get_total_spo_and_total_stake(epoch).await?; self.epoch_data = Some(EpochData { cardano_era, @@ -350,6 +357,7 @@ impl EpochService for MithrilEpochService { next_signers, signed_entity_config, total_spo, + total_stake, }); self.computed_epoch_data = None; @@ -485,6 +493,10 @@ impl EpochService for MithrilEpochService { fn total_spo(&self) -> StdResult<&u32> { Ok(&self.unwrap_data()?.total_spo) } + + fn total_stake(&self) -> StdResult<&u64> { + Ok(&self.unwrap_data()?.total_stake) + } } #[cfg(test)] @@ -508,6 +520,7 @@ pub struct FakeEpochServiceBuilder { pub next_signers_with_stake: Vec, pub signed_entity_config: SignedEntityConfig, pub total_spo: u32, + pub total_stake: u64, } #[cfg(test)] @@ -527,6 +540,7 @@ impl FakeEpochServiceBuilder { next_signers_with_stake: signers, signed_entity_config: SignedEntityConfig::dummy(), total_spo: 0, + total_stake: 0, } } @@ -563,6 +577,7 @@ impl FakeEpochServiceBuilder { next_signers, signed_entity_config: self.signed_entity_config, total_spo: self.total_spo, + total_stake: self.total_stake, }), computed_epoch_data: Some(ComputedEpochData { aggregate_verification_key: protocol_multi_signer @@ -760,6 +775,10 @@ impl EpochService for FakeEpochService { fn total_spo(&self) -> StdResult<&u32> { Ok(&self.unwrap_data()?.total_spo) } + + fn total_stake(&self) -> StdResult<&u64> { + Ok(&self.unwrap_data()?.total_stake) + } } #[cfg(test)] @@ -769,7 +788,9 @@ mod tests { BlockNumber, CardanoTransactionsSigningConfig, PartyId, StakeDistribution, }; use mithril_common::era::SupportedEra; - use mithril_common::test_utils::{fake_data, MithrilFixture, MithrilFixtureBuilder}; + use mithril_common::test_utils::{ + fake_data, MithrilFixture, MithrilFixtureBuilder, StakeDistributionGenerationMethod, + }; use mithril_persistence::store::adapter::MemoryAdapter; use std::collections::{BTreeSet, HashMap}; @@ -780,13 +801,13 @@ mod tests { use super::*; - fn stake_distribution_with_given_number_of_spo(total_spo: u32) -> StakeDistribution { - let mut stake_distribution: StakeDistribution = StakeDistribution::new(); - for i in 0..total_spo { - let party_id = format!("party-id-{i}"); - stake_distribution.insert(party_id.clone(), 0); - } - stake_distribution + fn build_uniform_stake_distribution(total_spo: u32, stake_by_spo: u64) -> StakeDistribution { + let fixture = MithrilFixtureBuilder::default() + .with_signers(total_spo as usize) + .with_stake_distribution(StakeDistributionGenerationMethod::Uniform(stake_by_spo)) + .build(); + + fixture.stake_distribution() } #[derive(Debug, Clone, PartialEq)] @@ -805,6 +826,7 @@ mod tests { next_signers: BTreeSet, signed_entity_config: SignedEntityConfig, total_spo: u32, + total_stake: u64, } #[derive(Debug, Clone, PartialEq)] @@ -844,6 +866,7 @@ mod tests { next_signers: service.next_signers()?.clone().into_iter().collect(), signed_entity_config: service.signed_entity_config()?.clone(), total_spo: *service.total_spo()?, + total_stake: *service.total_stake()?, }) } } @@ -881,6 +904,7 @@ mod tests { stored_next_epoch_settings: AggregatorEpochSettings, stored_signer_registration_epoch_settings: AggregatorEpochSettings, total_spo: u32, + total_stake: u64, } impl EpochServiceBuilder { @@ -907,7 +931,8 @@ mod tests { protocol_parameters: epoch_fixture.protocol_parameters(), cardano_transactions_signing_config: CardanoTransactionsSigningConfig::dummy(), }, - total_spo: 0, + total_spo: 1, + total_stake: 0, } } @@ -947,11 +972,23 @@ mod tests { chain_observer.set_current_era(self.cardano_era).await; let era_checker = EraChecker::new(self.mithril_era, Epoch::default()); - let stake_distribution = stake_distribution_with_given_number_of_spo(self.total_spo); - let mut stake_distribution_service = MockStakeDistributionService::new(); - stake_distribution_service - .expect_get_stake_distribution() - .returning(move |_| Ok(stake_distribution.clone())); + let stake_distribution_service = { + assert!( + self.total_stake % self.total_spo as u64 == 0, + "'total_stake' must be a multiple of 'total_spo' to create a uniform stake distribution" + ); + let stake_per_spo = self.total_stake / self.total_spo as u64; + + let stake_distribution = + build_uniform_stake_distribution(self.total_spo, stake_per_spo); + + let mut stake_distribution_service = MockStakeDistributionService::new(); + stake_distribution_service + .expect_get_stake_distribution() + .returning(move |_| Ok(stake_distribution.clone())); + + stake_distribution_service + }; MithrilEpochService::new( AggregatorEpochSettings { @@ -996,7 +1033,8 @@ mod tests { allowed_discriminants: SignedEntityConfig::dummy().allowed_discriminants, cardano_era: "CardanoEra".to_string(), mithril_era: SupportedEra::eras()[1], - total_spo: 37, + total_spo: 40, + total_stake: 20_000_000, ..EpochServiceBuilder::new(epoch, current_epoch_fixture.clone()) }; @@ -1033,7 +1071,8 @@ mod tests { current_signers: current_epoch_fixture.signers().into_iter().collect(), next_signers: next_epoch_fixture.signers().into_iter().collect(), signed_entity_config: SignedEntityConfig::dummy(), - total_spo: 37, + total_spo: 40, + total_stake: 20_000_000, } ); } @@ -1251,6 +1290,7 @@ mod tests { ), ("signed_entity_config", service.signed_entity_config().err()), ("total_spo", service.total_spo().err()), + ("total_stake", service.total_stake().err()), ] { let error = res.unwrap_or_else(|| panic!("getting {name} should have returned an error")); @@ -1287,6 +1327,7 @@ mod tests { assert!(service.next_signers().is_ok()); assert!(service.signed_entity_config().is_ok()); assert!(service.total_spo().is_ok()); + assert!(service.total_stake().is_ok()); for (name, res) in [ ( From ca3706c73a0914695a1c773dbd922104b7179d64 Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:42:02 +0100 Subject: [PATCH 6/7] refactor: use type aliases for `cardano_era`, `total_spo` and `total_stake` and improve comments --- .../src/services/epoch_service.rs | 76 ++++++++++--------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/mithril-aggregator/src/services/epoch_service.rs b/mithril-aggregator/src/services/epoch_service.rs index 3a6eff85b9f..bba144296cd 100644 --- a/mithril-aggregator/src/services/epoch_service.rs +++ b/mithril-aggregator/src/services/epoch_service.rs @@ -10,7 +10,7 @@ use thiserror::Error; use mithril_common::crypto_helper::ProtocolAggregateVerificationKey; use mithril_common::entities::{ CardanoTransactionsSigningConfig, Epoch, ProtocolParameters, SignedEntityConfig, - SignedEntityTypeDiscriminants, Signer, SignerWithStake, + SignedEntityTypeDiscriminants, Signer, SignerWithStake, Stake, }; use mithril_common::logging::LoggerExtensions; use mithril_common::protocol::{MultiSigner as ProtocolMultiSigner, SignerBuilder}; @@ -21,6 +21,9 @@ use crate::{ VerificationKeyStorer, }; +type TotalSPOs = u32; +type CardanoEra = String; + /// Errors dedicated to the CertifierService. #[derive(Debug, Error)] pub enum EpochServiceError { @@ -57,7 +60,7 @@ pub trait EpochService: Sync + Send { async fn precompute_epoch_data(&mut self) -> StdResult<()>; /// Get the current Cardano era. - fn cardano_era(&self) -> StdResult; + fn cardano_era(&self) -> StdResult; /// Get the current Mithril era. fn mithril_era(&self) -> StdResult; @@ -111,15 +114,15 @@ pub trait EpochService: Sync + Send { /// Get the [SignedEntityConfig] for the current epoch. fn signed_entity_config(&self) -> StdResult<&SignedEntityConfig>; - /// Get the total number of SPOs for the current epoch. - fn total_spo(&self) -> StdResult<&u32>; + /// Get the total number of SPOs for the current epoch in the Cardano stake distribution. + fn total_spo(&self) -> StdResult; - /// Get the total stake for the current epoch. - fn total_stake(&self) -> StdResult<&u64>; + /// Get the total stake for the current epoch in the Cardano stake distribution. + fn total_stake(&self) -> StdResult; } struct EpochData { - cardano_era: String, + cardano_era: CardanoEra, mithril_era: SupportedEra, epoch: Epoch, current_epoch_settings: AggregatorEpochSettings, @@ -130,8 +133,8 @@ struct EpochData { current_signers: Vec, next_signers: Vec, signed_entity_config: SignedEntityConfig, - total_spo: u32, - total_stake: u64, + total_spo: TotalSPOs, + total_stake: Stake, } struct ComputedEpochData { @@ -209,7 +212,7 @@ impl MithrilEpochService { } } - async fn get_cardano_era(&self) -> StdResult { + async fn get_cardano_era(&self) -> StdResult { let cardano_era = self .chain_observer .get_current_era() @@ -219,7 +222,7 @@ impl MithrilEpochService { Ok(cardano_era) } - async fn get_total_spo_and_total_stake(&self, epoch: Epoch) -> StdResult<(u32, u64)> { + async fn get_total_spo_and_total_stake(&self, epoch: Epoch) -> StdResult<(TotalSPOs, Stake)> { let stake_distribution = self .stake_distribution_service .get_stake_distribution(epoch) @@ -229,7 +232,7 @@ impl MithrilEpochService { })?; Ok(( - stake_distribution.len() as u32, + stake_distribution.len() as TotalSPOs, stake_distribution.values().sum(), )) } @@ -406,7 +409,7 @@ impl EpochService for MithrilEpochService { Ok(()) } - fn cardano_era(&self) -> StdResult { + fn cardano_era(&self) -> StdResult { Ok(self.unwrap_data()?.cardano_era.clone()) } @@ -490,12 +493,12 @@ impl EpochService for MithrilEpochService { Ok(&self.unwrap_data()?.signed_entity_config) } - fn total_spo(&self) -> StdResult<&u32> { - Ok(&self.unwrap_data()?.total_spo) + fn total_spo(&self) -> StdResult { + Ok(self.unwrap_data()?.total_spo) } - fn total_stake(&self) -> StdResult<&u64> { - Ok(&self.unwrap_data()?.total_stake) + fn total_stake(&self) -> StdResult { + Ok(self.unwrap_data()?.total_stake) } } @@ -510,7 +513,7 @@ pub struct FakeEpochService { #[cfg(test)] pub struct FakeEpochServiceBuilder { - pub cardano_era: String, + pub cardano_era: CardanoEra, pub mithril_era: SupportedEra, pub epoch: Epoch, pub current_epoch_settings: AggregatorEpochSettings, @@ -519,8 +522,8 @@ pub struct FakeEpochServiceBuilder { pub current_signers_with_stake: Vec, pub next_signers_with_stake: Vec, pub signed_entity_config: SignedEntityConfig, - pub total_spo: u32, - pub total_stake: u64, + pub total_spo: TotalSPOs, + pub total_stake: Stake, } #[cfg(test)] @@ -688,7 +691,7 @@ impl EpochService for FakeEpochService { Ok(()) } - fn cardano_era(&self) -> StdResult { + fn cardano_era(&self) -> StdResult { Ok(self.unwrap_data()?.cardano_era.clone()) } @@ -772,12 +775,12 @@ impl EpochService for FakeEpochService { Ok(&self.unwrap_data()?.signed_entity_config) } - fn total_spo(&self) -> StdResult<&u32> { - Ok(&self.unwrap_data()?.total_spo) + fn total_spo(&self) -> StdResult { + Ok(self.unwrap_data()?.total_spo) } - fn total_stake(&self) -> StdResult<&u64> { - Ok(&self.unwrap_data()?.total_stake) + fn total_stake(&self) -> StdResult { + Ok(self.unwrap_data()?.total_stake) } } @@ -785,7 +788,7 @@ impl EpochService for FakeEpochService { mod tests { use mithril_common::chain_observer::FakeObserver; use mithril_common::entities::{ - BlockNumber, CardanoTransactionsSigningConfig, PartyId, StakeDistribution, + BlockNumber, CardanoTransactionsSigningConfig, PartyId, Stake, StakeDistribution, }; use mithril_common::era::SupportedEra; use mithril_common::test_utils::{ @@ -801,7 +804,10 @@ mod tests { use super::*; - fn build_uniform_stake_distribution(total_spo: u32, stake_by_spo: u64) -> StakeDistribution { + fn build_uniform_stake_distribution( + total_spo: TotalSPOs, + stake_by_spo: Stake, + ) -> StakeDistribution { let fixture = MithrilFixtureBuilder::default() .with_signers(total_spo as usize) .with_stake_distribution(StakeDistributionGenerationMethod::Uniform(stake_by_spo)) @@ -812,7 +818,7 @@ mod tests { #[derive(Debug, Clone, PartialEq)] struct ExpectedEpochData { - cardano_era: String, + cardano_era: CardanoEra, mithril_era: SupportedEra, epoch: Epoch, protocol_parameters: ProtocolParameters, @@ -825,8 +831,8 @@ mod tests { current_signers: BTreeSet, next_signers: BTreeSet, signed_entity_config: SignedEntityConfig, - total_spo: u32, - total_stake: u64, + total_spo: TotalSPOs, + total_stake: Stake, } #[derive(Debug, Clone, PartialEq)] @@ -865,8 +871,8 @@ mod tests { current_signers: service.current_signers()?.clone().into_iter().collect(), next_signers: service.next_signers()?.clone().into_iter().collect(), signed_entity_config: service.signed_entity_config()?.clone(), - total_spo: *service.total_spo()?, - total_stake: *service.total_stake()?, + total_spo: service.total_spo()?, + total_stake: service.total_stake()?, }) } } @@ -895,7 +901,7 @@ mod tests { future_protocol_parameters: ProtocolParameters, network: CardanoNetwork, allowed_discriminants: BTreeSet, - cardano_era: String, + cardano_era: CardanoEra, mithril_era: SupportedEra, current_epoch: Epoch, signers_with_stake: Vec, @@ -903,8 +909,8 @@ mod tests { stored_current_epoch_settings: AggregatorEpochSettings, stored_next_epoch_settings: AggregatorEpochSettings, stored_signer_registration_epoch_settings: AggregatorEpochSettings, - total_spo: u32, - total_stake: u64, + total_spo: TotalSPOs, + total_stake: Stake, } impl EpochServiceBuilder { From b4f4c4fd34abf3786bc2db70c45821eae265ec42 Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Fri, 8 Nov 2024 15:12:05 +0100 Subject: [PATCH 7/7] chore: upgrade crate versions * mithril-aggregator from `0.5.106` to `0.5.107` * mithril-common from `0.4.83` to `0.4.84` --- Cargo.lock | 4 ++-- mithril-aggregator/Cargo.toml | 2 +- mithril-common/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b9e75b6d016..00a49249a68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3588,7 +3588,7 @@ dependencies = [ [[package]] name = "mithril-aggregator" -version = "0.5.106" +version = "0.5.107" dependencies = [ "anyhow", "async-trait", @@ -3745,7 +3745,7 @@ dependencies = [ [[package]] name = "mithril-common" -version = "0.4.83" +version = "0.4.84" dependencies = [ "anyhow", "async-trait", diff --git a/mithril-aggregator/Cargo.toml b/mithril-aggregator/Cargo.toml index 0c4c32ea42e..2a5ed33581e 100644 --- a/mithril-aggregator/Cargo.toml +++ b/mithril-aggregator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-aggregator" -version = "0.5.106" +version = "0.5.107" description = "A Mithril Aggregator server" authors = { workspace = true } edition = { workspace = true } diff --git a/mithril-common/Cargo.toml b/mithril-common/Cargo.toml index b5790070c71..5e523ed24f0 100644 --- a/mithril-common/Cargo.toml +++ b/mithril-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-common" -version = "0.4.83" +version = "0.4.84" description = "Common types, interfaces, and utilities for Mithril nodes." authors = { workspace = true } edition = { workspace = true }