@@ -2,12 +2,15 @@ use async_trait::async_trait;
2
2
use std:: collections:: HashMap ;
3
3
use tokio:: sync:: RwLock ;
4
4
5
- use mithril_common:: entities:: { Epoch , PartyId , Signer , SignerWithStake } ;
5
+ use mithril_common:: entities:: { Epoch , PartyId , Signer , SignerWithStake , StakeDistribution } ;
6
6
use mithril_common:: store:: { adapter:: StoreAdapter , StoreError } ;
7
7
8
8
type Adapter = Box < dyn StoreAdapter < Key = Epoch , Record = HashMap < PartyId , SignerWithStake > > > ;
9
9
10
10
/// Store and get signers verification keys for given epoch.
11
+ ///
12
+ /// Important note: This store works on the **recording** epoch, the epoch at which the signers
13
+ /// are signed into a certificate so they can sign single signatures at the next epoch.
11
14
#[ async_trait]
12
15
pub trait VerificationKeyStorer : Sync + Send {
13
16
/// Save the verification key, for the given [Signer] for the given [Epoch], returns the
@@ -26,6 +29,12 @@ pub trait VerificationKeyStorer: Sync + Send {
26
29
27
30
/// Prune all verification keys that are at or below the given epoch.
28
31
async fn prune_verification_keys ( & self , max_epoch_to_prune : Epoch ) -> Result < ( ) , StoreError > ;
32
+
33
+ /// Return the parties that are stored at the given epoch.
34
+ async fn get_stake_distribution_for_epoch (
35
+ & self ,
36
+ epoch : Epoch ,
37
+ ) -> Result < Option < StakeDistribution > , StoreError > ;
29
38
}
30
39
31
40
/// Store for the `VerificationKey`.
@@ -85,6 +94,19 @@ impl VerificationKeyStorer for VerificationKeyStore {
85
94
86
95
Ok ( ( ) )
87
96
}
97
+
98
+ async fn get_stake_distribution_for_epoch (
99
+ & self ,
100
+ epoch : Epoch ,
101
+ ) -> Result < Option < StakeDistribution > , StoreError > {
102
+ let record = self . adapter . read ( ) . await . get_record ( & epoch) . await ?;
103
+ Ok ( record. map ( |r| {
104
+ StakeDistribution :: from_iter (
105
+ r. into_iter ( )
106
+ . map ( |( party_id, signer) | ( party_id, signer. stake ) ) ,
107
+ )
108
+ } ) )
109
+ }
88
110
}
89
111
90
112
/// Macro that generate tests that a [VerificationKeyStorer] must pass
@@ -110,11 +132,21 @@ macro_rules! test_verification_key_storer {
110
132
test_suite:: get_verification_keys_for_empty_epoch( & $store_builder) . await ;
111
133
}
112
134
135
+ #[ tokio:: test]
136
+ async fn get_stake_distribution_for_empty_epoch( ) {
137
+ test_suite:: get_stake_distribution_for_empty_epoch( & $store_builder) . await ;
138
+ }
139
+
113
140
#[ tokio:: test]
114
141
async fn get_verification_keys_for_existing_epoch( ) {
115
142
test_suite:: get_verification_keys_for_existing_epoch( & $store_builder) . await ;
116
143
}
117
144
145
+ #[ tokio:: test]
146
+ async fn get_stake_distribution_for_existing_epoch( ) {
147
+ test_suite:: get_stake_distribution_for_existing_epoch( & $store_builder) . await ;
148
+ }
149
+
118
150
#[ tokio:: test]
119
151
async fn can_prune_keys_from_given_epoch_retention_limit( ) {
120
152
test_suite:: can_prune_keys_from_given_epoch_retention_limit( & $store_builder) . await ;
@@ -129,7 +161,7 @@ pub(crate) use test_verification_key_storer;
129
161
#[ macro_use]
130
162
#[ cfg( test) ]
131
163
pub mod test_suite {
132
- use mithril_common:: entities:: { Epoch , PartyId , Signer , SignerWithStake } ;
164
+ use mithril_common:: entities:: { Epoch , PartyId , Signer , SignerWithStake , StakeDistribution } ;
133
165
use mithril_common:: test_utils:: fake_keys;
134
166
use std:: collections:: { BTreeMap , HashMap } ;
135
167
use std:: sync:: Arc ;
@@ -233,6 +265,17 @@ pub mod test_suite {
233
265
assert ! ( res. is_none( ) ) ;
234
266
}
235
267
268
+ pub async fn get_stake_distribution_for_empty_epoch ( store_builder : & StoreBuilder ) {
269
+ let signers = build_signers ( 2 , 1 ) ;
270
+ let store = store_builder ( signers) ;
271
+ let res = store
272
+ . get_stake_distribution_for_epoch ( Epoch ( 0 ) )
273
+ . await
274
+ . unwrap ( ) ;
275
+
276
+ assert ! ( res. is_none( ) ) ;
277
+ }
278
+
236
279
pub async fn get_verification_keys_for_existing_epoch ( store_builder : & StoreBuilder ) {
237
280
let signers = build_signers ( 2 , 2 ) ;
238
281
let store = store_builder ( signers. clone ( ) ) ;
@@ -253,6 +296,26 @@ pub mod test_suite {
253
296
assert_eq ! ( expected_signers, res) ;
254
297
}
255
298
299
+ pub async fn get_stake_distribution_for_existing_epoch ( store_builder : & StoreBuilder ) {
300
+ let signers = build_signers ( 2 , 2 ) ;
301
+ let store = store_builder ( signers. clone ( ) ) ;
302
+
303
+ let expected: Option < StakeDistribution > = signers
304
+ . into_iter ( )
305
+ . filter ( |( e, _) | e == 1 )
306
+ . map ( |( _, signers) | {
307
+ StakeDistribution :: from_iter ( signers. into_iter ( ) . map ( |( p, s) | ( p, s. stake ) ) )
308
+ } )
309
+ . next ( ) ;
310
+ let res = store
311
+ . get_stake_distribution_for_epoch ( Epoch ( 1 ) )
312
+ . await
313
+ . unwrap ( )
314
+ . map ( |x| BTreeMap :: from_iter ( x. into_iter ( ) ) ) ;
315
+
316
+ assert_eq ! ( expected, res) ;
317
+ }
318
+
256
319
pub async fn can_prune_keys_from_given_epoch_retention_limit ( store_builder : & StoreBuilder ) {
257
320
let signers = build_signers ( 6 , 2 ) ;
258
321
let store = store_builder ( signers) ;
0 commit comments