1818 normalize_hyperparameters ,
1919 unlock_key ,
2020 blocks_to_duration ,
21+ float_to_u64 ,
22+ float_to_u16 ,
2123)
2224
2325if TYPE_CHECKING :
@@ -70,12 +72,76 @@ def allowed_value(
7072 return True , value
7173
7274
75+ def search_metadata (
76+ param_name : str , value : Union [str , bool , float , list [float ]], netuid : int , metadata
77+ ) -> tuple [bool , Optional [dict ]]:
78+ """
79+ Searches the substrate metadata AdminUtils pallet for a given parameter name. Crafts a response dict to be used
80+ as call parameters for setting this hyperparameter.
81+
82+ Args:
83+ param_name: the name of the hyperparameter
84+ value: the value to set the hyperparameter
85+ netuid: the specified netuid
86+ metadata: the subtensor.substrate.metadata
87+
88+ Returns:
89+ (success, dict of call params)
90+
91+ """
92+
93+ def string_to_bool (val ) -> bool :
94+ try :
95+ return {"true" : True , "1" : True , "0" : False , "false" : False }[val .lower ()]
96+ except KeyError :
97+ return ValueError
98+
99+ def type_converter_with_retry (type_ , val , arg_name ):
100+ try :
101+ if val is None :
102+ val = input (
103+ f"Enter a value for field '{ arg_name } ' with type '{ arg_type_output [type_ ]} ': "
104+ )
105+ return arg_types [type_ ](val )
106+ except ValueError :
107+ return type_converter_with_retry (type_ , None , arg_name )
108+
109+ arg_types = {"bool" : string_to_bool , "u16" : float_to_u16 , "u64" : float_to_u64 }
110+ arg_type_output = {"bool" : "bool" , "u16" : "float" , "u64" : "float" }
111+
112+ call_crafter = {"netuid" : netuid }
113+
114+ for pallet in metadata .pallets :
115+ if pallet .name == "AdminUtils" :
116+ for call in pallet .calls :
117+ if call .name == param_name :
118+ if "netuid" not in [x .name for x in call .args ]:
119+ return False , None
120+ call_args = [
121+ arg for arg in call .args if arg .value ["name" ] != "netuid"
122+ ]
123+ if len (call_args ) == 1 :
124+ arg = call_args [0 ].value
125+ call_crafter [arg ["name" ]] = type_converter_with_retry (
126+ arg ["typeName" ], value , arg ["name" ]
127+ )
128+ else :
129+ for arg_ in call_args :
130+ arg = arg_ .value
131+ call_crafter [arg ["name" ]] = type_converter_with_retry (
132+ arg ["typeName" ], None , arg ["name" ]
133+ )
134+ return True , call_crafter
135+ else :
136+ return False , None
137+
138+
73139async def set_hyperparameter_extrinsic (
74140 subtensor : "SubtensorInterface" ,
75141 wallet : "Wallet" ,
76142 netuid : int ,
77143 parameter : str ,
78- value : Union [str , bool , float , list [float ]],
144+ value : Optional [ Union [str , bool , float , list [float ] ]],
79145 wait_for_inclusion : bool = False ,
80146 wait_for_finalization : bool = True ,
81147) -> bool :
@@ -110,44 +176,58 @@ async def set_hyperparameter_extrinsic(
110176 if not unlock_key (wallet ).success :
111177 return False
112178
179+ arbitrary_extrinsic = False
180+
113181 extrinsic , sudo_ = HYPERPARAMS .get (parameter , ("" , False ))
114- if extrinsic is None :
115- err_console .print (":cross_mark: [red]Invalid hyperparameter specified.[/red]" )
116- return False
182+ if not extrinsic :
183+ arbitrary_extrinsic , call_params = search_metadata (
184+ parameter , value , netuid , subtensor .substrate .metadata
185+ )
186+ extrinsic = parameter
187+ if not arbitrary_extrinsic :
188+ err_console .print (
189+ ":cross_mark: [red]Invalid hyperparameter specified.[/red]"
190+ )
191+ return False
117192
193+ substrate = subtensor .substrate
194+ msg_value = value if not arbitrary_extrinsic else call_params
118195 with console .status (
119- f":satellite: Setting hyperparameter [{ COLOR_PALETTE ['GENERAL' ]['SUBHEADING' ]} ]{ parameter } [/{ COLOR_PALETTE ['GENERAL' ]['SUBHEADING' ]} ] to [{ COLOR_PALETTE ['GENERAL' ]['SUBHEADING' ]} ]{ value } [/{ COLOR_PALETTE ['GENERAL' ]['SUBHEADING' ]} ] on subnet: [{ COLOR_PALETTE ['GENERAL' ]['SUBHEADING' ]} ]{ netuid } [/{ COLOR_PALETTE ['GENERAL' ]['SUBHEADING' ]} ] ..." ,
196+ f":satellite: Setting hyperparameter [{ COLOR_PALETTE ['GENERAL' ]['SUBHEADING' ]} ]{ parameter } "
197+ f"[/{ COLOR_PALETTE ['GENERAL' ]['SUBHEADING' ]} ] to [{ COLOR_PALETTE ['GENERAL' ]['SUBHEADING' ]} ]{ msg_value } "
198+ f"[/{ COLOR_PALETTE ['GENERAL' ]['SUBHEADING' ]} ] on subnet: [{ COLOR_PALETTE ['GENERAL' ]['SUBHEADING' ]} ]"
199+ f"{ netuid } [/{ COLOR_PALETTE ['GENERAL' ]['SUBHEADING' ]} ] ..." ,
120200 spinner = "earth" ,
121201 ):
122- substrate = subtensor .substrate
123- extrinsic_params = await substrate .get_metadata_call_function (
124- "AdminUtils" , extrinsic
125- )
126- call_params : dict [str , Union [str , bool , float ]] = {"netuid" : netuid }
127-
128- # if input value is a list, iterate through the list and assign values
129- if isinstance (value , list ):
130- # Ensure that there are enough values for all non-netuid parameters
131- non_netuid_fields = [
132- param ["name" ]
133- for param in extrinsic_params ["fields" ]
134- if "netuid" not in param ["name" ]
135- ]
136-
137- if len (value ) < len (non_netuid_fields ):
138- raise ValueError (
139- "Not enough values provided in the list for all parameters"
140- )
141-
142- call_params .update (
143- {str (name ): val for name , val in zip (non_netuid_fields , value )}
202+ if not arbitrary_extrinsic :
203+ extrinsic_params = await substrate .get_metadata_call_function (
204+ "AdminUtils" , extrinsic
144205 )
206+ call_params = {"netuid" : netuid }
207+
208+ # if input value is a list, iterate through the list and assign values
209+ if isinstance (value , list ):
210+ # Ensure that there are enough values for all non-netuid parameters
211+ non_netuid_fields = [
212+ param ["name" ]
213+ for param in extrinsic_params ["fields" ]
214+ if "netuid" not in param ["name" ]
215+ ]
216+
217+ if len (value ) < len (non_netuid_fields ):
218+ raise ValueError (
219+ "Not enough values provided in the list for all parameters"
220+ )
145221
146- else :
147- value_argument = extrinsic_params ["fields" ][
148- len (extrinsic_params ["fields" ]) - 1
149- ]
150- call_params [str (value_argument ["name" ])] = value
222+ call_params .update (
223+ {str (name ): val for name , val in zip (non_netuid_fields , value )}
224+ )
225+
226+ else :
227+ value_argument = extrinsic_params ["fields" ][
228+ len (extrinsic_params ["fields" ]) - 1
229+ ]
230+ call_params [str (value_argument ["name" ])] = value
151231
152232 # create extrinsic call
153233 call_ = await substrate .compose_call (
@@ -167,11 +247,16 @@ async def set_hyperparameter_extrinsic(
167247 if not success :
168248 err_console .print (f":cross_mark: [red]Failed[/red]: { err_msg } " )
169249 await asyncio .sleep (0.5 )
170-
250+ elif arbitrary_extrinsic :
251+ console .print (
252+ f":white_heavy_check_mark: "
253+ f"[dark_sea_green3]Hyperparameter { parameter } values changed to { call_params } [/dark_sea_green3]"
254+ )
171255 # Successful registration, final check for membership
172256 else :
173257 console .print (
174- f":white_heavy_check_mark: [dark_sea_green3]Hyperparameter { parameter } changed to { value } [/dark_sea_green3]"
258+ f":white_heavy_check_mark: "
259+ f"[dark_sea_green3]Hyperparameter { parameter } changed to { value } [/dark_sea_green3]"
175260 )
176261 return True
177262
@@ -470,7 +555,7 @@ async def sudo_set_hyperparameter(
470555 subtensor : "SubtensorInterface" ,
471556 netuid : int ,
472557 param_name : str ,
473- param_value : str ,
558+ param_value : Optional [ str ] ,
474559):
475560 """Set subnet hyperparameters."""
476561
@@ -481,7 +566,12 @@ async def sudo_set_hyperparameter(
481566 "commit_reveal_weights_enabled" ,
482567 "liquid_alpha_enabled" ,
483568 ]:
484- normalized_value = param_value .lower () in ["true" , "True" , "1" ]
569+ normalized_value = param_value .lower () in ["true" , "1" ]
570+ elif param_value in ("True" , "False" ):
571+ normalized_value = {
572+ "True" : True ,
573+ "False" : False ,
574+ }[param_value ]
485575 else :
486576 normalized_value = param_value
487577
@@ -492,7 +582,6 @@ async def sudo_set_hyperparameter(
492582 f"Value is { normalized_value } but must be { value } "
493583 )
494584 return
495-
496585 success = await set_hyperparameter_extrinsic (
497586 subtensor , wallet , netuid , param_name , value
498587 )
0 commit comments