From 4f2bddf36bad6b0d4dafcdb23dd8eee43bf7a553 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 16 Dec 2024 16:49:19 +0200 Subject: [PATCH 01/16] Changed `ChainError` from `BaseException` to `Exception`. --- bittensor/core/errors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittensor/core/errors.py b/bittensor/core/errors.py index 6fd9729e8b..bbc35abd71 100644 --- a/bittensor/core/errors.py +++ b/bittensor/core/errors.py @@ -20,7 +20,7 @@ from bittensor.core.synapse import Synapse -class ChainError(BaseException): +class ChainError(Exception): """Base error for any chain related errors.""" From 477b77877e93bc774e3bf23736af9a882f305653 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 16 Dec 2024 17:14:59 +0200 Subject: [PATCH 02/16] Error type defs --- bittensor/core/errors.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bittensor/core/errors.py b/bittensor/core/errors.py index bbc35abd71..1db2fd66f9 100644 --- a/bittensor/core/errors.py +++ b/bittensor/core/errors.py @@ -17,7 +17,10 @@ from __future__ import annotations -from bittensor.core.synapse import Synapse +from typing import Optional, TYPE_CHECKING + +if TYPE_CHECKING: + from bittensor.core.synapse import Synapse class ChainError(Exception): @@ -81,7 +84,7 @@ class InvalidRequestNameError(Exception): class SynapseException(Exception): - def __init__(self, message="Synapse Exception", synapse: "Synapse" | None = None): + def __init__(self, message="Synapse Exception", synapse: Optional["Synapse"] = None): self.message = message self.synapse = synapse super().__init__(self.message) @@ -123,7 +126,7 @@ class SynapseDendriteNoneException(SynapseException): def __init__( self, message="Synapse Dendrite is None", - synapse: "Synapse" | None = None, + synapse: Optional["Synapse"] = None, ): self.message = message super().__init__(self.message, synapse) From e550f4dd222e7bbd7f35038925e5a1709bc4fa2e Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 16 Dec 2024 17:15:16 +0200 Subject: [PATCH 03/16] Fixed Optional Non-optional type defs. --- bittensor/core/subtensor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 39669793b6..4b699f09d5 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -505,7 +505,7 @@ def query_runtime_api( self, runtime_api: str, method: str, - params: Optional[Union[list[int], dict[str, int]]], + params: Optional[Union[list[int], dict[str, int]]] = None, block: Optional[int] = None, ) -> Optional[str]: """ @@ -956,13 +956,13 @@ def get_neuron_certificate( @networking.ensure_connected def neuron_for_uid( - self, uid: Optional[int], netuid: int, block: Optional[int] = None + self, uid: int, netuid: int, block: Optional[int] = None ) -> "NeuronInfo": """ Retrieves detailed information about a specific neuron identified by its unique identifier (UID) within a specified subnet (netuid) of the Bittensor network. This function provides a comprehensive view of a neuron's attributes, including its stake, rank, and operational status. Args: - uid (Optional[int]): The unique identifier of the neuron. + uid (int): The unique identifier of the neuron. netuid (int): The unique identifier of the subnet. block (Optional[int]): The blockchain block number for the query. From 464263ccec1d6512aa8916c2e7a55c73d91ddded Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Mon, 16 Dec 2024 10:26:18 -0500 Subject: [PATCH 04/16] chore: ruff --- bittensor/core/errors.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bittensor/core/errors.py b/bittensor/core/errors.py index 1db2fd66f9..87d6c37a90 100644 --- a/bittensor/core/errors.py +++ b/bittensor/core/errors.py @@ -84,7 +84,9 @@ class InvalidRequestNameError(Exception): class SynapseException(Exception): - def __init__(self, message="Synapse Exception", synapse: Optional["Synapse"] = None): + def __init__( + self, message="Synapse Exception", synapse: Optional["Synapse"] = None + ): self.message = message self.synapse = synapse super().__init__(self.message) From 30327b629e478ac00e0e14abd7acef4b6cd31ff8 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 16 Dec 2024 17:38:10 +0200 Subject: [PATCH 05/16] Change ChainError to subclass SubstrateRequestException --- bittensor/core/errors.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bittensor/core/errors.py b/bittensor/core/errors.py index 87d6c37a90..09b43d3729 100644 --- a/bittensor/core/errors.py +++ b/bittensor/core/errors.py @@ -19,11 +19,13 @@ from typing import Optional, TYPE_CHECKING +from substrateinterface.exceptions import SubstrateRequestException + if TYPE_CHECKING: from bittensor.core.synapse import Synapse -class ChainError(Exception): +class ChainError(SubstrateRequestException): """Base error for any chain related errors.""" From 35c4852351cd949c7cd35f8a65662aa35dbc5564 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 16 Dec 2024 18:27:33 +0200 Subject: [PATCH 06/16] Removes substrate call in format_error_message --- bittensor/core/extrinsics/commit_reveal.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bittensor/core/extrinsics/commit_reveal.py b/bittensor/core/extrinsics/commit_reveal.py index 7d0331c877..c16f663800 100644 --- a/bittensor/core/extrinsics/commit_reveal.py +++ b/bittensor/core/extrinsics/commit_reveal.py @@ -74,9 +74,7 @@ def _do_commit_reveal_v3( if response.is_success: return True, None else: - return False, format_error_message( - response.error_message, substrate=self.substrate - ) + return False, format_error_message(response.error_message) def commit_reveal_v3_extrinsic( From cea0983712125272fb8017aef2ecc302ec075331 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 16 Dec 2024 18:44:37 +0200 Subject: [PATCH 07/16] Fix test. --- tests/unit_tests/extrinsics/test_commit_reveal.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/unit_tests/extrinsics/test_commit_reveal.py b/tests/unit_tests/extrinsics/test_commit_reveal.py index 6d2f4549a6..3e95129343 100644 --- a/tests/unit_tests/extrinsics/test_commit_reveal.py +++ b/tests/unit_tests/extrinsics/test_commit_reveal.py @@ -146,9 +146,7 @@ def test_do_commit_reveal_v3_failure_due_to_error(mocker, subtensor): wait_for_inclusion=True, wait_for_finalization=True, ) - mocked_format_error_message.assert_called_once_with( - "Mocked error", substrate=subtensor.substrate - ) + mocked_format_error_message.assert_called_once_with("Mocked error") assert result == (False, "Formatted error") From d37d740b172c5879c18a803356d7d01a8ed8ae15 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 16 Dec 2024 19:03:02 +0200 Subject: [PATCH 08/16] Remove torch from the weights calls. --- bittensor/core/extrinsics/async_weights.py | 16 +++++----------- bittensor/core/extrinsics/commit_reveal.py | 16 +++++----------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/bittensor/core/extrinsics/async_weights.py b/bittensor/core/extrinsics/async_weights.py index 2c4f0d0a7b..572266c3f6 100644 --- a/bittensor/core/extrinsics/async_weights.py +++ b/bittensor/core/extrinsics/async_weights.py @@ -9,11 +9,11 @@ from bittensor.core.settings import version_as_int from bittensor.utils import format_error_message from bittensor.utils.btlogging import logging -from bittensor.utils.registration import torch, use_torch if TYPE_CHECKING: from bittensor_wallet import Wallet from bittensor.core.async_subtensor import AsyncSubtensor + from bittensor.utils.registration import torch async def _do_set_weights( @@ -106,16 +106,10 @@ async def set_weights_extrinsic( success (bool): Flag is ``true`` if extrinsic was finalized or included in the block. If we did not wait for finalization / inclusion, the response is ``true``. """ # First convert types. - if use_torch(): - if isinstance(uids, list): - uids = torch.tensor(uids, dtype=torch.int64) - if isinstance(weights, list): - weights = torch.tensor(weights, dtype=torch.float32) - else: - if isinstance(uids, list): - uids = np.array(uids, dtype=np.int64) - if isinstance(weights, list): - weights = np.array(weights, dtype=np.float32) + 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. weight_uids, weight_vals = weight_utils.convert_weights_and_uids_for_emit( diff --git a/bittensor/core/extrinsics/commit_reveal.py b/bittensor/core/extrinsics/commit_reveal.py index c16f663800..503f4c8dfb 100644 --- a/bittensor/core/extrinsics/commit_reveal.py +++ b/bittensor/core/extrinsics/commit_reveal.py @@ -9,12 +9,12 @@ from bittensor.utils import format_error_message from bittensor.utils.btlogging import logging from bittensor.utils.networking import ensure_connected -from bittensor.utils.registration import torch, use_torch from bittensor.utils.weight_utils import convert_weights_and_uids_for_emit if TYPE_CHECKING: from bittensor_wallet import Wallet from bittensor.core.subtensor import Subtensor + from bittensor.utils.registration import torch @ensure_connected @@ -105,16 +105,10 @@ def commit_reveal_v3_extrinsic( """ try: # Convert uids and weights - if use_torch(): - if isinstance(uids, list): - uids = torch.tensor(uids, dtype=torch.int64) - if isinstance(weights, list): - weights = torch.tensor(weights, dtype=torch.float32) - else: - if isinstance(uids, list): - uids = np.array(uids, dtype=np.int64) - if isinstance(weights, list): - weights = np.array(weights, dtype=np.float32) + 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) From 8501f3092f6d9ad57cbb95051ed3b6a03e4a036a Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 16 Dec 2024 19:07:41 +0200 Subject: [PATCH 09/16] Tests --- .../extrinsics/test_async_weights.py | 47 ----------- .../extrinsics/test_commit_reveal.py | 77 ------------------- 2 files changed, 124 deletions(-) diff --git a/tests/unit_tests/extrinsics/test_async_weights.py b/tests/unit_tests/extrinsics/test_async_weights.py index 3fac1f7736..da250afd94 100644 --- a/tests/unit_tests/extrinsics/test_async_weights.py +++ b/tests/unit_tests/extrinsics/test_async_weights.py @@ -278,53 +278,6 @@ async def test_set_weights_extrinsic_exception(subtensor, mocker): assert message == "Unexpected error" -@pytest.mark.asyncio -async def test_set_weights_extrinsic_if_use_torch(subtensor, mocker): - """Tests set_weights_extrinsic when use_torch is True.""" - # Preps - fake_wallet = mocker.Mock(autospec=Wallet) - fake_netuid = 1 - fake_uids = [1, 2, 3] - fake_weights = [0.1, 0.2, 0.7] - - mocked_use_torch = mocker.patch.object( - async_weights, "use_torch", return_value=True - ) - mocked_torch_tensor = mocker.patch.object( - async_weights.torch, "tensor", return_value=mocker.Mock() - ) - - mocked_do_set_weights = mocker.patch.object( - async_weights, "_do_set_weights", return_value=(False, "Test error message") - ) - mocked_convert_weights_and_uids_for_emit = mocker.patch.object( - async_weights.weight_utils, - "convert_weights_and_uids_for_emit", - return_value=(mocker.Mock(), mocker.Mock()), - ) - - # Call - result, message = await async_weights.set_weights_extrinsic( - subtensor=subtensor, - wallet=fake_wallet, - netuid=fake_netuid, - uids=fake_uids, - weights=fake_weights, - wait_for_inclusion=True, - wait_for_finalization=True, - ) - - # Asserts - mocked_do_set_weights.assert_called_once() - mocked_use_torch.assert_called_once() - mocked_convert_weights_and_uids_for_emit.assert_called() - mocked_torch_tensor.assert_called_with( - fake_weights, dtype=async_weights.torch.float32 - ) - assert result is False - assert message == "Test error message" - - @pytest.mark.asyncio async def test_do_commit_weights_success(subtensor, mocker): """Tests _do_commit_weights when the commit is successful.""" diff --git a/tests/unit_tests/extrinsics/test_commit_reveal.py b/tests/unit_tests/extrinsics/test_commit_reveal.py index 3e95129343..243ef7cd2d 100644 --- a/tests/unit_tests/extrinsics/test_commit_reveal.py +++ b/tests/unit_tests/extrinsics/test_commit_reveal.py @@ -150,81 +150,6 @@ def test_do_commit_reveal_v3_failure_due_to_error(mocker, subtensor): assert result == (False, "Formatted error") -def test_commit_reveal_v3_extrinsic_success_with_torch(mocker, subtensor, hyperparams): - """Test successful commit-reveal with torch tensors.""" - # Preps - fake_wallet = mocker.Mock(autospec=subtensor_module.Wallet) - fake_netuid = 1 - fake_uids = torch.tensor([1, 2, 3], dtype=torch.int64) - fake_weights = torch.tensor([0.1, 0.2, 0.7], dtype=torch.float32) - fake_commit_for_reveal = b"mock_commit_for_reveal" - fake_reveal_round = 1 - - # Mocks - mocker.patch.object(commit_reveal, "use_torch", return_value=True) - - mocked_uids = mocker.Mock() - mocked_weights = mocker.Mock() - mocked_convert_weights_and_uids_for_emit = mocker.patch.object( - commit_reveal, - "convert_weights_and_uids_for_emit", - return_value=(mocked_uids, mocked_weights), - ) - mocked_get_subnet_reveal_period_epochs = mocker.patch.object( - subtensor, "get_subnet_reveal_period_epochs" - ) - mocked_get_encrypted_commit = mocker.patch.object( - commit_reveal, - "get_encrypted_commit", - return_value=(fake_commit_for_reveal, fake_reveal_round), - ) - mock_do_commit_reveal_v3 = mocker.patch.object( - commit_reveal, "_do_commit_reveal_v3", return_value=(True, "Success") - ) - mock_block = mocker.patch.object(subtensor, "get_current_block", return_value=1) - mock_hyperparams = mocker.patch.object( - subtensor, - "get_subnet_hyperparameters", - return_value=hyperparams, - ) - - # Call - success, message = commit_reveal.commit_reveal_v3_extrinsic( - subtensor=subtensor, - wallet=fake_wallet, - netuid=fake_netuid, - uids=fake_uids, - weights=fake_weights, - wait_for_inclusion=True, - wait_for_finalization=True, - ) - - # Asserts - assert success is True - assert message == "reveal_round:1" - mocked_convert_weights_and_uids_for_emit.assert_called_once_with( - fake_uids, fake_weights - ) - mocked_get_encrypted_commit.assert_called_once_with( - uids=mocked_uids, - weights=mocked_weights, - subnet_reveal_period_epochs=mock_hyperparams.return_value.commit_reveal_weights_interval, - version_key=commit_reveal.version_as_int, - tempo=mock_hyperparams.return_value.tempo, - netuid=fake_netuid, - current_block=mock_block.return_value, - ) - mock_do_commit_reveal_v3.assert_called_once_with( - self=subtensor, - wallet=fake_wallet, - netuid=fake_netuid, - commit=fake_commit_for_reveal, - reveal_round=fake_reveal_round, - wait_for_inclusion=True, - wait_for_finalization=True, - ) - - def test_commit_reveal_v3_extrinsic_success_with_numpy(mocker, subtensor, hyperparams): """Test successful commit-reveal with numpy arrays.""" # Preps @@ -233,7 +158,6 @@ def test_commit_reveal_v3_extrinsic_success_with_numpy(mocker, subtensor, hyperp fake_uids = np.array([1, 2, 3], dtype=np.int64) fake_weights = np.array([0.1, 0.2, 0.7], dtype=np.float32) - mocker.patch.object(commit_reveal, "use_torch", return_value=False) mock_convert = mocker.patch.object( commit_reveal, "convert_weights_and_uids_for_emit", @@ -282,7 +206,6 @@ def test_commit_reveal_v3_extrinsic_response_false(mocker, subtensor, hyperparam fake_reveal_round = 1 # Mocks - mocker.patch.object(commit_reveal, "use_torch", return_value=True) mocker.patch.object( commit_reveal, "convert_weights_and_uids_for_emit", From 2f88cf1e513c507ae207845381f334b4a8d91930 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 16 Dec 2024 19:19:09 +0200 Subject: [PATCH 10/16] Added back in modified tests --- .../extrinsics/test_async_weights.py | 36 +++++++++ .../extrinsics/test_commit_reveal.py | 74 +++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/tests/unit_tests/extrinsics/test_async_weights.py b/tests/unit_tests/extrinsics/test_async_weights.py index da250afd94..07de1e289b 100644 --- a/tests/unit_tests/extrinsics/test_async_weights.py +++ b/tests/unit_tests/extrinsics/test_async_weights.py @@ -278,6 +278,42 @@ async def test_set_weights_extrinsic_exception(subtensor, mocker): assert message == "Unexpected error" +@pytest.mark.asyncio +async def test_set_weights_extrinsic_if_use_torch(subtensor, mocker): + """Tests set_weights_extrinsic when use_torch is True.""" + # Preps + fake_wallet = mocker.Mock(autospec=Wallet) + fake_netuid = 1 + fake_uids = [1, 2, 3] + fake_weights = [0.1, 0.2, 0.7] + + mocked_do_set_weights = mocker.patch.object( + async_weights, "_do_set_weights", return_value=(False, "Test error message") + ) + mocked_convert_weights_and_uids_for_emit = mocker.patch.object( + async_weights.weight_utils, + "convert_weights_and_uids_for_emit", + return_value=(mocker.Mock(), mocker.Mock()), + ) + + # Call + result, message = await async_weights.set_weights_extrinsic( + subtensor=subtensor, + wallet=fake_wallet, + netuid=fake_netuid, + uids=fake_uids, + weights=fake_weights, + wait_for_inclusion=True, + wait_for_finalization=True, + ) + + # Asserts + mocked_do_set_weights.assert_called_once() + mocked_convert_weights_and_uids_for_emit.assert_called() + assert result is False + assert message == "Test error message" + + @pytest.mark.asyncio async def test_do_commit_weights_success(subtensor, mocker): """Tests _do_commit_weights when the commit is successful.""" diff --git a/tests/unit_tests/extrinsics/test_commit_reveal.py b/tests/unit_tests/extrinsics/test_commit_reveal.py index 243ef7cd2d..e1f7c9f877 100644 --- a/tests/unit_tests/extrinsics/test_commit_reveal.py +++ b/tests/unit_tests/extrinsics/test_commit_reveal.py @@ -150,6 +150,80 @@ def test_do_commit_reveal_v3_failure_due_to_error(mocker, subtensor): assert result == (False, "Formatted error") +def test_commit_reveal_v3_extrinsic_success_with_torch(mocker, subtensor, hyperparams): + """Test successful commit-reveal with torch tensors.""" + # Preps + fake_wallet = mocker.Mock(autospec=subtensor_module.Wallet) + fake_netuid = 1 + fake_uids = torch.tensor([1, 2, 3], dtype=torch.int64) + fake_weights = torch.tensor([0.1, 0.2, 0.7], dtype=torch.float32) + fake_commit_for_reveal = b"mock_commit_for_reveal" + fake_reveal_round = 1 + + # Mocks + + mocked_uids = mocker.Mock() + mocked_weights = mocker.Mock() + mocked_convert_weights_and_uids_for_emit = mocker.patch.object( + commit_reveal, + "convert_weights_and_uids_for_emit", + return_value=(mocked_uids, mocked_weights), + ) + mocked_get_subnet_reveal_period_epochs = mocker.patch.object( + subtensor, "get_subnet_reveal_period_epochs" + ) + mocked_get_encrypted_commit = mocker.patch.object( + commit_reveal, + "get_encrypted_commit", + return_value=(fake_commit_for_reveal, fake_reveal_round), + ) + mock_do_commit_reveal_v3 = mocker.patch.object( + commit_reveal, "_do_commit_reveal_v3", return_value=(True, "Success") + ) + mock_block = mocker.patch.object(subtensor, "get_current_block", return_value=1) + mock_hyperparams = mocker.patch.object( + subtensor, + "get_subnet_hyperparameters", + return_value=hyperparams, + ) + + # Call + success, message = commit_reveal.commit_reveal_v3_extrinsic( + subtensor=subtensor, + wallet=fake_wallet, + netuid=fake_netuid, + uids=fake_uids, + weights=fake_weights, + wait_for_inclusion=True, + wait_for_finalization=True, + ) + + # Asserts + assert success is True + assert message == "reveal_round:1" + mocked_convert_weights_and_uids_for_emit.assert_called_once_with( + fake_uids, fake_weights + ) + mocked_get_encrypted_commit.assert_called_once_with( + uids=mocked_uids, + weights=mocked_weights, + subnet_reveal_period_epochs=mock_hyperparams.return_value.commit_reveal_weights_interval, + version_key=commit_reveal.version_as_int, + tempo=mock_hyperparams.return_value.tempo, + netuid=fake_netuid, + current_block=mock_block.return_value, + ) + mock_do_commit_reveal_v3.assert_called_once_with( + self=subtensor, + wallet=fake_wallet, + netuid=fake_netuid, + commit=fake_commit_for_reveal, + reveal_round=fake_reveal_round, + wait_for_inclusion=True, + wait_for_finalization=True, + ) + + def test_commit_reveal_v3_extrinsic_success_with_numpy(mocker, subtensor, hyperparams): """Test successful commit-reveal with numpy arrays.""" # Preps From f0be03d9748096b3d1e5ce792779ae556e633405 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 16 Dec 2024 19:23:47 +0200 Subject: [PATCH 11/16] Removed test that didn't do anything. --- .../extrinsics/test_async_weights.py | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/tests/unit_tests/extrinsics/test_async_weights.py b/tests/unit_tests/extrinsics/test_async_weights.py index 07de1e289b..da250afd94 100644 --- a/tests/unit_tests/extrinsics/test_async_weights.py +++ b/tests/unit_tests/extrinsics/test_async_weights.py @@ -278,42 +278,6 @@ async def test_set_weights_extrinsic_exception(subtensor, mocker): assert message == "Unexpected error" -@pytest.mark.asyncio -async def test_set_weights_extrinsic_if_use_torch(subtensor, mocker): - """Tests set_weights_extrinsic when use_torch is True.""" - # Preps - fake_wallet = mocker.Mock(autospec=Wallet) - fake_netuid = 1 - fake_uids = [1, 2, 3] - fake_weights = [0.1, 0.2, 0.7] - - mocked_do_set_weights = mocker.patch.object( - async_weights, "_do_set_weights", return_value=(False, "Test error message") - ) - mocked_convert_weights_and_uids_for_emit = mocker.patch.object( - async_weights.weight_utils, - "convert_weights_and_uids_for_emit", - return_value=(mocker.Mock(), mocker.Mock()), - ) - - # Call - result, message = await async_weights.set_weights_extrinsic( - subtensor=subtensor, - wallet=fake_wallet, - netuid=fake_netuid, - uids=fake_uids, - weights=fake_weights, - wait_for_inclusion=True, - wait_for_finalization=True, - ) - - # Asserts - mocked_do_set_weights.assert_called_once() - mocked_convert_weights_and_uids_for_emit.assert_called() - assert result is False - assert message == "Test error message" - - @pytest.mark.asyncio async def test_do_commit_weights_success(subtensor, mocker): """Tests _do_commit_weights when the commit is successful.""" From 58bc35bb355e2c5a8f902c68eed2d176a102ce33 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 16 Dec 2024 19:56:10 +0200 Subject: [PATCH 12/16] Optional arg fixed --- bittensor/utils/axon_utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bittensor/utils/axon_utils.py b/bittensor/utils/axon_utils.py index 3c73c8080d..d042358246 100644 --- a/bittensor/utils/axon_utils.py +++ b/bittensor/utils/axon_utils.py @@ -21,7 +21,9 @@ NANOSECONDS_IN_SECOND = 1_000_000_000 -def allowed_nonce_window_ns(current_time_ns: int, synapse_timeout: Optional[float]): +def allowed_nonce_window_ns( + current_time_ns: int, synapse_timeout: Optional[float] = None +) -> int: """ Calculates the allowed window for a nonce in nanoseconds. From 1de087079713f8defab04a38baf9a4df629b992a Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Tue, 17 Dec 2024 00:33:26 +0200 Subject: [PATCH 13/16] Correctly handle commit reveal enabled notimplemented in async_subtensor.py --- bittensor/core/async_subtensor.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bittensor/core/async_subtensor.py b/bittensor/core/async_subtensor.py index 23404499e3..2141055cca 100644 --- a/bittensor/core/async_subtensor.py +++ b/bittensor/core/async_subtensor.py @@ -1596,9 +1596,11 @@ async def set_weights( This function is crucial in shaping the network's collective intelligence, where each neuron's learning and contribution are influenced by the weights it sets towards others【81†source】. """ - if self.commit_reveal_enabled(netuid=netuid) is True: + if (await self.commit_reveal_enabled(netuid=netuid)) is True: # go with `commit reveal v3` extrinsic - raise NotImplemented("Not implemented yet for AsyncSubtensor. Coming soon.") + raise NotImplementedError( + "Not implemented yet for AsyncSubtensor. Coming soon." + ) else: # go with classic `set weights extrinsic` uid = await self.get_uid_for_hotkey_on_subnet( From 79ea823c6df1ce1e5f4d9052af10f138911acd99 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Mon, 16 Dec 2024 15:02:41 -0800 Subject: [PATCH 14/16] Adds retry in crv3 --- bittensor/core/subtensor.py | 39 ++++++++++++++++++++---------- tests/unit_tests/test_subtensor.py | 6 +++++ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 4b699f09d5..261221db4e 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -1812,23 +1812,36 @@ def set_weights( This function is crucial in shaping the network's collective intelligence, where each neuron's learning and contribution are influenced by the weights it sets towards others【81†source】. """ + retries = 0 + success = False + uid = self.get_uid_for_hotkey_on_subnet(wallet.hotkey.ss58_address, netuid) + if self.commit_reveal_enabled(netuid=netuid) is True: # go with `commit reveal v3` extrinsic - return commit_reveal_v3_extrinsic( - subtensor=self, - wallet=wallet, - netuid=netuid, - uids=uids, - weights=weights, - version_key=version_key, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - ) + message = "No attempt made. Perhaps it is too soon to commit weights!" + while ( + self.blocks_since_last_update(netuid, uid) + > self.weights_rate_limit(netuid) + and retries < max_retries + and success is False + ): + logging.info( + f"Committing weights for subnet #{netuid}. Attempt {retries + 1} of {max_retries}." + ) + success, message = commit_reveal_v3_extrinsic( + subtensor=self, + wallet=wallet, + netuid=netuid, + uids=uids, + weights=weights, + version_key=version_key, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + ) + retries += 1 + return success, message else: # go with classic `set weights` logic - uid = self.get_uid_for_hotkey_on_subnet(wallet.hotkey.ss58_address, netuid) - retries = 0 - success = False message = "No attempt made. Perhaps it is too soon to set weights!" while ( self.blocks_since_last_update(netuid, uid) # type: ignore diff --git a/tests/unit_tests/test_subtensor.py b/tests/unit_tests/test_subtensor.py index dea9d66ed0..bf156e2122 100644 --- a/tests/unit_tests/test_subtensor.py +++ b/tests/unit_tests/test_subtensor.py @@ -2850,6 +2850,12 @@ def test_set_weights_with_commit_reveal_enabled(subtensor, mocker): mocked_commit_reveal_v3_extrinsic = mocker.patch.object( subtensor_module, "commit_reveal_v3_extrinsic" ) + mocked_commit_reveal_v3_extrinsic.return_value = ( + True, + "Weights committed successfully", + ) + mocker.patch.object(subtensor, "blocks_since_last_update", return_value=181) + mocker.patch.object(subtensor, "weights_rate_limit", return_value=180) # Call result = subtensor.set_weights( From 67395431850c7a6d2283a83d2231b3c344accf14 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Mon, 16 Dec 2024 15:14:06 -0800 Subject: [PATCH 15/16] MyPy --- bittensor/core/subtensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 261221db4e..584ec3b23a 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -1820,8 +1820,8 @@ def set_weights( # go with `commit reveal v3` extrinsic message = "No attempt made. Perhaps it is too soon to commit weights!" while ( - self.blocks_since_last_update(netuid, uid) - > self.weights_rate_limit(netuid) + self.blocks_since_last_update(netuid, uid) # type: ignore + > self.weights_rate_limit(netuid) # type: ignore and retries < max_retries and success is False ): From 4c74af0cc83497ff6fa4b5f92252a122f75b6c6e Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Mon, 16 Dec 2024 15:37:59 -0800 Subject: [PATCH 16/16] Bumps version and changelog --- CHANGELOG.md | 13 +++++++++++++ VERSION | 2 +- bittensor/core/settings.py | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3819cdad38..0976792d33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 8.5.1 /2024-12-16 + +## What's Changed +* 8.5.0 bugfixes by @thewhaleking in https://github.com/opentensor/bittensor/pull/2541 +* Removes substrate call in format_error_message by @thewhaleking in https://github.com/opentensor/bittensor/pull/2542 +* Remove torch from the weights calls by @thewhaleking in https://github.com/opentensor/bittensor/pull/2543 +* optional arg fix by @thewhaleking in https://github.com/opentensor/bittensor/pull/2544 +* async cr3 not implemented by @thewhaleking in https://github.com/opentensor/bittensor/pull/2545 +* Backmerge master to staging 851 by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2546 +* Adds retry in CRv3 by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2547 + +**Full Changelog**: https://github.com/opentensor/bittensor/compare/v8.5.0...v8.5.1 + ## 8.5.0 /2024-12-12 ## What's Changed diff --git a/VERSION b/VERSION index 5eaed3b7ca..e0741a834a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.5.0 \ No newline at end of file +8.5.1 \ No newline at end of file diff --git a/bittensor/core/settings.py b/bittensor/core/settings.py index 2da8ecb5a1..04d94436ef 100644 --- a/bittensor/core/settings.py +++ b/bittensor/core/settings.py @@ -15,7 +15,7 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. -__version__ = "8.5.0" +__version__ = "8.5.1" import os import re