|
33 | 33 | from bittensor.core.chain_data.chain_identity import ChainIdentity
|
34 | 34 | from bittensor.core.chain_data.delegate_info import DelegatedInfo
|
35 | 35 | from bittensor.core.chain_data.utils import (
|
| 36 | + decode_block, |
36 | 37 | decode_metadata,
|
37 | 38 | decode_revealed_commitment,
|
38 | 39 | decode_revealed_commitment_with_hotkey,
|
|
60 | 61 | root_register_extrinsic,
|
61 | 62 | )
|
62 | 63 | from bittensor.core.extrinsics.asyncex.serving import (
|
| 64 | + get_last_bonds_reset, |
63 | 65 | publish_metadata,
|
64 | 66 | get_metadata,
|
65 | 67 | )
|
|
75 | 77 | )
|
76 | 78 | from bittensor.core.extrinsics.asyncex.transfer import transfer_extrinsic
|
77 | 79 | from bittensor.core.extrinsics.asyncex.unstaking import (
|
| 80 | + unstake_all_extrinsic, |
78 | 81 | unstake_extrinsic,
|
79 | 82 | unstake_multiple_extrinsic,
|
80 | 83 | )
|
@@ -1172,6 +1175,34 @@ async def get_commitment(
|
1172 | 1175 | except TypeError:
|
1173 | 1176 | return ""
|
1174 | 1177 |
|
| 1178 | + async def get_last_commitment_bonds_reset_block( |
| 1179 | + self, netuid: int, uid: int |
| 1180 | + ) -> Optional[int]: |
| 1181 | + """ |
| 1182 | + Retrieves the last block number when the bonds reset were triggered by publish_metadata for a specific neuron. |
| 1183 | +
|
| 1184 | + Arguments: |
| 1185 | + netuid (int): The unique identifier of the subnetwork. |
| 1186 | + uid (int): The unique identifier of the neuron. |
| 1187 | +
|
| 1188 | + Returns: |
| 1189 | + Optional[int]: The block number when the bonds were last reset, or None if not found. |
| 1190 | + """ |
| 1191 | + |
| 1192 | + metagraph = await self.metagraph(netuid) |
| 1193 | + try: |
| 1194 | + hotkey = metagraph.hotkeys[uid] |
| 1195 | + except IndexError: |
| 1196 | + logging.error( |
| 1197 | + "Your uid is not in the hotkeys. Please double-check your UID." |
| 1198 | + ) |
| 1199 | + return None |
| 1200 | + block = await get_last_bonds_reset(self, netuid, hotkey) |
| 1201 | + try: |
| 1202 | + return decode_block(block) |
| 1203 | + except TypeError: |
| 1204 | + return "" |
| 1205 | + |
1175 | 1206 | async def get_all_commitments(
|
1176 | 1207 | self,
|
1177 | 1208 | netuid: int,
|
@@ -1202,7 +1233,7 @@ async def get_all_commitments(
|
1202 | 1233 | )
|
1203 | 1234 | result = {}
|
1204 | 1235 | async for id_, value in query:
|
1205 |
| - result[decode_account_id(id_[0])] = decode_metadata(value) |
| 1236 | + result[decode_account_id(id_[0])] = decode_metadata(value.value) |
1206 | 1237 | return result
|
1207 | 1238 |
|
1208 | 1239 | async def get_revealed_commitment_by_hotkey(
|
@@ -2309,7 +2340,7 @@ async def get_subnet_hyperparameters(
|
2309 | 2340 | """
|
2310 | 2341 | result = await self.query_runtime_api(
|
2311 | 2342 | runtime_api="SubnetInfoRuntimeApi",
|
2312 |
| - method="get_subnet_hyperparams", |
| 2343 | + method="get_subnet_hyperparams_v2", |
2313 | 2344 | params=[netuid],
|
2314 | 2345 | block=block,
|
2315 | 2346 | block_hash=block_hash,
|
@@ -3125,6 +3156,7 @@ async def subnet(
|
3125 | 3156 |
|
3126 | 3157 | if isinstance(decoded := query.decode(), dict):
|
3127 | 3158 | return DynamicInfo.from_dict(decoded)
|
| 3159 | + return None |
3128 | 3160 |
|
3129 | 3161 | async def subnet_exists(
|
3130 | 3162 | self,
|
@@ -4639,6 +4671,90 @@ async def unstake(
|
4639 | 4671 | unstake_all=unstake_all,
|
4640 | 4672 | )
|
4641 | 4673 |
|
| 4674 | + async def unstake_all( |
| 4675 | + self, |
| 4676 | + wallet: "Wallet", |
| 4677 | + hotkey: str, |
| 4678 | + netuid: int, |
| 4679 | + rate_tolerance: Optional[float] = 0.005, |
| 4680 | + wait_for_inclusion: bool = True, |
| 4681 | + wait_for_finalization: bool = False, |
| 4682 | + period: Optional[int] = None, |
| 4683 | + ) -> tuple[bool, str]: |
| 4684 | + """Unstakes all TAO/Alpha associated with a hotkey from the specified subnets on the Bittensor network. |
| 4685 | +
|
| 4686 | + Arguments: |
| 4687 | + wallet: The wallet of the stake owner. |
| 4688 | + hotkey: The SS58 address of the hotkey to unstake from. |
| 4689 | + netuid: The unique identifier of the subnet. |
| 4690 | + rate_tolerance: The maximum allowed price change ratio when unstaking. For example, 0.005 = 0.5% maximum |
| 4691 | + price decrease. If not passed (None), then unstaking goes without price limit. Default is 0.005. |
| 4692 | + wait_for_inclusion: Waits for the transaction to be included in a block. Default is `True`. |
| 4693 | + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Default is `False`. |
| 4694 | + period: The number of blocks during which the transaction will remain valid after it's submitted. If the |
| 4695 | + transaction is not included in a block within that number of blocks, it will expire and be rejected. You |
| 4696 | + can think of it as an expiration date for the transaction. Default is `None`. |
| 4697 | +
|
| 4698 | + Returns: |
| 4699 | + tuple[bool, str]: |
| 4700 | + A tuple containing: |
| 4701 | + - `True` and a success message if the unstake operation succeeded; |
| 4702 | + - `False` and an error message otherwise. |
| 4703 | +
|
| 4704 | + Example: |
| 4705 | + # If you would like to unstake all stakes in all subnets safely, use default `rate_tolerance` or pass your |
| 4706 | + value: |
| 4707 | + import bittensor as bt |
| 4708 | +
|
| 4709 | + subtensor = bt.AsyncSubtensor() |
| 4710 | + wallet = bt.Wallet("my_wallet") |
| 4711 | + netuid = 14 |
| 4712 | + hotkey = "5%SOME_HOTKEY_WHERE_IS_YOUR_STAKE_NOW%" |
| 4713 | +
|
| 4714 | + wallet_stakes = await subtensor.get_stake_info_for_coldkey(coldkey_ss58=wallet.coldkey.ss58_address) |
| 4715 | +
|
| 4716 | + for stake in wallet_stakes: |
| 4717 | + result = await subtensor.unstake_all( |
| 4718 | + wallet=wallet, |
| 4719 | + hotkey_ss58=stake.hotkey_ss58, |
| 4720 | + netuid=stake.netuid, |
| 4721 | + ) |
| 4722 | + print(result) |
| 4723 | +
|
| 4724 | + # If you would like to unstake all stakes in all subnets unsafely, use `rate_tolerance=None`: |
| 4725 | + import bittensor as bt |
| 4726 | +
|
| 4727 | + subtensor = bt.AsyncSubtensor() |
| 4728 | + wallet = bt.Wallet("my_wallet") |
| 4729 | + netuid = 14 |
| 4730 | + hotkey = "5%SOME_HOTKEY_WHERE_IS_YOUR_STAKE_NOW%" |
| 4731 | +
|
| 4732 | + wallet_stakes = await subtensor.get_stake_info_for_coldkey(coldkey_ss58=wallet.coldkey.ss58_address) |
| 4733 | +
|
| 4734 | + for stake in wallet_stakes: |
| 4735 | + result = await subtensor.unstake_all( |
| 4736 | + wallet=wallet, |
| 4737 | + hotkey_ss58=stake.hotkey_ss58, |
| 4738 | + netuid=stake.netuid, |
| 4739 | + rate_tolerance=None, |
| 4740 | + ) |
| 4741 | + print(result) |
| 4742 | + """ |
| 4743 | + if netuid != 0: |
| 4744 | + logging.debug( |
| 4745 | + f"Unstaking without Alpha price control from subnet [blue]#{netuid}[/blue]." |
| 4746 | + ) |
| 4747 | + return await unstake_all_extrinsic( |
| 4748 | + subtensor=self, |
| 4749 | + wallet=wallet, |
| 4750 | + hotkey=hotkey, |
| 4751 | + netuid=netuid, |
| 4752 | + rate_tolerance=rate_tolerance, |
| 4753 | + wait_for_inclusion=wait_for_inclusion, |
| 4754 | + wait_for_finalization=wait_for_finalization, |
| 4755 | + period=period, |
| 4756 | + ) |
| 4757 | + |
4642 | 4758 | async def unstake_multiple(
|
4643 | 4759 | self,
|
4644 | 4760 | wallet: "Wallet",
|
|
0 commit comments