11import logging
2+ import time
23from src .blockchain_api import BlockchainApi
34from src .pc_epoch_calculator import PartnerChainEpochCalculator
45from src .partner_chain_rpc import DParam
@@ -350,20 +351,64 @@ def __find_first_pc_epoch_with_committee_rotation(self, get_pc_epoch_committee,
350351 @mark .candidate_status ("active" )
351352 @mark .test_key ('ETCM-6987' )
352353 def test_active_trustless_candidates_were_in_committee (
353- self , trustless_rotation_candidates : Candidates , get_candidate_participation : int
354+ self , trustless_rotation_candidates : Candidates , update_committee_attendance , db : Session , config : ApiConfig , api : BlockchainApi , current_mc_epoch
354355 ):
355356 """Test that active trustless candidates participated in committees
356357
357358 * get a list of trustless candidates for a given mainchain epoch
358359 * verify that each active candidate included in committees within an mainchain epoch
360+
361+ Note: Committees are selected based on data from the previous epoch, so a candidate
362+ who becomes active in epoch N will participate in committees starting from epoch N+1.
363+ However, if epoch N+1 hasn't completed yet, we check epoch N instead.
359364 """
360365 for candidate in trustless_rotation_candidates :
361- logging .info (
362- f"Verifying if { candidate .name } is found in committee for MC epoch { candidate .next_status_epoch } "
366+ # Committees are selected based on previous epoch data, so check the next epoch
367+ participation_epoch = candidate .next_status_epoch + 1
368+
369+ # If the next epoch hasn't completed yet, check the current epoch instead
370+ if participation_epoch > current_mc_epoch - 1 :
371+ participation_epoch = candidate .next_status_epoch
372+ logging .info (
373+ f"Next epoch { candidate .next_status_epoch + 1 } not yet complete, checking epoch { participation_epoch } "
374+ f"for candidate { candidate .name } (became active in epoch { candidate .next_status_epoch } )"
375+ )
376+ else :
377+ logging .info (
378+ f"Verifying if { candidate .name } is found in committee for MC epoch { participation_epoch } "
379+ f"(became active in epoch { candidate .next_status_epoch } )"
380+ )
381+
382+ # Update attendance for the epoch when candidate should participate
383+ try :
384+ update_committee_attendance (participation_epoch )
385+ except (ValueError , Exception ) as e :
386+ # If we can't get committee data for the epoch, skip this candidate
387+ if participation_epoch == candidate .next_status_epoch + 1 :
388+ # Try the current epoch instead
389+ participation_epoch = candidate .next_status_epoch
390+ logging .info (
391+ f"Could not get committee data for epoch { candidate .next_status_epoch + 1 } , "
392+ f"checking epoch { participation_epoch } instead for candidate { candidate .name } "
393+ )
394+ try :
395+ update_committee_attendance (participation_epoch )
396+ except (ValueError , Exception ):
397+ skip (f"Cannot check participation for candidate { candidate .name } - epochs not available" )
398+ else :
399+ skip (f"Cannot check participation for candidate { candidate .name } - epoch { participation_epoch } not available" )
400+
401+ query = (
402+ select (StakeDistributionCommittee )
403+ .where (StakeDistributionCommittee .mc_epoch == participation_epoch )
404+ .where (StakeDistributionCommittee .pc_pub_key == config .nodes_config .nodes [candidate .name ].public_key )
363405 )
364- assert get_candidate_participation (candidate ) > 0 , (
406+ committee_entry = db .scalars (query ).first ()
407+ actual_attendance = committee_entry .actual_attendance if committee_entry else 0
408+
409+ assert actual_attendance > 0 , (
365410 f"Trustless candidate { candidate .name } not found in any committees on mc epoch "
366- f"{ candidate .next_status_epoch } "
411+ f"{ participation_epoch } (became active in epoch { candidate .next_status_epoch } ) "
367412 )
368413
369414 @mark .candidate_status ("inactive" )
@@ -491,7 +536,6 @@ def test_authorities_matching_committee(self, api: BlockchainApi, config: ApiCon
491536 # There's a delay between selecting a committee and it being in power, which means the current
492537 # committee was selected based on inputs from the previous epoch
493538 committee = api .get_epoch_committee (current_epoch ).result ['committee' ]
494- authorities = api .get_authorities ()
495539
496540 if api .get_pc_epoch () > current_epoch :
497541 skip ("Epoch has changed while getting committee from partner chain rpc and blockchain api" )
@@ -504,6 +548,13 @@ def test_authorities_matching_committee(self, api: BlockchainApi, config: ApiCon
504548 validators_names .append (key )
505549 break
506550
551+ # Wait for authorities to sync with the committee
552+ time .sleep (30 )
553+ authorities = api .get_authorities ()
554+
555+ if api .get_pc_epoch () > current_epoch :
556+ skip ("Epoch has changed while getting committee from partner chain rpc and blockchain api" )
557+
507558 authorities_names = []
508559 for authority in authorities :
509560 for key , value in config .nodes_config .nodes .items ():
0 commit comments