meshtensor-cli 9.18.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. meshtensor_cli/__init__.py +22 -0
  2. meshtensor_cli/cli.py +10742 -0
  3. meshtensor_cli/doc_generation_helper.py +4 -0
  4. meshtensor_cli/src/__init__.py +1085 -0
  5. meshtensor_cli/src/commands/__init__.py +0 -0
  6. meshtensor_cli/src/commands/axon/__init__.py +0 -0
  7. meshtensor_cli/src/commands/axon/axon.py +132 -0
  8. meshtensor_cli/src/commands/crowd/__init__.py +0 -0
  9. meshtensor_cli/src/commands/crowd/contribute.py +621 -0
  10. meshtensor_cli/src/commands/crowd/contributors.py +200 -0
  11. meshtensor_cli/src/commands/crowd/create.py +783 -0
  12. meshtensor_cli/src/commands/crowd/dissolve.py +219 -0
  13. meshtensor_cli/src/commands/crowd/refund.py +233 -0
  14. meshtensor_cli/src/commands/crowd/update.py +418 -0
  15. meshtensor_cli/src/commands/crowd/utils.py +124 -0
  16. meshtensor_cli/src/commands/crowd/view.py +991 -0
  17. meshtensor_cli/src/commands/governance/__init__.py +0 -0
  18. meshtensor_cli/src/commands/governance/governance.py +794 -0
  19. meshtensor_cli/src/commands/liquidity/__init__.py +0 -0
  20. meshtensor_cli/src/commands/liquidity/liquidity.py +699 -0
  21. meshtensor_cli/src/commands/liquidity/utils.py +202 -0
  22. meshtensor_cli/src/commands/proxy.py +700 -0
  23. meshtensor_cli/src/commands/stake/__init__.py +0 -0
  24. meshtensor_cli/src/commands/stake/add.py +799 -0
  25. meshtensor_cli/src/commands/stake/auto_staking.py +306 -0
  26. meshtensor_cli/src/commands/stake/children_hotkeys.py +865 -0
  27. meshtensor_cli/src/commands/stake/claim.py +770 -0
  28. meshtensor_cli/src/commands/stake/list.py +738 -0
  29. meshtensor_cli/src/commands/stake/move.py +1211 -0
  30. meshtensor_cli/src/commands/stake/remove.py +1466 -0
  31. meshtensor_cli/src/commands/stake/wizard.py +323 -0
  32. meshtensor_cli/src/commands/subnets/__init__.py +0 -0
  33. meshtensor_cli/src/commands/subnets/mechanisms.py +515 -0
  34. meshtensor_cli/src/commands/subnets/price.py +733 -0
  35. meshtensor_cli/src/commands/subnets/subnets.py +2908 -0
  36. meshtensor_cli/src/commands/sudo.py +1294 -0
  37. meshtensor_cli/src/commands/tc/__init__.py +0 -0
  38. meshtensor_cli/src/commands/tc/tc.py +190 -0
  39. meshtensor_cli/src/commands/treasury/__init__.py +0 -0
  40. meshtensor_cli/src/commands/treasury/treasury.py +194 -0
  41. meshtensor_cli/src/commands/view.py +354 -0
  42. meshtensor_cli/src/commands/wallets.py +2311 -0
  43. meshtensor_cli/src/commands/weights.py +467 -0
  44. meshtensor_cli/src/meshtensor/__init__.py +0 -0
  45. meshtensor_cli/src/meshtensor/balances.py +313 -0
  46. meshtensor_cli/src/meshtensor/chain_data.py +1263 -0
  47. meshtensor_cli/src/meshtensor/extrinsics/__init__.py +0 -0
  48. meshtensor_cli/src/meshtensor/extrinsics/mev_shield.py +174 -0
  49. meshtensor_cli/src/meshtensor/extrinsics/registration.py +1861 -0
  50. meshtensor_cli/src/meshtensor/extrinsics/root.py +550 -0
  51. meshtensor_cli/src/meshtensor/extrinsics/serving.py +255 -0
  52. meshtensor_cli/src/meshtensor/extrinsics/transfer.py +239 -0
  53. meshtensor_cli/src/meshtensor/meshtensor_interface.py +2598 -0
  54. meshtensor_cli/src/meshtensor/minigraph.py +254 -0
  55. meshtensor_cli/src/meshtensor/networking.py +12 -0
  56. meshtensor_cli/src/meshtensor/templates/main-filters.j2 +24 -0
  57. meshtensor_cli/src/meshtensor/templates/main-header.j2 +36 -0
  58. meshtensor_cli/src/meshtensor/templates/neuron-details.j2 +111 -0
  59. meshtensor_cli/src/meshtensor/templates/price-multi.j2 +113 -0
  60. meshtensor_cli/src/meshtensor/templates/price-single.j2 +99 -0
  61. meshtensor_cli/src/meshtensor/templates/subnet-details-header.j2 +49 -0
  62. meshtensor_cli/src/meshtensor/templates/subnet-details.j2 +32 -0
  63. meshtensor_cli/src/meshtensor/templates/subnet-metrics.j2 +57 -0
  64. meshtensor_cli/src/meshtensor/templates/subnets-table.j2 +28 -0
  65. meshtensor_cli/src/meshtensor/templates/table.j2 +267 -0
  66. meshtensor_cli/src/meshtensor/templates/view.css +1058 -0
  67. meshtensor_cli/src/meshtensor/templates/view.j2 +43 -0
  68. meshtensor_cli/src/meshtensor/templates/view.js +1053 -0
  69. meshtensor_cli/src/meshtensor/utils.py +2007 -0
  70. meshtensor_cli/version.py +23 -0
  71. meshtensor_cli-9.18.1.dist-info/METADATA +261 -0
  72. meshtensor_cli-9.18.1.dist-info/RECORD +74 -0
  73. meshtensor_cli-9.18.1.dist-info/WHEEL +4 -0
  74. meshtensor_cli-9.18.1.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,467 @@
1
+ import asyncio
2
+ import json
3
+ import os
4
+ from datetime import datetime, timedelta
5
+ from typing import TYPE_CHECKING, Optional
6
+
7
+ from meshtensor_wallet import Wallet
8
+ import numpy as np
9
+ from numpy.typing import NDArray
10
+ from async_substrate_interface.errors import SubstrateRequestException
11
+
12
+ from meshtensor_cli.src.meshtensor.utils import (
13
+ confirm_action,
14
+ print_error,
15
+ print_success,
16
+ console,
17
+ format_error_message,
18
+ json_console,
19
+ get_hotkey_pub_ss58,
20
+ print_extrinsic_id,
21
+ )
22
+ from meshtensor_cli.src.meshtensor.extrinsics.root import (
23
+ convert_weights_and_uids_for_emit,
24
+ generate_weight_hash,
25
+ )
26
+
27
+ if TYPE_CHECKING:
28
+ from meshtensor_cli.src.meshtensor.meshtensor_interface import MeshtensorInterface
29
+
30
+
31
+ # helpers and extrinsics
32
+
33
+
34
+ class SetWeightsExtrinsic:
35
+ def __init__(
36
+ self,
37
+ meshtensor: "MeshtensorInterface",
38
+ wallet: Wallet,
39
+ netuid: int,
40
+ proxy: Optional[str],
41
+ uids: NDArray,
42
+ weights: NDArray,
43
+ salt: list[int],
44
+ version_key: int,
45
+ prompt: bool = False,
46
+ decline: bool = False,
47
+ quiet: bool = False,
48
+ wait_for_inclusion: bool = False,
49
+ wait_for_finalization: bool = False,
50
+ ):
51
+ self.meshtensor = meshtensor
52
+ self.wallet = wallet
53
+ self.netuid = netuid
54
+ self.proxy = proxy
55
+ self.uids = uids
56
+ self.weights = weights
57
+ self.salt = salt
58
+ self.version_key = version_key
59
+ self.prompt = prompt
60
+ self.decline = decline
61
+ self.quiet = quiet
62
+ self.wait_for_inclusion = wait_for_inclusion
63
+ self.wait_for_finalization = wait_for_finalization
64
+
65
+ async def set_weights_extrinsic(self) -> tuple[bool, str, Optional[str]]:
66
+ """
67
+ Sets the inter-neuronal weights for the specified neuron. This process involves specifying the
68
+ influence or trust a neuron places on other neurons in the network, which is a fundamental aspect
69
+ of Meshtensor's decentralized learning architecture.
70
+
71
+ This function is crucial in shaping the network's collective intelligence, where each neuron's
72
+ learning and contribution are influenced by the weights it sets towards others.
73
+
74
+ Returns:
75
+ Tuple[bool, str]:
76
+ `True` if the setting of weights is successful, False otherwise. And `msg`, a string
77
+ value describing the success or potential error.
78
+ """
79
+
80
+ # Reformat and normalize.
81
+ weight_uids, weight_vals = convert_weights_and_uids_for_emit(
82
+ self.uids, self.weights
83
+ )
84
+
85
+ # Ask before moving on.
86
+ formatted_weight_vals = [float(v / 65535) for v in weight_vals]
87
+ if self.prompt and not confirm_action(
88
+ f"Do you want to set weights:\n[bold white]"
89
+ f" weights: {formatted_weight_vals}\n uids: {weight_uids}[/bold white ]?",
90
+ decline=self.decline,
91
+ quiet=self.quiet,
92
+ ):
93
+ return False, "Prompt refused.", None
94
+
95
+ # Check if the commit-reveal mechanism is active for the given netuid.
96
+ if bool(
97
+ await self.meshtensor.get_hyperparameter(
98
+ param_name="get_commit_reveal_weights_enabled",
99
+ netuid=self.netuid,
100
+ reuse_block=False,
101
+ )
102
+ ):
103
+ return await self._commit_reveal(
104
+ weight_uids,
105
+ weight_vals,
106
+ )
107
+ else:
108
+ return await self._set_weights_without_commit_reveal(
109
+ weight_uids,
110
+ weight_vals,
111
+ )
112
+
113
+ async def commit_weights(
114
+ self,
115
+ uids: list[int],
116
+ weights: list[int],
117
+ ) -> tuple[bool, Optional[str], Optional[str]]:
118
+ """
119
+ Commits a hash of the neuron's weights to the Meshtensor blockchain using the provided wallet.
120
+ This action serves as a commitment or snapshot of the neuron's current weight distribution.
121
+
122
+ Args:
123
+ uids (np.ndarray): NumPy array of neuron UIDs for which weights are being committed.
124
+ weights (np.ndarray): NumPy array of weight values corresponding to each UID.
125
+
126
+ Returns:
127
+ Tuple[bool, str]: ``True`` if the weight commitment is successful, False otherwise. And `msg`, a string
128
+ value describing the success or potential error.
129
+
130
+ This function allows neurons to create a tamper-proof record of their weight distribution at a specific point in time,
131
+ enhancing transparency and accountability within the Meshtensor network.
132
+ """
133
+
134
+ # Generate the hash of the weights
135
+ commit_hash = generate_weight_hash(
136
+ address=get_hotkey_pub_ss58(self.wallet),
137
+ netuid=self.netuid,
138
+ uids=uids,
139
+ values=weights,
140
+ salt=self.salt,
141
+ version_key=self.version_key,
142
+ )
143
+
144
+ # _logger.info("Commit Hash: {}".format(commit_hash))
145
+ try:
146
+ success, message, ext_id = await self.do_commit_weights(
147
+ commit_hash=commit_hash
148
+ )
149
+ except SubstrateRequestException as e:
150
+ print_error(f"Error committing weights: {format_error_message(e)}")
151
+ # meshtensor.logging.error(f"Error committing weights: {e}")
152
+ success = False
153
+ message = "No attempt made. Perhaps it is too soon to commit weights!"
154
+ ext_id = None
155
+
156
+ return success, message, ext_id
157
+
158
+ async def _commit_reveal(
159
+ self, weight_uids: list[int], weight_vals: list[int]
160
+ ) -> tuple[bool, str, Optional[str]]:
161
+ interval = int(
162
+ await self.meshtensor.get_hyperparameter(
163
+ param_name="get_commit_reveal_period",
164
+ netuid=self.netuid,
165
+ reuse_block=False,
166
+ )
167
+ )
168
+
169
+ if not self.salt:
170
+ # Generate a random salt of specified length to be used in the commit-reveal process
171
+ salt_length = 8
172
+ self.salt = list(os.urandom(salt_length))
173
+
174
+ # Attempt to commit the weights to the blockchain.
175
+ commit_success, commit_msg, ext_id = await self.commit_weights(
176
+ uids=weight_uids,
177
+ weights=weight_vals,
178
+ )
179
+
180
+ if commit_success:
181
+ current_time = datetime.now().astimezone().replace(microsecond=0)
182
+ reveal_time = (current_time + timedelta(seconds=interval)).isoformat()
183
+ cli_retry_cmd = f"--netuid {self.netuid} --uids {weight_uids} --weights {self.weights} --reveal-using-salt {self.salt}"
184
+ # Print params to screen and notify user this is a blocking operation
185
+ print_success("Weights hash committed to chain")
186
+ console.print(
187
+ f":alarm_clock: [dark_orange3]Weights hash will be revealed at {reveal_time}[/dark_orange3]"
188
+ )
189
+ console.print(
190
+ ":alarm_clock: [red]WARNING: Turning off your computer will prevent this process from executing!!![/red]"
191
+ )
192
+ console.print(
193
+ f"To manually retry after {reveal_time} run:\n{cli_retry_cmd}"
194
+ )
195
+
196
+ # meshtensor.logging.info(msg=f"Weights hash committed and will be revealed at {reveal_time}")
197
+
198
+ console.print(
199
+ "Note: BTCLI will wait until the reveal time. To place BTCLI into background:"
200
+ )
201
+ console.print(
202
+ "[red]CTRL+Z[/red] followed by the command [red]bg[/red] and [red]ENTER[/red]"
203
+ )
204
+ console.print(
205
+ "To bring BTLCI into the foreground use the command [red]fg[/red] and [red]ENTER[/red]"
206
+ )
207
+
208
+ # Attempt executing reveal function after a delay of 'interval'
209
+ await self.meshtensor.substrate.close()
210
+ await asyncio.sleep(interval)
211
+ async with self.meshtensor:
212
+ return await self.reveal(weight_uids, weight_vals)
213
+ else:
214
+ print_error(f"Failed: error:{commit_msg}")
215
+ # meshtensor.logging.error(msg=commit_msg, prefix="Set weights with hash commit",
216
+ # suffix=f"<red>Failed: {commit_msg}</red>")
217
+ return False, f"Failed to commit weights hash. {commit_msg}", None
218
+
219
+ async def reveal(self, weight_uids, weight_vals) -> tuple[bool, str, Optional[str]]:
220
+ # Attempt to reveal the weights using the salt.
221
+ success, msg, ext_id = await self.reveal_weights_extrinsic(
222
+ weight_uids, weight_vals
223
+ )
224
+
225
+ if success:
226
+ if not self.wait_for_finalization and not self.wait_for_inclusion:
227
+ return True, "Not waiting for finalization or inclusion.", ext_id
228
+
229
+ print_success("Weights hash revealed on chain")
230
+ return (
231
+ True,
232
+ "Successfully revealed previously committed weights hash.",
233
+ ext_id,
234
+ )
235
+ else:
236
+ return False, "Failed to reveal weights.", None
237
+
238
+ async def _set_weights_without_commit_reveal(
239
+ self,
240
+ weight_uids,
241
+ weight_vals,
242
+ ) -> tuple[bool, str, Optional[str]]:
243
+ async def _do_set_weights() -> tuple[bool, str, Optional[str]]:
244
+ call = await self.meshtensor.substrate.compose_call(
245
+ call_module="MeshtensorModule",
246
+ call_function="set_weights",
247
+ call_params={
248
+ "dests": weight_uids,
249
+ "weights": weight_vals,
250
+ "netuid": self.netuid,
251
+ "version_key": self.version_key,
252
+ },
253
+ )
254
+ # Period dictates how long the extrinsic will stay as part of waiting pool
255
+ success, err_msg, response = await self.meshtensor.sign_and_send_extrinsic(
256
+ call=call,
257
+ sign_with="hotkey",
258
+ wallet=self.wallet,
259
+ era={"period": 5},
260
+ wait_for_finalization=True,
261
+ wait_for_inclusion=True,
262
+ proxy=self.proxy,
263
+ )
264
+ # We only wait here if we expect finalization.
265
+ if not self.wait_for_finalization and not self.wait_for_inclusion:
266
+ return True, "Not waiting for finalization or inclusion.", None
267
+
268
+ if success:
269
+ ext_id_ = await response.get_extrinsic_identifier()
270
+ await print_extrinsic_id(response)
271
+ return True, "Successfully set weights.", ext_id_
272
+ else:
273
+ return False, err_msg, None
274
+
275
+ with console.status(
276
+ f":satellite: Setting weights on [white]{self.meshtensor.network}[/white] ..."
277
+ ):
278
+ success, error_message, ext_id = await _do_set_weights()
279
+
280
+ if not self.wait_for_finalization and not self.wait_for_inclusion:
281
+ return True, "Not waiting for finalization or inclusion.", None
282
+
283
+ if success:
284
+ print_success("Finalized")
285
+ # meshtensor.logging.success(prefix="Set weights", suffix="<green>Finalized: </green>" + str(success))
286
+ return True, "Successfully set weights and finalized.", ext_id
287
+ else:
288
+ # meshtensor.logging.error(msg=error_message, prefix="Set weights", suffix="<red>Failed: </red>")
289
+ return False, error_message, None
290
+
291
+ async def reveal_weights_extrinsic(
292
+ self, weight_uids, weight_vals
293
+ ) -> tuple[bool, str, Optional[str]]:
294
+ if self.prompt and not confirm_action(
295
+ "Would you like to reveal weights?", decline=self.decline, quiet=self.quiet
296
+ ):
297
+ return False, "User cancelled the operation.", None
298
+
299
+ call = await self.meshtensor.substrate.compose_call(
300
+ call_module="MeshtensorModule",
301
+ call_function="reveal_weights",
302
+ call_params={
303
+ "netuid": self.netuid,
304
+ "uids": weight_uids,
305
+ "values": weight_vals,
306
+ "salt": self.salt,
307
+ "version_key": self.version_key,
308
+ },
309
+ )
310
+ success, error_message, response = await self.meshtensor.sign_and_send_extrinsic(
311
+ call=call,
312
+ wallet=self.wallet,
313
+ sign_with="hotkey",
314
+ wait_for_inclusion=self.wait_for_inclusion,
315
+ wait_for_finalization=self.wait_for_finalization,
316
+ proxy=self.proxy,
317
+ )
318
+
319
+ if not self.wait_for_finalization and not self.wait_for_inclusion:
320
+ return True, "", None
321
+
322
+ if success:
323
+ await print_extrinsic_id(response)
324
+ return (
325
+ True,
326
+ "Successfully revealed weights.",
327
+ await response.get_extrinsic_identifier(),
328
+ )
329
+ else:
330
+ return False, error_message, None
331
+
332
+ async def do_commit_weights(
333
+ self, commit_hash
334
+ ) -> tuple[bool, Optional[str], Optional[str]]:
335
+ call = await self.meshtensor.substrate.compose_call(
336
+ call_module="MeshtensorModule",
337
+ call_function="commit_weights",
338
+ call_params={
339
+ "netuid": self.netuid,
340
+ "commit_hash": commit_hash,
341
+ },
342
+ )
343
+ success, err_msg, response = await self.meshtensor.sign_and_send_extrinsic(
344
+ call=call,
345
+ wallet=self.wallet,
346
+ sign_with="hotkey",
347
+ wait_for_inclusion=self.wait_for_inclusion,
348
+ wait_for_finalization=self.wait_for_finalization,
349
+ proxy=self.proxy,
350
+ )
351
+
352
+ if not self.wait_for_finalization and not self.wait_for_inclusion:
353
+ return True, None, None
354
+
355
+ if success:
356
+ ext_id = await response.get_extrinsic_identifier()
357
+ await print_extrinsic_id(response)
358
+ return True, None, ext_id
359
+ else:
360
+ return False, err_msg, None
361
+
362
+
363
+ # commands
364
+
365
+
366
+ async def reveal_weights(
367
+ meshtensor: "MeshtensorInterface",
368
+ wallet: Wallet,
369
+ netuid: int,
370
+ proxy: Optional[str],
371
+ uids: list[int],
372
+ weights: list[float],
373
+ salt: list[int],
374
+ version: int,
375
+ json_output: bool = False,
376
+ prompt: bool = True,
377
+ ) -> None:
378
+ """Reveal weights for a specific subnet."""
379
+ uids_ = np.array(
380
+ uids,
381
+ dtype=np.int64,
382
+ )
383
+ weights_ = np.array(
384
+ weights,
385
+ dtype=np.float32,
386
+ )
387
+ salt_ = np.array(
388
+ salt,
389
+ dtype=np.int64,
390
+ )
391
+ weight_uids, weight_vals = convert_weights_and_uids_for_emit(
392
+ uids=uids_, weights=weights_
393
+ )
394
+ # Call the reveal function in the module set_weights from extrinsics package
395
+ extrinsic = SetWeightsExtrinsic(
396
+ meshtensor=meshtensor,
397
+ wallet=wallet,
398
+ netuid=netuid,
399
+ uids=uids_,
400
+ weights=weights_,
401
+ salt=list(salt_),
402
+ version_key=version,
403
+ prompt=prompt,
404
+ proxy=proxy,
405
+ )
406
+ success, message, ext_id = await extrinsic.reveal(weight_uids, weight_vals)
407
+ if json_output:
408
+ json_console.print(
409
+ json.dumps(
410
+ {"success": success, "message": message, "extrinsic_identifier": ext_id}
411
+ )
412
+ )
413
+ else:
414
+ if success:
415
+ console.print("Weights revealed successfully")
416
+ else:
417
+ print_error(f"Failed to reveal weights: {message}")
418
+
419
+
420
+ async def commit_weights(
421
+ meshtensor: "MeshtensorInterface",
422
+ wallet: Wallet,
423
+ netuid: int,
424
+ uids: list[int],
425
+ proxy: Optional[str],
426
+ weights: list[float],
427
+ salt: list[int],
428
+ version: int,
429
+ json_output: bool = False,
430
+ prompt: bool = True,
431
+ ):
432
+ """Commits weights and then reveals them for a specific subnet"""
433
+ uids_ = np.array(
434
+ uids,
435
+ dtype=np.int64,
436
+ )
437
+ weights_ = np.array(
438
+ weights,
439
+ dtype=np.float32,
440
+ )
441
+ salt_ = np.array(
442
+ salt,
443
+ dtype=np.int64,
444
+ )
445
+ extrinsic = SetWeightsExtrinsic(
446
+ meshtensor=meshtensor,
447
+ wallet=wallet,
448
+ netuid=netuid,
449
+ uids=uids_,
450
+ weights=weights_,
451
+ salt=list(salt_),
452
+ version_key=version,
453
+ prompt=prompt,
454
+ proxy=proxy,
455
+ )
456
+ success, message, ext_id = await extrinsic.set_weights_extrinsic()
457
+ if json_output:
458
+ json_console.print(
459
+ json.dumps(
460
+ {"success": success, "message": message, "extrinsic_identifier": ext_id}
461
+ )
462
+ )
463
+ else:
464
+ if success:
465
+ console.print("Weights set successfully")
466
+ else:
467
+ print_error(f"Failed to commit weights: {message}")
File without changes