Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/9.0.0rc4 #2648

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 9.0.0rc4 /2025-02-07
* Fix for extra fields from chain data by @roman-opentensor in https://github.com/opentensor/bittensor/pull/2647
* Adds get_all_commitments and fixes commitment tests and query_map @thewhaleking in https://github.com/opentensor/bittensor/pull/2644

**Full Changelog**: https://github.com/opentensor/bittensor/compare/v9.0.0rc2...v9.0.0rc3

## 9.0.0rc3 /2025-02-06

## What's Changed
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9.0.0rc3
9.0.0rc4
54 changes: 47 additions & 7 deletions bittensor/core/async_subtensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
decode_account_id,
DynamicInfo,
)
from bittensor.core.chain_data.utils import decode_metadata
from bittensor.core.config import Config
from bittensor.core.errors import SubstrateRequestException
from bittensor.core.extrinsics.asyncex.commit_reveal import commit_reveal_v3_extrinsic
Expand Down Expand Up @@ -342,7 +343,7 @@ async def query_map(
block_hash=block_hash,
reuse_block_hash=reuse_block,
)
return getattr(result, "value", None)
return result

async def query_map_subtensor(
self,
Expand Down Expand Up @@ -927,7 +928,12 @@ async def get_children(
return False, [], format_error_message(e)

async def get_commitment(
self, netuid: int, uid: int, block: Optional[int] = None
self,
netuid: int,
uid: int,
block: Optional[int] = None,
block_hash: Optional[str] = None,
reuse_block: bool = False,
) -> str:
"""
Retrieves the on-chain commitment for a specific neuron in the Bittensor network.
Expand All @@ -937,6 +943,8 @@ async def get_commitment(
uid (int): The unique identifier of the neuron.
block (Optional[int]): The block number to retrieve the commitment from. If None, the latest block is used.
Default is ``None``.
block_hash (Optional[str]): The hash of the block to retrieve the subnet unique identifiers from.
reuse_block (bool): Whether to reuse the last-used block hash.

Returns:
str: The commitment data as a string.
Expand All @@ -950,15 +958,47 @@ async def get_commitment(
)
return ""

metadata = await get_metadata(self, netuid, hotkey, block)
metadata = await get_metadata(
self, netuid, hotkey, block, block_hash, reuse_block
)
try:
commitment = metadata["info"]["fields"][0] # type: ignore
hex_data = commitment[list(commitment.keys())[0]][2:] # type: ignore
return bytes.fromhex(hex_data).decode()

return decode_metadata(metadata)
except TypeError:
return ""

async def get_all_commitments(
self,
netuid: int,
block: Optional[int] = None,
block_hash: Optional[str] = None,
reuse_block: bool = False,
) -> dict[str, str]:
"""
Retrieves the on-chain commitments for a specific subnet in the Bittensor network.

Arguments:
netuid (int): The unique identifier of the subnetwork.
block (Optional[int]): The block number to retrieve the commitment from. If None, the latest block is used.
Default is ``None``.
block_hash (Optional[str]): The hash of the block to retrieve the subnet unique identifiers from.
reuse_block (bool): Whether to reuse the last-used block hash.

Returns:
dict[str, str]: A mapping of the ss58:commitment with the commitment as a string
"""
query = await self.query_map(
module="Commitments",
name="CommitmentOf",
params=[netuid],
block=block,
block_hash=block_hash,
reuse_block=reuse_block,
)
result = {}
async for id_, value in query:
result[decode_account_id(id_[0])] = decode_account_id(value)
return result

async def get_current_weight_commit_info(
self,
netuid: int,
Expand Down
10 changes: 8 additions & 2 deletions bittensor/core/chain_data/info_base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from dataclasses import dataclass
from dataclasses import dataclass, fields
from typing import Any, TypeVar

from bittensor.core.errors import SubstrateRequestException
Expand All @@ -13,7 +13,13 @@ class InfoBase:
@classmethod
def from_dict(cls, decoded: dict) -> T:
try:
return cls._from_dict(decoded)
class_fields = {f.name for f in fields(cls)}
extra_keys = decoded.keys() - class_fields
instance = cls._from_dict(
{k: v for k, v in decoded.items() if k in class_fields}
)
[setattr(instance, k, decoded[k]) for k in extra_keys]
return instance
except KeyError as e:
raise SubstrateRequestException(
f"The {cls} structure is missing {e} from the chain.",
Expand Down
7 changes: 6 additions & 1 deletion bittensor/core/chain_data/metagraph_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from bittensor.core.chain_data.subnet_identity import SubnetIdentity
from bittensor.core.chain_data.utils import decode_account_id
from bittensor.utils import u64_normalized_float as u64tf, u16_normalized_float as u16tf
from bittensor.utils.balance import Balance
from bittensor.utils.balance import Balance, fixed_to_float


# to balance with unit (just shortcut)
Expand Down Expand Up @@ -68,6 +68,7 @@ class MetagraphInfo(InfoBase):
pending_alpha_emission: Balance # pending alpha to be distributed
pending_root_emission: Balance # pending tao for root divs to be distributed
subnet_volume: Balance # volume of the subnet in TAO
moving_price: Balance # subnet moving price.

# Hparams for epoch
rho: int # subnet rho param
Expand Down Expand Up @@ -168,6 +169,9 @@ def _from_dict(cls, decoded: dict) -> "MetagraphInfo":
)
decoded["pending_root_emission"] = _tbwu(decoded["pending_root_emission"])
decoded["subnet_volume"] = _tbwu(decoded["subnet_volume"], _netuid)
decoded["moving_price"] = Balance.from_tao(
fixed_to_float(decoded.get("moving_price"), 32)
)

# Hparams for epoch
decoded["kappa"] = u16tf(decoded["kappa"])
Expand Down Expand Up @@ -243,6 +247,7 @@ class MetagraphInfoPool:
alpha_in: float
tao_in: float
subnet_volume: float
moving_price: float


@dataclass
Expand Down
6 changes: 6 additions & 0 deletions bittensor/core/chain_data/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,9 @@ def process_stake_data(stake_data: list) -> dict:
account_id = decode_account_id(account_id_bytes)
decoded_stake_data.update({account_id: Balance.from_rao(stake_)})
return decoded_stake_data


def decode_metadata(metadata: dict) -> str:
commitment = metadata["info"]["fields"][0][0]
bytes_tuple = commitment[next(iter(commitment.keys()))][0]
return bytes(bytes_tuple).decode()
2 changes: 1 addition & 1 deletion bittensor/core/extrinsics/asyncex/serving.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,4 +306,4 @@ async def get_metadata(
block_hash=block_hash,
reuse_block_hash=reuse_block,
)
return getattr(commit_data, "value", None)
return commit_data
4 changes: 2 additions & 2 deletions bittensor/core/extrinsics/serving.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,12 @@ def publish_metadata(

def get_metadata(
subtensor: "Subtensor", netuid: int, hotkey: str, block: Optional[int] = None
) -> str:
) -> bytes:
"""Fetches metadata from the blockchain for a given hotkey and netuid."""
commit_data = subtensor.substrate.query(
module="Commitments",
storage_function="CommitmentOf",
params=[netuid, hotkey],
block_hash=subtensor.determine_block_hash(block),
)
return getattr(commit_data, "value", None)
return commit_data
1 change: 1 addition & 0 deletions bittensor/core/metagraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,7 @@ def _apply_metagraph_info_mixin(self, metagraph_info: "MetagraphInfo"):
alpha_in=metagraph_info.alpha_in.tao,
tao_in=metagraph_info.tao_in.tao,
subnet_volume=metagraph_info.subnet_volume.tao,
moving_price=metagraph_info.moving_price.tao,
)
self.emissions = MetagraphInfoEmissions(
alpha_out_emission=metagraph_info.alpha_out_emission.tao,
Expand Down
2 changes: 1 addition & 1 deletion bittensor/core/settings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "9.0.0rc3"
__version__ = "9.0.0rc4"

import os
import re
Expand Down
23 changes: 18 additions & 5 deletions bittensor/core/subtensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
SubnetInfo,
decode_account_id,
)
from bittensor.core.chain_data.utils import decode_metadata
from bittensor.core.config import Config
from bittensor.core.extrinsics.commit_reveal import commit_reveal_v3_extrinsic
from bittensor.core.extrinsics.commit_weights import (
Expand Down Expand Up @@ -210,7 +211,7 @@ def query_map(
params=params,
block_hash=self.determine_block_hash(block=block),
)
return getattr(result, "value", None)
return result

def query_map_subtensor(
self, name: str, block: Optional[int] = None, params: Optional[list] = None
Expand Down Expand Up @@ -731,15 +732,27 @@ def get_commitment(self, netuid: int, uid: int, block: Optional[int] = None) ->
)
return ""

metadata = get_metadata(self, netuid, hotkey, block)
metadata = cast(dict, get_metadata(self, netuid, hotkey, block))
try:
commitment = metadata["info"]["fields"][0] # type: ignore
hex_data = commitment[list(commitment.keys())[0]][2:] # type: ignore
return bytes.fromhex(hex_data).decode()
return decode_metadata(metadata)

except TypeError:
return ""

def get_all_commitments(
self, netuid: int, block: Optional[int] = None
) -> dict[str, str]:
query = self.query_map(
module="Commitments",
name="CommitmentOf",
params=[netuid],
block=block,
)
result = {}
for id_, value in query:
result[decode_account_id(id_[0])] = decode_account_id(value)
return result

def get_current_weight_commit_info(
self, netuid: int, block: Optional[int] = None
) -> list:
Expand Down
12 changes: 7 additions & 5 deletions bittensor/utils/balance.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,16 +285,18 @@ class FixedPoint(TypedDict):
bits: int


def fixed_to_float(fixed: Union[FixedPoint, ScaleType]) -> float:
# Currently this is stored as a U64F64
def fixed_to_float(
fixed: Union[FixedPoint, ScaleType], frac_bits: int = 64, total_bits: int = 128
) -> float:
# By default, this is a U64F64
# which is 64 bits of integer and 64 bits of fractional
frac_bits = 64

data: int = fixed["bits"]

# Shift bits to extract integer part (assuming 64 bits for integer part)
integer_part = data >> frac_bits
# Logical and to get the fractional part; remaining is the integer part
fractional_part = data & (2**frac_bits - 1)
# Shift to get the integer part from the remaining bits
integer_part = data >> (total_bits - frac_bits)

frac_float = fractional_part / (2**frac_bits)

Expand Down
8 changes: 4 additions & 4 deletions tests/integration_tests/test_subtensor_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from bittensor.core.chain_data.axon_info import AxonInfo
from bittensor.core.subtensor import Subtensor
from bittensor.utils.balance import Balance
from tests.helpers.helpers import FakeConnectContextManager
from tests.helpers.helpers import FakeWebsocket


@pytest.fixture
Expand All @@ -29,12 +29,12 @@ async def prepare_test(mocker, seed):
) as f:
metadata_v15 = MetadataV15.decode_from_metadata_option(f.read())
registry = PortableRegistry.from_metadata_v15(metadata_v15)
subtensor = Subtensor("unknown", _mock=True)
subtensor.substrate.metadata_v15 = metadata_v15
mocker.patch(
"async_substrate_interface.sync_substrate.connect",
mocker.Mock(return_value=FakeConnectContextManager(seed=seed)),
mocker.Mock(return_value=FakeWebsocket(seed=seed)),
)
subtensor = Subtensor("unknown", _mock=True)
subtensor.substrate.metadata_v15 = metadata_v15
mocker.patch.object(subtensor.substrate, "registry", registry)
return subtensor

Expand Down
Loading
Loading