@@ -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
118121struct 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
133137struct 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