diff --git a/bittensor/core/extrinsics/commit_weights.py b/bittensor/core/extrinsics/commit_weights.py index c53a527ea..ef93a15d3 100644 --- a/bittensor/core/extrinsics/commit_weights.py +++ b/bittensor/core/extrinsics/commit_weights.py @@ -19,8 +19,6 @@ from typing import Optional, TYPE_CHECKING -from retry import retry - from bittensor.core.extrinsics.utils import submit_extrinsic from bittensor.utils import format_error_message from bittensor.utils.btlogging import logging @@ -60,37 +58,33 @@ def do_commit_weights( This method ensures that the weight commitment is securely recorded on the Bittensor blockchain, providing a verifiable record of the neuron's weight distribution at a specific point in time. """ - @retry(delay=1, tries=3, backoff=2, max_delay=4) - def make_substrate_call_with_retry(): - call = self.substrate.compose_call( - call_module="SubtensorModule", - call_function="commit_weights", - call_params={ - "netuid": netuid, - "commit_hash": commit_hash, - }, - ) - extrinsic = self.substrate.create_signed_extrinsic( - call=call, - keypair=wallet.hotkey, - ) - response = submit_extrinsic( - substrate=self.substrate, - extrinsic=extrinsic, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - ) - - if not wait_for_finalization and not wait_for_inclusion: - return True, None + call = self.substrate.compose_call( + call_module="SubtensorModule", + call_function="commit_weights", + call_params={ + "netuid": netuid, + "commit_hash": commit_hash, + }, + ) + extrinsic = self.substrate.create_signed_extrinsic( + call=call, + keypair=wallet.hotkey, + ) + response = submit_extrinsic( + substrate=self.substrate, + extrinsic=extrinsic, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + ) - response.process_events() - if response.is_success: - return True, None - else: - return False, response.error_message + if not wait_for_finalization and not wait_for_inclusion: + return True, None - return make_substrate_call_with_retry() + response.process_events() + if response.is_success: + return True, None + else: + return False, response.error_message def commit_weights_extrinsic( @@ -174,40 +168,36 @@ def do_reveal_weights( This method ensures that the weight revelation is securely recorded on the Bittensor blockchain, providing transparency and accountability for the neuron's weight distribution. """ - @retry(delay=1, tries=3, backoff=2, max_delay=4) - def make_substrate_call_with_retry(): - call = self.substrate.compose_call( - call_module="SubtensorModule", - call_function="reveal_weights", - call_params={ - "netuid": netuid, - "uids": uids, - "values": values, - "salt": salt, - "version_key": version_key, - }, - ) - extrinsic = self.substrate.create_signed_extrinsic( - call=call, - keypair=wallet.hotkey, - ) - response = submit_extrinsic( - substrate=self.substrate, - extrinsic=extrinsic, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - ) - - if not wait_for_finalization and not wait_for_inclusion: - return True, None + call = self.substrate.compose_call( + call_module="SubtensorModule", + call_function="reveal_weights", + call_params={ + "netuid": netuid, + "uids": uids, + "values": values, + "salt": salt, + "version_key": version_key, + }, + ) + extrinsic = self.substrate.create_signed_extrinsic( + call=call, + keypair=wallet.hotkey, + ) + response = submit_extrinsic( + substrate=self.substrate, + extrinsic=extrinsic, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + ) - response.process_events() - if response.is_success: - return True, None - else: - return False, response.error_message + if not wait_for_finalization and not wait_for_inclusion: + return True, None - return make_substrate_call_with_retry() + response.process_events() + if response.is_success: + return True, None + else: + return False, response.error_message def reveal_weights_extrinsic( diff --git a/bittensor/core/extrinsics/registration.py b/bittensor/core/extrinsics/registration.py index de38869a8..bd926575a 100644 --- a/bittensor/core/extrinsics/registration.py +++ b/bittensor/core/extrinsics/registration.py @@ -19,7 +19,6 @@ from typing import Union, Optional, TYPE_CHECKING from bittensor_wallet.errors import KeyFileError -from retry import retry from bittensor.utils import format_error_message from bittensor.utils.btlogging import logging @@ -59,46 +58,39 @@ def _do_pow_register( success (bool): ``True`` if the extrinsic was included in a block. error (Optional[str]): ``None`` on success or not waiting for inclusion/finalization, otherwise the error message. """ + # create extrinsic call + call = self.substrate.compose_call( + call_module="SubtensorModule", + call_function="register", + call_params={ + "netuid": netuid, + "block_number": pow_result.block_number, + "nonce": pow_result.nonce, + "work": [int(byte_) for byte_ in pow_result.seal], + "hotkey": wallet.hotkey.ss58_address, + "coldkey": wallet.coldkeypub.ss58_address, + }, + ) + extrinsic = self.substrate.create_signed_extrinsic(call=call, keypair=wallet.hotkey) + response = self.substrate.submit_extrinsic( + extrinsic, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + ) - @retry(delay=1, tries=3, backoff=2, max_delay=4) - def make_substrate_call_with_retry(): - # create extrinsic call - call = self.substrate.compose_call( - call_module="SubtensorModule", - call_function="register", - call_params={ - "netuid": netuid, - "block_number": pow_result.block_number, - "nonce": pow_result.nonce, - "work": [int(byte_) for byte_ in pow_result.seal], - "hotkey": wallet.hotkey.ss58_address, - "coldkey": wallet.coldkeypub.ss58_address, - }, - ) - extrinsic = self.substrate.create_signed_extrinsic( - call=call, keypair=wallet.hotkey - ) - response = self.substrate.submit_extrinsic( - extrinsic, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - ) - - # We only wait here if we expect finalization. - if not wait_for_finalization and not wait_for_inclusion: - return True, None - - # process if registration successful, try again if pow is still valid - response.process_events() - if not response.is_success: - return False, format_error_message( - response.error_message, substrate=self.substrate - ) - # Successful registration - else: - return True, None + # We only wait here if we expect finalization. + if not wait_for_finalization and not wait_for_inclusion: + return True, None - return make_substrate_call_with_retry() + # process if registration successful, try again if pow is still valid + response.process_events() + if not response.is_success: + return False, format_error_message( + response.error_message, substrate=self.substrate + ) + # Successful registration + else: + return True, None def register_extrinsic( @@ -297,41 +289,37 @@ def _do_burned_register( Tuple[bool, Optional[str]]: A tuple containing a boolean indicating success or failure, and an optional error message. """ - @retry(delay=1, tries=3, backoff=2, max_delay=4) - def make_substrate_call_with_retry(): - # create extrinsic call - call = self.substrate.compose_call( - call_module="SubtensorModule", - call_function="burned_register", - call_params={ - "netuid": netuid, - "hotkey": wallet.hotkey.ss58_address, - }, - ) - extrinsic = self.substrate.create_signed_extrinsic( - call=call, keypair=wallet.coldkey - ) - response = self.substrate.submit_extrinsic( - extrinsic, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - ) - - # We only wait here if we expect finalization. - if not wait_for_finalization and not wait_for_inclusion: - return True, None + # create extrinsic call + call = self.substrate.compose_call( + call_module="SubtensorModule", + call_function="burned_register", + call_params={ + "netuid": netuid, + "hotkey": wallet.hotkey.ss58_address, + }, + ) + extrinsic = self.substrate.create_signed_extrinsic( + call=call, keypair=wallet.coldkey + ) + response = self.substrate.submit_extrinsic( + extrinsic, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + ) - # process if registration successful, try again if pow is still valid - response.process_events() - if not response.is_success: - return False, format_error_message( - response.error_message, substrate=self.substrate - ) - # Successful registration - else: - return True, None + # We only wait here if we expect finalization. + if not wait_for_finalization and not wait_for_inclusion: + return True, None - return make_substrate_call_with_retry() + # process if registration successful, try again if pow is still valid + response.process_events() + if not response.is_success: + return False, format_error_message( + response.error_message, substrate=self.substrate + ) + # Successful registration + else: + return True, None def burned_register_extrinsic( diff --git a/bittensor/core/extrinsics/root.py b/bittensor/core/extrinsics/root.py index de7221214..572bf7388 100644 --- a/bittensor/core/extrinsics/root.py +++ b/bittensor/core/extrinsics/root.py @@ -4,7 +4,6 @@ import numpy as np from bittensor_wallet.errors import KeyFileError from numpy.typing import NDArray -from retry import retry from bittensor.core.settings import version_as_int from bittensor.utils import format_error_message, weight_utils @@ -24,38 +23,34 @@ def _do_root_register( wait_for_inclusion: bool = False, wait_for_finalization: bool = True, ) -> tuple[bool, Optional[str]]: - @retry(delay=1, tries=3, backoff=2, max_delay=4) - def make_substrate_call_with_retry(): - # create extrinsic call - call = self.substrate.compose_call( - call_module="SubtensorModule", - call_function="root_register", - call_params={"hotkey": wallet.hotkey.ss58_address}, - ) - extrinsic = self.substrate.create_signed_extrinsic( - call=call, keypair=wallet.coldkey - ) - response = self.substrate.submit_extrinsic( - extrinsic, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - ) - - # We only wait here if we expect finalization. - if not wait_for_finalization and not wait_for_inclusion: - return True + # create extrinsic call + call = self.substrate.compose_call( + call_module="SubtensorModule", + call_function="root_register", + call_params={"hotkey": wallet.hotkey.ss58_address}, + ) + extrinsic = self.substrate.create_signed_extrinsic( + call=call, keypair=wallet.coldkey + ) + response = self.substrate.submit_extrinsic( + extrinsic, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + ) - # process if registration successful, try again if pow is still valid - response.process_events() - if not response.is_success: - return False, format_error_message( - response.error_message, substrate=self.substrate - ) - # Successful registration - else: - return True, None + # We only wait here if we expect finalization. + if not wait_for_finalization and not wait_for_inclusion: + return True, None - return make_substrate_call_with_retry() + # process if registration successful, try again if pow is still valid + response.process_events() + if not response.is_success: + return False, format_error_message( + response.error_message, substrate=self.substrate + ) + # Successful registration + else: + return True, None def root_register_extrinsic( @@ -147,41 +142,37 @@ def _do_set_root_weights( This method is vital for the dynamic weighting mechanism in Bittensor, where neurons adjust their trust in other neurons based on observed performance and contributions on the root network. """ - @retry(delay=2, tries=3, backoff=2, max_delay=4) - def make_substrate_call_with_retry(): - call = self.substrate.compose_call( - call_module="SubtensorModule", - call_function="set_root_weights", - call_params={ - "dests": uids, - "weights": vals, - "netuid": netuid, - "version_key": version_key, - "hotkey": wallet.hotkey.ss58_address, - }, - ) - # Period dictates how long the extrinsic will stay as part of waiting pool - extrinsic = self.substrate.create_signed_extrinsic( - call=call, - keypair=wallet.coldkey, - era={"period": 5}, - ) - response = self.substrate.submit_extrinsic( - extrinsic, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - ) - # We only wait here if we expect finalization. - if not wait_for_finalization and not wait_for_inclusion: - return True, "Not waiting for finalziation or inclusion." - - response.process_events() - if response.is_success: - return True, "Successfully set weights." - else: - return False, response.error_message + call = self.substrate.compose_call( + call_module="SubtensorModule", + call_function="set_root_weights", + call_params={ + "dests": uids, + "weights": vals, + "netuid": netuid, + "version_key": version_key, + "hotkey": wallet.hotkey.ss58_address, + }, + ) + # Period dictates how long the extrinsic will stay as part of waiting pool + extrinsic = self.substrate.create_signed_extrinsic( + call=call, + keypair=wallet.coldkey, + era={"period": 5}, + ) + response = self.substrate.submit_extrinsic( + extrinsic, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + ) + # We only wait here if we expect finalization. + if not wait_for_finalization and not wait_for_inclusion: + return True, "Not waiting for finalziation or inclusion." - return make_substrate_call_with_retry() + response.process_events() + if response.is_success: + return True, "Successfully set weights." + else: + return False, response.error_message @legacy_torch_api_compat diff --git a/bittensor/core/extrinsics/serving.py b/bittensor/core/extrinsics/serving.py index b4ce24971..b3ca2df40 100644 --- a/bittensor/core/extrinsics/serving.py +++ b/bittensor/core/extrinsics/serving.py @@ -17,8 +17,6 @@ from typing import Optional, TYPE_CHECKING -from retry import retry - from bittensor.core.errors import MetadataError from bittensor.core.extrinsics.utils import submit_extrinsic from bittensor.core.settings import version_as_int @@ -59,32 +57,26 @@ def do_serve_axon( This function is crucial for initializing and announcing a neuron's ``Axon`` service on the network, enhancing the decentralized computation capabilities of Bittensor. """ - @retry(delay=1, tries=3, backoff=2, max_delay=4) - def make_substrate_call_with_retry(): - call = self.substrate.compose_call( - call_module="SubtensorModule", - call_function="serve_axon", - call_params=call_params, - ) - extrinsic = self.substrate.create_signed_extrinsic( - call=call, keypair=wallet.hotkey - ) - response = submit_extrinsic( - substrate=self.substrate, - extrinsic=extrinsic, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - ) - if wait_for_inclusion or wait_for_finalization: - response.process_events() - if response.is_success: - return True, None - else: - return False, response.error_message - else: + call = self.substrate.compose_call( + call_module="SubtensorModule", + call_function="serve_axon", + call_params=call_params, + ) + extrinsic = self.substrate.create_signed_extrinsic(call=call, keypair=wallet.hotkey) + response = submit_extrinsic( + substrate=self.substrate, + extrinsic=extrinsic, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + ) + if wait_for_inclusion or wait_for_finalization: + response.process_events() + if response.is_success: return True, None - - return make_substrate_call_with_retry() + else: + return False, response.error_message + else: + return True, None def serve_extrinsic( @@ -295,15 +287,10 @@ def publish_metadata( # Community uses this function directly @net.ensure_connected def get_metadata(self, netuid: int, hotkey: str, block: Optional[int] = None) -> str: - @retry(delay=2, tries=3, backoff=2, max_delay=4) - def make_substrate_call_with_retry(): - with self.substrate as substrate: - return substrate.query( - module="Commitments", - storage_function="CommitmentOf", - params=[netuid, hotkey], - block_hash=None if block is None else substrate.get_block_hash(block), - ) - - commit_data = make_substrate_call_with_retry() - return commit_data.value + with self.substrate as substrate: + return substrate.query( + module="Commitments", + storage_function="CommitmentOf", + params=[netuid, hotkey], + block_hash=None if block is None else substrate.get_block_hash(block), + ).value diff --git a/bittensor/core/extrinsics/set_weights.py b/bittensor/core/extrinsics/set_weights.py index 0475b4222..bb7950809 100644 --- a/bittensor/core/extrinsics/set_weights.py +++ b/bittensor/core/extrinsics/set_weights.py @@ -20,7 +20,6 @@ import numpy as np from numpy.typing import NDArray -from retry import retry from bittensor.core.extrinsics.utils import submit_extrinsic from bittensor.core.settings import version_as_int @@ -66,43 +65,39 @@ def do_set_weights( This method is vital for the dynamic weighting mechanism in Bittensor, where neurons adjust their trust in other neurons based on observed performance and contributions. """ - @retry(delay=1, tries=3, backoff=2, max_delay=4) - def make_substrate_call_with_retry(): - call = self.substrate.compose_call( - call_module="SubtensorModule", - call_function="set_weights", - call_params={ - "dests": uids, - "weights": vals, - "netuid": netuid, - "version_key": version_key, - }, - ) - # Period dictates how long the extrinsic will stay as part of waiting pool - extrinsic = self.substrate.create_signed_extrinsic( - call=call, - keypair=wallet.hotkey, - era={"period": 5}, - ) - response = submit_extrinsic( - substrate=self.substrate, - extrinsic=extrinsic, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - ) - # We only wait here if we expect finalization. - if not wait_for_finalization and not wait_for_inclusion: - return True, "Not waiting for finalization or inclusion." - - response.process_events() - if response.is_success: - return True, "Successfully set weights." - else: - return False, format_error_message( - response.error_message, substrate=self.substrate - ) + call = self.substrate.compose_call( + call_module="SubtensorModule", + call_function="set_weights", + call_params={ + "dests": uids, + "weights": vals, + "netuid": netuid, + "version_key": version_key, + }, + ) + # Period dictates how long the extrinsic will stay as part of waiting pool + extrinsic = self.substrate.create_signed_extrinsic( + call=call, + keypair=wallet.hotkey, + era={"period": 5}, + ) + response = submit_extrinsic( + substrate=self.substrate, + extrinsic=extrinsic, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + ) + # We only wait here if we expect finalization. + if not wait_for_finalization and not wait_for_inclusion: + return True, "Not waiting for finalization or inclusion." - return make_substrate_call_with_retry() + response.process_events() + if response.is_success: + return True, "Successfully set weights." + else: + return False, format_error_message( + response.error_message, substrate=self.substrate + ) # Community uses this extrinsic directly and via `subtensor.set_weights` diff --git a/bittensor/core/extrinsics/transfer.py b/bittensor/core/extrinsics/transfer.py index b2e060606..4af1add27 100644 --- a/bittensor/core/extrinsics/transfer.py +++ b/bittensor/core/extrinsics/transfer.py @@ -17,8 +17,6 @@ from typing import Optional, Union, TYPE_CHECKING -from retry import retry - from bittensor.core.extrinsics.utils import submit_extrinsic from bittensor.core.settings import NETWORK_EXPLORER_MAP from bittensor.utils import ( @@ -62,35 +60,31 @@ def do_transfer( error (dict): Error message from subtensor if transfer failed. """ - @retry(delay=1, tries=3, backoff=2, max_delay=4) - def make_substrate_call_with_retry(): - call = self.substrate.compose_call( - call_module="Balances", - call_function="transfer_allow_death", - call_params={"dest": dest, "value": transfer_balance.rao}, - ) - extrinsic = self.substrate.create_signed_extrinsic( - call=call, keypair=wallet.coldkey - ) - response = submit_extrinsic( - substrate=self.substrate, - extrinsic=extrinsic, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - ) - # We only wait here if we expect finalization. - if not wait_for_finalization and not wait_for_inclusion: - return True, None, None - - # Otherwise continue with finalization. - response.process_events() - if response.is_success: - block_hash = response.block_hash - return True, block_hash, None - else: - return False, None, response.error_message - - return make_substrate_call_with_retry() + call = self.substrate.compose_call( + call_module="Balances", + call_function="transfer_allow_death", + call_params={"dest": dest, "value": transfer_balance.rao}, + ) + extrinsic = self.substrate.create_signed_extrinsic( + call=call, keypair=wallet.coldkey + ) + response = submit_extrinsic( + substrate=self.substrate, + extrinsic=extrinsic, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + ) + # We only wait here if we expect finalization. + if not wait_for_finalization and not wait_for_inclusion: + return True, None, None + + # Otherwise continue with finalization. + response.process_events() + if response.is_success: + block_hash = response.block_hash + return True, block_hash, None + else: + return False, None, response.error_message # Community uses this extrinsic directly and via `subtensor.transfer` diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 8f5d147f7..a11aa192b 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -30,7 +30,6 @@ import scalecodec from bittensor_wallet import Wallet from numpy.typing import NDArray -from retry import retry from scalecodec.base import RuntimeConfiguration from scalecodec.exceptions import RemainingScaleBytesNotEmptyException from scalecodec.type_registry import load_type_registry_preset @@ -450,18 +449,14 @@ def query_subtensor( This query function is essential for accessing detailed information about the network and its neurons, providing valuable insights into the state and dynamics of the Bittensor ecosystem. """ - @retry(delay=1, tries=3, backoff=2, max_delay=4, logger=logging) - def make_substrate_call_with_retry() -> "ScaleType": - return self.substrate.query( - module="SubtensorModule", - storage_function=name, - params=params, - block_hash=( - None if block is None else self.substrate.get_block_hash(block) - ), - ) - - return make_substrate_call_with_retry() + return self.substrate.query( + module="SubtensorModule", + storage_function=name, + params=params, + block_hash=( + None if block is None else self.substrate.get_block_hash(block) + ), + ) @networking.ensure_connected def query_map_subtensor( @@ -480,19 +475,14 @@ def query_map_subtensor( This function is particularly useful for analyzing and understanding complex network structures and relationships within the Bittensor ecosystem, such as inter-neuronal connections and stake distributions. """ - - @retry(delay=1, tries=3, backoff=2, max_delay=4, logger=logging) - def make_substrate_call_with_retry(): - return self.substrate.query_map( - module="SubtensorModule", - storage_function=name, - params=params, - block_hash=( - None if block is None else self.substrate.get_block_hash(block) - ), - ) - - return make_substrate_call_with_retry() + return self.substrate.query_map( + module="SubtensorModule", + storage_function=name, + params=params, + block_hash=( + None if block is None else self.substrate.get_block_hash(block) + ), + ) def query_runtime_api( self, @@ -563,16 +553,11 @@ def state_call( The state call function provides a more direct and flexible way of querying blockchain data, useful for specific use cases where standard queries are insufficient. """ - - @retry(delay=1, tries=3, backoff=2, max_delay=4, logger=logging) - def make_substrate_call_with_retry() -> dict[Any, Any]: - block_hash = None if block is None else self.substrate.get_block_hash(block) - return self.substrate.rpc_request( - method="state_call", - params=[method, data, block_hash] if block_hash else [method, data], - ) - - return make_substrate_call_with_retry() + block_hash = None if block is None else self.substrate.get_block_hash(block) + return self.substrate.rpc_request( + method="state_call", + params=[method, data, block_hash] if block_hash else [method, data], + ) @networking.ensure_connected def query_map( @@ -596,19 +581,14 @@ def query_map( This function is particularly useful for retrieving detailed and structured data from various blockchain modules, offering insights into the network's state and the relationships between its different components. """ - - @retry(delay=1, tries=3, backoff=2, max_delay=4, logger=logging) - def make_substrate_call_with_retry() -> "QueryMapResult": - return self.substrate.query_map( - module=module, - storage_function=name, - params=params, - block_hash=( - None if block is None else self.substrate.get_block_hash(block) - ), - ) - - return make_substrate_call_with_retry() + return self.substrate.query_map( + module=module, + storage_function=name, + params=params, + block_hash=( + None if block is None else self.substrate.get_block_hash(block) + ), + ) @networking.ensure_connected def query_constant( @@ -627,18 +607,13 @@ def query_constant( Constants queried through this function can include critical network parameters such as inflation rates, consensus rules, or validation thresholds, providing a deeper understanding of the Bittensor network's operational parameters. """ - - @retry(delay=1, tries=3, backoff=2, max_delay=4, logger=logging) - def make_substrate_call_with_retry(): - return self.substrate.get_constant( - module_name=module_name, - constant_name=constant_name, - block_hash=( - None if block is None else self.substrate.get_block_hash(block) - ), - ) - - return make_substrate_call_with_retry() + return self.substrate.get_constant( + module_name=module_name, + constant_name=constant_name, + block_hash=( + None if block is None else self.substrate.get_block_hash(block) + ), + ) @networking.ensure_connected def query_module( @@ -662,19 +637,14 @@ def query_module( This versatile query function is key to accessing a wide range of data and insights from different parts of the Bittensor blockchain, enhancing the understanding and analysis of the network's state and dynamics. """ - - @retry(delay=1, tries=3, backoff=2, max_delay=4, logger=logging) - def make_substrate_call_with_retry() -> "ScaleType": - return self.substrate.query( - module=module, - storage_function=name, - params=params, - block_hash=( - None if block is None else self.substrate.get_block_hash(block) - ), - ) - - return make_substrate_call_with_retry() + return self.substrate.query( + module=module, + storage_function=name, + params=params, + block_hash=( + None if block is None else self.substrate.get_block_hash(block) + ), + ) # Common subtensor methods def metagraph( @@ -777,12 +747,7 @@ def get_current_block(self) -> int: Knowing the current block number is essential for querying real-time data and performing time-sensitive operations on the blockchain. It serves as a reference point for network activities and data synchronization. """ - - @retry(delay=1, tries=3, backoff=2, max_delay=4, logger=logging) - def make_substrate_call_with_retry(): - return self.substrate.get_block_number(None) # type: ignore - - return make_substrate_call_with_retry() + return self.substrate.get_block_number(None) # type: ignore def is_hotkey_registered_any( self, hotkey_ss58: str, block: Optional[int] = None @@ -1230,18 +1195,15 @@ def neuron_for_uid( if uid is None: return NeuronInfo.get_null_neuron() - @retry(delay=1, tries=3, backoff=2, max_delay=4, logger=logging) - def make_substrate_call_with_retry(): - block_hash = None if block is None else self.substrate.get_block_hash(block) - params = [netuid, uid] - if block_hash: - params = params + [block_hash] - return self.substrate.rpc_request( - method="neuronInfo_getNeuron", - params=params, # custom rpc method - ) + block_hash = None if block is None else self.substrate.get_block_hash(block) + params = [netuid, uid] + if block_hash: + params = params + [block_hash] - json_body = make_substrate_call_with_retry() + json_body = self.substrate.rpc_request( + method="neuronInfo_getNeuron", + params=params, # custom rpc method + ) if not (result := json_body.get("result", None)): return NeuronInfo.get_null_neuron() @@ -1454,17 +1416,12 @@ def get_all_subnets_info(self, block: Optional[int] = None) -> list[SubnetInfo]: Gaining insights into the subnets' details assists in understanding the network's composition, the roles of different subnets, and their unique features. """ + block_hash = None if block is None else self.substrate.get_block_hash(block) - @retry(delay=1, tries=3, backoff=2, max_delay=4) - def make_substrate_call_with_retry(): - block_hash = None if block is None else self.substrate.get_block_hash(block) - - return self.substrate.rpc_request( - method="subnetInfo_getSubnetsInfo", # custom rpc method - params=[block_hash] if block_hash else [], - ) - - json_body = make_substrate_call_with_retry() + json_body = self.substrate.rpc_request( + method="subnetInfo_getSubnetsInfo", # custom rpc method + params=[block_hash] if block_hash else [], + ) if not (result := json_body.get("result", None)): return [] @@ -1662,25 +1619,21 @@ def get_balance(self, address: str, block: Optional[int] = None) -> "Balance": This function is important for monitoring account holdings and managing financial transactions within the Bittensor ecosystem. It helps in assessing the economic status and capacity of network participants. """ try: - - @retry(delay=1, tries=3, backoff=2, max_delay=4, logger=logging) - def make_substrate_call_with_retry(): - return self.substrate.query( - module="System", - storage_function="Account", - params=[address], - block_hash=( - None if block is None else self.substrate.get_block_hash(block) - ), - ) - - result = make_substrate_call_with_retry() + result = self.substrate.query( + module="System", + storage_function="Account", + params=[address], + block_hash=( + None if block is None else self.substrate.get_block_hash(block) + ), + ) except RemainingScaleBytesNotEmptyException: logging.error( "Received a corrupted message. This likely points to an error with the network or subnet." ) return Balance(1000) + return Balance(result.value["data"]["free"]) # Used in community via `bittensor.core.subtensor.Subtensor.transfer` @@ -1967,20 +1920,14 @@ def get_delegate_by_hotkey( This function is essential for understanding the roles and influence of delegate neurons within the Bittensor network's consensus and governance structures. """ + encoded_hotkey = ss58_to_vec_u8(hotkey_ss58) - @retry(delay=1, tries=3, backoff=2, max_delay=4) - def make_substrate_call_with_retry(encoded_hotkey_: list[int]): - block_hash = None if block is None else self.substrate.get_block_hash(block) - - return self.substrate.rpc_request( - method="delegateInfo_getDelegate", # custom rpc method - params=( - [encoded_hotkey_, block_hash] if block_hash else [encoded_hotkey_] - ), - ) + block_hash = None if block is None else self.substrate.get_block_hash(block) - encoded_hotkey = ss58_to_vec_u8(hotkey_ss58) - json_body = make_substrate_call_with_retry(encoded_hotkey) + json_body = self.substrate.rpc_request( + method="delegateInfo_getDelegate", # custom rpc method + params=([encoded_hotkey, block_hash] if block_hash else [encoded_hotkey]), + ) if not (result := json_body.get("result", None)): return None diff --git a/bittensor/utils/registration.py b/bittensor/utils/registration.py index 4dd6d8ec6..f190f668d 100644 --- a/bittensor/utils/registration.py +++ b/bittensor/utils/registration.py @@ -740,9 +740,7 @@ def _solve_for_difficulty_fast( @retry(Exception, tries=3, delay=1) -def _get_block_with_retry( - subtensor: "Subtensor", netuid: int -) -> tuple[int, int, bytes]: +def _get_block_with_retry(subtensor: "Subtensor", netuid: int) -> tuple[int, int, str]: """ Gets the current block number, difficulty, and block hash from the substrate node. diff --git a/tests/unit_tests/test_subtensor.py b/tests/unit_tests/test_subtensor.py index c88990368..201acae38 100644 --- a/tests/unit_tests/test_subtensor.py +++ b/tests/unit_tests/test_subtensor.py @@ -2069,34 +2069,6 @@ def test_get_all_subnets_info_no_data(mocker, subtensor, result_): subtensor_module.SubnetInfo.list_from_vec_u8.assert_not_called() -def test_get_all_subnets_info_retry(mocker, subtensor): - """Test get_all_subnets_info retries on failure.""" - # Prep - block = 123 - subnet_data = [1, 2, 3] - mocker.patch.object( - subtensor.substrate, "get_block_hash", return_value="mock_block_hash" - ) - mock_response = {"result": subnet_data} - mock_rpc_request = mocker.patch.object( - subtensor.substrate, - "rpc_request", - side_effect=[Exception, Exception, mock_response], - ) - mocker.patch.object( - subtensor_module.SubnetInfo, "list_from_vec_u8", return_value=["some_data"] - ) - - # Call - result = subtensor.get_all_subnets_info(block) - - # Asserts - subtensor.substrate.get_block_hash.assert_called_with(block) - assert mock_rpc_request.call_count == 3 - subtensor_module.SubnetInfo.list_from_vec_u8.assert_called_once_with(subnet_data) - assert result == ["some_data"] - - def test_get_delegate_take_success(subtensor, mocker): """Verify `get_delegate_take` method successful path.""" # Preps