bittensor-cli 9.0.2__py3-none-any.whl → 9.1.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/cli.py +84 -18
- bittensor_cli/src/__init__.py +3 -0
- bittensor_cli/src/bittensor/balances.py +5 -6
- bittensor_cli/src/bittensor/chain_data.py +287 -25
- bittensor_cli/src/bittensor/subtensor_interface.py +54 -12
- bittensor_cli/src/bittensor/utils.py +13 -2
- bittensor_cli/src/commands/stake/add.py +2 -4
- bittensor_cli/src/commands/stake/children_hotkeys.py +2 -0
- bittensor_cli/src/commands/stake/move.py +17 -24
- bittensor_cli/src/commands/stake/remove.py +3 -8
- bittensor_cli/src/commands/subnets/subnets.py +6 -7
- bittensor_cli/src/commands/sudo.py +5 -0
- bittensor_cli/src/commands/view.py +2876 -0
- bittensor_cli/version.py +2 -1
- {bittensor_cli-9.0.2.dist-info → bittensor_cli-9.1.0.dist-info}/METADATA +1 -1
- {bittensor_cli-9.0.2.dist-info → bittensor_cli-9.1.0.dist-info}/RECORD +19 -18
- {bittensor_cli-9.0.2.dist-info → bittensor_cli-9.1.0.dist-info}/WHEEL +0 -0
- {bittensor_cli-9.0.2.dist-info → bittensor_cli-9.1.0.dist-info}/entry_points.txt +0 -0
- {bittensor_cli-9.0.2.dist-info → bittensor_cli-9.1.0.dist-info}/top_level.txt +0 -0
bittensor_cli/cli.py
CHANGED
@@ -32,7 +32,7 @@ from bittensor_cli.version import __version__, __version_as_int__
|
|
32
32
|
from bittensor_cli.src.bittensor import utils
|
33
33
|
from bittensor_cli.src.bittensor.balances import Balance
|
34
34
|
from async_substrate_interface.errors import SubstrateRequestException
|
35
|
-
from bittensor_cli.src.commands import sudo, wallets
|
35
|
+
from bittensor_cli.src.commands import sudo, wallets, view
|
36
36
|
from bittensor_cli.src.commands import weights as weights_cmds
|
37
37
|
from bittensor_cli.src.commands.subnets import price, subnets
|
38
38
|
from bittensor_cli.src.commands.stake import (
|
@@ -74,8 +74,6 @@ except ImportError:
|
|
74
74
|
pass
|
75
75
|
|
76
76
|
|
77
|
-
|
78
|
-
|
79
77
|
_epilog = "Made with [bold red]:heart:[/bold red] by The Openτensor Foundaτion"
|
80
78
|
|
81
79
|
np.set_printoptions(precision=8, suppress=True, floatmode="fixed")
|
@@ -195,8 +193,7 @@ class Options:
|
|
195
193
|
)
|
196
194
|
wait_for_finalization = typer.Option(
|
197
195
|
True,
|
198
|
-
help="If `True`, waits until the transaction is finalized "
|
199
|
-
"on the blockchain.",
|
196
|
+
help="If `True`, waits until the transaction is finalized on the blockchain.",
|
200
197
|
)
|
201
198
|
prompt = typer.Option(
|
202
199
|
True,
|
@@ -481,7 +478,7 @@ def version_callback(value: bool):
|
|
481
478
|
f"{repo.active_branch.name}/"
|
482
479
|
f"{repo.commit()}"
|
483
480
|
)
|
484
|
-
except (
|
481
|
+
except (TypeError, GitError):
|
485
482
|
version = f"BTCLI version: {__version__}"
|
486
483
|
typer.echo(version)
|
487
484
|
raise typer.Exit()
|
@@ -515,6 +512,7 @@ class CLIManager:
|
|
515
512
|
subnets_app: typer.Typer
|
516
513
|
weights_app: typer.Typer
|
517
514
|
utils_app = typer.Typer(epilog=_epilog)
|
515
|
+
view_app: typer.Typer
|
518
516
|
asyncio_runner = asyncio
|
519
517
|
|
520
518
|
def __init__(self):
|
@@ -564,6 +562,7 @@ class CLIManager:
|
|
564
562
|
self.sudo_app = typer.Typer(epilog=_epilog)
|
565
563
|
self.subnets_app = typer.Typer(epilog=_epilog)
|
566
564
|
self.weights_app = typer.Typer(epilog=_epilog)
|
565
|
+
self.view_app = typer.Typer(epilog=_epilog)
|
567
566
|
|
568
567
|
# config alias
|
569
568
|
self.app.add_typer(
|
@@ -641,6 +640,14 @@ class CLIManager:
|
|
641
640
|
self.utils_app, name="utils", no_args_is_help=True, hidden=True
|
642
641
|
)
|
643
642
|
|
643
|
+
# view app
|
644
|
+
self.app.add_typer(
|
645
|
+
self.view_app,
|
646
|
+
name="view",
|
647
|
+
short_help="HTML view commands",
|
648
|
+
no_args_is_help=True,
|
649
|
+
)
|
650
|
+
|
644
651
|
# config commands
|
645
652
|
self.config_app.command("set")(self.set_config)
|
646
653
|
self.config_app.command("get")(self.get_config)
|
@@ -808,6 +815,11 @@ class CLIManager:
|
|
808
815
|
"commit", rich_help_panel=HELP_PANELS["WEIGHTS"]["COMMIT_REVEAL"]
|
809
816
|
)(self.weights_commit)
|
810
817
|
|
818
|
+
# view commands
|
819
|
+
self.view_app.command(
|
820
|
+
"dashboard", rich_help_panel=HELP_PANELS["VIEW"]["DASHBOARD"]
|
821
|
+
)(self.view_dashboard)
|
822
|
+
|
811
823
|
# Sub command aliases
|
812
824
|
# Weights
|
813
825
|
self.wallet_app.command(
|
@@ -1338,7 +1350,7 @@ class CLIManager:
|
|
1338
1350
|
if value in Constants.networks:
|
1339
1351
|
value = value + f" ({Constants.network_map[value]})"
|
1340
1352
|
if key == "rate_tolerance":
|
1341
|
-
value = f"{value} ({value*100}%)" if value is not None else "None"
|
1353
|
+
value = f"{value} ({value * 100}%)" if value is not None else "None"
|
1342
1354
|
|
1343
1355
|
elif key in deprecated_configs:
|
1344
1356
|
continue
|
@@ -1367,19 +1379,19 @@ class CLIManager:
|
|
1367
1379
|
"""
|
1368
1380
|
if rate_tolerance is not None:
|
1369
1381
|
console.print(
|
1370
|
-
f"[dim][blue]Rate tolerance[/blue]: [bold cyan]{rate_tolerance} ({rate_tolerance*100}%)[/bold cyan]."
|
1382
|
+
f"[dim][blue]Rate tolerance[/blue]: [bold cyan]{rate_tolerance} ({rate_tolerance * 100}%)[/bold cyan]."
|
1371
1383
|
)
|
1372
1384
|
return rate_tolerance
|
1373
1385
|
elif self.config.get("rate_tolerance") is not None:
|
1374
1386
|
config_slippage = self.config["rate_tolerance"]
|
1375
1387
|
console.print(
|
1376
|
-
f"[dim][blue]Rate tolerance[/blue]: [bold cyan]{config_slippage} ({config_slippage*100}%)[/bold cyan] (from config)."
|
1388
|
+
f"[dim][blue]Rate tolerance[/blue]: [bold cyan]{config_slippage} ({config_slippage * 100}%)[/bold cyan] (from config)."
|
1377
1389
|
)
|
1378
1390
|
return config_slippage
|
1379
1391
|
else:
|
1380
1392
|
console.print(
|
1381
1393
|
"[dim][blue]Rate tolerance[/blue]: "
|
1382
|
-
+ f"[bold cyan]{defaults.rate_tolerance} ({defaults.rate_tolerance*100}%)[/bold cyan] "
|
1394
|
+
+ f"[bold cyan]{defaults.rate_tolerance} ({defaults.rate_tolerance * 100}%)[/bold cyan] "
|
1383
1395
|
+ "by default. Set this using "
|
1384
1396
|
+ "[dark_sea_green3 italic]`btcli config set`[/dark_sea_green3 italic] "
|
1385
1397
|
+ "or "
|
@@ -3323,9 +3335,9 @@ class CLIManager:
|
|
3323
3335
|
def stake_move(
|
3324
3336
|
self,
|
3325
3337
|
network: Optional[list[str]] = Options.network,
|
3326
|
-
wallet_name=Options.wallet_name,
|
3327
|
-
wallet_path=Options.wallet_path,
|
3328
|
-
wallet_hotkey=Options.wallet_hotkey,
|
3338
|
+
wallet_name: Optional[str] = Options.wallet_name,
|
3339
|
+
wallet_path: Optional[str] = Options.wallet_path,
|
3340
|
+
wallet_hotkey: Optional[str] = Options.wallet_hotkey,
|
3329
3341
|
origin_netuid: Optional[int] = typer.Option(
|
3330
3342
|
None, "--origin-netuid", help="Origin netuid"
|
3331
3343
|
),
|
@@ -3535,14 +3547,45 @@ class CLIManager:
|
|
3535
3547
|
)
|
3536
3548
|
self.verbosity_handler(quiet, verbose)
|
3537
3549
|
|
3550
|
+
if not wallet_name:
|
3551
|
+
wallet_name = Prompt.ask(
|
3552
|
+
"Enter the [blue]origin wallet name[/blue]",
|
3553
|
+
default=self.config.get("wallet_name") or defaults.wallet.name,
|
3554
|
+
)
|
3538
3555
|
wallet = self.wallet_ask(
|
3539
|
-
wallet_name,
|
3540
|
-
wallet_path,
|
3541
|
-
wallet_hotkey,
|
3542
|
-
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
3543
|
-
validate=WV.WALLET_AND_HOTKEY,
|
3556
|
+
wallet_name, wallet_path, wallet_hotkey, ask_for=[WO.NAME]
|
3544
3557
|
)
|
3545
3558
|
|
3559
|
+
if not wallet_hotkey:
|
3560
|
+
origin_hotkey = Prompt.ask(
|
3561
|
+
"Enter the [blue]origin hotkey[/blue] name or "
|
3562
|
+
"[blue]ss58 address[/blue] where the stake will be moved from",
|
3563
|
+
default=self.config.get("wallet_hotkey") or defaults.wallet.hotkey,
|
3564
|
+
)
|
3565
|
+
if is_valid_ss58_address(origin_hotkey):
|
3566
|
+
origin_hotkey = origin_hotkey
|
3567
|
+
else:
|
3568
|
+
wallet = self.wallet_ask(
|
3569
|
+
wallet_name,
|
3570
|
+
wallet_path,
|
3571
|
+
origin_hotkey,
|
3572
|
+
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
|
3573
|
+
validate=WV.WALLET_AND_HOTKEY,
|
3574
|
+
)
|
3575
|
+
origin_hotkey = wallet.hotkey.ss58_address
|
3576
|
+
else:
|
3577
|
+
if is_valid_ss58_address(wallet_hotkey):
|
3578
|
+
origin_hotkey = wallet_hotkey
|
3579
|
+
else:
|
3580
|
+
wallet = self.wallet_ask(
|
3581
|
+
wallet_name,
|
3582
|
+
wallet_path,
|
3583
|
+
wallet_hotkey,
|
3584
|
+
ask_for=[],
|
3585
|
+
validate=WV.WALLET_AND_HOTKEY,
|
3586
|
+
)
|
3587
|
+
origin_hotkey = wallet.hotkey.ss58_address
|
3588
|
+
|
3546
3589
|
if not dest_ss58:
|
3547
3590
|
dest_ss58 = Prompt.ask(
|
3548
3591
|
"Enter the [blue]destination wallet name[/blue] or [blue]coldkey SS58 address[/blue]"
|
@@ -3580,6 +3623,7 @@ class CLIManager:
|
|
3580
3623
|
move_stake.transfer_stake(
|
3581
3624
|
wallet=wallet,
|
3582
3625
|
subtensor=self.initialize_chain(network),
|
3626
|
+
origin_hotkey=origin_hotkey,
|
3583
3627
|
origin_netuid=origin_netuid,
|
3584
3628
|
dest_netuid=dest_netuid,
|
3585
3629
|
dest_coldkey_ss58=dest_ss58,
|
@@ -5041,6 +5085,28 @@ class CLIManager:
|
|
5041
5085
|
)
|
5042
5086
|
)
|
5043
5087
|
|
5088
|
+
def view_dashboard(
|
5089
|
+
self,
|
5090
|
+
network: Optional[list[str]] = Options.network,
|
5091
|
+
wallet_name: str = Options.wallet_name,
|
5092
|
+
wallet_path: str = Options.wallet_path,
|
5093
|
+
wallet_hotkey: str = Options.wallet_hotkey,
|
5094
|
+
quiet: bool = Options.quiet,
|
5095
|
+
verbose: bool = Options.verbose,
|
5096
|
+
):
|
5097
|
+
"""
|
5098
|
+
Display html dashboard with subnets list, stake, and neuron information.
|
5099
|
+
"""
|
5100
|
+
self.verbosity_handler(quiet, verbose)
|
5101
|
+
if is_linux():
|
5102
|
+
print_linux_dependency_message()
|
5103
|
+
wallet = self.wallet_ask(
|
5104
|
+
wallet_name, wallet_path, wallet_hotkey, ask_for=[WO.NAME, WO.PATH]
|
5105
|
+
)
|
5106
|
+
return self._run_command(
|
5107
|
+
view.display_network_dashboard(wallet, self.initialize_chain(network))
|
5108
|
+
)
|
5109
|
+
|
5044
5110
|
@staticmethod
|
5045
5111
|
@utils_app.command("convert")
|
5046
5112
|
def convert(
|
bittensor_cli/src/__init__.py
CHANGED
@@ -297,17 +297,16 @@ class Balance:
|
|
297
297
|
return self
|
298
298
|
|
299
299
|
|
300
|
-
def fixed_to_float(fixed:
|
301
|
-
#
|
300
|
+
def fixed_to_float(fixed, frac_bits: int = 64, total_bits: int = 128) -> float:
|
301
|
+
# By default, this is a U64F64
|
302
302
|
# which is 64 bits of integer and 64 bits of fractional
|
303
|
-
# uint_bits = 64
|
304
|
-
frac_bits = 64
|
305
303
|
|
306
304
|
data: int = fixed["bits"]
|
307
305
|
|
308
|
-
#
|
309
|
-
integer_part = data >> frac_bits
|
306
|
+
# Logical and to get the fractional part; remaining is the integer part
|
310
307
|
fractional_part = data & (2**frac_bits - 1)
|
308
|
+
# Shift to get the integer part from the remaining bits
|
309
|
+
integer_part = data >> (total_bits - frac_bits)
|
311
310
|
|
312
311
|
frac_float = fractional_part / (2**frac_bits)
|
313
312
|
|
@@ -6,11 +6,12 @@ from typing import Optional, Any, Union
|
|
6
6
|
import netaddr
|
7
7
|
from scalecodec.utils.ss58 import ss58_encode
|
8
8
|
|
9
|
-
from bittensor_cli.src.bittensor.balances import Balance
|
9
|
+
from bittensor_cli.src.bittensor.balances import Balance, fixed_to_float
|
10
10
|
from bittensor_cli.src.bittensor.networking import int_to_ip
|
11
11
|
from bittensor_cli.src.bittensor.utils import (
|
12
12
|
SS58_FORMAT,
|
13
|
-
u16_normalized_float,
|
13
|
+
u16_normalized_float as u16tf,
|
14
|
+
u64_normalized_float as u64tf,
|
14
15
|
decode_account_id,
|
15
16
|
)
|
16
17
|
|
@@ -57,6 +58,31 @@ def process_stake_data(stake_data, netuid):
|
|
57
58
|
return decoded_stake_data
|
58
59
|
|
59
60
|
|
61
|
+
def _tbwu(val: int, netuid: Optional[int] = 0) -> Balance:
|
62
|
+
"""Returns a Balance object from a value and unit."""
|
63
|
+
return Balance.from_rao(val).set_unit(netuid)
|
64
|
+
|
65
|
+
|
66
|
+
def _chr_str(codes: tuple[int]) -> str:
|
67
|
+
"""Converts a tuple of integer Unicode code points into a string."""
|
68
|
+
return "".join(map(chr, codes))
|
69
|
+
|
70
|
+
|
71
|
+
def process_nested(data: Union[tuple, dict], chr_transform):
|
72
|
+
"""Processes nested data structures by applying a transformation function to their elements."""
|
73
|
+
if isinstance(data, (list, tuple)):
|
74
|
+
if len(data) > 0 and isinstance(data[0], dict):
|
75
|
+
return [
|
76
|
+
{k: chr_transform(v) for k, v in item.items()}
|
77
|
+
if item is not None
|
78
|
+
else None
|
79
|
+
for item in data
|
80
|
+
]
|
81
|
+
return {}
|
82
|
+
elif isinstance(data, dict):
|
83
|
+
return {k: chr_transform(v) for k, v in data.items()}
|
84
|
+
|
85
|
+
|
60
86
|
@dataclass
|
61
87
|
class AxonInfo:
|
62
88
|
version: int
|
@@ -312,13 +338,13 @@ class NeuronInfo(InfoBase):
|
|
312
338
|
stake=total_stake,
|
313
339
|
stake_dict=stake_dict,
|
314
340
|
total_stake=total_stake,
|
315
|
-
rank=
|
341
|
+
rank=u16tf(decoded.get("rank")),
|
316
342
|
emission=decoded.get("emission") / 1e9,
|
317
|
-
incentive=
|
318
|
-
consensus=
|
319
|
-
trust=
|
320
|
-
validator_trust=
|
321
|
-
dividends=
|
343
|
+
incentive=u16tf(decoded.get("incentive")),
|
344
|
+
consensus=u16tf(decoded.get("consensus")),
|
345
|
+
trust=u16tf(decoded.get("trust")),
|
346
|
+
validator_trust=u16tf(decoded.get("validator_trust")),
|
347
|
+
dividends=u16tf(decoded.get("dividends")),
|
322
348
|
last_update=decoded.get("last_update"),
|
323
349
|
validator_permit=decoded.get("validator_permit"),
|
324
350
|
weights=[[e[0], e[1]] for e in decoded.get("weights")],
|
@@ -426,22 +452,22 @@ class NeuronInfoLite(InfoBase):
|
|
426
452
|
coldkey=coldkey,
|
427
453
|
),
|
428
454
|
coldkey=coldkey,
|
429
|
-
consensus=
|
430
|
-
dividends=
|
455
|
+
consensus=u16tf(consensus),
|
456
|
+
dividends=u16tf(dividends),
|
431
457
|
emission=emission / 1e9,
|
432
458
|
hotkey=hotkey,
|
433
|
-
incentive=
|
459
|
+
incentive=u16tf(incentive),
|
434
460
|
last_update=last_update,
|
435
461
|
netuid=netuid,
|
436
462
|
pruning_score=pruning_score,
|
437
|
-
rank=
|
463
|
+
rank=u16tf(rank),
|
438
464
|
stake_dict=stake_dict,
|
439
465
|
stake=stake,
|
440
466
|
total_stake=stake,
|
441
|
-
trust=
|
467
|
+
trust=u16tf(trust),
|
442
468
|
uid=uid,
|
443
469
|
validator_permit=validator_permit,
|
444
|
-
validator_trust=
|
470
|
+
validator_trust=u16tf(validator_trust),
|
445
471
|
)
|
446
472
|
|
447
473
|
return neuron
|
@@ -492,7 +518,7 @@ class DelegateInfo(InfoBase):
|
|
492
518
|
total_stake=total_stake,
|
493
519
|
nominators=nominators,
|
494
520
|
owner_ss58=owner,
|
495
|
-
take=
|
521
|
+
take=u16tf(decoded.get("take")),
|
496
522
|
validator_permits=decoded.get("validator_permits"),
|
497
523
|
registrations=decoded.get("registrations"),
|
498
524
|
return_per_1000=Balance.from_rao(decoded.get("return_per_1000")),
|
@@ -528,7 +554,7 @@ class DelegateInfoLite(InfoBase):
|
|
528
554
|
if decoded_take == 65535:
|
529
555
|
fixed_take = None
|
530
556
|
else:
|
531
|
-
fixed_take =
|
557
|
+
fixed_take = u16tf(decoded_take)
|
532
558
|
|
533
559
|
return cls(
|
534
560
|
hotkey_ss58=ss58_encode(decoded.get("delegate_ss58"), SS58_FORMAT),
|
@@ -581,7 +607,7 @@ class SubnetInfo(InfoBase):
|
|
581
607
|
tempo=decoded.get("tempo"),
|
582
608
|
modality=decoded.get("network_modality"),
|
583
609
|
connection_requirements={
|
584
|
-
str(int(netuid)):
|
610
|
+
str(int(netuid)): u16tf(int(req))
|
585
611
|
for (netuid, req) in decoded.get("network_connect")
|
586
612
|
},
|
587
613
|
emission_value=decoded.get("emission_value"),
|
@@ -844,19 +870,17 @@ class SubnetState(InfoBase):
|
|
844
870
|
coldkeys=[decode_account_id(val) for val in decoded.get("coldkeys")],
|
845
871
|
active=decoded.get("active"),
|
846
872
|
validator_permit=decoded.get("validator_permit"),
|
847
|
-
pruning_score=[
|
848
|
-
u16_normalized_float(val) for val in decoded.get("pruning_score")
|
849
|
-
],
|
873
|
+
pruning_score=[u16tf(val) for val in decoded.get("pruning_score")],
|
850
874
|
last_update=decoded.get("last_update"),
|
851
875
|
emission=[
|
852
876
|
Balance.from_rao(val).set_unit(netuid)
|
853
877
|
for val in decoded.get("emission")
|
854
878
|
],
|
855
|
-
dividends=[
|
856
|
-
incentives=[
|
857
|
-
consensus=[
|
858
|
-
trust=[
|
859
|
-
rank=[
|
879
|
+
dividends=[u16tf(val) for val in decoded.get("dividends")],
|
880
|
+
incentives=[u16tf(val) for val in decoded.get("incentives")],
|
881
|
+
consensus=[u16tf(val) for val in decoded.get("consensus")],
|
882
|
+
trust=[u16tf(val) for val in decoded.get("trust")],
|
883
|
+
rank=[u16tf(val) for val in decoded.get("rank")],
|
860
884
|
block_at_registration=decoded.get("block_at_registration"),
|
861
885
|
alpha_stake=[
|
862
886
|
Balance.from_rao(val).set_unit(netuid)
|
@@ -871,3 +895,241 @@ class SubnetState(InfoBase):
|
|
871
895
|
],
|
872
896
|
emission_history=decoded.get("emission_history"),
|
873
897
|
)
|
898
|
+
|
899
|
+
|
900
|
+
@dataclass
|
901
|
+
class ChainIdentity(InfoBase):
|
902
|
+
"""Dataclass for chain identity information."""
|
903
|
+
|
904
|
+
name: str
|
905
|
+
url: str
|
906
|
+
github: str
|
907
|
+
image: str
|
908
|
+
discord: str
|
909
|
+
description: str
|
910
|
+
additional: str
|
911
|
+
|
912
|
+
@classmethod
|
913
|
+
def _from_dict(cls, decoded: dict) -> "ChainIdentity":
|
914
|
+
"""Returns a ChainIdentity object from decoded chain data."""
|
915
|
+
return cls(
|
916
|
+
name=decoded["name"],
|
917
|
+
url=decoded["url"],
|
918
|
+
github=decoded["github_repo"],
|
919
|
+
image=decoded["image"],
|
920
|
+
discord=decoded["discord"],
|
921
|
+
description=decoded["description"],
|
922
|
+
additional=decoded["additional"],
|
923
|
+
)
|
924
|
+
|
925
|
+
|
926
|
+
@dataclass
|
927
|
+
class MetagraphInfo(InfoBase):
|
928
|
+
# Subnet index
|
929
|
+
netuid: int
|
930
|
+
|
931
|
+
# Name and symbol
|
932
|
+
name: str
|
933
|
+
symbol: str
|
934
|
+
identity: Optional[SubnetIdentity]
|
935
|
+
network_registered_at: int
|
936
|
+
|
937
|
+
# Keys for owner.
|
938
|
+
owner_hotkey: str # hotkey
|
939
|
+
owner_coldkey: str # coldkey
|
940
|
+
|
941
|
+
# Tempo terms.
|
942
|
+
block: int # block at call.
|
943
|
+
tempo: int # epoch tempo
|
944
|
+
last_step: int
|
945
|
+
blocks_since_last_step: int
|
946
|
+
|
947
|
+
# Subnet emission terms
|
948
|
+
subnet_emission: Balance # subnet emission via tao
|
949
|
+
alpha_in: Balance # amount of alpha in reserve
|
950
|
+
alpha_out: Balance # amount of alpha outstanding
|
951
|
+
tao_in: Balance # amount of tao injected per block
|
952
|
+
alpha_out_emission: Balance # amount injected in alpha reserves per block
|
953
|
+
alpha_in_emission: Balance # amount injected outstanding per block
|
954
|
+
tao_in_emission: Balance # amount of tao injected per block
|
955
|
+
pending_alpha_emission: Balance # pending alpha to be distributed
|
956
|
+
pending_root_emission: Balance # pending tao for root divs to be distributed
|
957
|
+
subnet_volume: Balance # volume of the subnet in TAO
|
958
|
+
moving_price: Balance # subnet moving price.
|
959
|
+
|
960
|
+
# Hparams for epoch
|
961
|
+
rho: int # subnet rho param
|
962
|
+
kappa: float # subnet kappa param
|
963
|
+
|
964
|
+
# Validator params
|
965
|
+
min_allowed_weights: float # min allowed weights per val
|
966
|
+
max_weights_limit: float # max allowed weights per val
|
967
|
+
weights_version: int # allowed weights version
|
968
|
+
weights_rate_limit: int # rate limit on weights.
|
969
|
+
activity_cutoff: int # validator weights cut off period in blocks
|
970
|
+
max_validators: int # max allowed validators.
|
971
|
+
|
972
|
+
# Registration
|
973
|
+
num_uids: int
|
974
|
+
max_uids: int
|
975
|
+
burn: Balance # current burn cost.
|
976
|
+
difficulty: float # current difficulty.
|
977
|
+
registration_allowed: bool # allows registrations.
|
978
|
+
pow_registration_allowed: bool # pow registration enabled.
|
979
|
+
immunity_period: int # subnet miner immunity period
|
980
|
+
min_difficulty: float # min pow difficulty
|
981
|
+
max_difficulty: float # max pow difficulty
|
982
|
+
min_burn: Balance # min tao burn
|
983
|
+
max_burn: Balance # max tao burn
|
984
|
+
adjustment_alpha: float # adjustment speed for registration params.
|
985
|
+
adjustment_interval: int # pow and burn adjustment interval
|
986
|
+
target_regs_per_interval: int # target registrations per interval
|
987
|
+
max_regs_per_block: int # max registrations per block.
|
988
|
+
serving_rate_limit: int # axon serving rate limit
|
989
|
+
|
990
|
+
# CR
|
991
|
+
commit_reveal_weights_enabled: bool # Is CR enabled.
|
992
|
+
commit_reveal_period: int # Commit reveal interval
|
993
|
+
|
994
|
+
# Bonds
|
995
|
+
liquid_alpha_enabled: bool # Bonds liquid enabled.
|
996
|
+
alpha_high: float # Alpha param high
|
997
|
+
alpha_low: float # Alpha param low
|
998
|
+
bonds_moving_avg: float # Bonds moving avg
|
999
|
+
|
1000
|
+
# Metagraph info.
|
1001
|
+
hotkeys: list[str] # hotkey per UID
|
1002
|
+
coldkeys: list[str] # coldkey per UID
|
1003
|
+
identities: list[Optional[ChainIdentity]] # coldkeys identities
|
1004
|
+
axons: list[AxonInfo] # UID axons.
|
1005
|
+
active: list[bool] # Active per UID
|
1006
|
+
validator_permit: list[bool] # Val permit per UID
|
1007
|
+
pruning_score: list[float] # Pruning per UID
|
1008
|
+
last_update: list[int] # Last update per UID
|
1009
|
+
emission: list[Balance] # Emission per UID
|
1010
|
+
dividends: list[float] # Dividends per UID
|
1011
|
+
incentives: list[float] # Mining incentives per UID
|
1012
|
+
consensus: list[float] # Consensus per UID
|
1013
|
+
trust: list[float] # Trust per UID
|
1014
|
+
rank: list[float] # Rank per UID
|
1015
|
+
block_at_registration: list[int] # Reg block per UID
|
1016
|
+
alpha_stake: list[Balance] # Alpha staked per UID
|
1017
|
+
tao_stake: list[Balance] # TAO staked per UID
|
1018
|
+
total_stake: list[Balance] # Total stake per UID
|
1019
|
+
|
1020
|
+
# Dividend break down.
|
1021
|
+
tao_dividends_per_hotkey: list[
|
1022
|
+
tuple[str, Balance]
|
1023
|
+
] # List of dividend payouts in tao via root.
|
1024
|
+
alpha_dividends_per_hotkey: list[
|
1025
|
+
tuple[str, Balance]
|
1026
|
+
] # List of dividend payout in alpha via subnet.
|
1027
|
+
|
1028
|
+
@classmethod
|
1029
|
+
def _fix_decoded(cls, decoded: dict) -> "MetagraphInfo":
|
1030
|
+
"""Returns a MetagraphInfo object from decoded chain data."""
|
1031
|
+
# Subnet index
|
1032
|
+
_netuid = decoded["netuid"]
|
1033
|
+
|
1034
|
+
# Name and symbol
|
1035
|
+
decoded.update({"name": bytes(decoded.get("name")).decode()})
|
1036
|
+
decoded.update({"symbol": bytes(decoded.get("symbol")).decode()})
|
1037
|
+
for key in ["identities", "identity"]:
|
1038
|
+
raw_data = decoded.get(key)
|
1039
|
+
processed = process_nested(raw_data, _chr_str)
|
1040
|
+
decoded.update({key: processed})
|
1041
|
+
|
1042
|
+
return cls(
|
1043
|
+
# Subnet index
|
1044
|
+
netuid=_netuid,
|
1045
|
+
# Name and symbol
|
1046
|
+
name=decoded["name"],
|
1047
|
+
symbol=decoded["symbol"],
|
1048
|
+
identity=decoded["identity"],
|
1049
|
+
network_registered_at=decoded["network_registered_at"],
|
1050
|
+
# Keys for owner.
|
1051
|
+
owner_hotkey=decoded["owner_hotkey"],
|
1052
|
+
owner_coldkey=decoded["owner_coldkey"],
|
1053
|
+
# Tempo terms.
|
1054
|
+
block=decoded["block"],
|
1055
|
+
tempo=decoded["tempo"],
|
1056
|
+
last_step=decoded["last_step"],
|
1057
|
+
blocks_since_last_step=decoded["blocks_since_last_step"],
|
1058
|
+
# Subnet emission terms
|
1059
|
+
subnet_emission=_tbwu(decoded["subnet_emission"]),
|
1060
|
+
alpha_in=_tbwu(decoded["alpha_in"], _netuid),
|
1061
|
+
alpha_out=_tbwu(decoded["alpha_out"], _netuid),
|
1062
|
+
tao_in=_tbwu(decoded["tao_in"]),
|
1063
|
+
alpha_out_emission=_tbwu(decoded["alpha_out_emission"], _netuid),
|
1064
|
+
alpha_in_emission=_tbwu(decoded["alpha_in_emission"], _netuid),
|
1065
|
+
tao_in_emission=_tbwu(decoded["tao_in_emission"]),
|
1066
|
+
pending_alpha_emission=_tbwu(decoded["pending_alpha_emission"], _netuid),
|
1067
|
+
pending_root_emission=_tbwu(decoded["pending_root_emission"]),
|
1068
|
+
subnet_volume=_tbwu(decoded["subnet_volume"], _netuid),
|
1069
|
+
moving_price=Balance.from_tao(
|
1070
|
+
fixed_to_float(decoded.get("moving_price"), 32)
|
1071
|
+
),
|
1072
|
+
# Hparams for epoch
|
1073
|
+
rho=decoded["rho"],
|
1074
|
+
kappa=decoded["kappa"],
|
1075
|
+
# Validator params
|
1076
|
+
min_allowed_weights=u16tf(decoded["min_allowed_weights"]),
|
1077
|
+
max_weights_limit=u16tf(decoded["max_weights_limit"]),
|
1078
|
+
weights_version=decoded["weights_version"],
|
1079
|
+
weights_rate_limit=decoded["weights_rate_limit"],
|
1080
|
+
activity_cutoff=decoded["activity_cutoff"],
|
1081
|
+
max_validators=decoded["max_validators"],
|
1082
|
+
# Registration
|
1083
|
+
num_uids=decoded["num_uids"],
|
1084
|
+
max_uids=decoded["max_uids"],
|
1085
|
+
burn=_tbwu(decoded["burn"]),
|
1086
|
+
difficulty=u64tf(decoded["difficulty"]),
|
1087
|
+
registration_allowed=decoded["registration_allowed"],
|
1088
|
+
pow_registration_allowed=decoded["pow_registration_allowed"],
|
1089
|
+
immunity_period=decoded["immunity_period"],
|
1090
|
+
min_difficulty=u64tf(decoded["min_difficulty"]),
|
1091
|
+
max_difficulty=u64tf(decoded["max_difficulty"]),
|
1092
|
+
min_burn=_tbwu(decoded["min_burn"]),
|
1093
|
+
max_burn=_tbwu(decoded["max_burn"]),
|
1094
|
+
adjustment_alpha=u64tf(decoded["adjustment_alpha"]),
|
1095
|
+
adjustment_interval=decoded["adjustment_interval"],
|
1096
|
+
target_regs_per_interval=decoded["target_regs_per_interval"],
|
1097
|
+
max_regs_per_block=decoded["max_regs_per_block"],
|
1098
|
+
serving_rate_limit=decoded["serving_rate_limit"],
|
1099
|
+
# CR
|
1100
|
+
commit_reveal_weights_enabled=decoded["commit_reveal_weights_enabled"],
|
1101
|
+
commit_reveal_period=decoded["commit_reveal_period"],
|
1102
|
+
# Bonds
|
1103
|
+
liquid_alpha_enabled=decoded["liquid_alpha_enabled"],
|
1104
|
+
alpha_high=u16tf(decoded["alpha_high"]),
|
1105
|
+
alpha_low=u16tf(decoded["alpha_low"]),
|
1106
|
+
bonds_moving_avg=u64tf(decoded["bonds_moving_avg"]),
|
1107
|
+
# Metagraph info.
|
1108
|
+
hotkeys=[decode_account_id(ck) for ck in decoded.get("hotkeys", [])],
|
1109
|
+
coldkeys=[decode_account_id(hk) for hk in decoded.get("coldkeys", [])],
|
1110
|
+
identities=decoded["identities"],
|
1111
|
+
axons=decoded.get("axons", []),
|
1112
|
+
active=decoded["active"],
|
1113
|
+
validator_permit=decoded["validator_permit"],
|
1114
|
+
pruning_score=[u16tf(ps) for ps in decoded.get("pruning_score", [])],
|
1115
|
+
last_update=decoded["last_update"],
|
1116
|
+
emission=[_tbwu(em, _netuid) for em in decoded.get("emission", [])],
|
1117
|
+
dividends=[u16tf(dv) for dv in decoded.get("dividends", [])],
|
1118
|
+
incentives=[u16tf(ic) for ic in decoded.get("incentives", [])],
|
1119
|
+
consensus=[u16tf(cs) for cs in decoded.get("consensus", [])],
|
1120
|
+
trust=[u16tf(tr) for tr in decoded.get("trust", [])],
|
1121
|
+
rank=[u16tf(rk) for rk in decoded.get("rank", [])],
|
1122
|
+
block_at_registration=decoded["block_at_registration"],
|
1123
|
+
alpha_stake=[_tbwu(ast, _netuid) for ast in decoded["alpha_stake"]],
|
1124
|
+
tao_stake=[_tbwu(ts) for ts in decoded["tao_stake"]],
|
1125
|
+
total_stake=[_tbwu(ts, _netuid) for ts in decoded["total_stake"]],
|
1126
|
+
# Dividend break down
|
1127
|
+
tao_dividends_per_hotkey=[
|
1128
|
+
(decode_account_id(alpha[0]), _tbwu(alpha[1]))
|
1129
|
+
for alpha in decoded["tao_dividends_per_hotkey"]
|
1130
|
+
],
|
1131
|
+
alpha_dividends_per_hotkey=[
|
1132
|
+
(decode_account_id(adphk[0]), _tbwu(adphk[1], _netuid))
|
1133
|
+
for adphk in decoded["alpha_dividends_per_hotkey"]
|
1134
|
+
],
|
1135
|
+
)
|