Skip to content

Commit dbbfbc0

Browse files
authored
Merge branch 'staging' into backmerge/9.7.1
2 parents be9808d + bfd53bd commit dbbfbc0

File tree

8 files changed

+421
-174
lines changed

8 files changed

+421
-174
lines changed

bittensor/core/async_subtensor.py

Lines changed: 136 additions & 85 deletions
Large diffs are not rendered by default.

bittensor/core/settings.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@
126126
"_mock": False,
127127
},
128128
"wallet": {
129-
"name": "default",
130-
"hotkey": "default",
131-
"path": str(WALLETS_DIR),
129+
"name": os.getenv("BT_WALLET_NAME") or "default",
130+
"hotkey": os.getenv("BT_WALLET_HOTKEY") or "default",
131+
"path": os.getenv("BT_WALLET_PATH") or str(WALLETS_DIR),
132132
},
133133
}
134134
)

bittensor/core/subtensor.py

Lines changed: 127 additions & 85 deletions
Large diffs are not rendered by default.

bittensor/core/subtensor_api/subnets.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def __init__(self, subtensor: Union["_Subtensor", "_AsyncSubtensor"]):
1414
self.bonds = subtensor.bonds
1515
self.difficulty = subtensor.difficulty
1616
self.get_all_subnets_info = subtensor.get_all_subnets_info
17+
self.get_parents = subtensor.get_parents
1718
self.get_children = subtensor.get_children
1819
self.get_children_pending = subtensor.get_children_pending
1920
self.get_current_weight_commit_info = subtensor.get_current_weight_commit_info

bittensor/core/subtensor_api/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def add_legacy_methods(subtensor: "SubtensorApi"):
3636
subtensor.get_balance = subtensor._subtensor.get_balance
3737
subtensor.get_balances = subtensor._subtensor.get_balances
3838
subtensor.get_block_hash = subtensor._subtensor.get_block_hash
39+
subtensor.get_parents = subtensor._subtensor.get_parents
3940
subtensor.get_children = subtensor._subtensor.get_children
4041
subtensor.get_children_pending = subtensor._subtensor.get_children_pending
4142
subtensor.get_commitment = subtensor._subtensor.get_commitment

tests/e2e_tests/test_hotkeys.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def test_hotkeys(subtensor, alice_wallet, dave_wallet):
6969
)
7070
is True
7171
)
72-
logging.console.success(f"✅ Test [green]test_hotkeys[/green] passed")
72+
logging.console.success("✅ Test [green]test_hotkeys[/green] passed")
7373

7474

7575
@pytest.mark.asyncio
@@ -276,6 +276,10 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w
276276
assert success is True
277277
assert children == [(1.0, bob_wallet.hotkey.ss58_address)]
278278

279+
parent_ = subtensor.get_parents(bob_wallet.hotkey.ss58_address, dave_subnet_netuid)
280+
281+
assert parent_ == [(1.0, alice_wallet.hotkey.ss58_address)]
282+
279283
# pending queue is empty
280284
pending, cooldown = subtensor.get_children_pending(
281285
alice_wallet.hotkey.ss58_address,

tests/unit_tests/test_async_subtensor.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,6 +1981,90 @@ async def test_get_children_substrate_request_exception(subtensor, mocker):
19811981
assert result == (False, [], "Formatted error message")
19821982

19831983

1984+
@pytest.mark.asyncio
1985+
async def test_get_parents_success(subtensor, mocker):
1986+
"""Tests get_parents when parents are successfully retrieved and formatted."""
1987+
# Preps
1988+
fake_hotkey = "valid_hotkey"
1989+
fake_netuid = 1
1990+
fake_parents = mocker.Mock(
1991+
value=[
1992+
(1000, ["parent_key_1"]),
1993+
(2000, ["parent_key_2"]),
1994+
]
1995+
)
1996+
1997+
mocked_query = mocker.AsyncMock(return_value=fake_parents)
1998+
subtensor.substrate.query = mocked_query
1999+
2000+
mocked_decode_account_id = mocker.Mock(
2001+
side_effect=["decoded_parent_key_1", "decoded_parent_key_2"]
2002+
)
2003+
mocker.patch.object(async_subtensor, "decode_account_id", mocked_decode_account_id)
2004+
2005+
expected_formatted_parents = [
2006+
(u64_normalized_float(1000), "decoded_parent_key_1"),
2007+
(u64_normalized_float(2000), "decoded_parent_key_2"),
2008+
]
2009+
2010+
# Call
2011+
result = await subtensor.get_parents(hotkey=fake_hotkey, netuid=fake_netuid)
2012+
2013+
# Asserts
2014+
mocked_query.assert_called_once_with(
2015+
block_hash=None,
2016+
module="SubtensorModule",
2017+
storage_function="ParentKeys",
2018+
params=[fake_hotkey, fake_netuid],
2019+
reuse_block_hash=False,
2020+
)
2021+
mocked_decode_account_id.assert_has_calls(
2022+
[mocker.call("parent_key_1"), mocker.call("parent_key_2")]
2023+
)
2024+
assert result == expected_formatted_parents
2025+
2026+
2027+
@pytest.mark.asyncio
2028+
async def test_get_parents_no_parents(subtensor, mocker):
2029+
"""Tests get_parents when there are no parents to retrieve."""
2030+
# Preps
2031+
fake_hotkey = "valid_hotkey"
2032+
fake_netuid = 1
2033+
fake_parents = []
2034+
2035+
mocked_query = mocker.AsyncMock(return_value=fake_parents)
2036+
subtensor.substrate.query = mocked_query
2037+
2038+
# Call
2039+
result = await subtensor.get_parents(hotkey=fake_hotkey, netuid=fake_netuid)
2040+
2041+
# Asserts
2042+
mocked_query.assert_called_once_with(
2043+
block_hash=None,
2044+
module="SubtensorModule",
2045+
storage_function="ParentKeys",
2046+
params=[fake_hotkey, fake_netuid],
2047+
reuse_block_hash=False,
2048+
)
2049+
assert result == []
2050+
2051+
2052+
@pytest.mark.asyncio
2053+
async def test_get_parents_substrate_request_exception(subtensor, mocker):
2054+
"""Tests get_parents when SubstrateRequestException is raised."""
2055+
# Preps
2056+
fake_hotkey = "valid_hotkey"
2057+
fake_netuid = 1
2058+
fake_exception = async_subtensor.SubstrateRequestException("Test Exception")
2059+
2060+
mocked_query = mocker.AsyncMock(side_effect=fake_exception)
2061+
subtensor.substrate.query = mocked_query
2062+
2063+
# Call
2064+
with pytest.raises(async_subtensor.SubstrateRequestException):
2065+
await subtensor.get_parents(hotkey=fake_hotkey, netuid=fake_netuid)
2066+
2067+
19842068
@pytest.mark.asyncio
19852069
async def test_get_children_pending(mock_substrate, subtensor):
19862070
mock_substrate.query.return_value.value = [

tests/unit_tests/test_subtensor.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3746,3 +3746,67 @@ def test_get_next_epoch_start_block(mocker, subtensor, call_return, expected):
37463746
)
37473747
subtensor.tempo.assert_called_once_with(netuid=netuid, block=block)
37483748
assert result == expected
3749+
3750+
3751+
def test_get_parents_success(subtensor, mocker):
3752+
"""Tests get_parents when parents are successfully retrieved and formatted."""
3753+
# Preps
3754+
fake_hotkey = "valid_hotkey"
3755+
fake_netuid = 1
3756+
fake_parents = mocker.Mock(
3757+
value=[
3758+
(1000, ["parent_key_1"]),
3759+
(2000, ["parent_key_2"]),
3760+
]
3761+
)
3762+
3763+
mocked_query = mocker.MagicMock(return_value=fake_parents)
3764+
subtensor.substrate.query = mocked_query
3765+
3766+
mocked_decode_account_id = mocker.Mock(
3767+
side_effect=["decoded_parent_key_1", "decoded_parent_key_2"]
3768+
)
3769+
mocker.patch.object(subtensor_module, "decode_account_id", mocked_decode_account_id)
3770+
3771+
expected_formatted_parents = [
3772+
(u64_normalized_float(1000), "decoded_parent_key_1"),
3773+
(u64_normalized_float(2000), "decoded_parent_key_2"),
3774+
]
3775+
3776+
# Call
3777+
result = subtensor.get_parents(hotkey=fake_hotkey, netuid=fake_netuid)
3778+
3779+
# Asserts
3780+
mocked_query.assert_called_once_with(
3781+
block_hash=None,
3782+
module="SubtensorModule",
3783+
storage_function="ParentKeys",
3784+
params=[fake_hotkey, fake_netuid],
3785+
)
3786+
mocked_decode_account_id.assert_has_calls(
3787+
[mocker.call("parent_key_1"), mocker.call("parent_key_2")]
3788+
)
3789+
assert result == expected_formatted_parents
3790+
3791+
3792+
def test_get_parents_no_parents(subtensor, mocker):
3793+
"""Tests get_parents when there are no parents to retrieve."""
3794+
# Preps
3795+
fake_hotkey = "valid_hotkey"
3796+
fake_netuid = 1
3797+
fake_parents = []
3798+
3799+
mocked_query = mocker.MagicMock(return_value=fake_parents)
3800+
subtensor.substrate.query = mocked_query
3801+
3802+
# Call
3803+
result = subtensor.get_parents(hotkey=fake_hotkey, netuid=fake_netuid)
3804+
3805+
# Asserts
3806+
mocked_query.assert_called_once_with(
3807+
block_hash=None,
3808+
module="SubtensorModule",
3809+
storage_function="ParentKeys",
3810+
params=[fake_hotkey, fake_netuid],
3811+
)
3812+
assert result == []

0 commit comments

Comments
 (0)