@@ -146,4 +146,182 @@ mod tests {
146146 assert ! ( result. contains( & ( "2024-10-30" . to_string( ) , "metric_1" . to_string( ) , 16 ) ) ) ;
147147 }
148148 }
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+ }
149327}
0 commit comments