@@ -21,12 +21,13 @@ async def check_validator_registration(session, relay_url, pubkey):
2121 """Check if a validator is registered with a specific relay"""
2222 url = f"{ relay_url } /relay/v1/data/validator_registration"
2323 try :
24- async with session .get (url , params = {'pubkey' : pubkey }) as response :
24+ async with session .get (url , params = {'pubkey' : pubkey }, timeout = 5 ) as response :
2525 if response .status == 200 :
2626 return True
2727 return False
28- except :
29- raise RelayRequestException (f"Failed to request validator registration from { relay_url } " )
28+ except Exception as e :
29+ print (f"Warning: Could not check registration status for { relay_url } : { str (e )} " )
30+ return None # Return None to indicate unknown status
3031
3132async def get_validator_keys_from_csm (config ):
3233 csm = CSM (config )
@@ -39,37 +40,125 @@ async def check_relays(config, args):
3940
4041 # Get whitelisted relays
4142 relay_tuples = await get_whitelisted_relays (config )
42- # Extract just the URLs from the relay tuples
4343 relay_urls = [relay [0 ] for relay in relay_tuples ]
44- print (f"Found { len (relay_urls )} whitelisted relays" )
44+
45+ # Separate mandatory and optional relays
46+ mandatory_relays = [relay [0 ] for relay in relay_tuples if relay [2 ]] # relay[2] is the mandatory flag
47+ optional_relays = [relay [0 ] for relay in relay_tuples if not relay [2 ]]
48+
49+ print (f"Found { len (relay_urls )} whitelisted relays ({ len (mandatory_relays )} mandatory, { len (optional_relays )} optional)" )
4550
4651 # Get validator public keys from CSM
4752 validator_keys = await get_validator_keys_from_csm (config )
48- print (f"Found { len (validator_keys )} validators in CSM" )
53+
54+ # If pubkey is specified, only check that validator
55+ if hasattr (args , 'pubkey' ) and args .pubkey :
56+ if args .pubkey not in validator_keys :
57+ print (f"Error: Validator { args .pubkey } not found in CSM" )
58+ return
59+ validator_keys = [args .pubkey ]
60+ print (f"Checking specific validator: { args .pubkey } " )
61+ else :
62+ print (f"Found { len (validator_keys )} validators in CSM" )
4963
5064 # Check registration for each validator with each relay
5165 async with aiohttp .ClientSession () as session :
5266 results = {}
53- for validator in validator_keys :
54- results [validator ] = {'total' : 0 , 'relays' : []}
67+
68+ # Process validators in chunks to limit concurrency
69+ chunk_size = 10
70+ for i in range (0 , len (validator_keys ), chunk_size ):
71+ validator_chunk = validator_keys [i :i + chunk_size ]
72+
73+ tasks = []
74+ for validator in validator_chunk :
75+ results [validator ] = {
76+ 'mandatory_total' : 0 ,
77+ 'optional_total' : 0 ,
78+ 'mandatory_relays' : [],
79+ 'optional_relays' : [],
80+ 'unknown' : []
81+ }
82+ for relay_url in relay_urls :
83+ tasks .append (check_validator_registration (session , relay_url , validator ))
84+
85+ chunk_results = await asyncio .gather (* tasks )
86+
87+ for validator_idx , validator in enumerate (validator_chunk ):
88+ for relay_idx , is_registered in enumerate (chunk_results [validator_idx * len (relay_urls ):(validator_idx + 1 ) * len (relay_urls )]):
89+ relay_url = relay_urls [relay_idx ]
90+ if is_registered is True :
91+ if relay_url in mandatory_relays :
92+ results [validator ]['mandatory_total' ] += 1
93+ results [validator ]['mandatory_relays' ].append (relay_url )
94+ else :
95+ results [validator ]['optional_total' ] += 1
96+ results [validator ]['optional_relays' ].append (relay_url )
97+ elif is_registered is None :
98+ results [validator ]['unknown' ].append (relay_url )
99+
100+ if not args .pubkey : # Only show progress for bulk checks
101+ print (f"Processed { min (i + chunk_size , len (validator_keys ))} /{ len (validator_keys )} validators..." )
102+
103+ # Print results based on mode
104+ if args .pubkey or (hasattr (args , 'detailed' ) and args .detailed ):
105+ print_detailed_report (results , relay_tuples , mandatory_relays , optional_relays )
106+ else :
107+ print_summary_report (results , mandatory_relays , optional_relays )
108+
109+ def print_summary_report (results , mandatory_relays , optional_relays ):
110+ """Print condensed summary of validator relay registration status"""
111+ print ("\n Relay Coverage Summary:" )
112+ print ("-" * 50 )
113+
114+ ok_count = 0
115+ not_ok_count = 0
116+
117+ for validator , data in results .items ():
118+ is_ok = data ['mandatory_total' ] >= 2 # At least 2 mandatory relays required
119+ status = "OK" if is_ok else "NOT OK"
120+
121+ if is_ok :
122+ ok_count += 1
123+ else :
124+ not_ok_count += 1
55125
56- for relay_url in relay_urls :
57- is_registered = await check_validator_registration (session , relay_url , validator )
58- if is_registered :
59- results [validator ]['total' ] += 1
60- results [validator ]['relays' ].append (relay_url )
126+ mandatory_coverage = f"{ data ['mandatory_total' ]} /{ len (mandatory_relays )} "
127+ optional_coverage = f"{ data ['optional_total' ]} /{ len (optional_relays )} "
128+
129+ print (f"Validator { validator } : { status :6} (Mandatory: { mandatory_coverage } , Optional: { optional_coverage } )" )
130+
131+ print (f"\n Summary: { ok_count } validators OK, { not_ok_count } validators NOT OK" )
132+
133+ def print_detailed_report (results , relay_tuples , mandatory_relays , optional_relays ):
134+ """Print detailed report of validator relay registration status"""
135+ print ("\n Detailed Relay Coverage Report:" )
136+ print ("-" * 50 )
137+
138+ for validator , data in results .items ():
139+ is_ok = data ['mandatory_total' ] >= 2
140+ status = "OK" if is_ok else "NOT OK"
141+
142+ print (f"\n Validator { validator } : { status } " )
143+ print (f"Registered with { data ['mandatory_total' ]} /{ len (mandatory_relays )} mandatory relays" )
144+ print (f"Registered with { data ['optional_total' ]} /{ len (optional_relays )} optional relays" )
145+
146+ if data ['unknown' ]:
147+ print (f"Could not check status for { len (data ['unknown' ])} relay(s):" )
148+ for relay in data ['unknown' ]:
149+ relay_info = next (r for r in relay_tuples if r [0 ] == relay )
150+ print (f" ? { relay } ({ relay_info [1 ]} - { relay_info [3 ]} )" )
151+
152+ missing_mandatory = set (mandatory_relays ) - set (data ['mandatory_relays' ])
153+ if missing_mandatory :
154+ print ("Missing mandatory registrations:" )
155+ for relay in missing_mandatory :
156+ relay_info = next (r for r in relay_tuples if r [0 ] == relay )
157+ print (f" - { relay } ({ relay_info [1 ]} - { relay_info [3 ]} )" )
61158
62- # Print results
63- print ("\n Relay coverage report:" )
64- print ("-" * 50 )
65- for validator , data in results .items ():
66- coverage_pct = (data ['total' ] / len (relay_urls )) * 100
67- print (f"\n Validator { validator [:12 ]} ..." )
68- print (f"Registered with { data ['total' ]} /{ len (relay_urls )} relays ({ coverage_pct :.1f} %)" )
69- if data ['total' ] < len (relay_urls ):
70- print ("Missing registrations for relays:" )
71- missing_relays = set (relay_urls ) - set (data ['relays' ])
72- for relay in missing_relays :
73- # Find the full relay info for prettier printing
74- relay_info = next (r for r in relay_tuples if r [0 ] == relay )
75- print (f" - { relay } ({ relay_info [1 ]} - { relay_info [3 ]} )" )
159+ missing_optional = set (optional_relays ) - set (data ['optional_relays' ])
160+ if missing_optional :
161+ print ("Missing optional registrations:" )
162+ for relay in missing_optional :
163+ relay_info = next (r for r in relay_tuples if r [0 ] == relay )
164+ print (f" - { relay } ({ relay_info [1 ]} - { relay_info [3 ]} )" )
0 commit comments