bittensor-cli 8.3.1__py3-none-any.whl → 8.4.0__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.
- bittensor_cli/__init__.py +1 -1
- bittensor_cli/cli.py +11 -7
- bittensor_cli/src/__init__.py +13 -9
- bittensor_cli/src/bittensor/async_substrate_interface.py +29 -35
- bittensor_cli/src/bittensor/extrinsics/registration.py +15 -14
- bittensor_cli/src/bittensor/subtensor_interface.py +5 -24
- bittensor_cli/src/bittensor/utils.py +12 -1
- bittensor_cli/src/commands/subnets.py +2 -5
- bittensor_cli/src/commands/sudo.py +4 -3
- bittensor_cli/src/commands/wallets.py +22 -10
- {bittensor_cli-8.3.1.dist-info → bittensor_cli-8.4.0.dist-info}/METADATA +3 -4
- {bittensor_cli-8.3.1.dist-info → bittensor_cli-8.4.0.dist-info}/RECORD +15 -15
- {bittensor_cli-8.3.1.dist-info → bittensor_cli-8.4.0.dist-info}/WHEEL +1 -1
- {bittensor_cli-8.3.1.dist-info → bittensor_cli-8.4.0.dist-info}/entry_points.txt +0 -0
- {bittensor_cli-8.3.1.dist-info → bittensor_cli-8.4.0.dist-info}/top_level.txt +0 -0
bittensor_cli/__init__.py
CHANGED
bittensor_cli/cli.py
CHANGED
@@ -58,7 +58,7 @@ except ImportError:
|
|
58
58
|
pass
|
59
59
|
|
60
60
|
|
61
|
-
__version__ = "8.
|
61
|
+
__version__ = "8.4.0"
|
62
62
|
|
63
63
|
|
64
64
|
_core_version = re.match(r"^\d+\.\d+\.\d+", __version__).group(0)
|
@@ -127,8 +127,6 @@ class Options:
|
|
127
127
|
use_password = typer.Option(
|
128
128
|
True,
|
129
129
|
help="Set this to `True` to protect the generated Bittensor key with a password.",
|
130
|
-
is_flag=True,
|
131
|
-
flag_value=False,
|
132
130
|
)
|
133
131
|
public_hex_key = typer.Option(None, help="The public key in hex format.")
|
134
132
|
ss58_address = typer.Option(
|
@@ -1843,8 +1841,6 @@ class CLIManager:
|
|
1843
1841
|
use_password: bool = typer.Option(
|
1844
1842
|
False, # Overriden to False
|
1845
1843
|
help="Set to 'True' to protect the generated Bittensor key with a password.",
|
1846
|
-
is_flag=True,
|
1847
|
-
flag_value=True,
|
1848
1844
|
),
|
1849
1845
|
quiet: bool = Options.quiet,
|
1850
1846
|
verbose: bool = Options.verbose,
|
@@ -1901,8 +1897,6 @@ class CLIManager:
|
|
1901
1897
|
use_password: bool = typer.Option(
|
1902
1898
|
False, # Overriden to False
|
1903
1899
|
help="Set to 'True' to protect the generated Bittensor key with a password.",
|
1904
|
-
is_flag=True,
|
1905
|
-
flag_value=True,
|
1906
1900
|
),
|
1907
1901
|
quiet: bool = Options.quiet,
|
1908
1902
|
verbose: bool = Options.verbose,
|
@@ -3910,6 +3904,16 @@ class CLIManager:
|
|
3910
3904
|
)
|
3911
3905
|
param_name = hyperparam_list[choice - 1]
|
3912
3906
|
|
3907
|
+
if param_name in ["alpha_high", "alpha_low"]:
|
3908
|
+
param_name = "alpha_values"
|
3909
|
+
low_val = FloatPrompt.ask(
|
3910
|
+
"Enter the new value for [dark_orange]alpha_low[/dark_orange]"
|
3911
|
+
)
|
3912
|
+
high_val = FloatPrompt.ask(
|
3913
|
+
"Enter the new value for [dark_orange]alpha_high[/dark_orange]"
|
3914
|
+
)
|
3915
|
+
param_value = f"{low_val},{high_val}"
|
3916
|
+
|
3913
3917
|
if not param_value:
|
3914
3918
|
param_value = Prompt.ask(
|
3915
3919
|
f"Enter the new value for [dark_orange]{param_name}[/dark_orange] in the VALUE column format"
|
bittensor_cli/src/__init__.py
CHANGED
@@ -318,28 +318,32 @@ NETWORK_EXPLORER_MAP = {
|
|
318
318
|
|
319
319
|
|
320
320
|
HYPERPARAMS = {
|
321
|
-
"
|
321
|
+
"rho": "sudo_set_rho",
|
322
|
+
"kappa": "sudo_set_kappa",
|
323
|
+
"immunity_period": "sudo_set_immunity_period",
|
324
|
+
"min_allowed_weights": "sudo_set_min_allowed_weights",
|
325
|
+
"max_weights_limit": "sudo_set_max_weight_limit",
|
326
|
+
"tempo": "sudo_set_tempo",
|
322
327
|
"min_difficulty": "sudo_set_min_difficulty",
|
323
328
|
"max_difficulty": "sudo_set_max_difficulty",
|
324
329
|
"weights_version": "sudo_set_weights_version_key",
|
325
330
|
"weights_rate_limit": "sudo_set_weights_set_rate_limit",
|
326
|
-
"
|
327
|
-
"immunity_period": "sudo_set_immunity_period",
|
328
|
-
"min_allowed_weights": "sudo_set_min_allowed_weights",
|
331
|
+
"adjustment_interval": "sudo_set_adjustment_interval",
|
329
332
|
"activity_cutoff": "sudo_set_activity_cutoff",
|
330
|
-
"
|
331
|
-
"network_pow_registration_allowed": "sudo_set_network_pow_registration_allowed",
|
333
|
+
"target_regs_per_interval": "sudo_set_target_registrations_per_interval",
|
332
334
|
"min_burn": "sudo_set_min_burn",
|
333
335
|
"max_burn": "sudo_set_max_burn",
|
336
|
+
"bonds_moving_avg": "sudo_set_bonds_moving_average",
|
337
|
+
"max_regs_per_block": "sudo_set_max_registrations_per_block",
|
338
|
+
"serving_rate_limit": "sudo_set_serving_rate_limit",
|
339
|
+
"max_validators": "sudo_set_max_allowed_validators",
|
334
340
|
"adjustment_alpha": "sudo_set_adjustment_alpha",
|
335
|
-
"rho": "sudo_set_rho",
|
336
|
-
"kappa": "sudo_set_kappa",
|
337
341
|
"difficulty": "sudo_set_difficulty",
|
338
|
-
"bonds_moving_avg": "sudo_set_bonds_moving_average",
|
339
342
|
"commit_reveal_weights_interval": "sudo_set_commit_reveal_weights_interval",
|
340
343
|
"commit_reveal_weights_enabled": "sudo_set_commit_reveal_weights_enabled",
|
341
344
|
"alpha_values": "sudo_set_alpha_values",
|
342
345
|
"liquid_alpha_enabled": "sudo_set_liquid_alpha_enabled",
|
346
|
+
"registration_allowed": "sudo_set_network_registration_allowed",
|
343
347
|
}
|
344
348
|
|
345
349
|
# Help Panels for cli help
|
@@ -4,12 +4,11 @@ import random
|
|
4
4
|
from collections import defaultdict
|
5
5
|
from dataclasses import dataclass
|
6
6
|
from hashlib import blake2b
|
7
|
-
from typing import Optional, Any, Union, Callable, Awaitable, cast
|
7
|
+
from typing import Optional, Any, Union, Callable, Awaitable, cast, TYPE_CHECKING
|
8
8
|
|
9
9
|
from async_property import async_property
|
10
10
|
from bt_decode import PortableRegistry, decode as decode_by_type_string, MetadataV15
|
11
11
|
from bittensor_wallet import Keypair
|
12
|
-
from packaging import version
|
13
12
|
from scalecodec import GenericExtrinsic
|
14
13
|
from scalecodec.base import ScaleBytes, ScaleType, RuntimeConfigurationObject
|
15
14
|
from scalecodec.type_registry import load_type_registry_preset
|
@@ -20,7 +19,13 @@ from substrateinterface.exceptions import (
|
|
20
19
|
BlockNotFound,
|
21
20
|
)
|
22
21
|
from substrateinterface.storage import StorageKey
|
23
|
-
import
|
22
|
+
from websockets.asyncio.client import connect
|
23
|
+
from websockets.exceptions import ConnectionClosed
|
24
|
+
|
25
|
+
from bittensor_cli.src.bittensor.utils import hex_to_bytes
|
26
|
+
|
27
|
+
if TYPE_CHECKING:
|
28
|
+
from websockets.asyncio.client import ClientConnection
|
24
29
|
|
25
30
|
ResultHandler = Callable[[dict, Any], Awaitable[tuple[dict, bool]]]
|
26
31
|
|
@@ -434,7 +439,7 @@ class RuntimeCache:
|
|
434
439
|
self.block_hashes[block_hash] = runtime
|
435
440
|
|
436
441
|
def retrieve(
|
437
|
-
self, block: Optional[int], block_hash: Optional[str]
|
442
|
+
self, block: Optional[int] = None, block_hash: Optional[str] = None
|
438
443
|
) -> Optional["Runtime"]:
|
439
444
|
if block is not None:
|
440
445
|
return self.blocks.get(block)
|
@@ -625,7 +630,7 @@ class Websocket:
|
|
625
630
|
# TODO allow setting max concurrent connections and rpc subscriptions per connection
|
626
631
|
# TODO reconnection logic
|
627
632
|
self.ws_url = ws_url
|
628
|
-
self.ws: Optional[
|
633
|
+
self.ws: Optional["ClientConnection"] = None
|
629
634
|
self.id = 0
|
630
635
|
self.max_subscriptions = max_subscriptions
|
631
636
|
self.max_connections = max_connections
|
@@ -647,15 +652,12 @@ class Websocket:
|
|
647
652
|
self._exit_task.cancel()
|
648
653
|
if not self._initialized:
|
649
654
|
self._initialized = True
|
650
|
-
await
|
655
|
+
self.ws = await asyncio.wait_for(
|
656
|
+
connect(self.ws_url, **self._options), timeout=10
|
657
|
+
)
|
651
658
|
self._receiving_task = asyncio.create_task(self._start_receiving())
|
652
659
|
return self
|
653
660
|
|
654
|
-
async def _connect(self):
|
655
|
-
self.ws = await asyncio.wait_for(
|
656
|
-
websockets.connect(self.ws_url, **self._options), timeout=10
|
657
|
-
)
|
658
|
-
|
659
661
|
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
660
662
|
async with self._lock:
|
661
663
|
self._in_use -= 1
|
@@ -696,9 +698,7 @@ class Websocket:
|
|
696
698
|
|
697
699
|
async def _recv(self) -> None:
|
698
700
|
try:
|
699
|
-
response = json.loads(
|
700
|
-
await cast(websockets.WebSocketClientProtocol, self.ws).recv()
|
701
|
-
)
|
701
|
+
response = json.loads(await self.ws.recv())
|
702
702
|
async with self._lock:
|
703
703
|
self._open_subscriptions -= 1
|
704
704
|
if "id" in response:
|
@@ -707,7 +707,7 @@ class Websocket:
|
|
707
707
|
self._received[response["params"]["subscription"]] = response
|
708
708
|
else:
|
709
709
|
raise KeyError(response)
|
710
|
-
except
|
710
|
+
except ConnectionClosed:
|
711
711
|
raise
|
712
712
|
except KeyError as e:
|
713
713
|
raise e
|
@@ -718,7 +718,7 @@ class Websocket:
|
|
718
718
|
await self._recv()
|
719
719
|
except asyncio.CancelledError:
|
720
720
|
pass
|
721
|
-
except
|
721
|
+
except ConnectionClosed:
|
722
722
|
# TODO try reconnect, but only if it's needed
|
723
723
|
raise
|
724
724
|
|
@@ -735,7 +735,7 @@ class Websocket:
|
|
735
735
|
try:
|
736
736
|
await self.ws.send(json.dumps({**payload, **{"id": original_id}}))
|
737
737
|
return original_id
|
738
|
-
except
|
738
|
+
except ConnectionClosed:
|
739
739
|
raise
|
740
740
|
|
741
741
|
async def retrieve(self, item_id: int) -> Optional[dict]:
|
@@ -772,13 +772,13 @@ class AsyncSubstrateInterface:
|
|
772
772
|
"""
|
773
773
|
self.chain_endpoint = chain_endpoint
|
774
774
|
self.__chain = chain_name
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
775
|
+
self.ws = Websocket(
|
776
|
+
chain_endpoint,
|
777
|
+
options={
|
778
|
+
"max_size": 2**32,
|
779
|
+
"write_limit": 2**16,
|
780
|
+
},
|
781
|
+
)
|
782
782
|
self._lock = asyncio.Lock()
|
783
783
|
self.last_block_hash: Optional[str] = None
|
784
784
|
self.config = {
|
@@ -1135,7 +1135,7 @@ class AsyncSubstrateInterface:
|
|
1135
1135
|
-------
|
1136
1136
|
StorageKey
|
1137
1137
|
"""
|
1138
|
-
|
1138
|
+
await self.init_runtime(block_hash=block_hash)
|
1139
1139
|
|
1140
1140
|
return StorageKey.create_from_storage_function(
|
1141
1141
|
pallet,
|
@@ -1555,7 +1555,7 @@ class AsyncSubstrateInterface:
|
|
1555
1555
|
self,
|
1556
1556
|
response: dict,
|
1557
1557
|
subscription_id: Union[int, str],
|
1558
|
-
value_scale_type: Optional[str],
|
1558
|
+
value_scale_type: Optional[str] = None,
|
1559
1559
|
storage_item: Optional[ScaleType] = None,
|
1560
1560
|
runtime: Optional[Runtime] = None,
|
1561
1561
|
result_handler: Optional[ResultHandler] = None,
|
@@ -1769,7 +1769,6 @@ class AsyncSubstrateInterface:
|
|
1769
1769
|
call_params = {}
|
1770
1770
|
|
1771
1771
|
await self.init_runtime(block_hash=block_hash)
|
1772
|
-
|
1773
1772
|
call = self.runtime_config.create_scale_object(
|
1774
1773
|
type_string="Call", metadata=self.metadata
|
1775
1774
|
)
|
@@ -2087,7 +2086,8 @@ class AsyncSubstrateInterface:
|
|
2087
2086
|
|
2088
2087
|
:return: The signed Extrinsic
|
2089
2088
|
"""
|
2090
|
-
|
2089
|
+
if not self.metadata:
|
2090
|
+
await self.init_runtime()
|
2091
2091
|
|
2092
2092
|
# Check requirements
|
2093
2093
|
if not isinstance(call, GenericCall):
|
@@ -2140,7 +2140,6 @@ class AsyncSubstrateInterface:
|
|
2140
2140
|
extrinsic = self.runtime_config.create_scale_object(
|
2141
2141
|
type_string="Extrinsic", metadata=self.metadata
|
2142
2142
|
)
|
2143
|
-
|
2144
2143
|
value = {
|
2145
2144
|
"account_id": f"0x{keypair.public_key.hex()}",
|
2146
2145
|
"signature": f"0x{signature.hex()}",
|
@@ -2158,9 +2157,7 @@ class AsyncSubstrateInterface:
|
|
2158
2157
|
signature_cls = self.runtime_config.get_decoder_class("ExtrinsicSignature")
|
2159
2158
|
if issubclass(signature_cls, self.runtime_config.get_decoder_class("Enum")):
|
2160
2159
|
value["signature_version"] = signature_version
|
2161
|
-
|
2162
2160
|
extrinsic.encode(value)
|
2163
|
-
|
2164
2161
|
return extrinsic
|
2165
2162
|
|
2166
2163
|
async def get_chain_finalised_head(self):
|
@@ -2564,10 +2561,7 @@ class AsyncSubstrateInterface:
|
|
2564
2561
|
item_key = None
|
2565
2562
|
|
2566
2563
|
try:
|
2567
|
-
|
2568
|
-
item_bytes = bytes.fromhex(item[1][2:])
|
2569
|
-
except ValueError:
|
2570
|
-
item_bytes = bytes.fromhex(item[1])
|
2564
|
+
item_bytes = hex_to_bytes(item[1])
|
2571
2565
|
|
2572
2566
|
item_value = await self.decode_scale(
|
2573
2567
|
type_string=value_type,
|
@@ -18,7 +18,6 @@ import typing
|
|
18
18
|
from typing import Optional
|
19
19
|
import subprocess
|
20
20
|
|
21
|
-
import backoff
|
22
21
|
from bittensor_wallet import Wallet
|
23
22
|
from Crypto.Hash import keccak
|
24
23
|
import numpy as np
|
@@ -37,6 +36,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
37
36
|
print_verbose,
|
38
37
|
print_error,
|
39
38
|
unlock_key,
|
39
|
+
hex_to_bytes,
|
40
40
|
)
|
41
41
|
|
42
42
|
if typing.TYPE_CHECKING:
|
@@ -687,7 +687,7 @@ async def run_faucet_extrinsic(
|
|
687
687
|
tpb: int = 256,
|
688
688
|
num_processes: Optional[int] = None,
|
689
689
|
update_interval: Optional[int] = None,
|
690
|
-
log_verbose: bool =
|
690
|
+
log_verbose: bool = True,
|
691
691
|
max_successes: int = 3,
|
692
692
|
) -> tuple[bool, str]:
|
693
693
|
r"""Runs a continual POW to get a faucet of TAO on the test net.
|
@@ -735,8 +735,12 @@ async def run_faucet_extrinsic(
|
|
735
735
|
# Attempt rolling registration.
|
736
736
|
attempts = 1
|
737
737
|
successes = 1
|
738
|
+
pow_result: Optional[POWSolution]
|
738
739
|
while True:
|
739
740
|
try:
|
741
|
+
account_nonce = await subtensor.substrate.get_account_nonce(
|
742
|
+
wallet.coldkey.ss58_address
|
743
|
+
)
|
740
744
|
pow_result = None
|
741
745
|
while pow_result is None or await pow_result.is_stale(subtensor=subtensor):
|
742
746
|
# Solve latest POW.
|
@@ -745,7 +749,7 @@ async def run_faucet_extrinsic(
|
|
745
749
|
if prompt:
|
746
750
|
err_console.print("CUDA is not available.")
|
747
751
|
return False, "CUDA is not available."
|
748
|
-
pow_result
|
752
|
+
pow_result = await create_pow(
|
749
753
|
subtensor,
|
750
754
|
wallet,
|
751
755
|
-1,
|
@@ -758,7 +762,7 @@ async def run_faucet_extrinsic(
|
|
758
762
|
log_verbose=log_verbose,
|
759
763
|
)
|
760
764
|
else:
|
761
|
-
pow_result
|
765
|
+
pow_result = await create_pow(
|
762
766
|
subtensor,
|
763
767
|
wallet,
|
764
768
|
-1,
|
@@ -778,7 +782,7 @@ async def run_faucet_extrinsic(
|
|
778
782
|
},
|
779
783
|
)
|
780
784
|
extrinsic = await subtensor.substrate.create_signed_extrinsic(
|
781
|
-
call=call, keypair=wallet.coldkey
|
785
|
+
call=call, keypair=wallet.coldkey, nonce=account_nonce
|
782
786
|
)
|
783
787
|
response = await subtensor.substrate.submit_extrinsic(
|
784
788
|
extrinsic,
|
@@ -863,7 +867,7 @@ async def _check_for_newest_block_and_update(
|
|
863
867
|
block_number, difficulty, block_hash = await _get_block_with_retry(
|
864
868
|
subtensor=subtensor, netuid=netuid
|
865
869
|
)
|
866
|
-
block_bytes =
|
870
|
+
block_bytes = hex_to_bytes(block_hash)
|
867
871
|
|
868
872
|
update_curr_block(
|
869
873
|
curr_diff,
|
@@ -970,7 +974,7 @@ async def _block_solver(
|
|
970
974
|
subtensor=subtensor, netuid=netuid
|
971
975
|
)
|
972
976
|
|
973
|
-
block_bytes =
|
977
|
+
block_bytes = hex_to_bytes(block_hash)
|
974
978
|
old_block_number = block_number
|
975
979
|
# Set to current block
|
976
980
|
_update_curr_block(
|
@@ -1245,11 +1249,9 @@ def _terminate_workers_and_wait_for_exit(
|
|
1245
1249
|
worker.terminate()
|
1246
1250
|
|
1247
1251
|
|
1248
|
-
# TODO verify this works with async
|
1249
|
-
@backoff.on_exception(backoff.constant, Exception, interval=1, max_tries=3)
|
1250
1252
|
async def _get_block_with_retry(
|
1251
1253
|
subtensor: "SubtensorInterface", netuid: int
|
1252
|
-
) -> tuple[int, int,
|
1254
|
+
) -> tuple[int, int, str]:
|
1253
1255
|
"""
|
1254
1256
|
Gets the current block number, difficulty, and block hash from the substrate node.
|
1255
1257
|
|
@@ -1261,10 +1263,9 @@ async def _get_block_with_retry(
|
|
1261
1263
|
:raises Exception: If the block hash is None.
|
1262
1264
|
:raises ValueError: If the difficulty is None.
|
1263
1265
|
"""
|
1264
|
-
|
1265
|
-
block_hash =
|
1266
|
-
|
1267
|
-
) # TODO check if I need to do all this
|
1266
|
+
block = await subtensor.substrate.get_block()
|
1267
|
+
block_hash = block["header"]["hash"]
|
1268
|
+
block_number = block["header"]["number"]
|
1268
1269
|
try:
|
1269
1270
|
difficulty = (
|
1270
1271
|
1_000_000
|
@@ -35,6 +35,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
35
35
|
err_console,
|
36
36
|
decode_hex_identity_dict,
|
37
37
|
validate_chain_endpoint,
|
38
|
+
hex_to_bytes,
|
38
39
|
)
|
39
40
|
|
40
41
|
|
@@ -213,12 +214,7 @@ class SubtensorInterface:
|
|
213
214
|
block_hash=block_hash,
|
214
215
|
)
|
215
216
|
if hex_bytes_result is not None:
|
216
|
-
|
217
|
-
bytes_result = bytes.fromhex(hex_bytes_result[2:])
|
218
|
-
except ValueError:
|
219
|
-
bytes_result = bytes.fromhex(hex_bytes_result)
|
220
|
-
|
221
|
-
return DelegateInfo.list_from_vec_u8(bytes_result)
|
217
|
+
return DelegateInfo.list_from_vec_u8(hex_to_bytes(hex_bytes_result))
|
222
218
|
else:
|
223
219
|
return []
|
224
220
|
|
@@ -254,12 +250,7 @@ class SubtensorInterface:
|
|
254
250
|
if hex_bytes_result is None:
|
255
251
|
return []
|
256
252
|
|
257
|
-
|
258
|
-
bytes_result = bytes.fromhex(hex_bytes_result[2:])
|
259
|
-
except ValueError:
|
260
|
-
bytes_result = bytes.fromhex(hex_bytes_result)
|
261
|
-
|
262
|
-
return StakeInfo.list_from_vec_u8(bytes_result)
|
253
|
+
return StakeInfo.list_from_vec_u8(hex_to_bytes(hex_bytes_result))
|
263
254
|
|
264
255
|
async def get_stake_for_coldkey_and_hotkey(
|
265
256
|
self, hotkey_ss58: str, coldkey_ss58: str, block_hash: Optional[str]
|
@@ -654,12 +645,7 @@ class SubtensorInterface:
|
|
654
645
|
if hex_bytes_result is None:
|
655
646
|
return []
|
656
647
|
|
657
|
-
|
658
|
-
bytes_result = bytes.fromhex(hex_bytes_result[2:])
|
659
|
-
except ValueError:
|
660
|
-
bytes_result = bytes.fromhex(hex_bytes_result)
|
661
|
-
|
662
|
-
return NeuronInfoLite.list_from_vec_u8(bytes_result)
|
648
|
+
return NeuronInfoLite.list_from_vec_u8(hex_to_bytes(hex_bytes_result))
|
663
649
|
|
664
650
|
async def neuron_for_uid(
|
665
651
|
self, uid: Optional[int], netuid: int, block_hash: Optional[str] = None
|
@@ -988,12 +974,7 @@ class SubtensorInterface:
|
|
988
974
|
if hex_bytes_result is None:
|
989
975
|
return []
|
990
976
|
|
991
|
-
|
992
|
-
bytes_result = bytes.fromhex(hex_bytes_result[2:])
|
993
|
-
else:
|
994
|
-
bytes_result = bytes.fromhex(hex_bytes_result)
|
995
|
-
|
996
|
-
return SubnetHyperparameters.from_vec_u8(bytes_result)
|
977
|
+
return SubnetHyperparameters.from_vec_u8(hex_to_bytes(hex_bytes_result))
|
997
978
|
|
998
979
|
async def get_vote_data(
|
999
980
|
self,
|
@@ -581,7 +581,7 @@ def decode_hex_identity_dict(info_dictionary) -> dict[str, Any]:
|
|
581
581
|
def get_decoded(data: str) -> str:
|
582
582
|
"""Decodes a hex-encoded string."""
|
583
583
|
try:
|
584
|
-
return
|
584
|
+
return hex_to_bytes(data).decode()
|
585
585
|
except UnicodeDecodeError:
|
586
586
|
print(f"Could not decode: {key}: {item}")
|
587
587
|
|
@@ -1016,3 +1016,14 @@ def unlock_key(
|
|
1016
1016
|
if print_out:
|
1017
1017
|
err_console.print(f":cross_mark: [red]{err_msg}[/red]")
|
1018
1018
|
return UnlockStatus(False, err_msg)
|
1019
|
+
|
1020
|
+
|
1021
|
+
def hex_to_bytes(hex_str: str) -> bytes:
|
1022
|
+
"""
|
1023
|
+
Converts a hex-encoded string into bytes. Handles 0x-prefixed and non-prefixed hex-encoded strings.
|
1024
|
+
"""
|
1025
|
+
if hex_str.startswith("0x"):
|
1026
|
+
bytes_result = bytes.fromhex(hex_str[2:])
|
1027
|
+
else:
|
1028
|
+
bytes_result = bytes.fromhex(hex_str)
|
1029
|
+
return bytes_result
|
@@ -28,6 +28,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
28
28
|
render_table,
|
29
29
|
update_metadata_table,
|
30
30
|
unlock_key,
|
31
|
+
hex_to_bytes,
|
31
32
|
)
|
32
33
|
|
33
34
|
if TYPE_CHECKING:
|
@@ -155,12 +156,8 @@ async def subnets_list(
|
|
155
156
|
hex_bytes_result = await subtensor.query_runtime_api(
|
156
157
|
runtime_api="SubnetInfoRuntimeApi", method="get_subnets_info", params=[]
|
157
158
|
)
|
158
|
-
try:
|
159
|
-
bytes_result = bytes.fromhex(hex_bytes_result[2:])
|
160
|
-
except ValueError:
|
161
|
-
bytes_result = bytes.fromhex(hex_bytes_result)
|
162
159
|
|
163
|
-
return SubnetInfo.list_from_vec_u8(
|
160
|
+
return SubnetInfo.list_from_vec_u8(hex_to_bytes(hex_bytes_result))
|
164
161
|
|
165
162
|
if not reuse_last:
|
166
163
|
subnets: list[SubnetInfo]
|
@@ -178,19 +178,20 @@ async def sudo_set_hyperparameter(
|
|
178
178
|
|
179
179
|
normalized_value: Union[str, bool]
|
180
180
|
if param_name in [
|
181
|
-
"
|
181
|
+
"registration_allowed",
|
182
182
|
"network_pow_registration_allowed",
|
183
183
|
"commit_reveal_weights_enabled",
|
184
184
|
"liquid_alpha_enabled",
|
185
185
|
]:
|
186
|
-
normalized_value = param_value.lower() in ["true", "1"]
|
186
|
+
normalized_value = param_value.lower() in ["true", "True", "1"]
|
187
187
|
else:
|
188
188
|
normalized_value = param_value
|
189
189
|
|
190
190
|
is_allowed_value, value = allowed_value(param_name, normalized_value)
|
191
191
|
if not is_allowed_value:
|
192
192
|
err_console.print(
|
193
|
-
f"Hyperparameter {param_name} value is not within bounds.
|
193
|
+
f"Hyperparameter [dark_orange]{param_name}[/dark_orange] value is not within bounds. "
|
194
|
+
f"Value is {normalized_value} but must be {value}"
|
194
195
|
)
|
195
196
|
return
|
196
197
|
|
@@ -15,23 +15,19 @@ from bittensor_wallet.keyfile import Keyfile
|
|
15
15
|
from fuzzywuzzy import fuzz
|
16
16
|
from rich import box
|
17
17
|
from rich.align import Align
|
18
|
-
from rich.prompt import Confirm
|
18
|
+
from rich.prompt import Confirm
|
19
19
|
from rich.table import Column, Table
|
20
20
|
from rich.tree import Tree
|
21
21
|
from rich.padding import Padding
|
22
22
|
from rich.prompt import IntPrompt
|
23
|
-
from scalecodec import ScaleBytes
|
24
|
-
import scalecodec
|
25
23
|
import typer
|
26
24
|
|
27
|
-
from bittensor_cli.src import TYPE_REGISTRY
|
28
25
|
from bittensor_cli.src.bittensor import utils
|
29
26
|
from bittensor_cli.src.bittensor.balances import Balance
|
30
27
|
from bittensor_cli.src.bittensor.chain_data import (
|
31
28
|
DelegateInfo,
|
32
29
|
NeuronInfoLite,
|
33
30
|
StakeInfo,
|
34
|
-
custom_rpc_type_registry,
|
35
31
|
decode_account_id,
|
36
32
|
)
|
37
33
|
from bittensor_cli.src.bittensor.extrinsics.registration import (
|
@@ -46,7 +42,6 @@ from bittensor_cli.src.bittensor.utils import (
|
|
46
42
|
RAO_PER_TAO,
|
47
43
|
console,
|
48
44
|
convert_blocks_to_time,
|
49
|
-
decode_scale_bytes,
|
50
45
|
err_console,
|
51
46
|
print_error,
|
52
47
|
print_verbose,
|
@@ -56,6 +51,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
56
51
|
validate_coldkey_presence,
|
57
52
|
retry_prompt,
|
58
53
|
unlock_key,
|
54
|
+
hex_to_bytes,
|
59
55
|
)
|
60
56
|
|
61
57
|
|
@@ -660,8 +656,13 @@ async def overview(
|
|
660
656
|
neurons
|
661
657
|
)
|
662
658
|
|
659
|
+
has_alerts = False
|
663
660
|
alerts_table = Table(show_header=True, header_style="bold magenta")
|
664
661
|
alerts_table.add_column("🥩 alert!")
|
662
|
+
alerts_table.add_row(
|
663
|
+
"[bold]Detected the following stake(s) associated with coldkey(s) that are not linked to any local hotkeys:[/bold]"
|
664
|
+
)
|
665
|
+
alerts_table.add_row("")
|
665
666
|
|
666
667
|
coldkeys_to_check = []
|
667
668
|
ck_stakes = await subtensor.get_total_stake_for_coldkey(
|
@@ -684,12 +685,23 @@ async def overview(
|
|
684
685
|
if difference == 0:
|
685
686
|
continue # We have all our stake registered.
|
686
687
|
|
688
|
+
has_alerts = True
|
687
689
|
coldkeys_to_check.append(coldkey_wallet)
|
688
690
|
alerts_table.add_row(
|
689
|
-
"
|
690
|
-
abs(difference),
|
691
|
+
"[light_goldenrod2]{}[/light_goldenrod2] stake associated with coldkey [bright_magenta]{}[/bright_magenta] (ss58: [bright_magenta]{}[/bright_magenta])".format(
|
692
|
+
abs(difference),
|
693
|
+
coldkey_wallet.name,
|
694
|
+
coldkey_wallet.coldkeypub.ss58_address,
|
691
695
|
)
|
692
696
|
)
|
697
|
+
if has_alerts:
|
698
|
+
alerts_table.add_row("")
|
699
|
+
alerts_table.add_row(
|
700
|
+
"[bold yellow]Note:[/bold yellow] This stake might be delegated, staked to another user's hotkey, or associated with a hotkey not present in your wallet."
|
701
|
+
)
|
702
|
+
alerts_table.add_row(
|
703
|
+
"You can find out more by executing `[bold]btcli wallet inspect[/bold]` command."
|
704
|
+
)
|
693
705
|
|
694
706
|
if coldkeys_to_check:
|
695
707
|
# We have some stake that is not with a registered hotkey.
|
@@ -743,7 +755,7 @@ async def overview(
|
|
743
755
|
grid = Table.grid(pad_edge=True)
|
744
756
|
|
745
757
|
# If there are any alerts, add them to the grid
|
746
|
-
if
|
758
|
+
if has_alerts:
|
747
759
|
grid.add_row(alerts_table)
|
748
760
|
|
749
761
|
# Add title
|
@@ -1176,7 +1188,7 @@ def _process_neurons_for_netuids(
|
|
1176
1188
|
:return: netuids mapped to decoded neurons
|
1177
1189
|
"""
|
1178
1190
|
all_results = [
|
1179
|
-
(netuid, NeuronInfoLite.list_from_vec_u8(
|
1191
|
+
(netuid, NeuronInfoLite.list_from_vec_u8(hex_to_bytes(result)))
|
1180
1192
|
if result
|
1181
1193
|
else (netuid, [])
|
1182
1194
|
for netuid, result in netuids_with_all_neurons_hex_bytes
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: bittensor-cli
|
3
|
-
Version: 8.
|
3
|
+
Version: 8.4.0
|
4
4
|
Summary: Bittensor CLI
|
5
5
|
Home-page: https://github.com/opentensor/btcli
|
6
6
|
Author: bittensor.com
|
@@ -32,7 +32,6 @@ Requires-Dist: fuzzywuzzy~=0.18.0
|
|
32
32
|
Requires-Dist: netaddr~=1.3.0
|
33
33
|
Requires-Dist: numpy>=2.0.1
|
34
34
|
Requires-Dist: Jinja2
|
35
|
-
Requires-Dist: packaging
|
36
35
|
Requires-Dist: pycryptodome
|
37
36
|
Requires-Dist: PyYAML~=6.0.1
|
38
37
|
Requires-Dist: pytest
|
@@ -41,8 +40,8 @@ Requires-Dist: rich~=13.7
|
|
41
40
|
Requires-Dist: scalecodec==1.2.11
|
42
41
|
Requires-Dist: substrate-interface~=1.7.9
|
43
42
|
Requires-Dist: typer~=0.12
|
44
|
-
Requires-Dist: websockets>=
|
45
|
-
Requires-Dist: bittensor-wallet>=2.1.
|
43
|
+
Requires-Dist: websockets>=14.1
|
44
|
+
Requires-Dist: bittensor-wallet>=2.1.3
|
46
45
|
Requires-Dist: bt-decode==0.2.0a0
|
47
46
|
Provides-Extra: cuda
|
48
47
|
Requires-Dist: cubit>=1.1.0; extra == "cuda"
|
@@ -1,31 +1,31 @@
|
|
1
|
-
bittensor_cli/__init__.py,sha256=
|
2
|
-
bittensor_cli/cli.py,sha256=
|
1
|
+
bittensor_cli/__init__.py,sha256=0dDE_gb7wXMgoxy5mCs0B4IjiojCNSEiBmyJTyKwCTg,1217
|
2
|
+
bittensor_cli/cli.py,sha256=1C9xRsNq3CZHEsYcvw50IemjLxQ7olSljX6wK1WwK6g,170025
|
3
3
|
bittensor_cli/doc_generation_helper.py,sha256=GexqjEIKulWg84hpNBEchJ840oOgOi7DWpt447nsdNI,91
|
4
|
-
bittensor_cli/src/__init__.py,sha256=
|
4
|
+
bittensor_cli/src/__init__.py,sha256=1_hTPLBqA6gV8HTL-v0_RVTPt7TQJEJEv-TIw9f79OE,12055
|
5
5
|
bittensor_cli/src/bittensor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
-
bittensor_cli/src/bittensor/async_substrate_interface.py,sha256=
|
6
|
+
bittensor_cli/src/bittensor/async_substrate_interface.py,sha256=o7Pe_Nxsys8aPm_xsih2xR8ArhZrUu9yYobf8qBvT5s,103185
|
7
7
|
bittensor_cli/src/bittensor/balances.py,sha256=102mg1iiliLSLx-EocQseWGHiWzRqcBBM-MRoObOdKo,10075
|
8
8
|
bittensor_cli/src/bittensor/chain_data.py,sha256=IsHWjmhJbTvud2i3IM1sfmBHP82VxNHC1iFDAtlLgXc,26490
|
9
9
|
bittensor_cli/src/bittensor/minigraph.py,sha256=17AjEA75MO7ez_NekOJSaAz6ARjPt99QG_7E1RJ_u_k,8891
|
10
10
|
bittensor_cli/src/bittensor/networking.py,sha256=pZLMs8YXpZzDMLXWMBb_Bj6TVkm_q9khyY-lnbwVMuE,462
|
11
|
-
bittensor_cli/src/bittensor/subtensor_interface.py,sha256=
|
12
|
-
bittensor_cli/src/bittensor/utils.py,sha256=
|
11
|
+
bittensor_cli/src/bittensor/subtensor_interface.py,sha256=_99AjukDm7ijEwQUA6TXctZFrj9IRuOzJdheKNmbZ5s,42775
|
12
|
+
bittensor_cli/src/bittensor/utils.py,sha256=60h45hRVTaLhhOOTHmNurY3wHb0Jpt9pIhS3joVM7d4,35505
|
13
13
|
bittensor_cli/src/bittensor/extrinsics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
-
bittensor_cli/src/bittensor/extrinsics/registration.py,sha256=
|
14
|
+
bittensor_cli/src/bittensor/extrinsics/registration.py,sha256=87L7xs64beu0htRaiykaJcYLyRmxoFzF5PFNumNuhcw,59010
|
15
15
|
bittensor_cli/src/bittensor/extrinsics/root.py,sha256=huycqHbSTFBNIhQ846MuBqwBEtQCSVDW3y3yPAqPzeU,19121
|
16
16
|
bittensor_cli/src/bittensor/extrinsics/transfer.py,sha256=yC5oKgoKAXszMzfrof3GbeGppESUMgSqJFFGOMMALuc,8686
|
17
17
|
bittensor_cli/src/bittensor/templates/table.j2,sha256=P2EFiksnO1cQsB8zjK6hVJwUryHTsLslzRE0YtobAV8,10601
|
18
18
|
bittensor_cli/src/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
19
|
bittensor_cli/src/commands/root.py,sha256=hohGfh7w9Lu7z264rbmFkwRCStyZrtdBZVMt20RwiqA,62186
|
20
|
-
bittensor_cli/src/commands/subnets.py,sha256=
|
21
|
-
bittensor_cli/src/commands/sudo.py,sha256=
|
22
|
-
bittensor_cli/src/commands/wallets.py,sha256=
|
20
|
+
bittensor_cli/src/commands/subnets.py,sha256=_M2EJLdHaLBN04C22A-Xn6weN-3j5dU5frLe6W5Q2rs,33175
|
21
|
+
bittensor_cli/src/commands/sudo.py,sha256=sr4hW27EwW_O7lz0fwPLN3xRpVKNsdBasETIbGDhkb0,8209
|
22
|
+
bittensor_cli/src/commands/wallets.py,sha256=BuPJiEDOpHuGRx3zekU2QkFQjFpCUP-Kdk4opS5YfWo,60678
|
23
23
|
bittensor_cli/src/commands/weights.py,sha256=UHakAMTNqRkg_fkiyebbZAT9T3UEf93MmdbFgPSbqUw,16520
|
24
24
|
bittensor_cli/src/commands/stake/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
25
|
bittensor_cli/src/commands/stake/children_hotkeys.py,sha256=j239HdawvHp9rTbIx9MI9v9hkaKbA5OaN_cIQISkHdw,28606
|
26
26
|
bittensor_cli/src/commands/stake/stake.py,sha256=7TyFtL5wnXvGvD-GckNrNTRdcu3RewAfx_JfEekugFU,56147
|
27
|
-
bittensor_cli-8.
|
28
|
-
bittensor_cli-8.
|
29
|
-
bittensor_cli-8.
|
30
|
-
bittensor_cli-8.
|
31
|
-
bittensor_cli-8.
|
27
|
+
bittensor_cli-8.4.0.dist-info/METADATA,sha256=XJctL-W1oJCDVKEvsDOrEG_oh6t8ycRPeXudbVaQ174,6788
|
28
|
+
bittensor_cli-8.4.0.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
29
|
+
bittensor_cli-8.4.0.dist-info/entry_points.txt,sha256=hBTLGLbVxmAKy69XSKaUZvjTCmyEzDGZKq4S8UOto8I,49
|
30
|
+
bittensor_cli-8.4.0.dist-info/top_level.txt,sha256=DvgvXpmTtI_Q1BbDZMlK90LFcGFCreN1daViEPV2iFw,14
|
31
|
+
bittensor_cli-8.4.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|