From 8e661c10971e6673d54fdea45f5205f0c5983d57 Mon Sep 17 00:00:00 2001 From: Roman <167799377+roman-opentensor@users.noreply.github.com> Date: Fri, 25 Oct 2024 10:59:38 -0700 Subject: [PATCH 01/10] Make Metagraph class RAO compatible (#2368) * Update Balance * Update Metagraph * ruff * add `SubnetState` into `custom_rpc_type_registry` and update metagrapg.S field * update settings.TYPE_REGISTRY and metagraph * ruff * tests fixed * List -> list * review fixes * ruff --- bittensor/core/chain_data/__init__.py | 1 + bittensor/core/chain_data/subnet_state.py | 90 ++++++++++ bittensor/core/chain_data/utils.py | 24 +++ bittensor/core/metagraph.py | 92 +++++++++- bittensor/core/settings.py | 160 +++++++++++++++++- bittensor/core/subtensor.py | 8 +- bittensor/utils/balance.py | 37 +++- bittensor/utils/mock/subtensor_mock.py | 9 + .../test_metagraph_integration.py | 10 +- tests/unit_tests/test_metagraph.py | 1 + 10 files changed, 406 insertions(+), 26 deletions(-) create mode 100644 bittensor/core/chain_data/subnet_state.py diff --git a/bittensor/core/chain_data/__init__.py b/bittensor/core/chain_data/__init__.py index 9ad1e38881..08f220861d 100644 --- a/bittensor/core/chain_data/__init__.py +++ b/bittensor/core/chain_data/__init__.py @@ -17,6 +17,7 @@ from .stake_info import StakeInfo from .subnet_hyperparameters import SubnetHyperparameters from .subnet_info import SubnetInfo +from .subnet_state import SubnetState from .utils import custom_rpc_type_registry ProposalCallData = GenericCall diff --git a/bittensor/core/chain_data/subnet_state.py b/bittensor/core/chain_data/subnet_state.py new file mode 100644 index 0000000000..53cda11b44 --- /dev/null +++ b/bittensor/core/chain_data/subnet_state.py @@ -0,0 +1,90 @@ +""" +This module defines the `SubnetState` data class and associated methods for handling and decoding +subnetwork states in the Bittensor network. +""" + +from dataclasses import dataclass +from typing import Optional + +from scalecodec.utils.ss58 import ss58_encode + +from bittensor.core.chain_data.utils import ( + ChainDataType, + from_scale_encoding, + SS58_FORMAT, +) +from bittensor.utils import u16_normalized_float +from bittensor.utils.balance import Balance + + +@dataclass +class SubnetState: + netuid: int + hotkeys: list[str] + coldkeys: list[str] + active: list[bool] + validator_permit: list[bool] + pruning_score: list[float] + last_update: list[int] + emission: list[Balance] + dividends: list[float] + incentives: list[float] + consensus: list[float] + trust: list[float] + rank: list[float] + block_at_registration: list[int] + local_stake: list[Balance] + global_stake: list[Balance] + stake_weight: list[float] + emission_history: list[list[int]] + + @classmethod + def from_vec_u8(cls, vec_u8: list[int]) -> Optional["SubnetState"]: + if len(vec_u8) == 0: + return None + decoded = from_scale_encoding(vec_u8, ChainDataType.SubnetState, is_option=True) + if decoded is None: + return None + return SubnetState.fix_decoded_values(decoded) + + @classmethod + def list_from_vec_u8(cls, vec_u8: list[int]) -> list["SubnetState"]: + decoded = from_scale_encoding( + vec_u8, ChainDataType.SubnetState, is_vec=True, is_option=True + ) + if decoded is None: + return [] + decoded = [SubnetState.fix_decoded_values(d) for d in decoded] + return decoded + + @classmethod + def fix_decoded_values(cls, decoded: dict) -> "SubnetState": + netuid = decoded["netuid"] + return SubnetState( + netuid=netuid, + hotkeys=[ss58_encode(val, SS58_FORMAT) for val in decoded["hotkeys"]], + coldkeys=[ss58_encode(val, SS58_FORMAT) for val in decoded["coldkeys"]], + active=decoded["active"], + validator_permit=decoded["validator_permit"], + pruning_score=[ + u16_normalized_float(val) for val in decoded["pruning_score"] + ], + last_update=decoded["last_update"], + emission=[ + Balance.from_rao(val).set_unit(netuid) for val in decoded["emission"] + ], + dividends=[u16_normalized_float(val) for val in decoded["dividends"]], + incentives=[u16_normalized_float(val) for val in decoded["incentives"]], + consensus=[u16_normalized_float(val) for val in decoded["consensus"]], + trust=[u16_normalized_float(val) for val in decoded["trust"]], + rank=[u16_normalized_float(val) for val in decoded["rank"]], + block_at_registration=decoded["block_at_registration"], + local_stake=[ + Balance.from_rao(val).set_unit(netuid) for val in decoded["local_stake"] + ], + global_stake=[ + Balance.from_rao(val).set_unit(0) for val in decoded["global_stake"] + ], + stake_weight=[u16_normalized_float(val) for val in decoded["stake_weight"]], + emission_history=decoded["emission_history"], + ) diff --git a/bittensor/core/chain_data/utils.py b/bittensor/core/chain_data/utils.py index 9c21c9d22e..dbf17a1c8d 100644 --- a/bittensor/core/chain_data/utils.py +++ b/bittensor/core/chain_data/utils.py @@ -22,6 +22,7 @@ class ChainDataType(Enum): SubnetHyperparameters = 8 ScheduledColdkeySwapInfo = 9 AccountId = 10 + SubnetState = 11 def from_scale_encoding( @@ -208,6 +209,29 @@ def from_scale_encoding_using_type_string( ["ip_type_and_protocol", "Compact"], ], }, + "SubnetState": { + "type": "struct", + "type_mapping": [ + ["netuid", "Compact"], + ["hotkeys", "Vec"], + ["coldkeys", "Vec"], + ["active", "Vec"], + ["validator_permit", "Vec"], + ["pruning_score", "Vec>"], + ["last_update", "Vec>"], + ["emission", "Vec>"], + ["dividends", "Vec>"], + ["incentives", "Vec>"], + ["consensus", "Vec>"], + ["trust", "Vec>"], + ["rank", "Vec>"], + ["block_at_registration", "Vec>"], + ["local_stake", "Vec>"], + ["global_stake", "Vec>"], + ["stake_weight", "Vec>"], + ["emission_history", "Vec>>"], + ], + }, "StakeInfo": { "type": "struct", "type_mapping": [ diff --git a/bittensor/core/metagraph.py b/bittensor/core/metagraph.py index 208eaa6b9f..bdab996542 100644 --- a/bittensor/core/metagraph.py +++ b/bittensor/core/metagraph.py @@ -25,7 +25,11 @@ import numpy as np from numpy.typing import NDArray +from substrateinterface.exceptions import SubstrateRequestException +from bittensor.core import settings +from bittensor.core.chain_data import AxonInfo, SubnetState +from bittensor.utils.balance import Balance from bittensor.utils.btlogging import logging from bittensor.utils.registration import torch, use_torch from bittensor.utils.weight_utils import ( @@ -33,8 +37,6 @@ convert_bond_uids_and_vals_to_tensor, convert_root_weight_uids_and_vals_to_tensor, ) -from . import settings -from .chain_data import AxonInfo # For annotation purposes if typing.TYPE_CHECKING: @@ -210,20 +212,54 @@ class MetagraphMixin(ABC): weights: Union["torch.nn.Parameter", NDArray] bonds: Union["torch.nn.Parameter", NDArray] uids: Union["torch.nn.Parameter", NDArray] + local_stake: Union["torch.nn.Parameter", NDArray] + global_stake: Union["torch.nn.Parameter", NDArray] + stake_weights: Union["torch.nn.Parameter", NDArray] axons: list[AxonInfo] @property - def S(self) -> Union[NDArray, "torch.nn.Parameter"]: + def GS(self) -> list[Balance]: """ - Represents the stake of each neuron in the Bittensor network. Stake is an important concept in the - Bittensor ecosystem, signifying the amount of network weight (or “stake”) each neuron holds, - represented on a digital ledger. The stake influences a neuron's ability to contribute to and benefit - from the network, playing a crucial role in the distribution of incentives and decision-making processes. + Represents the global stake of each neuron in the Bittensor network. Returns: - NDArray: A tensor representing the stake of each neuron in the network. Higher values signify a greater stake held by the respective neuron. + List[Balance]: The list of global stake of each neuron in the network. """ - return self.total_stake + return self.global_stake + + @property + def LS(self) -> list[Balance]: + """ + Represents the local stake of each neuron in the Bittensor network. + + Returns: + List[Balance]: The list of local stake of each neuron in the network. + """ + return self.local_stake + + @property + def SW(self) -> list[float]: + """ + Represents the stake weights of each neuron in the Bittensor network. + + Returns: + List[float]: Each value is calculated based on local_stake and global_stake. + """ + return self.stake_weights + + @property + def S(self) -> float: + """ + Represents the value between 0.0 and 1.0. This gives the users do blacklists in terms of stake values. + Returns: + float: The value between 0.0 and 1.0 or None if stake_weights doesn't have zero index value. + """ + try: + value = self.stake_weights[0] * max(self.global_stake).tao + except IndexError: + logging.warning("Stake weights is empty.") + value = None + return value @property def R(self) -> Union[NDArray, "torch.nn.Parameter"]: @@ -578,6 +614,9 @@ def sync( if not lite: self._set_weights_and_bonds(subtensor=subtensor) + # Fills in the stake associated attributes of a class instance from a chain response. + self._get_all_stakes_from_chain(subtensor=subtensor) + def _initialize_subtensor(self, subtensor: "Subtensor"): """ Initializes the subtensor to be used for syncing the metagraph. @@ -748,6 +787,35 @@ def _process_weights_or_bonds( def _set_metagraph_attributes(self, block, subtensor): pass + def _get_all_stakes_from_chain(self, subtensor: "Subtensor"): + """Fills in the stake associated attributes of a class instance from a chain response.""" + try: + hex_bytes_result = subtensor.query_runtime_api( + runtime_api="SubnetInfoRuntimeApi", + method="get_subnet_state", + params=[self.netuid], + ) + + if hex_bytes_result is None: + logging.debug( + f"Unable to retrieve subnet state for netuid `{self.netuid}`." + ) + return [] + + if hex_bytes_result.startswith("0x"): + bytes_result = bytes.fromhex(hex_bytes_result[2:]) + else: + bytes_result = bytes.fromhex(hex_bytes_result) + + subnet_state: "SubnetState" = SubnetState.from_vec_u8(bytes_result) + self.global_stake = subnet_state.global_stake + self.local_stake = subnet_state.local_stake + self.stake_weights = subnet_state.stake_weight + except (SubstrateRequestException, AttributeError): + logging.debug( + "Fields `global_stake`, `local_stake`, `stake_weights` can be obtained only from the RAO network." + ) + def _process_root_weights( self, data: list, attribute: str, subtensor: "Subtensor" ) -> Union[NDArray, "torch.nn.Parameter"]: @@ -984,6 +1052,9 @@ def __init__( self.uids = torch.nn.Parameter( torch.tensor([], dtype=torch.int64), requires_grad=False ) + self.local_stake: list[Balance] = [] + self.global_stake: list[Balance] = [] + self.stake_weights: list[float] = [] self.axons: list[AxonInfo] = [] if sync: self.sync(block=None, lite=lite) @@ -1163,6 +1234,9 @@ def __init__( self.weights = np.array([], dtype=np.float32) self.bonds = np.array([], dtype=np.int64) self.uids = np.array([], dtype=np.int64) + self.local_stake: list[Balance] = [] + self.global_stake: list[Balance] = [] + self.stake_weights: list[float] = [] self.axons: list[AxonInfo] = [] if sync: self.sync(block=None, lite=lite) diff --git a/bittensor/core/settings.py b/bittensor/core/settings.py index 29948b612e..b3a3bb4b3a 100644 --- a/bittensor/core/settings.py +++ b/bittensor/core/settings.py @@ -75,6 +75,7 @@ def turn_console_on(): FINNEY_ENTRYPOINT = "wss://entrypoint-finney.opentensor.ai:443" FINNEY_TEST_ENTRYPOINT = "wss://test.finney.opentensor.ai:443/" ARCHIVE_ENTRYPOINT = "wss://archive.chain.opentensor.ai:443/" +RAO_ENDPOINT = "wss://rao.chain.opentensor.ai:443/" LOCAL_ENTRYPOINT = os.getenv("BT_SUBTENSOR_CHAIN_ENDPOINT") or "ws://127.0.0.1:9946" # Currency Symbols Bittensor @@ -228,17 +229,26 @@ def turn_console_on(): ], "type": "Vec", }, - "get_subnet_info": { + "get_all_dynamic_info": { + "params": [], + "type": "Vec", + }, + "get_subnet_info_v2": { "params": [ - { - "name": "netuid", - "type": "u16", - }, + {"name": "netuid", "type": "u16"}, ], "type": "Vec", }, - "get_subnets_info": { - "params": [], + "get_dynamic_info": { + "params": [ + {"name": "netuid", "type": "u16"}, + ], + "type": "Vec", + }, + "get_subnet_state": { + "params": [ + {"name": "netuid", "type": "u16"}, + ], "type": "Vec", }, } @@ -357,3 +367,139 @@ def __apply_nest_asyncio(): __apply_nest_asyncio() + +units = [ + "\u03c4", # τ (tau, 0) + "\u03b1", # α (alpha, 1) + "\u03b2", # β (beta, 2) + "\u03b3", # γ (gamma, 3) + "\u03b4", # δ (delta, 4) + "\u03b5", # ε (epsilon, 5) + "\u03b6", # ζ (zeta, 6) + "\u03b7", # η (eta, 7) + "\u03b8", # θ (theta, 8) + "\u03b9", # ι (iota, 9) + "\u03ba", # κ (kappa, 10) + "\u03bb", # λ (lambda, 11) + "\u03bc", # μ (mu, 12) + "\u03bd", # ν (nu, 13) + "\u03be", # ξ (xi, 14) + "\u03bf", # ο (omicron, 15) + "\u03c0", # π (pi, 16) + "\u03c1", # ρ (rho, 17) + "\u03c3", # σ (sigma, 18) + "t", # t (tau, 19) + "\u03c5", # υ (upsilon, 20) + "\u03c6", # φ (phi, 21) + "\u03c7", # χ (chi, 22) + "\u03c8", # ψ (psi, 23) + "\u03c9", # ω (omega, 24) + # Hebrew letters + "\u05d0", # א (aleph, 25) + "\u05d1", # ב (bet, 26) + "\u05d2", # ג (gimel, 27) + "\u05d3", # ד (dalet, 28) + "\u05d4", # ה (he, 29) + "\u05d5", # ו (vav, 30) + "\u05d6", # ז (zayin, 31) + "\u05d7", # ח (het, 32) + "\u05d8", # ט (tet, 33) + "\u05d9", # י (yod, 34) + "\u05da", # ך (final kaf, 35) + "\u05db", # כ (kaf, 36) + "\u05dc", # ל (lamed, 37) + "\u05dd", # ם (final mem, 38) + "\u05de", # מ (mem, 39) + "\u05df", # ן (final nun, 40) + "\u05e0", # נ (nun, 41) + "\u05e1", # ס (samekh, 42) + "\u05e2", # ע (ayin, 43) + "\u05e3", # ף (final pe, 44) + "\u05e4", # פ (pe, 45) + "\u05e5", # ץ (final tsadi, 46) + "\u05e6", # צ (tsadi, 47) + "\u05e7", # ק (qof, 48) + "\u05e8", # ר (resh, 49) + "\u05e9", # ש (shin, 50) + "\u05ea", # ת (tav, 51) + # Georgian Alphabet (Mkhedruli) + "\u10d0", # ა (Ani, 97) + "\u10d1", # ბ (Bani, 98) + "\u10d2", # გ (Gani, 99) + "\u10d3", # დ (Doni, 100) + "\u10d4", # ე (Eni, 101) + "\u10d5", # ვ (Vini, 102) + # Armenian Alphabet + "\u0531", # Ա (Ayp, 103) + "\u0532", # Բ (Ben, 104) + "\u0533", # Գ (Gim, 105) + "\u0534", # Դ (Da, 106) + "\u0535", # Ե (Ech, 107) + "\u0536", # Զ (Za, 108) + # "\u055e", # ՞ (Question mark, 109) + # Runic Alphabet + "\u16a0", # ᚠ (Fehu, wealth, 81) + "\u16a2", # ᚢ (Uruz, strength, 82) + "\u16a6", # ᚦ (Thurisaz, giant, 83) + "\u16a8", # ᚨ (Ansuz, god, 84) + "\u16b1", # ᚱ (Raidho, ride, 85) + "\u16b3", # ᚲ (Kaunan, ulcer, 86) + "\u16c7", # ᛇ (Eihwaz, yew, 87) + "\u16c9", # ᛉ (Algiz, protection, 88) + "\u16d2", # ᛒ (Berkanan, birch, 89) + # Cyrillic Alphabet + "\u0400", # Ѐ (Ie with grave, 110) + "\u0401", # Ё (Io, 111) + "\u0402", # Ђ (Dje, 112) + "\u0403", # Ѓ (Gje, 113) + "\u0404", # Є (Ukrainian Ie, 114) + "\u0405", # Ѕ (Dze, 115) + # Coptic Alphabet + "\u2c80", # Ⲁ (Alfa, 116) + "\u2c81", # ⲁ (Small Alfa, 117) + "\u2c82", # Ⲃ (Vida, 118) + "\u2c83", # ⲃ (Small Vida, 119) + "\u2c84", # Ⲅ (Gamma, 120) + "\u2c85", # ⲅ (Small Gamma, 121) + # Arabic letters + "\u0627", # ا (alef, 52) + "\u0628", # ب (ba, 53) + "\u062a", # ت (ta, 54) + "\u062b", # ث (tha, 55) + "\u062c", # ج (jeem, 56) + "\u062d", # ح (ha, 57) + "\u062e", # خ (kha, 58) + "\u062f", # د (dal, 59) + "\u0630", # ذ (dhal, 60) + "\u0631", # ر (ra, 61) + "\u0632", # ز (zay, 62) + "\u0633", # س (seen, 63) + "\u0634", # ش (sheen, 64) + "\u0635", # ص (sad, 65) + "\u0636", # ض (dad, 66) + "\u0637", # ط (ta, 67) + "\u0638", # ظ (dha, 68) + "\u0639", # ع (ain, 69) + "\u063a", # غ (ghain, 70) + "\u0641", # ف (fa, 71) + "\u0642", # ق (qaf, 72) + "\u0643", # ك (kaf, 73) + "\u0644", # ل (lam, 74) + "\u0645", # م (meem, 75) + "\u0646", # ن (noon, 76) + "\u0647", # ه (ha, 77) + "\u0648", # و (waw, 78) + "\u0649", # ى (alef maksura, 79) + "\u064a", # ي (ya, 80) + # Ogham Alphabet + "\u1680", #   (Space, 90) + "\u1681", # ᚁ (Beith, birch, 91) + "\u1682", # ᚂ (Luis, rowan, 92) + "\u1683", # ᚃ (Fearn, alder, 93) + "\u1684", # ᚄ (Sail, willow, 94) + "\u1685", # ᚅ (Nion, ash, 95) + "\u169b", # ᚛ (Forfeda, 96) + # Tifinagh Alphabet + "\u2d30", # ⴰ (Ya, 127) + "\u2d31", # ⴱ (Yab, 128) +] diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index ac6c46bc46..e6d958b10a 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -718,7 +718,7 @@ def determine_chain_endpoint_and_network( if network is None: return None, None - if network in ["finney", "local", "test", "archive"]: + if network in ["finney", "local", "test", "archive", "rao"]: if network == "finney": # Kiru Finney staging network. return network, settings.FINNEY_ENTRYPOINT @@ -728,6 +728,8 @@ def determine_chain_endpoint_and_network( return network, settings.FINNEY_TEST_ENTRYPOINT elif network == "archive": return network, settings.ARCHIVE_ENTRYPOINT + elif network == "rao": + return network, settings.RAO_ENDPOINT else: if ( network == settings.FINNEY_ENTRYPOINT @@ -744,6 +746,10 @@ def determine_chain_endpoint_and_network( or "archive.chain.opentensor.ai" in network ): return "archive", settings.ARCHIVE_ENTRYPOINT + elif ( + network == settings.RAO_ENDPOINT or "rao.chain.opentensor.ai" in network + ): + return "rao", settings.RAO_ENDPOINT elif "127.0.0.1" in network or "localhost" in network: return "local", network else: diff --git a/bittensor/utils/balance.py b/bittensor/utils/balance.py index 016db373a4..cecff54f6c 100644 --- a/bittensor/utils/balance.py +++ b/bittensor/utils/balance.py @@ -68,17 +68,26 @@ def __float__(self): def __str__(self): """Returns the Balance object as a string in the format "symbolvalue", where the value is in tao.""" - return f"{self.unit}{float(self.tao):,.9f}" + if self.unit == settings.units[0]: + return f"{self.unit} {float(self.tao):,.4f}" + else: + return f"{float(self.tao):,.4f} {self.unit}\u200e" def __rich__(self): - int_tao, fract_tao = format(float(self.tao), "f").split(".") - return f"[green]{self.unit}[/green][green]{int_tao}[/green][green].[/green][dim green]{fract_tao}[/dim green]" + return "[green]{}[/green][green]{}[/green][green].[/green][dim green]{}[/dim green]".format( + self.unit, + format(float(self.tao), "f").split(".")[0], + format(float(self.tao), "f").split(".")[1], + ) def __str_rao__(self): return f"{self.rao_unit}{int(self.rao)}" def __rich_rao__(self): - return f"[green]{self.rao_unit}{int(self.rao)}[/green]" + if settings.units.index(self.unit) != 0: + return f"[green]{int(self.rao)}{self.unit}[/green]" + else: + return f"[green]{self.unit}\u200e{int(self.rao)}[/green]" def __repr__(self): return self.__str__() @@ -265,4 +274,22 @@ def from_rao(amount: int): Returns: A Balance object representing the given amount. """ - return Balance(amount) + return Balance(int(amount)) + + @staticmethod + def get_unit(netuid: int): + units = settings.units + base = len(units) + if netuid < base: + return units[netuid] + else: + result = "" + while netuid > 0: + result = units[netuid % base] + result + netuid //= base + return result + + def set_unit(self, netuid: int): + self.unit = Balance.get_unit(netuid) + self.rao_unit = Balance.get_unit(netuid) + return self diff --git a/bittensor/utils/mock/subtensor_mock.py b/bittensor/utils/mock/subtensor_mock.py index 817be08434..9cc5cb6167 100644 --- a/bittensor/utils/mock/subtensor_mock.py +++ b/bittensor/utils/mock/subtensor_mock.py @@ -544,6 +544,15 @@ def query_map_subtensor( else: return MockMapResult([]) + def query_runtime_api( + self, + runtime_api: str, + method: str, + params: Optional[Union[list[int], dict[str, int]]], + block: Optional[int] = None, + ) -> Optional[str]: + return None + def query_constant( self, module_name: str, constant_name: str, block: Optional[int] = None ) -> Optional[object]: diff --git a/tests/integration_tests/test_metagraph_integration.py b/tests/integration_tests/test_metagraph_integration.py index 34bf4f590e..83b54ce4ce 100644 --- a/tests/integration_tests/test_metagraph_integration.py +++ b/tests/integration_tests/test_metagraph_integration.py @@ -15,11 +15,13 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. -import bittensor -import torch import os -from bittensor.utils.mock import MockSubtensor + +import torch + from bittensor.core.metagraph import METAGRAPH_STATE_DICT_NDARRAY_KEYS, get_save_dir +from bittensor.core.metagraph import Metagraph +from bittensor.utils.mock import MockSubtensor _subtensor_mock: MockSubtensor = MockSubtensor() @@ -33,7 +35,7 @@ def setUpModule(): class TestMetagraph: def setup_method(self): self.sub = MockSubtensor() - self.metagraph = bittensor.Metagraph(netuid=3, network="mock", sync=False) + self.metagraph = Metagraph(netuid=3, network="mock", sync=False) def test_print_empty(self): print(self.metagraph) diff --git a/tests/unit_tests/test_metagraph.py b/tests/unit_tests/test_metagraph.py index e4dca70a1d..b3cf293ddf 100644 --- a/tests/unit_tests/test_metagraph.py +++ b/tests/unit_tests/test_metagraph.py @@ -142,6 +142,7 @@ def metagraph_instance(): metagraph._assign_neurons = MagicMock() metagraph._set_metagraph_attributes = MagicMock() metagraph._set_weights_and_bonds = MagicMock() + metagraph._get_all_stakes_from_chain = MagicMock() return metagraph From d7778a0e36bd06027626ffb1c32d0af396788c36 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 25 Oct 2024 11:19:40 -0700 Subject: [PATCH 02/10] set rao endpoint as default --- bittensor/core/settings.py | 15 +++++++-------- bittensor/core/subtensor.py | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/bittensor/core/settings.py b/bittensor/core/settings.py index b3a3bb4b3a..6422430925 100644 --- a/bittensor/core/settings.py +++ b/bittensor/core/settings.py @@ -63,14 +63,6 @@ def turn_console_on(): # Bittensor networks name NETWORKS = ["local", "finney", "test", "archive"] -DEFAULT_ENDPOINT = "wss://entrypoint-finney.opentensor.ai:443" -DEFAULT_NETWORK = NETWORKS[1] - -# Create dirs if they don't exist -WALLETS_DIR.mkdir(parents=True, exist_ok=True) -MINERS_DIR.mkdir(parents=True, exist_ok=True) - - # Bittensor endpoints (Needs to use wss://) FINNEY_ENTRYPOINT = "wss://entrypoint-finney.opentensor.ai:443" FINNEY_TEST_ENTRYPOINT = "wss://test.finney.opentensor.ai:443/" @@ -78,6 +70,13 @@ def turn_console_on(): RAO_ENDPOINT = "wss://rao.chain.opentensor.ai:443/" LOCAL_ENTRYPOINT = os.getenv("BT_SUBTENSOR_CHAIN_ENDPOINT") or "ws://127.0.0.1:9946" +DEFAULT_ENDPOINT = RAO_ENDPOINT +DEFAULT_NETWORK = NETWORKS[1] + +# Create dirs if they don't exist +WALLETS_DIR.mkdir(parents=True, exist_ok=True) +MINERS_DIR.mkdir(parents=True, exist_ok=True) + # Currency Symbols Bittensor TAO_SYMBOL: str = chr(0x03C4) RAO_SYMBOL: str = chr(0x03C1) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index e6d958b10a..70a1349357 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -357,7 +357,7 @@ def add_args(cls, parser: "argparse.ArgumentParser", prefix: Optional[str] = Non prefix_str = "" if prefix is None else f"{prefix}." try: default_network = settings.DEFAULT_NETWORK - default_chain_endpoint = settings.FINNEY_ENTRYPOINT + default_chain_endpoint = settings.DEFAULT_ENDPOINT parser.add_argument( f"--{prefix_str}subtensor.network", From 99d206a05ab079a3972ef307751cd332da90277e Mon Sep 17 00:00:00 2001 From: Roman <167799377+roman-opentensor@users.noreply.github.com> Date: Fri, 25 Oct 2024 14:47:12 -0700 Subject: [PATCH 03/10] add Global Weight to metagraph + test (#2371) * add Global Weight to metagraph + test * ruff --- bittensor/core/metagraph.py | 17 ++++++++++++++ bittensor/core/settings.py | 4 ++-- bittensor/core/subtensor.py | 23 ++++++++++++++++++- .../test_subtensor_integration.py | 10 ++++---- 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/bittensor/core/metagraph.py b/bittensor/core/metagraph.py index bdab996542..9feb26c966 100644 --- a/bittensor/core/metagraph.py +++ b/bittensor/core/metagraph.py @@ -215,6 +215,7 @@ class MetagraphMixin(ABC): local_stake: Union["torch.nn.Parameter", NDArray] global_stake: Union["torch.nn.Parameter", NDArray] stake_weights: Union["torch.nn.Parameter", NDArray] + global_weight: Union["torch.nn.Parameter", NDArray] axons: list[AxonInfo] @property @@ -251,6 +252,7 @@ def SW(self) -> list[float]: def S(self) -> float: """ Represents the value between 0.0 and 1.0. This gives the users do blacklists in terms of stake values. + Returns: float: The value between 0.0 and 1.0 or None if stake_weights doesn't have zero index value. """ @@ -261,6 +263,16 @@ def S(self) -> float: value = None return value + @property + def GW(self) -> float: + """ + Represents Global Weights of subnet across all subnets. + + Returns: + float: The value of Global Weights. + """ + return self.global_weight + @property def R(self) -> Union[NDArray, "torch.nn.Parameter"]: """ @@ -614,6 +626,9 @@ def sync( if not lite: self._set_weights_and_bonds(subtensor=subtensor) + # Get global weight for netuid + self.global_weight = subtensor.get_global_weight(netuid=self.netuid) + # Fills in the stake associated attributes of a class instance from a chain response. self._get_all_stakes_from_chain(subtensor=subtensor) @@ -1055,6 +1070,7 @@ def __init__( self.local_stake: list[Balance] = [] self.global_stake: list[Balance] = [] self.stake_weights: list[float] = [] + self.global_weight: Optional[float] = None self.axons: list[AxonInfo] = [] if sync: self.sync(block=None, lite=lite) @@ -1237,6 +1253,7 @@ def __init__( self.local_stake: list[Balance] = [] self.global_stake: list[Balance] = [] self.stake_weights: list[float] = [] + self.global_weight: Optional[float] = None self.axons: list[AxonInfo] = [] if sync: self.sync(block=None, lite=lite) diff --git a/bittensor/core/settings.py b/bittensor/core/settings.py index 6422430925..147799ba15 100644 --- a/bittensor/core/settings.py +++ b/bittensor/core/settings.py @@ -61,7 +61,7 @@ def turn_console_on(): MINERS_DIR = USER_BITTENSOR_DIR / "miners" # Bittensor networks name -NETWORKS = ["local", "finney", "test", "archive"] +NETWORKS = ["local", "finney", "test", "archive", "rao"] # Bittensor endpoints (Needs to use wss://) FINNEY_ENTRYPOINT = "wss://entrypoint-finney.opentensor.ai:443" @@ -71,7 +71,7 @@ def turn_console_on(): LOCAL_ENTRYPOINT = os.getenv("BT_SUBTENSOR_CHAIN_ENDPOINT") or "ws://127.0.0.1:9946" DEFAULT_ENDPOINT = RAO_ENDPOINT -DEFAULT_NETWORK = NETWORKS[1] +DEFAULT_NETWORK = NETWORKS[4] # Create dirs if they don't exist WALLETS_DIR.mkdir(parents=True, exist_ok=True) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 70a1349357..89d93ffca2 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -75,7 +75,13 @@ transfer_extrinsic, ) from bittensor.core.metagraph import Metagraph -from bittensor.utils import networking, torch, ss58_to_vec_u8, u16_normalized_float +from bittensor.utils import ( + networking, + torch, + ss58_to_vec_u8, + u16_normalized_float, + u64_normalized_float, +) from bittensor.utils.balance import Balance from bittensor.utils.btlogging import logging from bittensor.utils.registration import legacy_torch_api_compat @@ -2053,6 +2059,21 @@ def make_substrate_call_with_retry(encoded_hotkey_: list[int]): return DelegateInfo.from_vec_u8(result) + def get_global_weight( + self, netuid: int, block: Optional[str] = None + ) -> Optional[float]: + """Returns the subnet Global Weight across all subnets.""" + result = self.substrate.query( + module="SubtensorModule", + storage_function="GlobalWeight", + params=[netuid], + block_hash=None if block is None else self.substrate.get_block_hash(block), + ) + if hasattr(result, "value"): + return u64_normalized_float(result.value) + + return None + # Subnet 27 uses this method _do_serve_prometheus = do_serve_prometheus # Subnet 27 uses this method name diff --git a/tests/integration_tests/test_subtensor_integration.py b/tests/integration_tests/test_subtensor_integration.py index 552e5ab993..1a81d18319 100644 --- a/tests/integration_tests/test_subtensor_integration.py +++ b/tests/integration_tests/test_subtensor_integration.py @@ -77,8 +77,10 @@ def test_network_overrides(self): """Tests that the network overrides the chain_endpoint.""" # Argument importance: chain_endpoint (arg) > network (arg) > config.subtensor.chain_endpoint > config.subtensor.network config0 = bittensor.Subtensor.config() - config0.subtensor.network = "finney" - config0.subtensor.chain_endpoint = "wss://finney.subtensor.io" # Should not match bittensor.core.settings.FINNEY_ENTRYPOINT + config0.subtensor.network = settings.DEFAULT_NETWORK + config0.subtensor.chain_endpoint = ( + settings.RAO_ENDPOINT + ) # Should not match bittensor.core.settings.FINNEY_ENTRYPOINT assert config0.subtensor.chain_endpoint != settings.FINNEY_ENTRYPOINT config1 = bittensor.Subtensor.config() @@ -246,8 +248,8 @@ def test_get_balance(self): def test_defaults_to_finney(self): sub = bittensor.Subtensor() - assert sub.network == "finney" - assert sub.chain_endpoint == settings.FINNEY_ENTRYPOINT + assert sub.network == settings.DEFAULT_NETWORK + assert sub.chain_endpoint == settings.DEFAULT_ENDPOINT def test_registration_multiprocessed_already_registered(self): work_blocks_before_is_registered = random.randint(5, 10) From fd5c7234f437e0dfb1cf520f9d4b54f5708c3acd Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Tue, 29 Oct 2024 21:43:48 +0200 Subject: [PATCH 04/10] Adds the rao branch of bittensor cli to prod requirements for rao games. --- requirements/prod.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements/prod.txt b/requirements/prod.txt index bed65e9d2e..a85380af7d 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -2,7 +2,8 @@ wheel setuptools~=70.0.0 aiohttp~=3.9 backoff -bittensor-cli +# bittensor-cli +git+https://github.com/opentensor/btcli.git@rao # only for rao games. bt-decode colorama~=0.4.6 fastapi~=0.110.1 From ff0100be5bf3aa872a5135bf4be2c9932a15b418 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Fri, 20 Dec 2024 14:02:00 -0800 Subject: [PATCH 05/10] Fixes requirements --- requirements/prod.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/prod.txt b/requirements/prod.txt index a85380af7d..3668e90775 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -3,7 +3,7 @@ setuptools~=70.0.0 aiohttp~=3.9 backoff # bittensor-cli -git+https://github.com/opentensor/btcli.git@rao # only for rao games. +git+https://github.com/opentensor/btcli.git@rao#egg=bittensor-cli bt-decode colorama~=0.4.6 fastapi~=0.110.1 From 892e465720ebc69bf981c164d9cc396e775a87fc Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Thu, 2 Jan 2025 18:46:03 -0800 Subject: [PATCH 06/10] Updates metagraph in rao-sdk --- bittensor/core/chain_data/subnet_state.py | 18 ++- bittensor/core/chain_data/utils.py | 6 +- bittensor/core/metagraph.py | 139 ++++++------------ bittensor/core/subtensor.py | 15 -- .../test_metagraph_integration.py | 7 +- 5 files changed, 65 insertions(+), 120 deletions(-) diff --git a/bittensor/core/chain_data/subnet_state.py b/bittensor/core/chain_data/subnet_state.py index 53cda11b44..b8a58a3aea 100644 --- a/bittensor/core/chain_data/subnet_state.py +++ b/bittensor/core/chain_data/subnet_state.py @@ -33,9 +33,9 @@ class SubnetState: trust: list[float] rank: list[float] block_at_registration: list[int] - local_stake: list[Balance] - global_stake: list[Balance] - stake_weight: list[float] + alpha_stake: list[Balance] + tao_stake: list[Balance] + total_stake: list[Balance] emission_history: list[list[int]] @classmethod @@ -79,12 +79,14 @@ def fix_decoded_values(cls, decoded: dict) -> "SubnetState": trust=[u16_normalized_float(val) for val in decoded["trust"]], rank=[u16_normalized_float(val) for val in decoded["rank"]], block_at_registration=decoded["block_at_registration"], - local_stake=[ - Balance.from_rao(val).set_unit(netuid) for val in decoded["local_stake"] + alpha_stake=[ + Balance.from_rao(val).set_unit(netuid) for val in decoded["alpha_stake"] ], - global_stake=[ - Balance.from_rao(val).set_unit(0) for val in decoded["global_stake"] + tao_stake=[ + Balance.from_rao(val).set_unit(0) for val in decoded["tao_stake"] + ], + total_stake=[ + Balance.from_rao(val).set_unit(netuid) for val in decoded["total_stake"] ], - stake_weight=[u16_normalized_float(val) for val in decoded["stake_weight"]], emission_history=decoded["emission_history"], ) diff --git a/bittensor/core/chain_data/utils.py b/bittensor/core/chain_data/utils.py index dbf17a1c8d..5b58d68ff4 100644 --- a/bittensor/core/chain_data/utils.py +++ b/bittensor/core/chain_data/utils.py @@ -226,9 +226,9 @@ def from_scale_encoding_using_type_string( ["trust", "Vec>"], ["rank", "Vec>"], ["block_at_registration", "Vec>"], - ["local_stake", "Vec>"], - ["global_stake", "Vec>"], - ["stake_weight", "Vec>"], + ["alpha_stake", "Vec>"], + ["tao_stake", "Vec>"], + ["total_stake", "Vec>"], ["emission_history", "Vec>>"], ], }, diff --git a/bittensor/core/metagraph.py b/bittensor/core/metagraph.py index 9feb26c966..cd40308a48 100644 --- a/bittensor/core/metagraph.py +++ b/bittensor/core/metagraph.py @@ -47,8 +47,6 @@ "version", "n", "block", - "stake", - "total_stake", "ranks", "trust", "consensus", @@ -68,8 +66,6 @@ - **version** (`str`): The version identifier of the metagraph state. - **n** (`int`): The total number of nodes in the metagraph. - **block** (`int`): The current block number in the blockchain or ledger. -- **stake** (`ndarray`): An array representing the stake of each node. -- **total_stake** (`float`): The sum of all individual stakes in the metagraph. - **ranks** (`ndarray`): An array of rank scores assigned to each node. - **trust** (`ndarray`): An array of trust scores for the nodes. - **consensus** (`ndarray`): An array indicating consensus levels among nodes. @@ -149,8 +145,6 @@ class MetagraphMixin(ABC): version (NDArray): The version number of the network, integral for tracking network updates. n (NDArray): The total number of neurons in the network, reflecting its size and complexity. block (NDArray): The current block number in the blockchain, crucial for synchronizing with the network's latest state. - stake: Represents the cryptocurrency staked by neurons, impacting their influence and earnings within the network. - total_stake: The cumulative stake across all neurons. ranks: Neuron rankings as per the Yuma Consensus algorithm, influencing their incentive distribution and network authority. trust: Scores indicating the reliability of neurons, mainly miners, within the network's operational context. consensus: Scores reflecting each neuron's alignment with the network's collective decisions. @@ -197,8 +191,6 @@ class MetagraphMixin(ABC): version: Union["torch.nn.Parameter", tuple[NDArray]] n: Union["torch.nn.Parameter", NDArray] block: Union["torch.nn.Parameter", NDArray] - stake: Union["torch.nn.Parameter", NDArray] - total_stake: Union["torch.nn.Parameter", NDArray] ranks: Union["torch.nn.Parameter", NDArray] trust: Union["torch.nn.Parameter", NDArray] consensus: Union["torch.nn.Parameter", NDArray] @@ -212,66 +204,40 @@ class MetagraphMixin(ABC): weights: Union["torch.nn.Parameter", NDArray] bonds: Union["torch.nn.Parameter", NDArray] uids: Union["torch.nn.Parameter", NDArray] - local_stake: Union["torch.nn.Parameter", NDArray] - global_stake: Union["torch.nn.Parameter", NDArray] - stake_weights: Union["torch.nn.Parameter", NDArray] - global_weight: Union["torch.nn.Parameter", NDArray] + alpha_stake: Union["torch.nn.Parameter", NDArray] + tao_stake: Union["torch.nn.Parameter", NDArray] + total_stake: Union["torch.nn.Parameter", NDArray] axons: list[AxonInfo] @property - def GS(self) -> list[Balance]: - """ - Represents the global stake of each neuron in the Bittensor network. - - Returns: - List[Balance]: The list of global stake of each neuron in the network. - """ - return self.global_stake - - @property - def LS(self) -> list[Balance]: + def Ts(self) -> list[Balance]: """ - Represents the local stake of each neuron in the Bittensor network. + Represents the tao stake of each neuron in the Bittensor network. Returns: - List[Balance]: The list of local stake of each neuron in the network. + List[Balance]: The list of tao stake of each neuron in the network. """ - return self.local_stake + return self.tao_stake @property - def SW(self) -> list[float]: + def AS(self) -> list[Balance]: """ - Represents the stake weights of each neuron in the Bittensor network. + Represents the alpha stake of each neuron in the Bittensor network. Returns: - List[float]: Each value is calculated based on local_stake and global_stake. + List[Balance]: The list of alpha stake of each neuron in the network. """ - return self.stake_weights + return self.alpha_stake @property - def S(self) -> float: + def S(self) -> list[float]: """ - Represents the value between 0.0 and 1.0. This gives the users do blacklists in terms of stake values. + Represents the total stake of each neuron in the Bittensor network. Returns: - float: The value between 0.0 and 1.0 or None if stake_weights doesn't have zero index value. + List[Balance]: The list of total stake of each neuron in the network. """ - try: - value = self.stake_weights[0] * max(self.global_stake).tao - except IndexError: - logging.warning("Stake weights is empty.") - value = None - return value - - @property - def GW(self) -> float: - """ - Represents Global Weights of subnet across all subnets. - - Returns: - float: The value of Global Weights. - """ - return self.global_weight + return self.total_stake @property def R(self) -> Union[NDArray, "torch.nn.Parameter"]: @@ -540,8 +506,6 @@ def state_dict(self): "version": self.version, "n": self.n, "block": self.block, - "stake": self.stake, - "total_stake": self.total_stake, "ranks": self.ranks, "trust": self.trust, "consensus": self.consensus, @@ -557,6 +521,9 @@ def state_dict(self): "uids": self.uids, "axons": self.axons, "neurons": self.neurons, + "alpha_stake": self.alpha_stake, + "tao_stake": self.tao_stake, + "total_stake": self.total_stake, } def sync( @@ -626,9 +593,6 @@ def sync( if not lite: self._set_weights_and_bonds(subtensor=subtensor) - # Get global weight for netuid - self.global_weight = subtensor.get_global_weight(netuid=self.netuid) - # Fills in the stake associated attributes of a class instance from a chain response. self._get_all_stakes_from_chain(subtensor=subtensor) @@ -823,12 +787,13 @@ def _get_all_stakes_from_chain(self, subtensor: "Subtensor"): bytes_result = bytes.fromhex(hex_bytes_result) subnet_state: "SubnetState" = SubnetState.from_vec_u8(bytes_result) - self.global_stake = subnet_state.global_stake - self.local_stake = subnet_state.local_stake - self.stake_weights = subnet_state.stake_weight + self.alpha_stake = subnet_state.alpha_stake + self.tao_stake = subnet_state.tao_stake + self.total_stake = subnet_state.total_stake + except (SubstrateRequestException, AttributeError): logging.debug( - "Fields `global_stake`, `local_stake`, `stake_weights` can be obtained only from the RAO network." + "Fields `alpha_stake`, `tao_stake`, `total_stake` can be obtained only from the RAO network." ) def _process_root_weights( @@ -1022,12 +987,6 @@ def __init__( self.block: torch.nn.Parameter = torch.nn.Parameter( torch.tensor([0], dtype=torch.int64), requires_grad=False ) - self.stake = torch.nn.Parameter( - torch.tensor([], dtype=torch.float32), requires_grad=False - ) - self.total_stake: torch.nn.Parameter = torch.nn.Parameter( - torch.tensor([], dtype=torch.float32), requires_grad=False - ) self.ranks: torch.nn.Parameter = torch.nn.Parameter( torch.tensor([], dtype=torch.float32), requires_grad=False ) @@ -1067,10 +1026,9 @@ def __init__( self.uids = torch.nn.Parameter( torch.tensor([], dtype=torch.int64), requires_grad=False ) - self.local_stake: list[Balance] = [] - self.global_stake: list[Balance] = [] - self.stake_weights: list[float] = [] - self.global_weight: Optional[float] = None + self.alpha_stake: list[Balance] = [] + self.tao_stake: list[Balance] = [] + self.total_stake: list[Balance] = [] self.axons: list[AxonInfo] = [] if sync: self.sync(block=None, lite=lite) @@ -1133,12 +1091,6 @@ def _set_metagraph_attributes(self, block: int, subtensor: "Subtensor"): self.validator_trust = self._create_tensor( [neuron.validator_trust for neuron in self.neurons], dtype=torch.float32 ) - self.total_stake = self._create_tensor( - [neuron.total_stake.tao for neuron in self.neurons], dtype=torch.float32 - ) - self.stake = self._create_tensor( - [neuron.stake for neuron in self.neurons], dtype=torch.float32 - ) self.axons = [n.axon_info for n in self.neurons] def load_from_path(self, dir_path: str) -> "Metagraph": @@ -1167,10 +1119,6 @@ def load_from_path(self, dir_path: str) -> "Metagraph": self.n = torch.nn.Parameter(state_dict["n"], requires_grad=False) self.block = torch.nn.Parameter(state_dict["block"], requires_grad=False) self.uids = torch.nn.Parameter(state_dict["uids"], requires_grad=False) - self.stake = torch.nn.Parameter(state_dict["stake"], requires_grad=False) - self.total_stake = torch.nn.Parameter( - state_dict["total_stake"], requires_grad=False - ) self.ranks = torch.nn.Parameter(state_dict["ranks"], requires_grad=False) self.trust = torch.nn.Parameter(state_dict["trust"], requires_grad=False) self.consensus = torch.nn.Parameter( @@ -1202,6 +1150,18 @@ def load_from_path(self, dir_path: str) -> "Metagraph": ) if "bonds" in state_dict: self.bonds = torch.nn.Parameter(state_dict["bonds"], requires_grad=False) + if "alpha_stake" in state_dict: + self.alpha_stake = torch.nn.Parameter( + state_dict["alpha_stake"], requires_grad=False + ) + if "tao_stake" in state_dict: + self.tao_stake = torch.nn.Parameter( + state_dict["tao_stake"], requires_grad=False + ) + if "total_stake" in state_dict: + self.total_stake = torch.nn.Parameter( + state_dict["total_stake"], requires_grad=False + ) return self @@ -1235,8 +1195,6 @@ def __init__( self.version = (np.array([settings.version_as_int], dtype=np.int64),) self.n = np.array([0], dtype=np.int64) self.block = np.array([0], dtype=np.int64) - self.stake = np.array([], dtype=np.float32) - self.total_stake = np.array([], dtype=np.float32) self.ranks = np.array([], dtype=np.float32) self.trust = np.array([], dtype=np.float32) self.consensus = np.array([], dtype=np.float32) @@ -1250,10 +1208,9 @@ def __init__( self.weights = np.array([], dtype=np.float32) self.bonds = np.array([], dtype=np.int64) self.uids = np.array([], dtype=np.int64) - self.local_stake: list[Balance] = [] - self.global_stake: list[Balance] = [] - self.stake_weights: list[float] = [] - self.global_weight: Optional[float] = None + self.alpha_stake: list[Balance] = [] + self.tao_stake: list[Balance] = [] + self.total_stake: list[Balance] = [] self.axons: list[AxonInfo] = [] if sync: self.sync(block=None, lite=lite) @@ -1312,12 +1269,6 @@ def _set_metagraph_attributes(self, block: int, subtensor: "Subtensor"): self.validator_trust = self._create_tensor( [neuron.validator_trust for neuron in self.neurons], dtype=np.float32 ) - self.total_stake = self._create_tensor( - [neuron.total_stake.tao for neuron in self.neurons], dtype=np.float32 - ) - self.stake = self._create_tensor( - [neuron.stake for neuron in self.neurons], dtype=np.float32 - ) self.axons = [n.axon_info for n in self.neurons] def load_from_path(self, dir_path: str) -> "Metagraph": @@ -1361,8 +1312,6 @@ def load_from_path(self, dir_path: str) -> "Metagraph": self.n = state_dict["n"] self.block = state_dict["block"] self.uids = state_dict["uids"] - self.stake = state_dict["stake"] - self.total_stake = state_dict["total_stake"] self.ranks = state_dict["ranks"] self.trust = state_dict["trust"] self.consensus = state_dict["consensus"] @@ -1379,6 +1328,12 @@ def load_from_path(self, dir_path: str) -> "Metagraph": self.weights = state_dict["weights"] if "bonds" in state_dict: self.bonds = state_dict["bonds"] + if "alpha_stake" in state_dict: + self.alpha_stake = state_dict["alpha_stake"] + if "tao_stake" in state_dict: + self.tao_stake = state_dict["tao_stake"] + if "total_stake" in state_dict: + self.total_stake = state_dict["total_stake"] return self diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 89d93ffca2..ee98870fce 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -2059,21 +2059,6 @@ def make_substrate_call_with_retry(encoded_hotkey_: list[int]): return DelegateInfo.from_vec_u8(result) - def get_global_weight( - self, netuid: int, block: Optional[str] = None - ) -> Optional[float]: - """Returns the subnet Global Weight across all subnets.""" - result = self.substrate.query( - module="SubtensorModule", - storage_function="GlobalWeight", - params=[netuid], - block_hash=None if block is None else self.substrate.get_block_hash(block), - ) - if hasattr(result, "value"): - return u64_normalized_float(result.value) - - return None - # Subnet 27 uses this method _do_serve_prometheus = do_serve_prometheus # Subnet 27 uses this method name diff --git a/tests/integration_tests/test_metagraph_integration.py b/tests/integration_tests/test_metagraph_integration.py index 83b54ce4ce..0f2eac0d30 100644 --- a/tests/integration_tests/test_metagraph_integration.py +++ b/tests/integration_tests/test_metagraph_integration.py @@ -78,8 +78,9 @@ def test_state_dict(self): assert "version" in state assert "n" in state assert "block" in state - assert "stake" in state assert "total_stake" in state + assert "alpha_stake" in state + assert "tao_stake" in state assert "ranks" in state assert "trust" in state assert "consensus" in state @@ -100,7 +101,6 @@ def test_properties(self): metagraph.coldkeys metagraph.addresses metagraph.validator_trust - metagraph.S metagraph.R metagraph.I metagraph.E @@ -110,3 +110,6 @@ def test_properties(self): metagraph.D metagraph.B metagraph.W + metagraph.Ts + metagraph.AS + metagraph.S From 9834d3fbbd64d0fc1636965ca11538a0d29eb17d Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Thu, 2 Jan 2025 18:58:11 -0800 Subject: [PATCH 07/10] Removes unused import --- bittensor/core/subtensor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index ee98870fce..9613668edb 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -80,7 +80,6 @@ torch, ss58_to_vec_u8, u16_normalized_float, - u64_normalized_float, ) from bittensor.utils.balance import Balance from bittensor.utils.btlogging import logging From 5143e7f67869f526b1e1805994ece3a5be171aff Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Thu, 2 Jan 2025 19:07:11 -0800 Subject: [PATCH 08/10] Improves types --- bittensor/core/metagraph.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/bittensor/core/metagraph.py b/bittensor/core/metagraph.py index cd40308a48..315c4e1dd7 100644 --- a/bittensor/core/metagraph.py +++ b/bittensor/core/metagraph.py @@ -207,7 +207,7 @@ class MetagraphMixin(ABC): alpha_stake: Union["torch.nn.Parameter", NDArray] tao_stake: Union["torch.nn.Parameter", NDArray] total_stake: Union["torch.nn.Parameter", NDArray] - axons: list[AxonInfo] + axons: list["AxonInfo"] @property def Ts(self) -> list[Balance]: @@ -1026,10 +1026,10 @@ def __init__( self.uids = torch.nn.Parameter( torch.tensor([], dtype=torch.int64), requires_grad=False ) - self.alpha_stake: list[Balance] = [] - self.tao_stake: list[Balance] = [] - self.total_stake: list[Balance] = [] - self.axons: list[AxonInfo] = [] + self.alpha_stake: list["Balance"] = [] + self.tao_stake: list["Balance"] = [] + self.total_stake: list["Balance"] = [] + self.axons: list["AxonInfo"] = [] if sync: self.sync(block=None, lite=lite) @@ -1208,10 +1208,10 @@ def __init__( self.weights = np.array([], dtype=np.float32) self.bonds = np.array([], dtype=np.int64) self.uids = np.array([], dtype=np.int64) - self.alpha_stake: list[Balance] = [] - self.tao_stake: list[Balance] = [] - self.total_stake: list[Balance] = [] - self.axons: list[AxonInfo] = [] + self.alpha_stake: list["Balance"] = [] + self.tao_stake: list["Balance"] = [] + self.total_stake: list["Balance"] = [] + self.axons: list["AxonInfo"] = [] if sync: self.sync(block=None, lite=lite) From 6a2cb1595ba7f18ef10c287b6e102de5c8e44440 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Thu, 2 Jan 2025 19:21:30 -0800 Subject: [PATCH 09/10] Updates type annotations --- bittensor/core/chain_data/subnet_state.py | 8 ++-- bittensor/core/metagraph.py | 58 +++++++++++------------ 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/bittensor/core/chain_data/subnet_state.py b/bittensor/core/chain_data/subnet_state.py index b8a58a3aea..ff1e3e6abf 100644 --- a/bittensor/core/chain_data/subnet_state.py +++ b/bittensor/core/chain_data/subnet_state.py @@ -26,16 +26,16 @@ class SubnetState: validator_permit: list[bool] pruning_score: list[float] last_update: list[int] - emission: list[Balance] + emission: list["Balance"] dividends: list[float] incentives: list[float] consensus: list[float] trust: list[float] rank: list[float] block_at_registration: list[int] - alpha_stake: list[Balance] - tao_stake: list[Balance] - total_stake: list[Balance] + alpha_stake: list["Balance"] + tao_stake: list["Balance"] + total_stake: list["Balance"] emission_history: list[list[int]] @classmethod diff --git a/bittensor/core/metagraph.py b/bittensor/core/metagraph.py index 315c4e1dd7..2395dd2b8d 100644 --- a/bittensor/core/metagraph.py +++ b/bittensor/core/metagraph.py @@ -28,8 +28,7 @@ from substrateinterface.exceptions import SubstrateRequestException from bittensor.core import settings -from bittensor.core.chain_data import AxonInfo, SubnetState -from bittensor.utils.balance import Balance +from bittensor.core.chain_data import SubnetState from bittensor.utils.btlogging import logging from bittensor.utils.registration import torch, use_torch from bittensor.utils.weight_utils import ( @@ -41,7 +40,8 @@ # For annotation purposes if typing.TYPE_CHECKING: from bittensor.core.subtensor import Subtensor - + from bittensor.utils.balance import Balance + from bittensor.core.chain_data import AxonInfo METAGRAPH_STATE_DICT_NDARRAY_KEYS = [ "version", @@ -188,54 +188,54 @@ class MetagraphMixin(ABC): netuid: int network: str - version: Union["torch.nn.Parameter", tuple[NDArray]] - n: Union["torch.nn.Parameter", NDArray] - block: Union["torch.nn.Parameter", NDArray] - ranks: Union["torch.nn.Parameter", NDArray] - trust: Union["torch.nn.Parameter", NDArray] - consensus: Union["torch.nn.Parameter", NDArray] - validator_trust: Union["torch.nn.Parameter", NDArray] - incentive: Union["torch.nn.Parameter", NDArray] - emission: Union["torch.nn.Parameter", NDArray] - dividends: Union["torch.nn.Parameter", NDArray] - active: Union["torch.nn.Parameter", NDArray] - last_update: Union["torch.nn.Parameter", NDArray] - validator_permit: Union["torch.nn.Parameter", NDArray] - weights: Union["torch.nn.Parameter", NDArray] - bonds: Union["torch.nn.Parameter", NDArray] - uids: Union["torch.nn.Parameter", NDArray] - alpha_stake: Union["torch.nn.Parameter", NDArray] - tao_stake: Union["torch.nn.Parameter", NDArray] - total_stake: Union["torch.nn.Parameter", NDArray] + version: Union["torch.nn.Parameter", tuple["NDArray"]] + n: Union["torch.nn.Parameter", "NDArray"] + block: Union["torch.nn.Parameter", "NDArray"] + ranks: Union["torch.nn.Parameter", "NDArray"] + trust: Union["torch.nn.Parameter", "NDArray"] + consensus: Union["torch.nn.Parameter", "NDArray"] + validator_trust: Union["torch.nn.Parameter", "NDArray"] + incentive: Union["torch.nn.Parameter", "NDArray"] + emission: Union["torch.nn.Parameter", "NDArray"] + dividends: Union["torch.nn.Parameter", "NDArray"] + active: Union["torch.nn.Parameter", "NDArray"] + last_update: Union["torch.nn.Parameter", "NDArray"] + validator_permit: Union["torch.nn.Parameter", "NDArray"] + weights: Union["torch.nn.Parameter", "NDArray"] + bonds: Union["torch.nn.Parameter", "NDArray"] + uids: Union["torch.nn.Parameter", "NDArray"] + alpha_stake: Union["torch.nn.Parameter", "NDArray"] + tao_stake: Union["torch.nn.Parameter", "NDArray"] + total_stake: Union["torch.nn.Parameter", "NDArray"] axons: list["AxonInfo"] @property - def Ts(self) -> list[Balance]: + def Ts(self) -> list["Balance"]: """ Represents the tao stake of each neuron in the Bittensor network. Returns: - List[Balance]: The list of tao stake of each neuron in the network. + list["Balance"]: The list of tao stake of each neuron in the network. """ return self.tao_stake @property - def AS(self) -> list[Balance]: + def AS(self) -> list["Balance"]: """ Represents the alpha stake of each neuron in the Bittensor network. Returns: - List[Balance]: The list of alpha stake of each neuron in the network. + list["Balance"]: The list of alpha stake of each neuron in the network. """ return self.alpha_stake @property - def S(self) -> list[float]: + def S(self) -> list["Balance"]: """ Represents the total stake of each neuron in the Bittensor network. Returns: - List[Balance]: The list of total stake of each neuron in the network. + list["Balance"]: The list of total stake of each neuron in the network. """ return self.total_stake @@ -743,7 +743,7 @@ def _process_weights_or_bonds( len(self.neurons), list(uids), list(values) ).astype(np.float32) ) - tensor_param: Union["torch.nn.Parameter", NDArray] = ( + tensor_param: Union["torch.nn.Parameter", "NDArray"] = ( ( torch.nn.Parameter(torch.stack(data_array), requires_grad=False) if len(data_array) From 76515bc0cf719dea7b06d94c78b530c2afb8957a Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Thu, 2 Jan 2025 19:23:49 -0800 Subject: [PATCH 10/10] cleanup --- bittensor/core/metagraph.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bittensor/core/metagraph.py b/bittensor/core/metagraph.py index 2395dd2b8d..0ff4ecf1bd 100644 --- a/bittensor/core/metagraph.py +++ b/bittensor/core/metagraph.py @@ -28,7 +28,8 @@ from substrateinterface.exceptions import SubstrateRequestException from bittensor.core import settings -from bittensor.core.chain_data import SubnetState +from bittensor.core.chain_data import AxonInfo, SubnetState +from bittensor.utils.balance import Balance from bittensor.utils.btlogging import logging from bittensor.utils.registration import torch, use_torch from bittensor.utils.weight_utils import ( @@ -40,8 +41,6 @@ # For annotation purposes if typing.TYPE_CHECKING: from bittensor.core.subtensor import Subtensor - from bittensor.utils.balance import Balance - from bittensor.core.chain_data import AxonInfo METAGRAPH_STATE_DICT_NDARRAY_KEYS = [ "version",