From 538995703cc19622bc093051308eadde0c8c97f7 Mon Sep 17 00:00:00 2001 From: Dairus01 Date: Sat, 27 Dec 2025 14:28:07 +0100 Subject: [PATCH 01/14] Clarify return ordering and units for get_revealed_commitment_by_hotkey --- bittensor/core/subtensor.py | 8 +++- tests/unit_tests/test_subtensor.py | 68 ++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 6862f3a1c4..2e80797d6c 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -3061,7 +3061,6 @@ def get_revealed_commitment_by_hotkey( hotkey_ss58: str, block: Optional[int] = None, ) -> Optional[tuple[tuple[int, str], ...]]: - # TODO: Clarify return ordering and units; add Examples """Retrieves hotkey related revealed commitment for a given subnet. Parameters: @@ -3070,8 +3069,13 @@ def get_revealed_commitment_by_hotkey( block: The block number to query. If `None`, queries the current chain head. Returns: - A tuple of reveal block and commitment message. + A tuple of tuples, where each inner tuple contains the reveal block number and the commitment message. + The return format is `((reveal_block, commitment_message), ...)`. + Example: + >>> subtensor.get_revealed_commitment_by_hotkey(netuid=1, hotkey_ss58="5C4hr...") + ((123, "commitment_string_1"), (150, "commitment_string_2")) + Notes: - """ diff --git a/tests/unit_tests/test_subtensor.py b/tests/unit_tests/test_subtensor.py index 0d70415874..c738fdc4d1 100644 --- a/tests/unit_tests/test_subtensor.py +++ b/tests/unit_tests/test_subtensor.py @@ -6430,3 +6430,71 @@ def test_mev_submit_encrypted_default_params(subtensor, fake_wallet, mocker): blocks_for_revealed_execution=3, ) assert result == mocked_submit_encrypted_extrinsic.return_value + +def test_get_revealed_commitment_by_hotkey_success(subtensor, mocker): + """Test get_revealed_commitment_by_hotkey returns correct structure.""" + + # Mock data + netuid = 1 + hotkey_ss58 = "5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM" + block = 123 + + # Mock the query response + # The query returns a list of tuples. Each tuple is (commitment_bytes, block_number) + # commitment_bytes structure: first byte is mode (offset), then commitment bytes. + # If mode is 0, offset is 1. + + # Example 1: block 100, message "hello" + commitment_1 = b'\x00' + b'hello' + block_1 = 100 + + # Example 2: block 150, message "world" + commitment_2 = b'\x00' + b'world' + block_2 = 150 + + mock_query_return = [ + (commitment_1, block_1), + (commitment_2, block_2) + ] + + mock_query_module = mocker.patch.object(subtensor, 'query_module', return_value=mock_query_return) + + result = subtensor.get_revealed_commitment_by_hotkey( + netuid=netuid, + hotkey_ss58=hotkey_ss58, + block=block + ) + + mock_query_module.assert_called_once_with( + module="Commitments", + name="RevealedCommitments", + params=[netuid, hotkey_ss58], + block=block, + ) + + # Verify result structure + assert isinstance(result, tuple) + assert len(result) == 2 + + # Order is preserved from the query result + assert result[0] == (100, "hello") + assert result[1] == (150, "world") + +def test_get_revealed_commitment_by_hotkey_invalid_address(subtensor): + """Test get_revealed_commitment_by_hotkey raises error for invalid address.""" + with pytest.raises(ValueError, match="Invalid ss58 address"): + subtensor.get_revealed_commitment_by_hotkey( + netuid=1, + hotkey_ss58="invalid_address" + ) + +def test_get_revealed_commitment_by_hotkey_none(subtensor, mocker): + """Test get_revealed_commitment_by_hotkey returns None when query returns None.""" + mocker.patch.object(subtensor, 'query_module', return_value=None) + + result = subtensor.get_revealed_commitment_by_hotkey( + netuid=1, + hotkey_ss58="5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM" + ) + + assert result is None From eeec6e4d43b33e21060f09db88dc58de7df40e8f Mon Sep 17 00:00:00 2001 From: Dairus Date: Sun, 28 Dec 2025 19:09:27 +0100 Subject: [PATCH 02/14] Add write permission for issues in workflow --- .github/workflows/monitor_requirements_size_master.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/monitor_requirements_size_master.yml b/.github/workflows/monitor_requirements_size_master.yml index 1cebb907e6..61d2763a03 100644 --- a/.github/workflows/monitor_requirements_size_master.yml +++ b/.github/workflows/monitor_requirements_size_master.yml @@ -12,6 +12,7 @@ on: permissions: pull-requests: write contents: read + issues: write jobs: read-python-versions: From c318f4cfd27112bbcb000a417dd5ddd9d7ad3ecb Mon Sep 17 00:00:00 2001 From: Dairus Date: Tue, 30 Dec 2025 00:26:03 -0800 Subject: [PATCH 03/14] Clarify return format in get_revealed_commitment_by_hotkey Updated docstring to clarify return format and removed example. --- bittensor/core/subtensor.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 2e80797d6c..7a36c9de0b 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -3061,6 +3061,7 @@ def get_revealed_commitment_by_hotkey( hotkey_ss58: str, block: Optional[int] = None, ) -> Optional[tuple[tuple[int, str], ...]]: + # TODO: Clarify return ordering and units; add Examples """Retrieves hotkey related revealed commitment for a given subnet. Parameters: @@ -3069,12 +3070,7 @@ def get_revealed_commitment_by_hotkey( block: The block number to query. If `None`, queries the current chain head. Returns: - A tuple of tuples, where each inner tuple contains the reveal block number and the commitment message. - The return format is `((reveal_block, commitment_message), ...)`. - - Example: - >>> subtensor.get_revealed_commitment_by_hotkey(netuid=1, hotkey_ss58="5C4hr...") - ((123, "commitment_string_1"), (150, "commitment_string_2")) + A tuple of reveal block and commitment message. Notes: - From 8fc34207c1780c356ec34a5927cac2bb5d6f8439 Mon Sep 17 00:00:00 2001 From: Dairus Date: Tue, 30 Dec 2025 00:28:34 -0800 Subject: [PATCH 04/14] Restore assertion in test_subtensor.py Restores assertion for result equality in the test case. --- tests/unit_tests/test_subtensor.py | 68 ------------------------------ 1 file changed, 68 deletions(-) diff --git a/tests/unit_tests/test_subtensor.py b/tests/unit_tests/test_subtensor.py index c738fdc4d1..0d70415874 100644 --- a/tests/unit_tests/test_subtensor.py +++ b/tests/unit_tests/test_subtensor.py @@ -6430,71 +6430,3 @@ def test_mev_submit_encrypted_default_params(subtensor, fake_wallet, mocker): blocks_for_revealed_execution=3, ) assert result == mocked_submit_encrypted_extrinsic.return_value - -def test_get_revealed_commitment_by_hotkey_success(subtensor, mocker): - """Test get_revealed_commitment_by_hotkey returns correct structure.""" - - # Mock data - netuid = 1 - hotkey_ss58 = "5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM" - block = 123 - - # Mock the query response - # The query returns a list of tuples. Each tuple is (commitment_bytes, block_number) - # commitment_bytes structure: first byte is mode (offset), then commitment bytes. - # If mode is 0, offset is 1. - - # Example 1: block 100, message "hello" - commitment_1 = b'\x00' + b'hello' - block_1 = 100 - - # Example 2: block 150, message "world" - commitment_2 = b'\x00' + b'world' - block_2 = 150 - - mock_query_return = [ - (commitment_1, block_1), - (commitment_2, block_2) - ] - - mock_query_module = mocker.patch.object(subtensor, 'query_module', return_value=mock_query_return) - - result = subtensor.get_revealed_commitment_by_hotkey( - netuid=netuid, - hotkey_ss58=hotkey_ss58, - block=block - ) - - mock_query_module.assert_called_once_with( - module="Commitments", - name="RevealedCommitments", - params=[netuid, hotkey_ss58], - block=block, - ) - - # Verify result structure - assert isinstance(result, tuple) - assert len(result) == 2 - - # Order is preserved from the query result - assert result[0] == (100, "hello") - assert result[1] == (150, "world") - -def test_get_revealed_commitment_by_hotkey_invalid_address(subtensor): - """Test get_revealed_commitment_by_hotkey raises error for invalid address.""" - with pytest.raises(ValueError, match="Invalid ss58 address"): - subtensor.get_revealed_commitment_by_hotkey( - netuid=1, - hotkey_ss58="invalid_address" - ) - -def test_get_revealed_commitment_by_hotkey_none(subtensor, mocker): - """Test get_revealed_commitment_by_hotkey returns None when query returns None.""" - mocker.patch.object(subtensor, 'query_module', return_value=None) - - result = subtensor.get_revealed_commitment_by_hotkey( - netuid=1, - hotkey_ss58="5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM" - ) - - assert result is None From 1fe3ae64a781f1700647b8d18ca29a582115ca61 Mon Sep 17 00:00:00 2001 From: Dairus Date: Tue, 30 Dec 2025 00:29:07 -0800 Subject: [PATCH 05/14] Update .github/workflows/monitor_requirements_size_master.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/monitor_requirements_size_master.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/monitor_requirements_size_master.yml b/.github/workflows/monitor_requirements_size_master.yml index 61d2763a03..af87292257 100644 --- a/.github/workflows/monitor_requirements_size_master.yml +++ b/.github/workflows/monitor_requirements_size_master.yml @@ -12,7 +12,7 @@ on: permissions: pull-requests: write contents: read - issues: write + issues: write jobs: read-python-versions: From 825d9c05c6a3c2b98d83ddcabd4ca886211daae6 Mon Sep 17 00:00:00 2001 From: Dairus Date: Tue, 30 Dec 2025 00:31:02 -0800 Subject: [PATCH 06/14] Update subtensor.py From 010ceedaa65d8e858c7860c00ef9329c51bff352 Mon Sep 17 00:00:00 2001 From: Roman <167799377+basfroman@users.noreply.github.com> Date: Tue, 30 Dec 2025 03:19:29 -0600 Subject: [PATCH 07/14] Update bittensor/core/subtensor.py --- bittensor/core/subtensor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 7a36c9de0b..24e5f6e814 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -3071,7 +3071,6 @@ def get_revealed_commitment_by_hotkey( Returns: A tuple of reveal block and commitment message. - Notes: - """ From 8135462aa8f39e0cb449610835eb5d3b15ec18c6 Mon Sep 17 00:00:00 2001 From: Roman <167799377+basfroman@users.noreply.github.com> Date: Tue, 30 Dec 2025 03:21:03 -0600 Subject: [PATCH 08/14] Update bittensor/core/subtensor.py --- bittensor/core/subtensor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 24e5f6e814..6862f3a1c4 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -3071,6 +3071,7 @@ def get_revealed_commitment_by_hotkey( Returns: A tuple of reveal block and commitment message. + Notes: - """ From 1f62fa73a0a5a3c05d7471e087c89216c1219387 Mon Sep 17 00:00:00 2001 From: Roman Ch Date: Tue, 30 Dec 2025 11:13:03 -0600 Subject: [PATCH 09/14] fix for async metagraph initialization --- bittensor/core/metagraph.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/bittensor/core/metagraph.py b/bittensor/core/metagraph.py index 633c139ea8..1d6017fb80 100644 --- a/bittensor/core/metagraph.py +++ b/bittensor/core/metagraph.py @@ -1391,7 +1391,7 @@ async def sync( await self._apply_extra_info(block=block) async def _initialize_subtensor( - self, subtensor: "AsyncSubtensor" + self, subtensor: Optional["AsyncSubtensor"] ) -> "AsyncSubtensor": """ Initializes the subtensor to be used for syncing the metagraph. @@ -1422,7 +1422,7 @@ async def _initialize_subtensor( # Lazy import due to circular import (subtensor -> metagraph, metagraph -> subtensor) from bittensor.core.async_subtensor import AsyncSubtensor - self.subtensor = AsyncSubtensor(network=self.chain_endpoint) + subtensor = AsyncSubtensor(network=self.chain_endpoint) await self.subtensor.initialize() self.subtensor = subtensor return subtensor @@ -1720,7 +1720,7 @@ def sync( # apply MetagraphInfo data to instance self._apply_extra_info(block=block) - def _initialize_subtensor(self, subtensor: "Subtensor") -> "Subtensor": + def _initialize_subtensor(self, subtensor: Optional["Subtensor"]) -> "Subtensor": """ Initializes the subtensor to be used for syncing the metagraph. @@ -1939,6 +1939,17 @@ async def async_metagraph( ) -> "AsyncMetagraph": """ Factory function to create an instantiated AsyncMetagraph, mainly for the ability to use sync at instantiation. + + Parameters: + netuid: The netuid of the subnet for which to create the AsyncMetagraph. + mechid: The mechid of the subnet for which to create the AsyncMetagraph. + network: The network to use for the AsyncMetagraph. + lite: Whether to use a lite version of the AsyncMetagraph. + sync: Whether to sync the AsyncMetagraph. + subtensor: The subtensor to use for the AsyncMetagraph. + + Returns: + AsyncMetagraph: The instantiated AsyncMetagraph. """ metagraph_ = AsyncMetagraph( netuid=netuid, From d58cddfda49b83bb2f98bc4ad83e557a4c19beae Mon Sep 17 00:00:00 2001 From: Roman Ch Date: Tue, 30 Dec 2025 11:59:59 -0600 Subject: [PATCH 10/14] correct `subtensor.initialize` --- bittensor/core/metagraph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittensor/core/metagraph.py b/bittensor/core/metagraph.py index 1d6017fb80..44f4a033c1 100644 --- a/bittensor/core/metagraph.py +++ b/bittensor/core/metagraph.py @@ -1423,7 +1423,7 @@ async def _initialize_subtensor( from bittensor.core.async_subtensor import AsyncSubtensor subtensor = AsyncSubtensor(network=self.chain_endpoint) - await self.subtensor.initialize() + await subtensor.initialize() self.subtensor = subtensor return subtensor From ef0658fe9f4153671842b800e8c48221626f3967 Mon Sep 17 00:00:00 2001 From: Roman Chkhaidze Date: Mon, 5 Jan 2026 14:35:29 -0800 Subject: [PATCH 11/14] skips user liquidity e2e test pending the rework --- tests/e2e_tests/test_liquidity.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/e2e_tests/test_liquidity.py b/tests/e2e_tests/test_liquidity.py index 3408b5ab22..674278ef14 100644 --- a/tests/e2e_tests/test_liquidity.py +++ b/tests/e2e_tests/test_liquidity.py @@ -9,6 +9,7 @@ ) +@pytest.mark.skip("Skips user liquidity e2e test pending the rework") def test_liquidity(subtensor, alice_wallet, bob_wallet): """ Tests the liquidity mechanism @@ -281,6 +282,7 @@ def test_liquidity(subtensor, alice_wallet, bob_wallet): logging.console.info("✅ Passed [blue]test_liquidity[/blue]") +@pytest.mark.skip("Skips user liquidity e2e test pending the rework") @pytest.mark.asyncio async def test_liquidity_async(async_subtensor, alice_wallet, bob_wallet): """ From 0ae1c319ac4164b989730c73bde3d85aa2d91243 Mon Sep 17 00:00:00 2001 From: Olexandr88 Date: Mon, 5 Jan 2026 11:48:08 +0200 Subject: [PATCH 12/14] chore: fix incorrect Optional type annotation in utils --- bittensor/utils/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bittensor/utils/__init__.py b/bittensor/utils/__init__.py index 419e00b79b..9d10f1f956 100644 --- a/bittensor/utils/__init__.py +++ b/bittensor/utils/__init__.py @@ -140,7 +140,7 @@ def strtobool(val: str) -> Union[bool, Literal["==SUPRESS=="]]: def _get_explorer_root_url_by_network_from_map( network: str, network_map: dict[str, dict[str, str]] -) -> Optional[dict[str, str]]: +) -> dict[str, str]: """ Returns the explorer root url for the given network name from the given network map. @@ -151,7 +151,7 @@ def _get_explorer_root_url_by_network_from_map( Returns: The explorer url for the given network. Or None if the network is not in the network map. """ - explorer_urls: Optional[dict[str, str]] = {} + explorer_urls: dict[str, str] = {} for entity_nm, entity_network_map in network_map.items(): if network in entity_network_map: explorer_urls[entity_nm] = entity_network_map[network] @@ -161,7 +161,7 @@ def _get_explorer_root_url_by_network_from_map( def get_explorer_url_for_network( network: str, block_hash: str, network_map: dict[str, dict[str, str]] -) -> Optional[dict[str, str]]: +) -> dict[str, str]: """ Returns the explorer url for the given block hash and network. @@ -174,9 +174,9 @@ def get_explorer_url_for_network( The explorer url for the given block hash and network. Or None if the network is not known. """ - explorer_urls: Optional[dict[str, str]] = {} - # Will be None if the network is not known. i.e. not in network_map - explorer_root_urls: Optional[dict[str, str]] = ( + explorer_urls: dict[str, str] = {} + + explorer_root_urls: dict[str, str] = ( _get_explorer_root_url_by_network_from_map(network, network_map) ) From 72994b612001c2de68d1769ab8d2fdc120dcda73 Mon Sep 17 00:00:00 2001 From: Olexandr88 Date: Thu, 8 Jan 2026 09:26:05 +0200 Subject: [PATCH 13/14] chore: run make check --- bittensor/utils/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bittensor/utils/__init__.py b/bittensor/utils/__init__.py index 9d10f1f956..1dd9fd205c 100644 --- a/bittensor/utils/__init__.py +++ b/bittensor/utils/__init__.py @@ -176,8 +176,8 @@ def get_explorer_url_for_network( explorer_urls: dict[str, str] = {} - explorer_root_urls: dict[str, str] = ( - _get_explorer_root_url_by_network_from_map(network, network_map) + explorer_root_urls: dict[str, str] = _get_explorer_root_url_by_network_from_map( + network, network_map ) if explorer_root_urls != {}: From 20b279040a8d88ae5c71588ae1e8811bb8f3a285 Mon Sep 17 00:00:00 2001 From: Olexandr88 Date: Fri, 9 Jan 2026 10:59:17 +0200 Subject: [PATCH 14/14] chore: remove unused test helper --- tests/helpers/__init__.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/helpers/__init__.py b/tests/helpers/__init__.py index 9097d72d70..7aed5c7ad3 100644 --- a/tests/helpers/__init__.py +++ b/tests/helpers/__init__.py @@ -9,8 +9,3 @@ get_mock_keypair, get_mock_wallet, ) - - -def is_running_in_circleci(): - """Checks that tests are running in the app.circleci.com environment.""" - return os.getenv("CIRCLECI") == "true"