1818 normalize_hyperparameters ,
1919 unlock_key ,
2020 blocks_to_duration ,
21+ float_to_u64 ,
22+ float_to_u16 ,
2123)
2224
2325if TYPE_CHECKING :
@@ -70,6 +72,44 @@ def allowed_value(
7072 return True , value
7173
7274
75+ def search_metadata (
76+ param_name : str , 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+ netuid: the specified netuid
85+ metadata: the subtensor.substrate.metadata
86+
87+ Returns:
88+ (success, dict of call params)
89+
90+ """
91+ arg_types = {"bool" : bool , "u16" : float_to_u16 , "u64" : float_to_u64 }
92+
93+ call_crafter = {"netuid" : netuid }
94+
95+ for pallet in metadata .pallets :
96+ if pallet .name == "AdminUtils" :
97+ for call in pallet .calls :
98+ if call .name == param_name :
99+ if "netuid" not in [x .name for x in call .args ]:
100+ return False , None
101+ for arg in call .args :
102+ if arg .name == "netuid" :
103+ continue
104+ raw_val = input (
105+ f"Enter a value for field '{ arg .name } ' with type '{ arg .typeName } '"
106+ )
107+ call_crafter [arg .name ] = arg_types [arg .typeName ](raw_val )
108+ return True , call_crafter
109+ else :
110+ return False , None
111+
112+
73113async def set_hyperparameter_extrinsic (
74114 subtensor : "SubtensorInterface" ,
75115 wallet : "Wallet" ,
@@ -110,44 +150,53 @@ async def set_hyperparameter_extrinsic(
110150 if not unlock_key (wallet ).success :
111151 return False
112152
153+ arbitrary_extrinsic = False
154+
113155 extrinsic , sudo_ = HYPERPARAMS .get (parameter , ("" , False ))
114156 if extrinsic is None :
115- err_console .print (":cross_mark: [red]Invalid hyperparameter specified.[/red]" )
116- return False
157+ arbitrary_extrinsic , call_params = search_metadata (
158+ parameter , netuid , subtensor .substrate .metadata
159+ )
160+ if not arbitrary_extrinsic :
161+ err_console .print (
162+ ":cross_mark: [red]Invalid hyperparameter specified.[/red]"
163+ )
164+ return False
117165
118166 with console .status (
119167 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' ]} ] ..." ,
120168 spinner = "earth" ,
121169 ):
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 )}
170+ if not arbitrary_extrinsic :
171+ substrate = subtensor .substrate
172+ extrinsic_params = await substrate .get_metadata_call_function (
173+ "AdminUtils" , extrinsic
144174 )
175+ call_params = {"netuid" : netuid }
176+
177+ # if input value is a list, iterate through the list and assign values
178+ if isinstance (value , list ):
179+ # Ensure that there are enough values for all non-netuid parameters
180+ non_netuid_fields = [
181+ param ["name" ]
182+ for param in extrinsic_params ["fields" ]
183+ if "netuid" not in param ["name" ]
184+ ]
185+
186+ if len (value ) < len (non_netuid_fields ):
187+ raise ValueError (
188+ "Not enough values provided in the list for all parameters"
189+ )
145190
146- else :
147- value_argument = extrinsic_params ["fields" ][
148- len (extrinsic_params ["fields" ]) - 1
149- ]
150- call_params [str (value_argument ["name" ])] = value
191+ call_params .update (
192+ {str (name ): val for name , val in zip (non_netuid_fields , value )}
193+ )
194+
195+ else :
196+ value_argument = extrinsic_params ["fields" ][
197+ len (extrinsic_params ["fields" ]) - 1
198+ ]
199+ call_params [str (value_argument ["name" ])] = value
151200
152201 # create extrinsic call
153202 call_ = await substrate .compose_call (
@@ -167,11 +216,16 @@ async def set_hyperparameter_extrinsic(
167216 if not success :
168217 err_console .print (f":cross_mark: [red]Failed[/red]: { err_msg } " )
169218 await asyncio .sleep (0.5 )
170-
219+ elif arbitrary_extrinsic :
220+ console .print (
221+ f":white_heavy_check_mark: "
222+ f"[dark_sea_green3]Hyperparameter { parameter } values changed to { call_params } [/dark_sea_green3]"
223+ )
171224 # Successful registration, final check for membership
172225 else :
173226 console .print (
174- f":white_heavy_check_mark: [dark_sea_green3]Hyperparameter { parameter } changed to { value } [/dark_sea_green3]"
227+ f":white_heavy_check_mark: "
228+ f"[dark_sea_green3]Hyperparameter { parameter } changed to { value } [/dark_sea_green3]"
175229 )
176230 return True
177231
@@ -481,7 +535,9 @@ async def sudo_set_hyperparameter(
481535 "commit_reveal_weights_enabled" ,
482536 "liquid_alpha_enabled" ,
483537 ]:
484- normalized_value = param_value .lower () in ["true" , "True" , "1" ]
538+ normalized_value = param_value .lower () in ["true" , "1" ]
539+ elif param_value in ("True" , "False" ):
540+ normalized_value = bool (param_value )
485541 else :
486542 normalized_value = param_value
487543
0 commit comments