@@ -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,14 +219,16 @@ 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)
222226 . await
223227 . with_context ( || "Epoch service failed to obtain stake distribution" ) ?;
224228
225- Ok ( stake_distribution. len ( ) as u32 )
229+ let total_stake = stake_distribution. values ( ) . copied ( ) . sum :: < u64 > ( ) ;
230+
231+ Ok ( ( stake_distribution. len ( ) as u32 , total_stake) )
226232 }
227233
228234 async fn get_signers_with_stake_at_epoch (
@@ -333,7 +339,7 @@ impl EpochService for MithrilEpochService {
333339 . clone ( ) ,
334340 } ;
335341
336- let total_spo = self . get_total_spo ( epoch) . await ?;
342+ let ( total_spo, total_stake ) = self . get_total_spo_and_total_stake ( epoch) . await ?;
337343
338344 self . epoch_data = Some ( EpochData {
339345 cardano_era,
@@ -348,6 +354,7 @@ impl EpochService for MithrilEpochService {
348354 next_signers,
349355 signed_entity_config,
350356 total_spo,
357+ total_stake,
351358 } ) ;
352359 self . computed_epoch_data = None ;
353360
@@ -483,6 +490,10 @@ impl EpochService for MithrilEpochService {
483490 fn total_spo ( & self ) -> StdResult < & u32 > {
484491 Ok ( & self . unwrap_data ( ) ?. total_spo )
485492 }
493+
494+ fn total_stake ( & self ) -> StdResult < & u64 > {
495+ Ok ( & self . unwrap_data ( ) ?. total_stake )
496+ }
486497}
487498
488499#[ cfg( test) ]
@@ -506,6 +517,7 @@ pub struct FakeEpochServiceBuilder {
506517 pub next_signers_with_stake : Vec < SignerWithStake > ,
507518 pub signed_entity_config : SignedEntityConfig ,
508519 pub total_spo : u32 ,
520+ pub total_stake : u64 ,
509521}
510522
511523#[ cfg( test) ]
@@ -525,6 +537,7 @@ impl FakeEpochServiceBuilder {
525537 next_signers_with_stake : signers,
526538 signed_entity_config : SignedEntityConfig :: dummy ( ) ,
527539 total_spo : 0 ,
540+ total_stake : 0 ,
528541 }
529542 }
530543
@@ -561,6 +574,7 @@ impl FakeEpochServiceBuilder {
561574 next_signers,
562575 signed_entity_config : self . signed_entity_config ,
563576 total_spo : self . total_spo ,
577+ total_stake : self . total_stake ,
564578 } ) ,
565579 computed_epoch_data : Some ( ComputedEpochData {
566580 aggregate_verification_key : protocol_multi_signer
@@ -758,6 +772,10 @@ impl EpochService for FakeEpochService {
758772 fn total_spo ( & self ) -> StdResult < & u32 > {
759773 Ok ( & self . unwrap_data ( ) ?. total_spo )
760774 }
775+
776+ fn total_stake ( & self ) -> StdResult < & u64 > {
777+ Ok ( & self . unwrap_data ( ) ?. total_stake )
778+ }
761779}
762780
763781#[ cfg( test) ]
@@ -767,7 +785,9 @@ mod tests {
767785 BlockNumber , CardanoTransactionsSigningConfig , PartyId , StakeDistribution ,
768786 } ;
769787 use mithril_common:: era:: SupportedEra ;
770- use mithril_common:: test_utils:: { fake_data, MithrilFixture , MithrilFixtureBuilder } ;
788+ use mithril_common:: test_utils:: {
789+ fake_data, MithrilFixture , MithrilFixtureBuilder , StakeDistributionGenerationMethod ,
790+ } ;
771791 use mithril_persistence:: store:: adapter:: MemoryAdapter ;
772792 use std:: collections:: { BTreeSet , HashMap } ;
773793
@@ -778,13 +798,19 @@ mod tests {
778798
779799 use super :: * ;
780800
781- fn stake_distribution_with_given_number_of_spo ( total_spo : u32 ) -> StakeDistribution {
782- let mut stake_distribution: StakeDistribution = StakeDistribution :: new ( ) ;
783- for i in 0 ..total_spo {
784- let party_id = format ! ( "party-id-{i}" ) ;
785- stake_distribution. insert ( party_id. clone ( ) , 0 ) ;
801+ fn build_stake_distribution ( total_spo : u32 , total_stake : u64 ) -> StakeDistribution {
802+ if total_stake % total_spo as u64 != 0 {
803+ panic ! ( "'total_stake' must be a multiple of 'total_spo' to facilitate the creation of a uniform stake distribution" ) ;
786804 }
787- stake_distribution
805+
806+ let fixture = MithrilFixtureBuilder :: default ( )
807+ . with_signers ( total_spo as usize )
808+ . with_stake_distribution ( StakeDistributionGenerationMethod :: Uniform (
809+ total_stake / total_spo as u64 ,
810+ ) )
811+ . build ( ) ;
812+
813+ fixture. stake_distribution ( )
788814 }
789815
790816 #[ derive( Debug , Clone , PartialEq ) ]
@@ -803,6 +829,7 @@ mod tests {
803829 next_signers : BTreeSet < Signer > ,
804830 signed_entity_config : SignedEntityConfig ,
805831 total_spo : u32 ,
832+ total_stake : u64 ,
806833 }
807834
808835 #[ derive( Debug , Clone , PartialEq ) ]
@@ -842,6 +869,7 @@ mod tests {
842869 next_signers : service. next_signers ( ) ?. clone ( ) . into_iter ( ) . collect ( ) ,
843870 signed_entity_config : service. signed_entity_config ( ) ?. clone ( ) ,
844871 total_spo : * service. total_spo ( ) ?,
872+ total_stake : * service. total_stake ( ) ?,
845873 } )
846874 }
847875 }
@@ -879,6 +907,7 @@ mod tests {
879907 stored_next_epoch_settings : AggregatorEpochSettings ,
880908 stored_signer_registration_epoch_settings : AggregatorEpochSettings ,
881909 total_spo : u32 ,
910+ total_stake : u64 ,
882911 }
883912
884913 impl EpochServiceBuilder {
@@ -905,7 +934,8 @@ mod tests {
905934 protocol_parameters : epoch_fixture. protocol_parameters ( ) ,
906935 cardano_transactions_signing_config : CardanoTransactionsSigningConfig :: dummy ( ) ,
907936 } ,
908- total_spo : 0 ,
937+ total_spo : 1 ,
938+ total_stake : 0 ,
909939 }
910940 }
911941
@@ -946,7 +976,7 @@ mod tests {
946976
947977 let era_checker = EraChecker :: new ( self . mithril_era , Epoch :: default ( ) ) ;
948978
949- let stake_distribution = stake_distribution_with_given_number_of_spo ( self . total_spo ) ;
979+ let stake_distribution = build_stake_distribution ( self . total_spo , self . total_stake ) ;
950980 let mut stake_distribution_service = MockStakeDistributionService :: new ( ) ;
951981 stake_distribution_service
952982 . expect_get_stake_distribution ( )
@@ -995,7 +1025,8 @@ mod tests {
9951025 allowed_discriminants : SignedEntityConfig :: dummy ( ) . allowed_discriminants ,
9961026 cardano_era : "CardanoEra" . to_string ( ) ,
9971027 mithril_era : SupportedEra :: eras ( ) [ 1 ] ,
998- total_spo : 37 ,
1028+ total_spo : 40 ,
1029+ total_stake : 20_000_000 ,
9991030 ..EpochServiceBuilder :: new ( epoch, current_epoch_fixture. clone ( ) )
10001031 } ;
10011032
@@ -1032,7 +1063,8 @@ mod tests {
10321063 current_signers: current_epoch_fixture. signers( ) . into_iter( ) . collect( ) ,
10331064 next_signers: next_epoch_fixture. signers( ) . into_iter( ) . collect( ) ,
10341065 signed_entity_config: SignedEntityConfig :: dummy( ) ,
1035- total_spo: 37 ,
1066+ total_spo: 40 ,
1067+ total_stake: 20_000_000 ,
10361068 }
10371069 ) ;
10381070 }
@@ -1250,6 +1282,7 @@ mod tests {
12501282 ) ,
12511283 ( "signed_entity_config" , service. signed_entity_config ( ) . err ( ) ) ,
12521284 ( "total_spo" , service. total_spo ( ) . err ( ) ) ,
1285+ ( "total_stake" , service. total_stake ( ) . err ( ) ) ,
12531286 ] {
12541287 let error =
12551288 res. unwrap_or_else ( || panic ! ( "getting {name} should have returned an error" ) ) ;
@@ -1286,6 +1319,7 @@ mod tests {
12861319 assert ! ( service. next_signers( ) . is_ok( ) ) ;
12871320 assert ! ( service. signed_entity_config( ) . is_ok( ) ) ;
12881321 assert ! ( service. total_spo( ) . is_ok( ) ) ;
1322+ assert ! ( service. total_stake( ) . is_ok( ) ) ;
12891323
12901324 for ( name, res) in [
12911325 (
0 commit comments