Source code for bittensor.core.extrinsics.asyncex.commit_reveal

"""This module provides async functionality for commit reveal in the Bittensor network."""

from typing import Optional, Union, TYPE_CHECKING

import numpy as np
from bittensor_commit_reveal import get_encrypted_commit
from numpy.typing import NDArray

from bittensor.core.settings import version_as_int
from bittensor.utils.btlogging import logging
from bittensor.utils.weight_utils import convert_weights_and_uids_for_emit

if TYPE_CHECKING:
    from bittensor_wallet import Wallet
    from bittensor.core.async_subtensor import AsyncSubtensor
    from bittensor.utils.registration import torch


async def _do_commit_reveal_v3(
    subtensor: "AsyncSubtensor",
    wallet: "Wallet",
    netuid: int,
    commit: bytes,
    reveal_round: int,
    wait_for_inclusion: bool = False,
    wait_for_finalization: bool = False,
) -> tuple[bool, Optional[str]]:
    """
    Executes the commit-reveal phase 3 for a given netuid and commit, and optionally waits for extrinsic inclusion or
    finalization.

    Arguments:
        subtensor: An instance of the AsyncSubtensor class.
        wallet: Wallet An instance of the Wallet class containing the user's keypair.
        netuid: int The network unique identifier.
        commit  bytes The commit data in bytes format.
        reveal_round: int The round number for the reveal phase.
        wait_for_inclusion: bool, optional Flag indicating whether to wait for the extrinsic to be included in a block.
        wait_for_finalization: bool, optional Flag indicating whether to wait for the extrinsic to be finalized.

    Returns:
        A tuple where the first element is a boolean indicating success or failure, and the second element is an
            optional string containing error message if any.
    """
    logging.info(
        f"Committing weights hash [blue]{commit.hex()}[/blue] for subnet #[blue]{netuid}[/blue] with "
        f"reveal round [blue]{reveal_round}[/blue]..."
    )

    call = await subtensor.substrate.compose_call(
        call_module="SubtensorModule",
        call_function="commit_crv3_weights",
        call_params={
            "netuid": netuid,
            "commit": commit,
            "reveal_round": reveal_round,
        },
    )
    return await subtensor.sign_and_send_extrinsic(
        call, wallet, wait_for_inclusion, wait_for_finalization, sign_with="hotkey"
    )


[docs] async def commit_reveal_v3_extrinsic( subtensor: "AsyncSubtensor", wallet: "Wallet", netuid: int, uids: Union[NDArray[np.int64], "torch.LongTensor", list], weights: Union[NDArray[np.float32], "torch.FloatTensor", list], version_key: int = version_as_int, wait_for_inclusion: bool = False, wait_for_finalization: bool = False, ) -> tuple[bool, str]: """ Commits and reveals weights for given subtensor and wallet with provided uids and weights. Arguments: subtensor: The AsyncSubtensor instance. wallet: The wallet to use for committing and revealing. netuid: The id of the network. uids: The uids to commit. weights: The weights associated with the uids. version_key: The version key to use for committing and revealing. Default is version_as_int. wait_for_inclusion: Whether to wait for the inclusion of the transaction. Default is False. wait_for_finalization: Whether to wait for the finalization of the transaction. Default is False. Returns: tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure, and the second element is a message associated with the result """ try: # Convert uids and weights if isinstance(uids, list): uids = np.array(uids, dtype=np.int64) if isinstance(weights, list): weights = np.array(weights, dtype=np.float32) # Reformat and normalize. uids, weights = convert_weights_and_uids_for_emit(uids, weights) current_block = await subtensor.substrate.get_block(None) subnet_hyperparameters = await subtensor.get_subnet_hyperparameters( netuid, block_hash=current_block["header"]["hash"] ) tempo = subnet_hyperparameters.tempo subnet_reveal_period_epochs = subnet_hyperparameters.commit_reveal_period # Encrypt `commit_hash` with t-lock and `get reveal_round` commit_for_reveal, reveal_round = get_encrypted_commit( uids=uids, weights=weights, version_key=version_key, tempo=tempo, current_block=current_block["header"]["number"], netuid=netuid, subnet_reveal_period_epochs=subnet_reveal_period_epochs, ) success, message = await _do_commit_reveal_v3( subtensor=subtensor, wallet=wallet, netuid=netuid, commit=commit_for_reveal, reveal_round=reveal_round, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, ) if success is not True: logging.error(message) return False, message logging.success( f"[green]Finalized![/green] Weights committed with reveal round [blue]{reveal_round}[/blue]." ) return True, f"reveal_round:{reveal_round}" except Exception as e: logging.error(f":cross_mark: [red]Failed. Error:[/red] {e}") return False, str(e)