Skip to content

Commit 1a4da29

Browse files
authored
Merge pull request #2612 from opentensor/feat/roman/fix-unit-tests+refactoring
[RAO] fix for unit test + refactoring
2 parents ec32d9f + 8385a85 commit 1a4da29

File tree

17 files changed

+228
-141
lines changed

17 files changed

+228
-141
lines changed

bittensor/core/async_subtensor.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
u16_normalized_float,
7777
_decode_hex_identity_dict,
7878
)
79-
from bittensor.utils.balance import Balance, fixed_to_float, FixedPoint
79+
from bittensor.utils.balance import Balance, fixed_to_float
8080
from bittensor.utils.btlogging import logging
8181
from bittensor.utils.delegates_details import DelegatesDetails
8282
from bittensor.utils.weight_utils import generate_weight_hash
@@ -822,6 +822,8 @@ async def get_balance(
822822
)
823823
return Balance(balance["data"]["free"])
824824

825+
balance = get_balance
826+
825827
async def get_balances(
826828
self,
827829
*addresses: str,
@@ -1501,7 +1503,7 @@ async def get_stake(
15011503
block_hash = await self.determine_block_hash(block, block_hash, reuse_block)
15021504

15031505
# Get alpha shares
1504-
alpha_shares: FixedPoint = await self.query_module(
1506+
alpha_shares = await self.query_module(
15051507
module="SubtensorModule",
15061508
name="Alpha",
15071509
block_hash=block_hash,
@@ -1520,7 +1522,7 @@ async def get_stake(
15201522
hotkey_alpha: int = getattr(hotkey_alpha_result, "value", 0)
15211523

15221524
# Get total hotkey shares
1523-
hotkey_shares: FixedPoint = await self.query_module(
1525+
hotkey_shares = await self.query_module(
15241526
module="SubtensorModule",
15251527
name="TotalHotkeyShares",
15261528
block_hash=block_hash,
@@ -1541,20 +1543,28 @@ async def get_stake(
15411543
get_stake_for_coldkey_and_hotkey = get_stake
15421544

15431545
async def get_stake_for_coldkey(
1544-
self, coldkey_ss58: str, block: Optional[int] = None
1546+
self,
1547+
coldkey_ss58: str,
1548+
block: Optional[int] = None,
1549+
block_hash: Optional[str] = None,
1550+
reuse_block: bool = False,
15451551
) -> Optional[list["StakeInfo"]]:
15461552
"""
15471553
Retrieves the stake information for a given coldkey.
15481554
15491555
Args:
15501556
coldkey_ss58 (str): The SS58 address of the coldkey.
15511557
block (Optional[int]): The block number at which to query the stake information.
1558+
block_hash (Optional[str]): The hash of the blockchain block number for the query.
1559+
reuse_block (bool): Whether to reuse the last-used block hash.
15521560
15531561
Returns:
15541562
Optional[list[StakeInfo]]: A list of StakeInfo objects, or ``None`` if no stake information is found.
15551563
"""
15561564
encoded_coldkey = ss58_to_vec_u8(coldkey_ss58)
1557-
block_hash = await self.determine_block_hash(block)
1565+
block_hash = await self.determine_block_hash(
1566+
block=block, block_hash=block_hash, reuse_block=reuse_block
1567+
)
15581568

15591569
hex_bytes_result = await self.query_runtime_api(
15601570
runtime_api="StakeInfoRuntimeApi",
@@ -3455,7 +3465,7 @@ async def transfer(
34553465
self,
34563466
wallet: "Wallet",
34573467
dest: str,
3458-
amount: Union["Balance", float],
3468+
amount: "Balance",
34593469
transfer_all: bool = False,
34603470
wait_for_inclusion: bool = True,
34613471
wait_for_finalization: bool = False,
@@ -3506,6 +3516,7 @@ async def unstake(
35063516
wallet (bittensor_wallet.wallet): The wallet associated with the neuron from which the stake is being
35073517
removed.
35083518
hotkey_ss58 (Optional[str]): The ``SS58`` address of the hotkey account to unstake from.
3519+
netuid (Optional[int]): Subnet unique ID.
35093520
amount (Balance): The amount of TAO to unstake. If not specified, unstakes all.
35103521
wait_for_inclusion (bool): Waits for the transaction to be included in a block.
35113522
wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain.
@@ -3543,6 +3554,7 @@ async def unstake_multiple(
35433554
wallet (bittensor_wallet.Wallet): The wallet linked to the coldkey from which the stakes are being
35443555
withdrawn.
35453556
hotkey_ss58s (List[str]): A list of hotkey ``SS58`` addresses to unstake from.
3557+
netuids (list[int]): Subnets unique IDs.
35463558
amounts (List[Union[Balance, float]]): The amounts of TAO to unstake from each hotkey. If not provided,
35473559
unstakes all available stakes.
35483560
wait_for_inclusion (bool): Waits for the transaction to be included in a block.

bittensor/core/extrinsics/asyncex/move_stake.py

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55

66
if TYPE_CHECKING:
77
from bittensor_wallet import Wallet
8-
from bittensor.core.subtensor import Subtensor
8+
from bittensor.core.async_subtensor import AsyncSubtensor
99

1010

1111
async def transfer_stake_extrinsic(
12-
subtensor: "Subtensor",
12+
subtensor: "AsyncSubtensor",
1313
wallet: "Wallet",
1414
destination_coldkey_ss58: str,
1515
hotkey_ss58: str,
@@ -19,6 +19,24 @@ async def transfer_stake_extrinsic(
1919
wait_for_inclusion: bool = True,
2020
wait_for_finalization: bool = False,
2121
) -> bool:
22+
"""
23+
Transfers stake from one coldkey to another in the Bittensor network.
24+
25+
Args:
26+
subtensor (AsyncSubtensor): The subtensor instance to interact with the blockchain.
27+
wallet (Wallet): The wallet containing the coldkey to authorize the transfer.
28+
destination_coldkey_ss58 (str): SS58 address of the destination coldkey.
29+
hotkey_ss58 (str): SS58 address of the hotkey associated with the stake.
30+
origin_netuid (int): Network UID of the origin subnet.
31+
destination_netuid (int): Network UID of the destination subnet.
32+
amount (Balance): The amount of stake to transfer as a `Balance` object.
33+
wait_for_inclusion (bool): If True, waits for transaction inclusion in a block. Defaults to `True`.
34+
wait_for_finalization (bool): If True, waits for transaction finalization. Defaults to `False`.
35+
36+
Returns:
37+
bool: True if the transfer was successful, False otherwise.
38+
"""
39+
2240
amount.set_unit(netuid=origin_netuid)
2341
# Verify ownership
2442
hotkey_owner = await subtensor.get_hotkey_owner(hotkey_ss58)
@@ -107,7 +125,7 @@ async def transfer_stake_extrinsic(
107125

108126

109127
async def swap_stake_extrinsic(
110-
subtensor: "Subtensor",
128+
subtensor: "AsyncSubtensor",
111129
wallet: "Wallet",
112130
hotkey_ss58: str,
113131
origin_netuid: int,
@@ -116,6 +134,22 @@ async def swap_stake_extrinsic(
116134
wait_for_inclusion: bool = True,
117135
wait_for_finalization: bool = False,
118136
) -> bool:
137+
"""
138+
Swaps stake from one subnet to another for a given hotkey in the Bittensor network.
139+
140+
Args:
141+
subtensor (AsyncSubtensor): The subtensor instance to interact with the blockchain.
142+
wallet (Wallet): The wallet containing the coldkey to authorize the swap.
143+
hotkey_ss58 (str): SS58 address of the hotkey associated with the stake.
144+
origin_netuid (int): Network UID of the origin subnet.
145+
destination_netuid (int): Network UID of the destination subnet.
146+
amount (Balance): The amount of stake to swap as a `Balance` object.
147+
wait_for_inclusion (bool): If True, waits for transaction inclusion in a block. Defaults to True.
148+
wait_for_finalization (bool): If True, waits for transaction finalization. Defaults to False.
149+
150+
Returns:
151+
bool: True if the swap was successful, False otherwise.
152+
"""
119153
amount.set_unit(netuid=origin_netuid)
120154
# Verify ownership
121155
hotkey_owner = await subtensor.get_hotkey_owner(hotkey_ss58)
@@ -203,7 +237,7 @@ async def swap_stake_extrinsic(
203237

204238

205239
async def move_stake_extrinsic(
206-
subtensor: "Subtensor",
240+
subtensor: "AsyncSubtensor",
207241
wallet: "Wallet",
208242
origin_hotkey: str,
209243
origin_netuid: int,
@@ -213,6 +247,23 @@ async def move_stake_extrinsic(
213247
wait_for_inclusion: bool = True,
214248
wait_for_finalization: bool = False,
215249
) -> bool:
250+
"""
251+
Moves stake from one hotkey to another within subnets in the Bittensor network.
252+
253+
Args:
254+
subtensor (Subtensor): The subtensor instance to interact with the blockchain.
255+
wallet (Wallet): The wallet containing the coldkey to authorize the move.
256+
origin_hotkey (str): SS58 address of the origin hotkey associated with the stake.
257+
origin_netuid (int): Network UID of the origin subnet.
258+
destination_hotkey (str): SS58 address of the destination hotkey.
259+
destination_netuid (int): Network UID of the destination subnet.
260+
amount (Balance): The amount of stake to move as a `Balance` object.
261+
wait_for_inclusion (bool): If True, waits for transaction inclusion in a block. Defaults to True.
262+
wait_for_finalization (bool): If True, waits for transaction finalization. Defaults to False.
263+
264+
Returns:
265+
bool: True if the move was successful, False otherwise.
266+
"""
216267
amount.set_unit(netuid=origin_netuid)
217268
# Verify ownership of origin hotkey
218269
origin_owner = await subtensor.get_hotkey_owner(origin_hotkey)

bittensor/core/extrinsics/asyncex/staking.py

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from bittensor.utils import unlock_key
66
from bittensor.utils.balance import Balance
77
from bittensor.utils.btlogging import logging
8+
from bittensor.core.extrinsics.utils import get_old_stakes
89

910
if TYPE_CHECKING:
1011
from bittensor_wallet import Wallet
@@ -184,27 +185,6 @@ async def add_stake_multiple_extrinsic(
184185
success: `True` if extrinsic was finalized or included in the block. `True` if any wallet was staked. If we did
185186
not wait for finalization/inclusion, the response is `True`.
186187
"""
187-
188-
async def get_old_stakes() -> list[Balance]:
189-
old_stakes = []
190-
all_stakes = await subtensor.get_stake_for_coldkey(
191-
coldkey_ss58=wallet.coldkeypub.ss58_address,
192-
)
193-
for hotkey_ss58, netuid in zip(hotkey_ss58s, netuids):
194-
stake = next(
195-
(
196-
stake.stake
197-
for stake in all_stakes
198-
if stake.hotkey_ss58 == hotkey_ss58
199-
and stake.coldkey_ss58 == wallet.coldkeypub.ss58_address
200-
and stake.netuid == netuid
201-
),
202-
Balance.from_tao(0), # Default to 0 balance if no match found
203-
)
204-
old_stakes.append(stake)
205-
206-
return old_stakes
207-
208188
if not isinstance(hotkey_ss58s, list) or not all(
209189
isinstance(hotkey_ss58, str) for hotkey_ss58 in hotkey_ss58s
210190
):
@@ -239,7 +219,13 @@ async def get_old_stakes() -> list[Balance]:
239219
f":satellite: [magenta]Syncing with chain:[/magenta] [blue]{subtensor.network}[/blue] [magenta]...[/magenta]"
240220
)
241221
block_hash = await subtensor.substrate.get_chain_head()
242-
old_stakes: list[Balance] = await get_old_stakes()
222+
223+
all_stakes = await subtensor.get_stake_for_coldkey(
224+
coldkey_ss58=wallet.coldkeypub.ss58_address, block_hash=block_hash
225+
)
226+
old_stakes: list[Balance] = get_old_stakes(
227+
wallet=wallet, hotkey_ss58s=hotkey_ss58s, netuids=netuids, all_stakes=all_stakes
228+
)
243229

244230
# Remove existential balance to keep key alive.
245231
# Keys must maintain a balance of at least 1000 rao to stay alive.

bittensor/core/extrinsics/asyncex/unstaking.py

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from bittensor.utils import unlock_key
66
from bittensor.utils.balance import Balance
77
from bittensor.utils.btlogging import logging
8+
from bittensor.core.extrinsics.utils import get_old_stakes
89

910
if TYPE_CHECKING:
1011
from bittensor_wallet import Wallet
@@ -164,27 +165,6 @@ async def unstake_multiple_extrinsic(
164165
success (bool): Flag is ``True`` if extrinsic was finalized or included in the block. Flag is ``True`` if any
165166
wallet was unstaked. If we did not wait for finalization / inclusion, the response is ``True``.
166167
"""
167-
168-
async def get_old_stakes() -> list[Balance]:
169-
old_stakes = []
170-
all_stakes = await subtensor.get_stake_for_coldkey(
171-
coldkey_ss58=wallet.coldkeypub.ss58_address,
172-
)
173-
for hotkey_ss58, netuid in zip(hotkey_ss58s, netuids):
174-
stake = next(
175-
(
176-
stake.stake
177-
for stake in all_stakes
178-
if stake.hotkey_ss58 == hotkey_ss58
179-
and stake.coldkey_ss58 == wallet.coldkeypub.ss58_address
180-
and stake.netuid == netuid
181-
),
182-
Balance.from_tao(0), # Default to 0 balance if no match found
183-
)
184-
old_stakes.append(stake)
185-
186-
return old_stakes
187-
188168
if not isinstance(hotkey_ss58s, list) or not all(
189169
isinstance(hotkey_ss58, str) for hotkey_ss58 in hotkey_ss58s
190170
):
@@ -223,10 +203,18 @@ async def get_old_stakes() -> list[Balance]:
223203
logging.info(
224204
f":satellite: [magenta]Syncing with chain:[/magenta] [blue]{subtensor.network}[/blue] [magenta]...[/magenta]"
225205
)
206+
226207
block_hash = await subtensor.substrate.get_chain_head()
227-
old_balance, old_stakes = await asyncio.gather(
208+
209+
all_stakes, old_balance = await asyncio.gather(
210+
subtensor.get_stake_for_coldkey(
211+
coldkey_ss58=wallet.coldkeypub.ss58_address, block_hash=block_hash
212+
),
228213
subtensor.get_balance(wallet.coldkeypub.ss58_address, block_hash=block_hash),
229-
get_old_stakes(),
214+
)
215+
216+
old_stakes: list[Balance] = get_old_stakes(
217+
wallet=wallet, hotkey_ss58s=hotkey_ss58s, netuids=netuids, all_stakes=all_stakes
230218
)
231219

232220
successful_unstakes = 0

bittensor/core/extrinsics/staking.py

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from typing import Optional, TYPE_CHECKING, Sequence
33

44
from bittensor.core.errors import StakeError, NotRegisteredError
5+
from bittensor.core.extrinsics.utils import get_old_stakes
56
from bittensor.utils import unlock_key
67
from bittensor.utils.balance import Balance
78
from bittensor.utils.btlogging import logging
@@ -27,6 +28,7 @@ def add_stake_extrinsic(
2728
subtensor: the Subtensor object to use
2829
wallet: Bittensor wallet object.
2930
hotkey_ss58: The `ss58` address of the hotkey account to stake to defaults to the wallet's hotkey.
31+
netuid (Optional[int]): Subnet unique ID.
3032
amount: Amount to stake as Bittensor balance, `None` if staking all.
3133
wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning `True`, or returns
3234
`False` if the extrinsic fails to enter the block within the timeout.
@@ -174,26 +176,6 @@ def add_stake_multiple_extrinsic(
174176
not wait for finalization/inclusion, the response is `True`.
175177
"""
176178

177-
def get_old_stakes() -> list[Balance]:
178-
old_stakes = []
179-
all_stakes = subtensor.get_stake_for_coldkey(
180-
coldkey_ss58=wallet.coldkeypub.ss58_address,
181-
)
182-
for hotkey_ss58, netuid in zip(hotkey_ss58s, netuids):
183-
stake = next(
184-
(
185-
stake.stake
186-
for stake in all_stakes
187-
if stake.hotkey_ss58 == hotkey_ss58
188-
and stake.coldkey_ss58 == wallet.coldkeypub.ss58_address
189-
and stake.netuid == netuid
190-
),
191-
Balance.from_tao(0), # Default to 0 balance if no match found
192-
)
193-
old_stakes.append(stake)
194-
195-
return old_stakes
196-
197179
if not isinstance(hotkey_ss58s, list) or not all(
198180
isinstance(hotkey_ss58, str) for hotkey_ss58 in hotkey_ss58s
199181
):
@@ -209,6 +191,7 @@ def get_old_stakes() -> list[Balance]:
209191
raise ValueError("netuids must be a list of the same length as hotkey_ss58s")
210192

211193
new_amounts: Sequence[Optional[Balance]]
194+
212195
if amounts is None:
213196
new_amounts = [None] * len(hotkey_ss58s)
214197
else:
@@ -228,7 +211,12 @@ def get_old_stakes() -> list[Balance]:
228211
f":satellite: [magenta]Syncing with chain:[/magenta] [blue]{subtensor.network}[/blue] [magenta]...[/magenta]"
229212
)
230213
block = subtensor.get_current_block()
231-
old_stakes: list[Balance] = get_old_stakes()
214+
all_stakes = subtensor.get_stake_for_coldkey(
215+
coldkey_ss58=wallet.coldkeypub.ss58_address,
216+
)
217+
old_stakes: list[Balance] = get_old_stakes(
218+
wallet=wallet, hotkey_ss58s=hotkey_ss58s, netuids=netuids, all_stakes=all_stakes
219+
)
232220

233221
# Remove existential balance to keep key alive.
234222
# Keys must maintain a balance of at least 1000 rao to stay alive.

0 commit comments

Comments
 (0)