@@ -146,4 +146,182 @@ mod tests {
146
146
assert ! ( result. contains( & ( "2024-10-30" . to_string( ) , "metric_1" . to_string( ) , 16 ) ) ) ;
147
147
}
148
148
}
149
+
150
+ mod signer_registration_summary {
151
+ use std:: sync:: Arc ;
152
+
153
+ use crate :: event_store:: {
154
+ database:: test_helper:: event_store_db_connection, TransmitterService ,
155
+ } ;
156
+ use crate :: test_tools:: TestLogger ;
157
+ use mithril_common:: entities:: Stake ;
158
+ use mithril_common:: { entities:: SignerWithStake , test_utils:: fake_data, StdResult } ;
159
+ use sqlite:: ConnectionThreadSafe ;
160
+
161
+ use super :: { EventMessage , EventPersister } ;
162
+
163
+ /// Insert a signer registration event in the database.
164
+ fn insert_registration_event (
165
+ persister : & EventPersister ,
166
+ epoch : & str ,
167
+ party_id : & str ,
168
+ stake : Stake ,
169
+ signer_node_version : & str ,
170
+ ) {
171
+ let ( tx, mut rx) = tokio:: sync:: mpsc:: unbounded_channel :: < EventMessage > ( ) ;
172
+ let transmitter_service = Arc :: new ( TransmitterService :: new ( tx, TestLogger :: stdout ( ) ) ) ;
173
+
174
+ let signers = fake_data:: signers_with_stakes ( 1 ) ;
175
+ let signer = SignerWithStake {
176
+ party_id : party_id. to_string ( ) ,
177
+ stake,
178
+ ..signers[ 0 ] . clone ( )
179
+ } ;
180
+
181
+ let _ = transmitter_service. send_signer_registration_event (
182
+ "Test" ,
183
+ & signer,
184
+ Some ( signer_node_version. to_string ( ) ) ,
185
+ epoch,
186
+ ) ;
187
+
188
+ let message: EventMessage = rx. try_recv ( ) . unwrap ( ) ;
189
+
190
+ let _event = persister. persist ( message) . unwrap ( ) ;
191
+ }
192
+
193
+ #[ derive( PartialEq ) ]
194
+ struct StakeSignerVersion {
195
+ epoch : i64 ,
196
+ version : String ,
197
+ total_epoch_stakes : i64 ,
198
+ stakes_version : i64 ,
199
+ stakes_ratio : String ,
200
+ pool_count : i64 ,
201
+ }
202
+ impl StakeSignerVersion {
203
+ fn new (
204
+ epoch : i64 ,
205
+ version : & str ,
206
+ total_epoch_stakes : i64 ,
207
+ stakes_version : i64 ,
208
+ stakes_ratio : & str ,
209
+ pool_count : i64 ,
210
+ ) -> Self {
211
+ Self {
212
+ epoch,
213
+ version : version. to_string ( ) ,
214
+ total_epoch_stakes,
215
+ stakes_version,
216
+ stakes_ratio : stakes_ratio. to_string ( ) ,
217
+ pool_count,
218
+ }
219
+ }
220
+ }
221
+
222
+ fn get_all_registrations (
223
+ connection : Arc < ConnectionThreadSafe > ,
224
+ ) -> StdResult < Vec < StakeSignerVersion > > {
225
+ let query = "select
226
+ epoch,
227
+ version,
228
+ total_epoch_stakes,
229
+ stakes_version,
230
+ stakes_ratio,
231
+ pool_count
232
+ from signer_registration_summary;" ;
233
+ let mut statement = connection. prepare ( query) ?;
234
+ let mut result = Vec :: new ( ) ;
235
+ while let Ok ( sqlite:: State :: Row ) = statement. next ( ) {
236
+ result. push ( StakeSignerVersion :: new (
237
+ statement. read :: < i64 , _ > ( "epoch" ) ?,
238
+ & statement. read :: < String , _ > ( "version" ) ?,
239
+ statement. read :: < i64 , _ > ( "total_epoch_stakes" ) ?,
240
+ statement. read :: < i64 , _ > ( "stakes_version" ) ?,
241
+ & statement. read :: < String , _ > ( "stakes_ratio" ) ?,
242
+ statement. read :: < i64 , _ > ( "pool_count" ) ?,
243
+ ) ) ;
244
+ }
245
+
246
+ Ok ( result)
247
+ }
248
+
249
+ #[ test]
250
+ fn retrieved_node_version ( ) {
251
+ let connection = Arc :: new ( event_store_db_connection ( ) . unwrap ( ) ) ;
252
+ let persister = EventPersister :: new ( connection. clone ( ) ) ;
253
+
254
+ insert_registration_event ( & persister, "3" , "A" , 15 , "0.2.234" ) ;
255
+ insert_registration_event ( & persister, "4" , "A" , 15 , "15.24.32" ) ;
256
+ insert_registration_event ( & persister, "5" , "A" , 15 , "0.4.789+ef0c28a" ) ;
257
+
258
+ let result = get_all_registrations ( connection) . unwrap ( ) ;
259
+
260
+ assert ! ( result. contains( & StakeSignerVersion :: new( 3 , "0.2.234" , 15 , 15 , "100 %" , 1 ) ) ) ;
261
+ assert ! ( result. contains( & StakeSignerVersion :: new( 4 , "15.24.32" , 15 , 15 , "100 %" , 1 ) ) ) ;
262
+ assert ! ( result. contains( & StakeSignerVersion :: new( 5 , "0.4.789" , 15 , 15 , "100 %" , 1 ) ) ) ;
263
+ }
264
+
265
+ #[ test]
266
+ fn retrieved_total_by_epoch ( ) {
267
+ let connection = Arc :: new ( event_store_db_connection ( ) . unwrap ( ) ) ;
268
+ let persister = EventPersister :: new ( connection. clone ( ) ) ;
269
+
270
+ insert_registration_event ( & persister, "8" , "A" , 20 , "1.0.2" ) ;
271
+ insert_registration_event ( & persister, "8" , "B" , 15 , "1.0.2" ) ;
272
+ insert_registration_event ( & persister, "9" , "A" , 56 , "1.0.2" ) ;
273
+ insert_registration_event ( & persister, "9" , "B" , 31 , "1.0.2" ) ;
274
+ let result = get_all_registrations ( connection) . unwrap ( ) ;
275
+
276
+ assert ! ( result. contains( & StakeSignerVersion :: new( 8 , "1.0.2" , 35 , 35 , "100 %" , 2 ) ) ) ;
277
+ assert ! ( result. contains( & StakeSignerVersion :: new( 9 , "1.0.2" , 87 , 87 , "100 %" , 2 ) ) ) ;
278
+ }
279
+
280
+ #[ test]
281
+ fn retrieved_percentage_per_version ( ) {
282
+ let connection = Arc :: new ( event_store_db_connection ( ) . unwrap ( ) ) ;
283
+ let persister = EventPersister :: new ( connection. clone ( ) ) ;
284
+
285
+ insert_registration_event ( & persister, "8" , "A" , 90 , "1.0.2" ) ;
286
+ insert_registration_event ( & persister, "8" , "B" , 30 , "1.0.2" ) ;
287
+ insert_registration_event ( & persister, "8" , "C" , 80 , "1.0.4" ) ;
288
+ let result = get_all_registrations ( connection) . unwrap ( ) ;
289
+
290
+ assert ! ( result. contains( & StakeSignerVersion :: new( 8 , "1.0.2" , 200 , 120 , "60 %" , 2 ) ) ) ;
291
+ assert ! ( result. contains( & StakeSignerVersion :: new( 8 , "1.0.4" , 200 , 80 , "40 %" , 1 ) ) ) ;
292
+ }
293
+
294
+ #[ test]
295
+ fn retrieved_percentage_per_epoch ( ) {
296
+ let connection = Arc :: new ( event_store_db_connection ( ) . unwrap ( ) ) ;
297
+ let persister = EventPersister :: new ( connection. clone ( ) ) ;
298
+
299
+ insert_registration_event ( & persister, "8" , "A" , 6 , "1.0.2" ) ;
300
+ insert_registration_event ( & persister, "8" , "B" , 4 , "1.0.4" ) ;
301
+ insert_registration_event ( & persister, "9" , "A" , 28 , "1.0.2" ) ;
302
+ insert_registration_event ( & persister, "9" , "B" , 12 , "1.0.4" ) ;
303
+ let result = get_all_registrations ( connection) . unwrap ( ) ;
304
+
305
+ assert ! ( result. contains( & StakeSignerVersion :: new( 8 , "1.0.2" , 10 , 6 , "60 %" , 1 ) ) ) ;
306
+ assert ! ( result. contains( & StakeSignerVersion :: new( 8 , "1.0.4" , 10 , 4 , "40 %" , 1 ) ) ) ;
307
+ assert ! ( result. contains( & StakeSignerVersion :: new( 9 , "1.0.2" , 40 , 28 , "70 %" , 1 ) ) ) ;
308
+ assert ! ( result. contains( & StakeSignerVersion :: new( 9 , "1.0.4" , 40 , 12 , "30 %" , 1 ) ) ) ;
309
+ }
310
+
311
+ #[ test]
312
+ fn with_multi_registrations_for_an_epoch_only_the_last_recorded_one_is_retained ( ) {
313
+ let connection = Arc :: new ( event_store_db_connection ( ) . unwrap ( ) ) ;
314
+ let persister = EventPersister :: new ( connection. clone ( ) ) ;
315
+
316
+ insert_registration_event ( & persister, "8" , "A" , 6 , "1.0.2" ) ;
317
+ insert_registration_event ( & persister, "8" , "A" , 8 , "1.0.2" ) ;
318
+ insert_registration_event ( & persister, "8" , "A" , 10 , "1.0.4" ) ;
319
+ insert_registration_event ( & persister, "8" , "A" , 7 , "1.0.3" ) ;
320
+
321
+ let result = get_all_registrations ( connection) . unwrap ( ) ;
322
+
323
+ assert ! ( result. contains( & StakeSignerVersion :: new( 8 , "1.0.3" , 7 , 7 , "100 %" , 1 ) ) ) ;
324
+ assert ! ( result. len( ) == 1 ) ;
325
+ }
326
+ }
149
327
}
0 commit comments