Skip to content

Commit 66409e9

Browse files
authored
Merge branch 'staging' into fix/2188-configure_uvicorn_event_loop
2 parents e6f2f14 + 4c6cfd2 commit 66409e9

File tree

6 files changed

+99
-2
lines changed

6 files changed

+99
-2
lines changed

bittensor/core/async_subtensor.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,41 @@ async def get_neuron_certificate(
14791479
return None
14801480
return None
14811481

1482+
async def get_all_neuron_certificates(
1483+
self,
1484+
netuid: int,
1485+
block: Optional[int] = None,
1486+
block_hash: Optional[str] = None,
1487+
reuse_block: bool = False,
1488+
) -> dict[str, Certificate]:
1489+
"""
1490+
Retrieves the TLS certificates for neurons within a specified subnet (netuid) of the Bittensor network.
1491+
1492+
Arguments:
1493+
netuid: The unique identifier of the subnet.
1494+
block: The blockchain block number for the query.
1495+
block_hash: The hash of the block to retrieve the parameter from. Do not specify if using block or
1496+
reuse_block.
1497+
reuse_block: Whether to use the last-used block. Do not set if using block_hash or block.
1498+
1499+
Returns:
1500+
{ss58: Certificate} for the key/Certificate pairs on the subnet
1501+
1502+
This function is used for certificate discovery for setting up mutual tls communication between neurons.
1503+
"""
1504+
query_certificates = await self.query_map(
1505+
module="SubtensorModule",
1506+
name="NeuronCertificates",
1507+
params=[netuid],
1508+
block=block,
1509+
block_hash=block_hash,
1510+
reuse_block=reuse_block,
1511+
)
1512+
output = {}
1513+
async for key, item in query_certificates:
1514+
output[decode_account_id(key)] = Certificate(item.value)
1515+
return output
1516+
14821517
async def get_neuron_for_pubkey_and_subnet(
14831518
self,
14841519
hotkey_ss58: str,

bittensor/core/subtensor.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,32 @@ def get_neuron_certificate(
11231123
return None
11241124
return None
11251125

1126+
def get_all_neuron_certificates(
1127+
self, netuid: int, block: Optional[int] = None
1128+
) -> dict[str, Certificate]:
1129+
"""
1130+
Retrieves the TLS certificates for neurons within a specified subnet (netuid) of the Bittensor network.
1131+
1132+
Arguments:
1133+
netuid: The unique identifier of the subnet.
1134+
block: The blockchain block number for the query.
1135+
1136+
Returns:
1137+
{ss58: Certificate} for the key/Certificate pairs on the subnet
1138+
1139+
This function is used for certificate discovery for setting up mutual tls communication between neurons.
1140+
"""
1141+
query_certificates = self.query_map(
1142+
module="SubtensorModule",
1143+
name="NeuronCertificates",
1144+
params=[netuid],
1145+
block=block,
1146+
)
1147+
output = {}
1148+
for key, item in query_certificates:
1149+
output[decode_account_id(key)] = Certificate(item.value)
1150+
return output
1151+
11261152
def get_neuron_for_pubkey_and_subnet(
11271153
self, hotkey_ss58: str, netuid: int, block: Optional[int] = None
11281154
) -> Optional["NeuronInfo"]:

bittensor/utils/balance.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,13 @@ def __float__(self):
5353
return self.tao
5454

5555
def __str__(self):
56-
"""Returns the Balance object as a string in the format "symbolvalue", where the value is in tao."""
57-
return f"{self.unit}{float(self.tao):,.9f}"
56+
"""
57+
Returns the Balance object as a string in the format "symbolvalue", where the value is in tao.
58+
"""
59+
if self.unit == units[0]:
60+
return f"{self.unit}{float(self.tao):,.9f}"
61+
else:
62+
return f"\u200e{float(self.tao):,.9f}{self.unit}\u200e"
5863

5964
def __rich__(self):
6065
int_tao, fract_tao = format(float(self.tao), "f").split(".")

tests/e2e_tests/test_neuron_certificate.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,8 @@ async def test_neuron_certificate(subtensor, alice_wallet):
4747
)
4848
== encoded_certificate
4949
)
50+
all_certs_query = subtensor.get_all_neuron_certificates(netuid=netuid)
51+
assert alice_wallet.hotkey.ss58_address in all_certs_query.keys()
52+
assert all_certs_query[alice_wallet.hotkey.ss58_address] == encoded_certificate
5053

5154
logging.info("✅ Passed test_neuron_certificate")

tests/unit_tests/test_async_subtensor.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2676,3 +2676,18 @@ async def test_set_subnet_identity(mocker, subtensor):
26762676
wait_for_inclusion=False,
26772677
)
26782678
assert result == mocked_extrinsic.return_value
2679+
2680+
2681+
@pytest.mark.asyncio
2682+
async def test_get_all_neuron_certificates(mocker, subtensor):
2683+
fake_netuid = 12
2684+
mocked_query_map_subtensor = mocker.AsyncMock()
2685+
mocker.patch.object(subtensor.substrate, "query_map", mocked_query_map_subtensor)
2686+
await subtensor.get_all_neuron_certificates(fake_netuid)
2687+
mocked_query_map_subtensor.assert_awaited_once_with(
2688+
module="SubtensorModule",
2689+
storage_function="NeuronCertificates",
2690+
params=[fake_netuid],
2691+
block_hash=None,
2692+
reuse_block_hash=False,
2693+
)

tests/unit_tests/test_subtensor.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3060,3 +3060,16 @@ def test_set_subnet_identity(mocker, subtensor):
30603060
wait_for_inclusion=False,
30613061
)
30623062
assert result == mocked_extrinsic.return_value
3063+
3064+
3065+
def test_get_all_neuron_certificates(mocker, subtensor):
3066+
fake_netuid = 12
3067+
mocked_query_map_subtensor = mocker.MagicMock()
3068+
mocker.patch.object(subtensor.substrate, "query_map", mocked_query_map_subtensor)
3069+
subtensor.get_all_neuron_certificates(fake_netuid)
3070+
mocked_query_map_subtensor.assert_called_once_with(
3071+
module="SubtensorModule",
3072+
storage_function="NeuronCertificates",
3073+
params=[fake_netuid],
3074+
block_hash=None,
3075+
)

0 commit comments

Comments
 (0)