Skip to content

Commit 1419034

Browse files
committed
feat: compute and store the total stake in the Epoch service
1 parent a723278 commit 1419034

File tree

1 file changed

+60
-19
lines changed

1 file changed

+60
-19
lines changed

mithril-aggregator/src/services/epoch_service.rs

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ pub trait EpochService: Sync + Send {
113113

114114
/// Get the total number of SPOs for the current epoch.
115115
fn total_spo(&self) -> StdResult<&u32>;
116+
117+
/// Get the total stake for the current epoch.
118+
fn total_stake(&self) -> StdResult<&u64>;
116119
}
117120

118121
struct EpochData {
@@ -128,6 +131,7 @@ struct EpochData {
128131
next_signers: Vec<Signer>,
129132
signed_entity_config: SignedEntityConfig,
130133
total_spo: u32,
134+
total_stake: u64,
131135
}
132136

133137
struct ComputedEpochData {
@@ -215,7 +219,7 @@ impl MithrilEpochService {
215219
Ok(cardano_era)
216220
}
217221

218-
async fn get_total_spo(&self, epoch: Epoch) -> StdResult<u32> {
222+
async fn get_total_spo_and_total_stake(&self, epoch: Epoch) -> StdResult<(u32, u64)> {
219223
let stake_distribution = self
220224
.stake_distribution_service
221225
.get_stake_distribution(epoch)
@@ -224,7 +228,10 @@ impl MithrilEpochService {
224228
format!("Epoch service failed to obtain the stake distribution for epoch: {epoch}")
225229
})?;
226230

227-
Ok(stake_distribution.len() as u32)
231+
Ok((
232+
stake_distribution.len() as u32,
233+
stake_distribution.values().sum(),
234+
))
228235
}
229236

230237
async fn get_signers_with_stake_at_epoch(
@@ -335,7 +342,7 @@ impl EpochService for MithrilEpochService {
335342
.clone(),
336343
};
337344

338-
let total_spo = self.get_total_spo(epoch).await?;
345+
let (total_spo, total_stake) = self.get_total_spo_and_total_stake(epoch).await?;
339346

340347
self.epoch_data = Some(EpochData {
341348
cardano_era,
@@ -350,6 +357,7 @@ impl EpochService for MithrilEpochService {
350357
next_signers,
351358
signed_entity_config,
352359
total_spo,
360+
total_stake,
353361
});
354362
self.computed_epoch_data = None;
355363

@@ -485,6 +493,10 @@ impl EpochService for MithrilEpochService {
485493
fn total_spo(&self) -> StdResult<&u32> {
486494
Ok(&self.unwrap_data()?.total_spo)
487495
}
496+
497+
fn total_stake(&self) -> StdResult<&u64> {
498+
Ok(&self.unwrap_data()?.total_stake)
499+
}
488500
}
489501

490502
#[cfg(test)]
@@ -508,6 +520,7 @@ pub struct FakeEpochServiceBuilder {
508520
pub next_signers_with_stake: Vec<SignerWithStake>,
509521
pub signed_entity_config: SignedEntityConfig,
510522
pub total_spo: u32,
523+
pub total_stake: u64,
511524
}
512525

513526
#[cfg(test)]
@@ -527,6 +540,7 @@ impl FakeEpochServiceBuilder {
527540
next_signers_with_stake: signers,
528541
signed_entity_config: SignedEntityConfig::dummy(),
529542
total_spo: 0,
543+
total_stake: 0,
530544
}
531545
}
532546

@@ -563,6 +577,7 @@ impl FakeEpochServiceBuilder {
563577
next_signers,
564578
signed_entity_config: self.signed_entity_config,
565579
total_spo: self.total_spo,
580+
total_stake: self.total_stake,
566581
}),
567582
computed_epoch_data: Some(ComputedEpochData {
568583
aggregate_verification_key: protocol_multi_signer
@@ -760,6 +775,10 @@ impl EpochService for FakeEpochService {
760775
fn total_spo(&self) -> StdResult<&u32> {
761776
Ok(&self.unwrap_data()?.total_spo)
762777
}
778+
779+
fn total_stake(&self) -> StdResult<&u64> {
780+
Ok(&self.unwrap_data()?.total_stake)
781+
}
763782
}
764783

765784
#[cfg(test)]
@@ -769,7 +788,9 @@ mod tests {
769788
BlockNumber, CardanoTransactionsSigningConfig, PartyId, StakeDistribution,
770789
};
771790
use mithril_common::era::SupportedEra;
772-
use mithril_common::test_utils::{fake_data, MithrilFixture, MithrilFixtureBuilder};
791+
use mithril_common::test_utils::{
792+
fake_data, MithrilFixture, MithrilFixtureBuilder, StakeDistributionGenerationMethod,
793+
};
773794
use mithril_persistence::store::adapter::MemoryAdapter;
774795
use std::collections::{BTreeSet, HashMap};
775796

@@ -780,13 +801,13 @@ mod tests {
780801

781802
use super::*;
782803

783-
fn stake_distribution_with_given_number_of_spo(total_spo: u32) -> StakeDistribution {
784-
let mut stake_distribution: StakeDistribution = StakeDistribution::new();
785-
for i in 0..total_spo {
786-
let party_id = format!("party-id-{i}");
787-
stake_distribution.insert(party_id.clone(), 0);
788-
}
789-
stake_distribution
804+
fn build_uniform_stake_distribution(total_spo: u32, stake_by_spo: u64) -> StakeDistribution {
805+
let fixture = MithrilFixtureBuilder::default()
806+
.with_signers(total_spo as usize)
807+
.with_stake_distribution(StakeDistributionGenerationMethod::Uniform(stake_by_spo))
808+
.build();
809+
810+
fixture.stake_distribution()
790811
}
791812

792813
#[derive(Debug, Clone, PartialEq)]
@@ -805,6 +826,7 @@ mod tests {
805826
next_signers: BTreeSet<Signer>,
806827
signed_entity_config: SignedEntityConfig,
807828
total_spo: u32,
829+
total_stake: u64,
808830
}
809831

810832
#[derive(Debug, Clone, PartialEq)]
@@ -844,6 +866,7 @@ mod tests {
844866
next_signers: service.next_signers()?.clone().into_iter().collect(),
845867
signed_entity_config: service.signed_entity_config()?.clone(),
846868
total_spo: *service.total_spo()?,
869+
total_stake: *service.total_stake()?,
847870
})
848871
}
849872
}
@@ -881,6 +904,7 @@ mod tests {
881904
stored_next_epoch_settings: AggregatorEpochSettings,
882905
stored_signer_registration_epoch_settings: AggregatorEpochSettings,
883906
total_spo: u32,
907+
total_stake: u64,
884908
}
885909

886910
impl EpochServiceBuilder {
@@ -907,7 +931,8 @@ mod tests {
907931
protocol_parameters: epoch_fixture.protocol_parameters(),
908932
cardano_transactions_signing_config: CardanoTransactionsSigningConfig::dummy(),
909933
},
910-
total_spo: 0,
934+
total_spo: 1,
935+
total_stake: 0,
911936
}
912937
}
913938

@@ -948,11 +973,23 @@ mod tests {
948973

949974
let era_checker = EraChecker::new(self.mithril_era, Epoch::default());
950975

951-
let stake_distribution = stake_distribution_with_given_number_of_spo(self.total_spo);
952-
let mut stake_distribution_service = MockStakeDistributionService::new();
953-
stake_distribution_service
954-
.expect_get_stake_distribution()
955-
.returning(move |_| Ok(stake_distribution.clone()));
976+
let stake_distribution_service = {
977+
assert!(
978+
self.total_stake % self.total_spo as u64 == 0,
979+
"'total_stake' must be a multiple of 'total_spo' to create a uniform stake distribution"
980+
);
981+
let stake_per_spo = self.total_stake / self.total_spo as u64;
982+
983+
let stake_distribution =
984+
build_uniform_stake_distribution(self.total_spo, stake_per_spo);
985+
986+
let mut stake_distribution_service = MockStakeDistributionService::new();
987+
stake_distribution_service
988+
.expect_get_stake_distribution()
989+
.returning(move |_| Ok(stake_distribution.clone()));
990+
991+
stake_distribution_service
992+
};
956993

957994
MithrilEpochService::new(
958995
AggregatorEpochSettings {
@@ -997,7 +1034,8 @@ mod tests {
9971034
allowed_discriminants: SignedEntityConfig::dummy().allowed_discriminants,
9981035
cardano_era: "CardanoEra".to_string(),
9991036
mithril_era: SupportedEra::eras()[1],
1000-
total_spo: 37,
1037+
total_spo: 40,
1038+
total_stake: 20_000_000,
10011039
..EpochServiceBuilder::new(epoch, current_epoch_fixture.clone())
10021040
};
10031041

@@ -1034,7 +1072,8 @@ mod tests {
10341072
current_signers: current_epoch_fixture.signers().into_iter().collect(),
10351073
next_signers: next_epoch_fixture.signers().into_iter().collect(),
10361074
signed_entity_config: SignedEntityConfig::dummy(),
1037-
total_spo: 37,
1075+
total_spo: 40,
1076+
total_stake: 20_000_000,
10381077
}
10391078
);
10401079
}
@@ -1252,6 +1291,7 @@ mod tests {
12521291
),
12531292
("signed_entity_config", service.signed_entity_config().err()),
12541293
("total_spo", service.total_spo().err()),
1294+
("total_stake", service.total_stake().err()),
12551295
] {
12561296
let error =
12571297
res.unwrap_or_else(|| panic!("getting {name} should have returned an error"));
@@ -1288,6 +1328,7 @@ mod tests {
12881328
assert!(service.next_signers().is_ok());
12891329
assert!(service.signed_entity_config().is_ok());
12901330
assert!(service.total_spo().is_ok());
1331+
assert!(service.total_stake().is_ok());
12911332

12921333
for (name, res) in [
12931334
(

0 commit comments

Comments
 (0)