Skip to content

Commit e4a033a

Browse files
Merge branch 'staging' into tests/zyzniewski/more_e2e_tests
2 parents 42bbd9f + 7d511a4 commit e4a033a

File tree

9 files changed

+113
-6
lines changed

9 files changed

+113
-6
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/chain_data/metagraph_info.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from dataclasses import dataclass
22
from typing import Optional, Union
33

4+
from bittensor.core import settings
45
from bittensor.core.chain_data.axon_info import AxonInfo
56
from bittensor.core.chain_data.chain_identity import ChainIdentity
67
from bittensor.core.chain_data.info_base import InfoBase
@@ -234,7 +235,10 @@ def _from_dict(cls, decoded: dict) -> "MetagraphInfo":
234235
rank=[u16tf(rk) for rk in decoded.get("rank", [])],
235236
block_at_registration=decoded["block_at_registration"],
236237
alpha_stake=[_tbwu(ast, _netuid) for ast in decoded["alpha_stake"]],
237-
tao_stake=[_tbwu(ts) for ts in decoded["tao_stake"]],
238+
tao_stake=[
239+
_tbwu(ts) * settings.ROOT_TAO_STAKE_WEIGHT
240+
for ts in decoded["tao_stake"]
241+
],
238242
total_stake=[_tbwu(ts, _netuid) for ts in decoded["total_stake"]],
239243
# Dividend break down
240244
tao_dividends_per_hotkey=[

bittensor/core/metagraph.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242

4343

4444
Tensor = Union["torch.nn.Parameter", NDArray]
45-
ROOT_TAO_STAKES_WEIGHT = 0.18
4645

4746

4847
METAGRAPH_STATE_DICT_NDARRAY_KEYS = [
@@ -1598,7 +1597,10 @@ async def _get_all_stakes_from_chain(self):
15981597
dtype=self._dtype_registry["float32"],
15991598
)
16001599
self.tao_stake = self._create_tensor(
1601-
[b.tao * ROOT_TAO_STAKES_WEIGHT for b in subnet_state.tao_stake],
1600+
[
1601+
b.tao * settings.ROOT_TAO_STAKE_WEIGHT
1602+
for b in subnet_state.tao_stake
1603+
],
16021604
dtype=self._dtype_registry["float32"],
16031605
)
16041606
self.total_stake = self.stake = self._create_tensor(
@@ -1902,7 +1904,10 @@ def _get_all_stakes_from_chain(self):
19021904
dtype=self._dtype_registry["float32"],
19031905
)
19041906
self.tao_stake = self._create_tensor(
1905-
[b.tao * ROOT_TAO_STAKES_WEIGHT for b in subnet_state.tao_stake],
1907+
[
1908+
b.tao * settings.ROOT_TAO_STAKE_WEIGHT
1909+
for b in subnet_state.tao_stake
1910+
],
19061911
dtype=self._dtype_registry["float32"],
19071912
)
19081913
self.total_stake = self.stake = self._create_tensor(

bittensor/core/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from munch import munchify
88

9+
ROOT_TAO_STAKE_WEIGHT = 0.18
910

1011
READ_ONLY = os.getenv("READ_ONLY") == "1"
1112

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
@@ -48,5 +48,8 @@ async def test_neuron_certificate(subtensor, alice_wallet):
4848
)
4949
== encoded_certificate
5050
)
51+
all_certs_query = subtensor.get_all_neuron_certificates(netuid=netuid)
52+
assert alice_wallet.hotkey.ss58_address in all_certs_query.keys()
53+
assert all_certs_query[alice_wallet.hotkey.ss58_address] == encoded_certificate
5154

5255
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)