Source code for bittensor.core.chain_data.utils

"""Chain data helper functions and data."""

from enum import Enum
from typing import Optional, Union

from scalecodec.base import RuntimeConfiguration, ScaleBytes
from scalecodec.type_registry import load_type_registry_preset
from scalecodec.utils.ss58 import ss58_encode

from bittensor.core.settings import SS58_FORMAT
from bittensor.utils.balance import Balance


[docs] class ChainDataType(Enum): NeuronInfo = 1 SubnetInfo = 2 DelegateInfo = 3 NeuronInfoLite = 4 DelegatedInfo = 5 StakeInfo = 6 IPInfo = 7 SubnetHyperparameters = 8 ScheduledColdkeySwapInfo = 9 AccountId = 10 SubnetState = 11 DynamicInfo = 12 SubnetIdentity = 13 MetagraphInfo = 14 ChainIdentity = 15 AxonInfo = 16
[docs] def from_scale_encoding( input_: Union[list[int], bytes, "ScaleBytes"], type_name: "ChainDataType", is_vec: bool = False, is_option: bool = False, ) -> Optional[dict]: """ Decodes input_ data from SCALE encoding based on the specified type name and modifiers. Args: input_ (Union[List[int], bytes, ScaleBytes]): The input_ data to decode. type_name (ChainDataType): The type of data being decoded. is_vec (bool): Whether the data is a vector of the specified type. Default is ``False``. is_option (bool): Whether the data is an optional value of the specified type. Default is ``False``. Returns: Optional[dict]: The decoded data as a dictionary, or ``None`` if the decoding fails. """ type_string = type_name.name if type_name == ChainDataType.DelegatedInfo: # DelegatedInfo is a tuple of (DelegateInfo, Compact<u64>) type_string = f"({ChainDataType.DelegateInfo.name}, Compact<u64>)" if is_option: type_string = f"Option<{type_string}>" if is_vec: type_string = f"Vec<{type_string}>" return from_scale_encoding_using_type_string(input_, type_string)
[docs] def from_scale_encoding_using_type_string( input_: Union[list[int], bytes, ScaleBytes], type_string: str ) -> Optional[dict]: """ Decodes SCALE encoded data to a dictionary based on the provided type string. Args: input_ (Union[List[int], bytes, ScaleBytes]): The SCALE encoded input data. type_string (str): The type string defining the structure of the data. Returns: Optional[dict]: The decoded data as a dictionary, or ``None`` if the decoding fails. Raises: TypeError: If the input_ is not a list[int], bytes, or ScaleBytes. """ if isinstance(input_, ScaleBytes): as_scale_bytes = input_ else: if isinstance(input_, list) and all([isinstance(i, int) for i in input_]): vec_u8 = input_ as_bytes = bytes(vec_u8) elif isinstance(input_, bytes): as_bytes = input_ else: raise TypeError("input_ must be a list[int], bytes, or ScaleBytes") as_scale_bytes = ScaleBytes(as_bytes) rpc_runtime_config = RuntimeConfiguration() rpc_runtime_config.update_type_registry(load_type_registry_preset("legacy")) obj = rpc_runtime_config.create_scale_object(type_string, data=as_scale_bytes) return obj.decode()
[docs] def decode_account_id(account_id_bytes: Union[bytes, str]) -> str: """ Decodes an AccountId from bytes to a Base64 string using SS58 encoding. Args: account_id_bytes (bytes): The AccountId in bytes that needs to be decoded. Returns: str: The decoded AccountId as a Base64 string. """ if isinstance(account_id_bytes, tuple) and isinstance(account_id_bytes[0], tuple): account_id_bytes = account_id_bytes[0] # Convert the AccountId bytes to a Base64 string return ss58_encode(bytes(account_id_bytes).hex(), SS58_FORMAT)
[docs] def process_stake_data(stake_data: list) -> dict: """ Processes stake data to decode account IDs and convert stakes from rao to Balance objects. Args: stake_data (list): A list of tuples where each tuple contains an account ID in bytes and a stake in rao. Returns: dict: A dictionary with account IDs as keys and their corresponding Balance objects as values. """ decoded_stake_data = {} for account_id_bytes, stake_ in stake_data: account_id = decode_account_id(account_id_bytes) decoded_stake_data.update({account_id: Balance.from_rao(stake_)}) return decoded_stake_data
[docs] 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()