diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index dd819957f4..261c8bda3c 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -138,6 +138,7 @@ jobs: - pull-docker-image strategy: fail-fast: false + max-parallel: 16 matrix: include: ${{ fromJson(needs.find-tests.outputs.test-files) }} uses: ./.github/workflows/_run-e2e-single.yaml diff --git a/bittensor/core/async_subtensor.py b/bittensor/core/async_subtensor.py index c329e41fee..14f91c1854 100644 --- a/bittensor/core/async_subtensor.py +++ b/bittensor/core/async_subtensor.py @@ -930,45 +930,6 @@ async def bonds( return b_map - async def commit( - self, wallet: "Wallet", netuid: int, data: str, period: Optional[int] = None - ) -> bool: - """Commits arbitrary data to the Bittensor network by publishing metadata. - - This method allows neurons to publish arbitrary data to the blockchain, which can be used for various purposes - such as sharing model updates, configuration data, or other network-relevant information. - - Arguments: - wallet: The wallet associated with the neuron committing the data. - netuid: The unique identifier of the subnet. - data: The data to be committed to the network. - period: The number of blocks during which the transaction will remain valid after it's submitted. If the - transaction is not included in a block within that number of blocks, it will expire and be rejected. You - can think of it as an expiration date for the transaction. - - Returns: - bool: True if the commit was successful, False otherwise. - - Example: - # Commit some data to subnet 1 - success = await subtensor.commit(wallet=my_wallet, netuid=1, data="Hello Bittensor!") - - # Commit with custom period - success = await subtensor.commit(wallet=my_wallet, netuid=1, data="Model update v2.0", period=100) - - Note: See - """ - return await publish_metadata( - subtensor=self, - wallet=wallet, - netuid=netuid, - data_type=f"Raw{len(data)}", - data=data.encode(), - period=period, - ) - - set_commitment = commit - async def commit_reveal_enabled( self, netuid: int, @@ -3840,23 +3801,29 @@ async def set_reveal_commitment( blocks_until_reveal: int = 360, block_time: Union[int, float] = 12, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, int]: """ Commits arbitrary data to the Bittensor network by publishing metadata. - Arguments: + Parameters: wallet: The wallet associated with the neuron committing the data. netuid: The unique identifier of the subnetwork. data: The data to be committed to the network. - blocks_until_reveal: The number of blocks from now after which the data will be revealed. - Defaults to ``360`` (the number of blocks in one epoch). - block_time: The number of seconds between each block. Defaults to ``12``. - period: The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + blocks_until_reveal: The number of blocks from now after which the data will be revealed. Then number of + blocks in one epoch. + block_time: The number of seconds between each block. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - bool: ``True`` if the commitment was successful, ``False`` otherwise. + bool: `True` if the commitment was successful, `False` otherwise. Note: A commitment can be set once per subnet epoch and is reset at the next epoch in the chain automatically. """ @@ -3875,6 +3842,9 @@ async def set_reveal_commitment( data_type="TimelockEncrypted", data=data_, period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ), reveal_round async def subnet( @@ -4307,39 +4277,40 @@ async def sign_and_send_extrinsic( async def add_stake( self, wallet: "Wallet", - hotkey_ss58: Optional[str] = None, - netuid: Optional[int] = None, - amount: Optional[Balance] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, + netuid: int, + hotkey_ss58: str, + amount: Balance, safe_staking: bool = False, allow_partial_stake: bool = False, rate_tolerance: float = 0.005, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Adds a stake from the specified wallet to the neuron identified by the SS58 address of its hotkey in specified subnet. Staking is a fundamental process in the Bittensor network that enables neurons to participate actively and earn incentives. - Arguments: + Parameters: wallet: The wallet to be used for staking. - hotkey_ss58: The SS58 address of the hotkey associated with the neuron to which you intend to delegate your - stake. If not specified, the wallet's hotkey will be used. Defaults to ``None``. netuid: The unique identifier of the subnet to which the neuron belongs. + hotkey_ss58: The `ss58` address of the hotkey account to stake to default to the wallet's hotkey. amount: The amount of TAO to stake. - wait_for_inclusion: Waits for the transaction to be included in a block. Defaults to `True`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Defaults to `False`. safe_staking: If true, enables price safety checks to protect against fluctuating prices. The stake will only execute if the price change doesn't exceed the rate tolerance. Default is ``False``. allow_partial_stake: If true and safe_staking is enabled, allows partial staking when the full amount would exceed the price tolerance. If false, the entire stake fails if it would exceed the tolerance. Default is ``False``. rate_tolerance: The maximum allowed price change ratio when staking. For example, 0.005 = 0.5% maximum price - increase. Only used when safe_staking is True. Default is ``0.005``. - period: The number of blocks during which the transaction will remain valid after it's submitted. If the - transaction is not included in a block within that number of blocks, it will expire and be rejected. You - can think of it as an expiration date for the transaction. Defaults to ``None``. + increase. Only used when safe_staking is True. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: bool: ``True`` if the staking is successful, ``False`` otherwise. @@ -4355,12 +4326,13 @@ async def add_stake( hotkey_ss58=hotkey_ss58, netuid=netuid, amount=amount, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, safe_staking=safe_staking, allow_partial_stake=allow_partial_stake, rate_tolerance=rate_tolerance, period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) async def add_liquidity( @@ -4371,26 +4343,27 @@ async def add_liquidity( price_low: Balance, price_high: Balance, hotkey: Optional[str] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """ Adds liquidity to the specified price range. - Arguments: + Parameters: wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. liquidity: The amount of liquidity to be added. price_low: The lower bound of the price tick range. In TAO. price_high: The upper bound of the price tick range. In TAO. - hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. Defaults to - `None`. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. + hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: Tuple[bool, str]: @@ -4398,7 +4371,7 @@ async def add_liquidity( - False and an error message if the submission fails or the wallet cannot be unlocked. Note: Adding is allowed even when user liquidity is enabled in specified subnet. Call ``toggle_user_liquidity`` - method to enable/disable user liquidity. + method to enable/disable user liquidity. """ return await add_liquidity_extrinsic( subtensor=self, @@ -4408,9 +4381,10 @@ async def add_liquidity( price_low=price_low, price_high=price_high, hotkey=hotkey, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) async def add_stake_multiple( @@ -4418,21 +4392,27 @@ async def add_stake_multiple( wallet: "Wallet", hotkey_ss58s: list[str], netuids: list[int], - amounts: Optional[list[Balance]] = None, + amounts: list[Balance], + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, + wait_for_finalization: bool = True, ) -> bool: """ Adds stakes to multiple neurons identified by their hotkey SS58 addresses. This bulk operation allows for efficient staking across different neurons from a single wallet. - Arguments: + Parameters: wallet: The wallet used for staking. hotkey_ss58s: List of ``SS58`` addresses of hotkeys to stake to. - netuids: list of subnet UIDs. - amounts: Corresponding amounts of TAO to stake for each hotkey. - wait_for_inclusion: Waits for the transaction to be included in a block. Defaults to `True`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Defaults to `False`. + netuids: List of subnet UIDs. + amounts: List of corresponding TAO amounts to bet for each netuid and hotkey. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: bool: ``True`` if the staking is successful for all specified neurons, ``False`` otherwise. @@ -4443,9 +4423,11 @@ async def add_stake_multiple( return await add_stake_multiple_extrinsic( subtensor=self, wallet=wallet, - hotkey_ss58s=hotkey_ss58s, netuids=netuids, + hotkey_ss58s=hotkey_ss58s, amounts=amounts, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, ) @@ -4454,44 +4436,47 @@ async def burned_register( self, wallet: "Wallet", netuid: int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Registers a neuron on the Bittensor network by recycling TAO. This method of registration involves recycling TAO tokens, allowing them to be re-mined by performing work on the network. - Arguments: + Parameters: wallet: The wallet associated with the neuron to be registered. netuid: The unique identifier of the subnet. - wait_for_inclusion: Waits for the transaction to be included in a block. Defaults to - ``False``. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. wait_for_finalization: Waits for the transaction to be finalized on the blockchain. - period: The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. Returns: - bool: `True` if the registration is successful, False otherwise. + bool: ``True`` if the registration is successful, False otherwise. """ async with self: if netuid == 0: return await root_register_extrinsic( subtensor=self, wallet=wallet, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) return await burned_register_extrinsic( subtensor=self, wallet=wallet, netuid=netuid, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) async def commit_weights( @@ -4502,29 +4487,30 @@ async def commit_weights( uids: Union[NDArray[np.int64], list], weights: Union[NDArray[np.int64], list], version_key: int = version_as_int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = False, max_retries: int = 5, period: Optional[int] = 16, + raise_error: bool = True, + wait_for_inclusion: bool = False, + wait_for_finalization: bool = False, ) -> tuple[bool, str]: """ Commits a hash of the subnet validator's weight vector to the Bittensor blockchain using the provided wallet. This action serves as a commitment or snapshot of the validator's current weight distribution. - Arguments: - wallet: The wallet associated with the subnet validator committing the weights. + Parameters: + wallet: The wallet associated with the neuron committing the weights. netuid: The unique identifier of the subnet. salt: list of randomly generated integers as salt to generated weighted hash. - uids: NumPy array of subnet miner neuron UIDs for which weights are being committed. - weights: of weight values corresponding toon_key - version_key: Integer representation of version key for compatibility with the network. - wait_for_inclusion: Waits for the transaction to be included in a block. Default is `False`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Default is - `False`. - max_retries: The number of maximum attempts to commit weights. Default is `5`. - period: The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + uids: NumPy array of neuron UIDs for which weights are being committed. + weights: NumPy array of weight values corresponding to each UID. + version_key: Version key for compatibility with the network. + max_retries: The number of maximum attempts to commit weights. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: tuple[bool, str]: @@ -4567,7 +4553,7 @@ async def commit_weights( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, - raise_error=True, + raise_error=raise_error, ) if success: break @@ -4584,24 +4570,25 @@ async def modify_liquidity( position_id: int, liquidity_delta: Balance, hotkey: Optional[str] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Modifies liquidity in liquidity position by adding or removing liquidity from it. - Arguments: + Parameters: wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. position_id: The id of the position record in the pool. liquidity_delta: The amount of liquidity to be added or removed (add if positive or remove if negative). - hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. Defaults to - `None`. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. + hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: Tuple[bool, str]: @@ -4635,7 +4622,7 @@ async def modify_liquidity( ) Note: Modifying is allowed even when user liquidity is enabled in specified subnet. Call `toggle_user_liquidity` - to enable/disable user liquidity. + to enable/disable user liquidity. """ return await modify_liquidity_extrinsic( subtensor=self, @@ -4644,40 +4631,43 @@ async def modify_liquidity( position_id=position_id, liquidity_delta=liquidity_delta, hotkey=hotkey, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) async def move_stake( self, wallet: "Wallet", - origin_hotkey: str, + origin_hotkey_ss58: str, origin_netuid: int, - destination_hotkey: str, + destination_hotkey_ss58: str, destination_netuid: int, amount: Optional[Balance] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - period: Optional[int] = None, move_all_stake: bool = False, + period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Moves stake to a different hotkey and/or subnet. Arguments: wallet: The wallet to move stake from. - origin_hotkey: The SS58 address of the source hotkey. + origin_hotkey_ss58: The SS58 address of the source hotkey. origin_netuid: The netuid of the source subnet. - destination_hotkey: The SS58 address of the destination hotkey. + destination_hotkey_ss58: The SS58 address of the destination hotkey. destination_netuid: The netuid of the destination subnet. amount: Amount of stake to move. + move_all_stake: If true, moves all stake from the source hotkey to the destination hotkey. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. wait_for_inclusion: Waits for the transaction to be included in a block. wait_for_finalization: Waits for the transaction to be finalized on the blockchain. - period: The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. - move_all_stake: If true, moves all stake from the source hotkey to the destination hotkey. Returns: success: True if the stake movement was successful. @@ -4686,23 +4676,22 @@ async def move_stake( return await move_stake_extrinsic( subtensor=self, wallet=wallet, - origin_hotkey=origin_hotkey, + origin_hotkey_ss58=origin_hotkey_ss58, origin_netuid=origin_netuid, - destination_hotkey=destination_hotkey, + destination_hotkey_ss58=destination_hotkey_ss58, destination_netuid=destination_netuid, amount=amount, + move_all_stake=move_all_stake, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, - move_all_stake=move_all_stake, ) async def register( self: "AsyncSubtensor", wallet: "Wallet", netuid: int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, max_allowed_attempts: int = 3, output_in_place: bool = False, cuda: bool = False, @@ -4712,33 +4701,37 @@ async def register( update_interval: Optional[int] = None, log_verbose: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ): """ - Registers a neuron on the Bittensor network using the provided wallet. + Registers a neuron on the Bittensor subnet with provided netuid using the provided wallet. Registration is a critical step for a neuron to become an active participant in the network, enabling it to stake, set weights, and receive incentives. - Arguments: + Parameters: wallet: The wallet associated with the neuron to be registered. - netuid: unique identifier of the subnet. - wait_for_inclusion: Waits for the transaction to be included in a block. Defaults to `False`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Defaults to + netuid: The unique identifier of the subnet. max_allowed_attempts: Maximum number of attempts to register the wallet. - output_in_place: If true, prints the progress of the proof of work to the console in-place. Meaning - the progress is printed on the same lines. Defaults to `True`. - cuda: If `true`, the wallet should be registered using CUDA device(s). Defaults to `False`. - dev_id: The CUDA device id to use, or a list of device ids. Defaults to `0` (zero). - tpb: The number of threads per block (CUDA). Default to `256`. - num_processes: The number of processes to use to register. Default to `None`. - update_interval: The number of nonces to solve between updates. Default to `None`. - log_verbose: If `true`, the registration process will log more information. Default to `False`. - period: The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + output_in_place: If true, prints the progress of the proof of work to the console in-place. Meaning the + progress is printed on the same lines. + cuda: If ``true``, the wallet should be registered using CUDA device(s). + dev_id: The CUDA device id to use, or a list of device ids. + tpb: The number of threads per block (CUDA). + num_processes: The number of processes to use to register. + update_interval: The number of nonces to solve between updates. + log_verbose: If ``true``, the registration process will log more information. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - bool: `True` if the registration is successful, False otherwise. + bool: ``True`` if the registration is successful, False otherwise. This function facilitates the entry of new neurons into the network, supporting the decentralized growth and scalability of the Bittensor ecosystem. @@ -4747,8 +4740,6 @@ async def register( subtensor=self, wallet=wallet, netuid=netuid, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, max_allowed_attempts=max_allowed_attempts, tpb=tpb, update_interval=update_interval, @@ -4758,27 +4749,30 @@ async def register( output_in_place=output_in_place, log_verbose=log_verbose, period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) async def register_subnet( self: "AsyncSubtensor", wallet: "Wallet", - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Registers a new subnetwork on the Bittensor network. - Arguments: + Parameters: wallet: The wallet to be used for subnet registration. - wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning `True`, - os `False` if the extrinsic fails to enter the block within the timeout. Default is `False`. - wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning - true, or returns false if the extrinsic fails to be finalized within the timeout. Default is `False`. - period: The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: bool: True if the subnet registration was successful, False otherwise. @@ -4786,9 +4780,10 @@ async def register_subnet( return await register_subnet_extrinsic( subtensor=self, wallet=wallet, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) async def remove_liquidity( @@ -4797,23 +4792,24 @@ async def remove_liquidity( netuid: int, position_id: int, hotkey: Optional[str] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Remove liquidity and credit balances back to wallet's hotkey stake. - Arguments: + Parameters: wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. position_id: The id of the position record in the pool. - hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. Defaults to - `None`. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. + hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: Tuple[bool, str]: @@ -4822,7 +4818,7 @@ async def remove_liquidity( Note: - Adding is allowed even when user liquidity is enabled in specified subnet. Call `toggle_user_liquidity` - extrinsic to enable/disable user liquidity. + extrinsic to enable/disable user liquidity. - To get the `position_id` use `get_liquidity_list` method. """ return await remove_liquidity_extrinsic( @@ -4831,9 +4827,10 @@ async def remove_liquidity( netuid=netuid, position_id=position_id, hotkey=hotkey, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) async def reveal_weights( @@ -4843,36 +4840,37 @@ async def reveal_weights( uids: Union[NDArray[np.int64], list], weights: Union[NDArray[np.int64], list], salt: Union[NDArray[np.int64], list], + max_retries: int = 5, version_key: int = version_as_int, + period: Optional[int] = 16, + raise_error: bool = True, wait_for_inclusion: bool = False, wait_for_finalization: bool = False, - max_retries: int = 5, - period: Optional[int] = None, ) -> tuple[bool, str]: """ Reveals the weight vector for a specific subnet on the Bittensor blockchain using the provided wallet. This action serves as a revelation of the subnet validator's previously committed weight distribution as part of the commit-reveal mechanism. - Arguments: + Parameters: wallet: The wallet associated with the subnet validator revealing the weights. netuid: unique identifier of the subnet. uids: NumPy array of subnet miner neuron UIDs for which weights are being revealed. weights: NumPy array of weight values corresponding to each UID. salt: NumPy array of salt values - version_key: Version key for compatibility with the network. Default is `int representation of - the Bittensor version`. - wait_for_inclusion: Waits for the transaction to be included in a block. Default is `False`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Default is - `False`. - max_retries: The number of maximum attempts to reveal weights. Default is `5`. - period: The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + max_retries: The number of maximum attempts to reveal weights. + version_key: Version key for compatibility with the network. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: - tuple[bool, str]: `True` if the weight revelation is successful, False otherwise. And `msg`, a string - value describing the success or potential error. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. This function allows subnet validators to reveal their previously committed weight vector. @@ -4892,10 +4890,10 @@ async def reveal_weights( weights=list(weights), salt=list(salt), version_key=version_key, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, - raise_error=True, ) if success: break @@ -4909,25 +4907,27 @@ async def root_set_pending_childkey_cooldown( self, wallet: "Wallet", cooldown: int, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = True, - period: Optional[int] = None, ) -> tuple[bool, str]: """Sets the pending childkey cooldown. - Arguments: + Parameters: wallet: bittensor wallet instance. cooldown: the number of blocks to setting pending childkey cooldown. - wait_for_inclusion: Waits for the transaction to be included in a block. Default is `False`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Default is - `False`. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure of the - operation, and the second element is a message providing additional information. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. Note: This operation can only be successfully performed if your wallet has root privileges. """ @@ -4935,43 +4935,44 @@ async def root_set_pending_childkey_cooldown( subtensor=self, wallet=wallet, cooldown=cooldown, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) # TODO: remove `block_hash` argument async def root_register( self, wallet: "Wallet", - block_hash: Optional[str] = None, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = True, - period: Optional[int] = None, ) -> bool: """ Register neuron by recycling some TAO. - Arguments: - wallet: Bittensor wallet instance. - block_hash: This argument will be removed in Bittensor v10 - wait_for_inclusion: Waits for the transaction to be included in a block. Default is `False`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Default is - `False`. - period: The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + Parameters: + wallet: The wallet associated with the neuron to be registered. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - `True` if registration was successful, otherwise `False`. + bool: ``True`` if the registration is successful, False otherwise. """ return await root_register_extrinsic( subtensor=self, wallet=wallet, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) async def set_children( @@ -4980,29 +4981,30 @@ async def set_children( hotkey: str, netuid: int, children: list[tuple[float, str]], + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = True, - raise_error: bool = False, - period: Optional[int] = None, ) -> tuple[bool, str]: """ Allows a coldkey to set children-keys. - Arguments: + Parameters: wallet: bittensor wallet instance. hotkey: The `SS58` address of the neuron's hotkey. netuid: The netuid value. children: A list of children with their proportions. - wait_for_inclusion: Waits for the transaction to be included in a block. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. - raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure of the - operation, and the second element is a message providing additional information. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. Raises: DuplicateChild: There are duplicates in the list of children. @@ -5023,10 +5025,10 @@ async def set_children( hotkey=hotkey, netuid=netuid, children=children, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - raise_error=raise_error, - period=period, ) async def set_delegate_take( @@ -5034,30 +5036,30 @@ async def set_delegate_take( wallet: "Wallet", hotkey_ss58: str, take: float, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = True, - raise_error: bool = False, - period: Optional[int] = None, ) -> tuple[bool, str]: """ Sets the delegate 'take' percentage for a neuron identified by its hotkey. The 'take' represents the percentage of rewards that the delegate claims from its nominators' stakes. - Arguments: + Parameters: wallet: bittensor wallet instance. hotkey_ss58: The ``SS58`` address of the neuron's hotkey. take: Percentage reward for the delegate. - wait_for_inclusion: Waits for the transaction to be included in a block. - wait_for_finalization: Waits for the transaction to be finalized on_error: Raises a relevant exception - rather than returning ``False`` if unsuccessful. - raise_error: raises a relevant exception rather than returning ``False`` if unsuccessful. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure of the - operation, and the second element is a message providing additional information. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. Raises: DelegateTakeTooHigh: Delegate take is too high. @@ -5072,7 +5074,6 @@ async def set_delegate_take( The delegate take is a critical parameter in the network's incentive structure, influencing the distribution of rewards among neurons and their nominators. """ - # u16 representation of the take take_u16 = int(take * 0xFFFF) @@ -5085,62 +5086,57 @@ async def set_delegate_take( logging.info(f"Updating {hotkey_ss58} take: current={current_take} new={take}") - if current_take_u16 < take_u16: - success, error = await increase_take_extrinsic( - self, - wallet, - hotkey_ss58, - take_u16, - wait_for_finalization=wait_for_finalization, - wait_for_inclusion=wait_for_inclusion, - raise_error=raise_error, - period=period, - ) - else: - success, error = await decrease_take_extrinsic( - self, - wallet, - hotkey_ss58, - take_u16, - wait_for_finalization=wait_for_finalization, - wait_for_inclusion=wait_for_inclusion, - raise_error=raise_error, - period=period, - ) + extrinsic_call = ( + increase_take_extrinsic + if current_take_u16 < take_u16 + else decrease_take_extrinsic + ) + + success, message = await extrinsic_call( + subtensor=self, + wallet=wallet, + hotkey_ss58=hotkey_ss58, + take=take_u16, + period=period, + raise_error=raise_error, + wait_for_finalization=wait_for_finalization, + wait_for_inclusion=wait_for_inclusion, + ) if success: logging.info(":white_heavy_check_mark: [green]Take Updated[/green]") - return success, error + return success, message async def set_subnet_identity( self, wallet: "Wallet", netuid: int, subnet_identity: SubnetIdentity, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """ Sets the identity of a subnet for a specific wallet and network. - Arguments: + Parameters: wallet: The wallet instance that will authorize the transaction. netuid: The unique ID of the network on which the operation takes place. - subnet_identity: The identity data of the subnet including attributes like name, GitHub - repository, contact, URL, discord, description, and any additional metadata. - wait_for_inclusion: Indicates if the function should wait for the transaction to be included in the - block. - wait_for_finalization: Indicates if the function should wait for the transaction to reach - finalization. + subnet_identity: The identity data of the subnet including attributes like name, GitHub repository, contact, + URL, discord, description, and any additional metadata. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure of the - operation, and the second element is a message providing additional information. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. """ return await set_subnet_identity_extrinsic( subtensor=self, @@ -5154,9 +5150,10 @@ async def set_subnet_identity( discord=subnet_identity.discord, description=subnet_identity.description, additional=subnet_identity.additional, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) async def set_weights( @@ -5165,12 +5162,14 @@ async def set_weights( netuid: int, uids: Union[NDArray[np.int64], "torch.LongTensor", list], weights: Union[NDArray[np.float32], "torch.FloatTensor", list], - version_key: int = version_as_int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = False, - max_retries: int = 5, block_time: float = 12.0, + commit_reveal_version: int = 4, + max_retries: int = 5, + version_key: int = version_as_int, period: Optional[int] = 8, + raise_error: bool = True, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ): """ Sets the weight vector for a neuron acting as a validator, specifying the weights assigned to subnet miners @@ -5180,26 +5179,27 @@ async def set_weights( work. These weight vectors are used by the Yuma Consensus algorithm to compute emissions for both validators and miners. - Arguments: + Parameters: wallet: The wallet associated with the subnet validator setting the weights. netuid: The unique identifier of the subnet. uids: The list of subnet miner neuron UIDs that the weights are being set for. weights: The corresponding weights to be set for each UID, representing the validator's evaluation of each miner's performance. - version_key: Version key for compatibility with the network. Default is int representation of - the Bittensor version. - wait_for_inclusion: Waits for the transaction to be included in a block. Default is `False`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Default is - `False`. - max_retries: The number of maximum attempts to set weights. Default is `5`. - block_time: The number of seconds for block duration. Default is 12.0 seconds. + block_time: The number of seconds for block duration. + commit_reveal_version: The version of the chain commit-reveal protocol to use. + max_retries: The number of maximum attempts to set weights. + version_key: Version key for compatibility with the network. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. Default is 8. + and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - tuple[bool, str]: `True` if the setting of weights is successful, False otherwise. And `msg`, a string - value describing the success or potential error. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. This function is crucial in the Yuma Consensus mechanism, where each validator's weight vector contributes to the overall weight matrix used to calculate emissions and maintain network consensus. @@ -5237,21 +5237,28 @@ async def _blocks_weight_limit() -> bool: and await _blocks_weight_limit() ): logging.info( - f"Committing weights for subnet #{netuid}. Attempt {retries + 1} of {max_retries}." + f"Committing weights for subnet [blue]{netuid}[/blue]. " + f"Attempt [blue]{retries + 1}[blue] of [green]{max_retries}[/green]." ) - success, message = await commit_reveal_extrinsic( - subtensor=self, - wallet=wallet, - netuid=netuid, - uids=uids, - weights=weights, - version_key=version_key, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - block_time=block_time, - period=period, - ) - retries += 1 + try: + success, message = await commit_reveal_extrinsic( + subtensor=self, + wallet=wallet, + netuid=netuid, + uids=uids, + weights=weights, + block_time=block_time, + commit_reveal_version=commit_reveal_version, + version_key=version_key, + period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + ) + except Exception as e: + logging.error(f"Error setting weights: {e}") + retries += 1 + return success, message else: # go with classic `set weights extrinsic` @@ -5273,9 +5280,10 @@ async def _blocks_weight_limit() -> bool: uids=uids, weights=weights, version_key=version_key, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) except Exception as e: logging.error(f"Error setting weights: {e}") @@ -5287,27 +5295,31 @@ async def serve_axon( self, netuid: int, axon: "Axon", - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, certificate: Optional[Certificate] = None, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ - Registers an ``Axon`` serving endpoint on the Bittensor network for a specific neuron. This function is used to - set up the Axon, a key component of a neuron that handles incoming queries and data processing tasks. + Registers an ``Axon`` serving endpoint on the Bittensor network for a specific neuron. - Arguments: + This function is used to set up the Axon, a key component of a neuron that handles incoming queries and data + processing tasks. + + Parameters: netuid: The unique identifier of the subnetwork. axon: The Axon instance to be registered for serving. - wait_for_inclusion: Waits for the transaction to be included in a block. Default is `False`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Default is `True`. - certificate: Certificate to use for TLS. If `None`, no TLS will be used. Defaults to `None`. - period: The number of blocks during which the transaction will remain valid after it's submitted. If the - transaction is not included in a block within that number of blocks, it will expire and be rejected. You - can think of it as an expiration date for the transaction. + certificate: Certificate to use for TLS. If ``None``, no TLS will be used. + period: The number of blocks during which the transaction will remain valid after it's + submitted. If the transaction is not included in a block within that number of blocks, it will expire + and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - bool: `True` if the Axon serve registration is successful, False otherwise. + bool: ``True`` if the Axon serve registration is successful, False otherwise. By registering an Axon, the neuron becomes an active part of the network's distributed computing infrastructure, contributing to the collective intelligence of Bittensor. @@ -5316,32 +5328,86 @@ async def serve_axon( subtensor=self, netuid=netuid, axon=axon, + certificate=certificate, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - certificate=certificate, + ) + + async def set_commitment( + self, + wallet: "Wallet", + netuid: int, + data: str, + period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, + ) -> bool: + """ + Commits arbitrary data to the Bittensor network by publishing metadata. + + This method allows neurons to publish arbitrary data to the blockchain, which can be used for various purposes + such as sharing model updates, configuration data, or other network-relevant information. + + Parameters: + wallet (bittensor_wallet.Wallet): The wallet associated with the neuron committing the data. + netuid (int): The unique identifier of the subnetwork. + data (str): The data to be committed to the network. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. + + Returns: + bool: `True` if the commitment was successful, `False` otherwise. + + Example: + # Commit some data to subnet 1 + success = await subtensor.commit(wallet=my_wallet, netuid=1, data="Hello Bittensor!") + + # Commit with custom period + success = await subtensor.commit(wallet=my_wallet, netuid=1, data="Model update v2.0", period=100) + + Note: See + """ + return await publish_metadata( + subtensor=self, + wallet=wallet, + netuid=netuid, + data_type=f"Raw{len(data)}", + data=data.encode(), period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) async def start_call( self, wallet: "Wallet", netuid: int, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = False, - period: Optional[int] = None, ) -> tuple[bool, str]: """ Submits a start_call extrinsic to the blockchain, to trigger the start call process for a subnet (used to start a new subnet's emission mechanism). - Arguments: + Parameters: wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to `True`. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to `False`. period: The number of blocks during which the transaction will remain valid after it's submitted. If the - transaction is not included in a block within that number of blocks, it will expire and be rejected. You - can think of it as an expiration date for the transaction. + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: Tuple[bool, str]: @@ -5352,9 +5418,10 @@ async def start_call( subtensor=self, wallet=wallet, netuid=netuid, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) async def swap_stake( @@ -5364,36 +5431,37 @@ async def swap_stake( origin_netuid: int, destination_netuid: int, amount: Balance, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - safe_staking: bool = False, + safe_swapping: bool = False, allow_partial_stake: bool = False, rate_tolerance: float = 0.005, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Moves stake between subnets while keeping the same coldkey-hotkey pair ownership. Like subnet hopping - same owner, same hotkey, just changing which subnet the stake is in. - Arguments: + Parameters: wallet: The wallet to swap stake from. hotkey_ss58: The SS58 address of the hotkey whose stake is being swapped. origin_netuid: The netuid from which stake is removed. destination_netuid: The netuid to which stake is added. amount: The amount to swap. - wait_for_inclusion: Waits for the transaction to be included in a block. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. - safe_staking: If true, enables price safety checks to protect against fluctuating prices. The swap will only - execute if the price ratio between subnets doesn't exceed the rate tolerance. Default is False. + safe_swapping: If true, enables price safety checks to protect against fluctuating prices. The swap + will only execute if the price ratio between subnets doesn't exceed the rate tolerance. allow_partial_stake: If true and safe_staking is enabled, allows partial stake swaps when the full amount - would exceed the price threshold. If false, the entire swap fails if it would exceed the threshold. - Default is False. + would exceed the price tolerance. If false, the entire swap fails if it would exceed the tolerance. rate_tolerance: The maximum allowed increase in the price ratio between subnets (origin_price/destination_price). For example, 0.005 = 0.5% maximum increase. Only used when - safe_staking is True. Default is 0.005. + safe_staking is True. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: success: True if the extrinsic was successful. @@ -5413,12 +5481,13 @@ async def swap_stake( origin_netuid=origin_netuid, destination_netuid=destination_netuid, amount=amount, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - safe_staking=safe_staking, + safe_swapping=safe_swapping, allow_partial_stake=allow_partial_stake, rate_tolerance=rate_tolerance, period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) async def toggle_user_liquidity( @@ -5426,21 +5495,23 @@ async def toggle_user_liquidity( wallet: "Wallet", netuid: int, enable: bool, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Allow to toggle user liquidity for specified subnet. - Arguments: + Parameters: wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. enable: Boolean indicating whether to enable user liquidity. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. - period: The number of blocks during which the transaction will remain valid after it's submitted. If the - transaction is not included in a block within that number of blocks, it will expire and be rejected. You - can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: Tuple[bool, str]: @@ -5454,9 +5525,10 @@ async def toggle_user_liquidity( wallet=wallet, netuid=netuid, enable=enable, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) async def transfer( @@ -5465,25 +5537,28 @@ async def transfer( destination: str, amount: Optional[Balance], transfer_all: bool = False, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, keep_alive: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = False, ) -> bool: """ Transfer token of amount to destination. - Arguments: + Parameters: wallet: Source wallet for the transfer. destination: Destination address for the transfer. amount: Number of tokens to transfer. `None` is transferring all. transfer_all: Flag to transfer all tokens. Default is `False`. - wait_for_inclusion: Waits for the transaction to be included in a block. Defaults to `True`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Defaults to `False`. keep_alive: Flag to keep the connection alive. Default is `True`. - period: The number of blocks during which the transaction will remain valid after it's submitted. If the - transaction is not included in a block within that number of blocks, it will expire and be rejected. You - can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. + Returns: `True` if the transferring was successful, otherwise `False`. """ @@ -5495,10 +5570,11 @@ async def transfer( destination=destination, amount=amount, transfer_all=transfer_all, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, keep_alive=keep_alive, period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) async def transfer_stake( @@ -5509,25 +5585,27 @@ async def transfer_stake( origin_netuid: int, destination_netuid: int, amount: Balance, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Transfers stake from one subnet to another while changing the coldkey owner. - Arguments: + Parameters: wallet: The wallet to transfer stake from. destination_coldkey_ss58: The destination coldkey SS58 address. hotkey_ss58: The hotkey SS58 address associated with the stake. origin_netuid: The source subnet UID. destination_netuid: The destination subnet UID. amount: Amount to transfer. - wait_for_inclusion: If true, waits for inclusion before returning. - wait_for_finalization: If true, waits for finalization before returning. - period: The number of blocks during which the transaction will remain valid after it's submitted. If the - transaction is not included in a block within that number of blocks, it will expire and be rejected. You - can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: success: True if the transfer was successful. @@ -5541,48 +5619,48 @@ async def transfer_stake( origin_netuid=origin_netuid, destination_netuid=destination_netuid, amount=amount, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) async def unstake( self, wallet: "Wallet", - hotkey_ss58: Optional[str] = None, - netuid: Optional[int] = None, # TODO why is this optional? - amount: Optional[Balance] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - safe_staking: bool = False, + netuid: int, + hotkey_ss58: str, + amount: Balance, allow_partial_stake: bool = False, + safe_unstaking: bool = False, rate_tolerance: float = 0.005, period: Optional[int] = None, - unstake_all: bool = False, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Removes a specified amount of stake from a single hotkey account. This function is critical for adjusting individual neuron stakes within the Bittensor network. - Arguments: - wallet: The wallet associated with the neuron from which the stake is being - removed. - hotkey_ss58: The `SS58` address of the hotkey account to unstake from. + Parameters: + wallet: The wallet associated with the neuron from which the stake is being removed. netuid: The unique identifier of the subnet. - amount: The amount of alpha to unstake. If not specified, unstakes all. - wait_for_inclusion: Waits for the transaction to be included in a block. Defaults to `True`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Defaults to `False`. - safe_staking: If true, enables price safety checks to protect against fluctuating prices. The unstake will - only execute if the price change doesn't exceed the rate tolerance. Default is False. + hotkey_ss58: The ``SS58`` address of the hotkey account to unstake from. + amount: The amount of alpha to unstake. If not specified, unstakes all. Alpha amount. allow_partial_stake: If true and safe_staking is enabled, allows partial unstaking when - the full amount would exceed the price threshold. If false, the entire unstake fails if it would exceed - the threshold. Default is False. - rate_tolerance: The maximum allowed price change ratio when unstaking. For example, 0.005 = 0.5% maximum - price decrease. Only used when safe_staking is True. Default is 0.005. - period: The number of blocks during which the transaction will remain valid after it's submitted. If the - transaction is not included in a block within that number of blocks, it will expire and be rejected. You - can think of it as an expiration date for the transaction. - unstake_all: If `True`, unstakes all tokens and `amount` is ignored. Default is `False` + the full amount would exceed the price tolerance. If false, the entire unstake fails if it would + exceed the tolerance. + rate_tolerance: The maximum allowed price change ratio when unstaking. For example, + 0.005 = 0.5% maximum price decrease. Only used when safe_staking is True. + safe_unstaking: If true, enables price safety checks to protect against fluctuating prices. The unstake + will only execute if the price change doesn't exceed the rate tolerance. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: bool: `True` if the unstaking process is successful, False otherwise. @@ -5597,13 +5675,13 @@ async def unstake( hotkey_ss58=hotkey_ss58, netuid=netuid, amount=amount, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - safe_staking=safe_staking, allow_partial_stake=allow_partial_stake, rate_tolerance=rate_tolerance, + safe_unstaking=safe_unstaking, period=period, - unstake_all=unstake_all, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) async def unstake_all( @@ -5612,23 +5690,25 @@ async def unstake_all( hotkey: str, netuid: int, rate_tolerance: Optional[float] = 0.005, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Unstakes all TAO/Alpha associated with a hotkey from the specified subnets on the Bittensor network. - Arguments: + Parameters: wallet: The wallet of the stake owner. hotkey: The SS58 address of the hotkey to unstake from. netuid: The unique identifier of the subnet. rate_tolerance: The maximum allowed price change ratio when unstaking. For example, 0.005 = 0.5% maximum price decrease. If not passed (None), then unstaking goes without price limit. Default is 0.005. - wait_for_inclusion: Waits for the transaction to be included in a block. Default is `True`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Default is `False`. - period: The number of blocks during which the transaction will remain valid after it's submitted. If the - transaction is not included in a block within that number of blocks, it will expire and be rejected. You - can think of it as an expiration date for the transaction. Default is `None`. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: tuple[bool, str]: @@ -5685,37 +5765,40 @@ async def unstake_all( hotkey=hotkey, netuid=netuid, rate_tolerance=rate_tolerance, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) async def unstake_multiple( self, wallet: "Wallet", - hotkey_ss58s: list[str], netuids: list[int], + hotkey_ss58s: list[str], amounts: Optional[list[Balance]] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - period: Optional[int] = None, unstake_all: bool = False, + period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Performs batch unstaking from multiple hotkey accounts, allowing a neuron to reduce its staked amounts efficiently. This function is useful for managing the distribution of stakes across multiple neurons. - Arguments: + Parameters: wallet: The wallet linked to the coldkey from which the stakes are being withdrawn. - hotkey_ss58s: A list of hotkey `SS58` addresses to unstake from. netuids: Subnets unique IDs. + hotkey_ss58s: A list of hotkey `SS58` addresses to unstake from. amounts: The amounts of TAO to unstake from each hotkey. If not provided, unstakes all. - wait_for_inclusion: Waits for the transaction to be included in a block. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. - period: The number of blocks during which the transaction will remain valid after it's submitted. If the - transaction is not included in a block within that number of blocks, it will expire and be rejected. You - can think of it as an expiration date for the transaction. unstake_all: If true, unstakes all tokens. Default is `False`. If `True` amounts are ignored. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: bool: `True` if the batch unstaking is successful, False otherwise. @@ -5726,13 +5809,14 @@ async def unstake_multiple( return await unstake_multiple_extrinsic( subtensor=self, wallet=wallet, - hotkey_ss58s=hotkey_ss58s, netuids=netuids, + hotkey_ss58s=hotkey_ss58s, amounts=amounts, + unstake_all=unstake_all, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, - unstake_all=unstake_all, ) diff --git a/bittensor/core/extrinsics/asyncex/children.py b/bittensor/core/extrinsics/asyncex/children.py index 46853642fe..7476ef8fb8 100644 --- a/bittensor/core/extrinsics/asyncex/children.py +++ b/bittensor/core/extrinsics/asyncex/children.py @@ -12,30 +12,31 @@ async def set_children_extrinsic( hotkey: str, netuid: int, children: list[tuple[float, str]], - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - raise_error: bool = False, period: Optional[int] = None, -): + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, +) -> tuple[bool, str]: """ Allows a coldkey to set children-keys. - Arguments: - subtensor: bittensor subtensor. + Parameters: + subtensor: The Subtensor client instance used for blockchain interaction. wallet: bittensor wallet instance. hotkey: The ``SS58`` address of the neuron's hotkey. netuid: The netuid value. children: A list of children with their proportions. - wait_for_inclusion: Waits for the transaction to be included in a block. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. - raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure of the operation, - and the second element is a message providing additional information. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. Raises: DuplicateChild: There are duplicates in the list of children. @@ -75,10 +76,10 @@ async def set_children_extrinsic( success, message = await subtensor.sign_and_send_extrinsic( call=call, wallet=wallet, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - raise_error=raise_error, - period=period, ) if not wait_for_finalization and not wait_for_inclusion: @@ -94,12 +95,29 @@ async def root_set_pending_childkey_cooldown_extrinsic( subtensor: "AsyncSubtensor", wallet: "Wallet", cooldown: int, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """ - Allows a coldkey to set children-keys. + Allows a root coldkey to set children-keys. + + Parameters: + subtensor: The Subtensor client instance used for blockchain interaction. + wallet: The wallet used to sign the extrinsic (must be unlocked). + cooldown: The cooldown period in blocks. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. + + Returns: + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. """ unlock = unlock_key(wallet) @@ -122,9 +140,10 @@ async def root_set_pending_childkey_cooldown_extrinsic( success, message = await subtensor.sign_and_send_extrinsic( call=sudo_call, wallet=wallet, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) if not wait_for_finalization and not wait_for_inclusion: diff --git a/bittensor/core/extrinsics/asyncex/commit_reveal.py b/bittensor/core/extrinsics/asyncex/commit_reveal.py index 78a7ef4824..fd1bd00f53 100644 --- a/bittensor/core/extrinsics/asyncex/commit_reveal.py +++ b/bittensor/core/extrinsics/asyncex/commit_reveal.py @@ -22,34 +22,37 @@ async def commit_reveal_extrinsic( netuid: int, uids: Union[NDArray[np.int64], "torch.LongTensor", list], weights: Union[NDArray[np.float32], "torch.FloatTensor", list], + block_time: Union[int, float] = 12.0, + commit_reveal_version: int = 4, version_key: int = version_as_int, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = False, wait_for_finalization: bool = False, - block_time: Union[int, float] = 12.0, - period: Optional[int] = None, - commit_reveal_version: int = 4, ) -> tuple[bool, str]: """ Commits and reveals weights for a given subtensor and wallet with provided uids and weights. - Arguments: - subtensor: The AsyncSubtensor instance. + Parameters: + subtensor: The Subtensor instance. wallet: The wallet to use for committing and revealing. netuid: The id of the network. uids: The uids to commit. weights: The weights associated with the uids. - version_key: The version key to use for committing and revealing. Default is version_as_int. - wait_for_inclusion: Whether to wait for the inclusion of the transaction. Default is False. - wait_for_finalization: Whether to wait for the finalization of the transaction. Default is False. - block_time (float): The number of seconds for block duration. Default is 12.0 seconds. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. - commit_reveal_version: The version of the chain commit-reveal protocol to use. Default is ``4``. + block_time: The number of seconds for block duration. + commit_reveal_version: The version of the chain commit-reveal protocol to use. + version_key: The version key to use for committing and revealing. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure, and the second - element is a message associated with the result + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. """ try: uids, weights = convert_and_normalize_weights_and_uids(uids, weights) @@ -96,6 +99,7 @@ async def commit_reveal_extrinsic( wait_for_finalization=wait_for_finalization, sign_with="hotkey", period=period, + raise_error=raise_error, ) if not success: diff --git a/bittensor/core/extrinsics/asyncex/liquidity.py b/bittensor/core/extrinsics/asyncex/liquidity.py index 8c41e1b66b..fc98f46631 100644 --- a/bittensor/core/extrinsics/asyncex/liquidity.py +++ b/bittensor/core/extrinsics/asyncex/liquidity.py @@ -18,26 +18,28 @@ async def add_liquidity_extrinsic( price_low: Balance, price_high: Balance, hotkey: Optional[str] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """ Adds liquidity to the specified price range. - Arguments: + Parameters: subtensor: The Subtensor client instance used for blockchain interaction. wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. liquidity: The amount of liquidity to be added. price_low: The lower bound of the price tick range. price_high: The upper bound of the price tick range. - hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. Defaults to `None`. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: Tuple[bool, str]: @@ -45,7 +47,7 @@ async def add_liquidity_extrinsic( - False and an error message if the submission fails or the wallet cannot be unlocked. Note: Adding is allowed even when user liquidity is enabled in specified subnet. Call - `toggle_user_liquidity_extrinsic` to enable/disable user liquidity. + `toggle_user_liquidity_extrinsic` to enable/disable user liquidity. """ if not (unlock := unlock_key(wallet)).success: logging.error(unlock.message) @@ -73,6 +75,7 @@ async def add_liquidity_extrinsic( wait_for_finalization=wait_for_finalization, use_nonce=True, period=period, + raise_error=raise_error, ) @@ -83,24 +86,26 @@ async def modify_liquidity_extrinsic( position_id: int, liquidity_delta: Balance, hotkey: Optional[str] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Modifies liquidity in liquidity position by adding or removing liquidity from it. - Arguments: + Parameters: subtensor: The Subtensor client instance used for blockchain interaction. wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. position_id: The id of the position record in the pool. liquidity_delta: The amount of liquidity to be added or removed (add if positive or remove if negative). hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. Defaults to `None`. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: Tuple[bool, str]: @@ -132,6 +137,7 @@ async def modify_liquidity_extrinsic( wait_for_finalization=wait_for_finalization, use_nonce=True, period=period, + raise_error=raise_error, ) @@ -141,31 +147,33 @@ async def remove_liquidity_extrinsic( netuid: int, position_id: int, hotkey: Optional[str] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Remove liquidity and credit balances back to wallet's hotkey stake. - Arguments: + Parameters: subtensor: The Subtensor client instance used for blockchain interaction. wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. position_id: The id of the position record in the pool. hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. Defaults to `None`. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: Tuple[bool, str]: - True and a success message if the extrinsic is successfully submitted or processed. - False and an error message if the submission fails or the wallet cannot be unlocked. - Note: Adding is allowed even when user liquidity is enabled in specified subnet. - Call `toggle_user_liquidity_extrinsic` to enable/disable user liquidity. + Note: Adding is allowed even when user liquidity is enabled in specified subnet. Call + `toggle_user_liquidity_extrinsic` to enable/disable user liquidity. """ if not (unlock := unlock_key(wallet)).success: logging.error(unlock.message) @@ -188,6 +196,7 @@ async def remove_liquidity_extrinsic( wait_for_finalization=wait_for_finalization, use_nonce=True, period=period, + raise_error=raise_error, ) @@ -196,22 +205,24 @@ async def toggle_user_liquidity_extrinsic( wallet: "Wallet", netuid: int, enable: bool, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Allow to toggle user liquidity for specified subnet. - Arguments: + Parameters: subtensor: The Subtensor client instance used for blockchain interaction. wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. enable: Boolean indicating whether to enable user liquidity. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: Tuple[bool, str]: @@ -234,4 +245,5 @@ async def toggle_user_liquidity_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) diff --git a/bittensor/core/extrinsics/asyncex/move_stake.py b/bittensor/core/extrinsics/asyncex/move_stake.py index d52f86f868..a401350251 100644 --- a/bittensor/core/extrinsics/asyncex/move_stake.py +++ b/bittensor/core/extrinsics/asyncex/move_stake.py @@ -45,26 +45,28 @@ async def transfer_stake_extrinsic( origin_netuid: int, destination_netuid: int, amount: Balance, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Transfers stake from one coldkey to another in the Bittensor network. - Args: - subtensor (AsyncSubtensor): The subtensor instance to interact with the blockchain. - wallet (Wallet): The wallet containing the coldkey to authorize the transfer. - destination_coldkey_ss58 (str): SS58 address of the destination coldkey. - hotkey_ss58 (str): SS58 address of the hotkey associated with the stake. - origin_netuid (int): Network UID of the origin subnet. - destination_netuid (int): Network UID of the destination subnet. - amount (Balance): The amount of stake to transfer as a `Balance` object. - wait_for_inclusion (bool): If True, waits for transaction inclusion in a block. Defaults to `True`. - wait_for_finalization (bool): If True, waits for transaction finalization. Defaults to `False`. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + Parameters: + subtensor: The subtensor instance to interact with the blockchain. + wallet: The wallet containing the coldkey to authorize the transfer. + destination_coldkey_ss58: SS58 address of the destination coldkey. + hotkey_ss58: SS58 address of the hotkey associated with the stake. + origin_netuid: Network UID of the origin subnet. + destination_netuid: Network UID of the destination subnet. + amount: The amount of stake to transfer as a `Balance` object. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: bool: True if the transfer was successful, False otherwise. @@ -108,12 +110,13 @@ async def transfer_stake_extrinsic( }, ) - success, err_msg = await subtensor.sign_and_send_extrinsic( + success, message = await subtensor.sign_and_send_extrinsic( call=call, wallet=wallet, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if success: @@ -141,7 +144,7 @@ async def transfer_stake_extrinsic( return True else: - logging.error(f":cross_mark: [red]Failed[/red]: {err_msg}") + logging.error(f":cross_mark: [red]Failed[/red]: {message}") return False except Exception as e: @@ -156,34 +159,37 @@ async def swap_stake_extrinsic( origin_netuid: int, destination_netuid: int, amount: Balance, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - safe_staking: bool = False, + safe_swapping: bool = False, allow_partial_stake: bool = False, rate_tolerance: float = 0.005, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Swaps stake from one subnet to another for a given hotkey in the Bittensor network. - Args: - subtensor (AsyncSubtensor): The subtensor instance to interact with the blockchain. - wallet (Wallet): The wallet containing the coldkey to authorize the swap. - hotkey_ss58 (str): SS58 address of the hotkey associated with the stake. - origin_netuid (int): Network UID of the origin subnet. - destination_netuid (int): Network UID of the destination subnet. - amount (Balance): The amount of stake to swap as a `Balance` object. - wait_for_inclusion (bool): If True, waits for transaction inclusion in a block. Defaults to True. - wait_for_finalization (bool): If True, waits for transaction finalization. Defaults to False. - safe_staking (bool): If true, enables price safety checks to protect against price impact. - allow_partial_stake (bool): If true, allows partial stake swaps when the full amount would exceed the price tolerance. - rate_tolerance (float): Maximum allowed increase in a price ratio (0.005 = 0.5%). - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + Parameters: + subtensor: Subtensor instance. + wallet: The wallet to swap stake from. + hotkey_ss58: The hotkey SS58 address associated with the stake. + origin_netuid: The source subnet UID. + destination_netuid: The destination subnet UID. + amount: Amount to swap. + safe_swapping: If true, enables price safety checks to protect against price impact. + allow_partial_stake: If true, allows partial stake swaps when the full amount would exceed the price tolerance. + rate_tolerance: Maximum allowed increase in a price ratio (0.005 = 0.5%). + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. + Returns: - bool: True if the swap was successful, False otherwise. + success (bool): True if the swap was successful. """ amount.set_unit(netuid=origin_netuid) @@ -212,7 +218,7 @@ async def swap_stake_extrinsic( "alpha_amount": amount.rao, } - if safe_staking: + if safe_swapping: origin_pool, destination_pool = await asyncio.gather( subtensor.subnet(netuid=origin_netuid), subtensor.subnet(netuid=destination_netuid), @@ -254,6 +260,7 @@ async def swap_stake_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if success: @@ -281,7 +288,7 @@ async def swap_stake_extrinsic( return True else: - if safe_staking and "Custom error: 8" in err_msg: + if safe_swapping and "Custom error: 8" in err_msg: logging.error( ":cross_mark: [red]Failed[/red]: Price ratio exceeded tolerance limit. Either increase price tolerance or enable partial staking." ) @@ -297,36 +304,38 @@ async def swap_stake_extrinsic( async def move_stake_extrinsic( subtensor: "AsyncSubtensor", wallet: "Wallet", - origin_hotkey: str, + origin_hotkey_ss58: str, origin_netuid: int, - destination_hotkey: str, + destination_hotkey_ss58: str, destination_netuid: int, - amount: Balance, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - period: Optional[int] = None, + amount: Optional[Balance] = None, move_all_stake: bool = False, + period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Moves stake from one hotkey to another within subnets in the Bittensor network. - Args: - subtensor: The subtensor instance to interact with the blockchain. - wallet: The wallet containing the coldkey to authorize the move. - origin_hotkey: SS58 address of the origin hotkey associated with the stake. - origin_netuid: Network UID of the origin subnet. - destination_hotkey: SS58 address of the destination hotkey. - destination_netuid: Network UID of the destination subnet. - amount: The amount of stake to move as a `Balance` object. - wait_for_inclusion: If True, waits for transaction inclusion in a block. Defaults to True. - wait_for_finalization: If True, waits for transaction finalization. Defaults to False. + Parameters: + subtensor: Subtensor instance. + wallet: The wallet to move stake from. + origin_hotkey_ss58: The SS58 address of the source hotkey. + origin_netuid: The netuid of the source subnet. + destination_hotkey_ss58: The SS58 address of the destination hotkey. + destination_netuid: The netuid of the destination subnet. + amount: Amount to move. + move_all_stake: If true, moves all stake from the source hotkey to the destination hotkey. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - move_all_stake: If true, moves all stake from the source hotkey to the destination hotkey. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - bool: True if the move was successful, False otherwise. + success: True if the move was successful. Otherwise, False. """ if not amount and not move_all_stake: logging.error( @@ -337,19 +346,19 @@ async def move_stake_extrinsic( # Check sufficient stake stake_in_origin, stake_in_destination = await _get_stake_in_origin_and_dest( subtensor=subtensor, - origin_hotkey_ss58=origin_hotkey, - destination_hotkey_ss58=destination_hotkey, - origin_coldkey_ss58=wallet.coldkeypub.ss58_address, - destination_coldkey_ss58=wallet.coldkeypub.ss58_address, + origin_hotkey_ss58=origin_hotkey_ss58, + destination_hotkey_ss58=destination_hotkey_ss58, origin_netuid=origin_netuid, destination_netuid=destination_netuid, + origin_coldkey_ss58=wallet.coldkeypub.ss58_address, + destination_coldkey_ss58=wallet.coldkeypub.ss58_address, ) if move_all_stake: amount = stake_in_origin elif stake_in_origin < amount: logging.error( - f":cross_mark: [red]Failed[/red]: Insufficient stake in origin hotkey: {origin_hotkey}. " + f":cross_mark: [red]Failed[/red]: Insufficient stake in origin hotkey: {origin_hotkey_ss58}. " f"Stake: {stake_in_origin}, amount: {amount}" ) return False @@ -358,7 +367,7 @@ async def move_stake_extrinsic( try: logging.info( - f"Moving stake from hotkey [blue]{origin_hotkey}[/blue] to hotkey [blue]{destination_hotkey}[/blue]\n" + f"Moving stake from hotkey [blue]{origin_hotkey_ss58}[/blue] to hotkey [blue]{destination_hotkey_ss58}[/blue]\n" f"Amount: [green]{amount}[/green] from netuid [yellow]{origin_netuid}[/yellow] to netuid " f"[yellow]{destination_netuid}[/yellow]" ) @@ -366,20 +375,21 @@ async def move_stake_extrinsic( call_module="SubtensorModule", call_function="move_stake", call_params={ - "origin_hotkey": origin_hotkey, + "origin_hotkey": origin_hotkey_ss58, "origin_netuid": origin_netuid, - "destination_hotkey": destination_hotkey, + "destination_hotkey": destination_hotkey_ss58, "destination_netuid": destination_netuid, "alpha_amount": amount.rao, }, ) - success, err_msg = await subtensor.sign_and_send_extrinsic( + success, message = await subtensor.sign_and_send_extrinsic( call=call, wallet=wallet, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if success: @@ -391,8 +401,8 @@ async def move_stake_extrinsic( # Get updated stakes origin_stake, dest_stake = await _get_stake_in_origin_and_dest( subtensor=subtensor, - origin_hotkey_ss58=origin_hotkey, - destination_hotkey_ss58=destination_hotkey, + origin_hotkey_ss58=origin_hotkey_ss58, + destination_hotkey_ss58=destination_hotkey_ss58, origin_coldkey_ss58=wallet.coldkeypub.ss58_address, destination_coldkey_ss58=wallet.coldkeypub.ss58_address, origin_netuid=origin_netuid, @@ -407,7 +417,7 @@ async def move_stake_extrinsic( return True else: - logging.error(f":cross_mark: [red]Failed[/red]: {err_msg}") + logging.error(f":cross_mark: [red]Failed[/red]: {message}") return False except Exception as e: diff --git a/bittensor/core/extrinsics/asyncex/registration.py b/bittensor/core/extrinsics/asyncex/registration.py index 051c1badf8..2e67368be5 100644 --- a/bittensor/core/extrinsics/asyncex/registration.py +++ b/bittensor/core/extrinsics/asyncex/registration.py @@ -23,29 +23,26 @@ async def burned_register_extrinsic( subtensor: "AsyncSubtensor", wallet: "Wallet", netuid: int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """Registers the wallet to chain by recycling TAO. - Args: + Parameters: subtensor: Subtensor instance. wallet: Bittensor wallet object. netuid: The ``netuid`` of the subnet to register on. - wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning ``True``, or returns - ``False`` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning ``True``, - or returns ``False`` if the extrinsic fails to be finalized within the timeout. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - raise_error: raises the relevant exception rather than returning `False` if unsuccessful. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - success (bool): Flag is ``True`` if extrinsic was finalized or included in the block. If we did not wait for - finalization / inclusion, the response is ``True``. + success: True if the extrinsic was successful. Otherwise, False. """ block_hash = await subtensor.substrate.get_chain_head() if not await subtensor.subnet_exists(netuid, block_hash=block_hash): @@ -139,21 +136,23 @@ async def burned_register_extrinsic( async def register_subnet_extrinsic( subtensor: "AsyncSubtensor", wallet: "Wallet", - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Registers a new subnetwork on the Bittensor blockchain asynchronously. - Args: - subtensor (AsyncSubtensor): The async subtensor interface to send the extrinsic. - wallet (Wallet): The wallet to be used for subnet registration. - wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning true. - wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning true. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + Parameters: + subtensor: The subtensor interface to send the extrinsic. + wallet: The wallet to be used for subnet registration. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: bool: True if the subnet registration was successful, False otherwise. @@ -182,6 +181,7 @@ async def register_subnet_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if not wait_for_finalization and not wait_for_inclusion: @@ -201,8 +201,6 @@ async def register_extrinsic( subtensor: "AsyncSubtensor", wallet: "Wallet", netuid: int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, max_allowed_attempts: int = 3, output_in_place: bool = True, cuda: bool = False, @@ -212,33 +210,36 @@ async def register_extrinsic( update_interval: Optional[int] = None, log_verbose: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: - """Registers the wallet to the chain. - - Args: - subtensor (bittensor.core.async_subtensor.AsyncSubtensor): initialized AsyncSubtensor object to use for chain - interactions - wallet (bittensor_wallet.Wallet): Bittensor wallet object. - netuid (int): The ``netuid`` of the subnet to register on. - wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning `True`, or returns - `False` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning - `True`, or returns `False` if the extrinsic fails to be finalized within the timeout. - max_allowed_attempts (int): Maximum number of attempts to register the wallet. - output_in_place (bool): Whether the POW solving should be outputted to the console as it goes along. - cuda (bool): If `True`, the wallet should be registered using CUDA device(s). + """Registers a neuron on the Bittensor subnet with provided netuid using the provided wallet. + + Registration is a critical step for a neuron to become an active participant in the network, enabling it to stake, + set weights, and receive incentives. + + Parameters: + subtensor: Subtensor object to use for chain interactions + wallet: Bittensor wallet object. + netuid: The ``netuid`` of the subnet to register on. + max_allowed_attempts: Maximum number of attempts to register the wallet. + output_in_place: Whether the POW solving should be outputted to the console as it goes along. + cuda: If `True`, the wallet should be registered using CUDA device(s). dev_id: The CUDA device id to use, or a list of device ids. tpb: The number of threads per block (CUDA). num_processes: The number of processes to use to register. update_interval: The number of nonces to solve between updates. log_verbose: If `True`, the registration process will log more information. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - `True` if extrinsic was finalized or included in the block. If we did not wait for finalization/inclusion, the - response is `True`. + bool: True if the subnet registration was successful, False otherwise. """ block_hash = await subtensor.substrate.get_chain_head() logging.debug("[magenta]Checking subnet status... [/magenta]") @@ -343,6 +344,7 @@ async def register_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if not success: @@ -405,34 +407,37 @@ async def set_subnet_identity_extrinsic( discord: str, description: str, additional: str, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """ Set the identity information for a given subnet. - Arguments: - subtensor (AsyncSubtensor): An instance of the Subtensor class to interact with the blockchain. - wallet (Wallet): A wallet instance used to sign and submit the extrinsic. - netuid (int): The unique ID for the subnet. - subnet_name (str): The name of the subnet to assign the identity information. - github_repo (str): URL of the GitHub repository related to the subnet. - subnet_contact (str): Subnet's contact information, e.g., email or contact link. - subnet_url (str): The URL of the subnet's primary web portal. - logo_url (str): The URL of the logo's primary web portal. - discord (str): Discord server or contact for the subnet. - description (str): A textual description of the subnet. - additional (str): Any additional metadata or information related to the subnet. - wait_for_inclusion (bool): Whether to wait for the extrinsic inclusion in a block (default: False). - wait_for_finalization (bool): Whether to wait for the extrinsic finalization in a block (default: True). - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + Parameters: + subtensor: An instance of the Subtensor class to interact with the blockchain. + wallet: A wallet instance used to sign and submit the extrinsic. + netuid: The unique ID for the subnet. + subnet_name: The name of the subnet to assign the identity information. + github_repo: URL of the GitHub repository related to the subnet. + subnet_contact: Subnet's contact information, e.g., email or contact link. + subnet_url: The URL of the subnet's primary web portal. + logo_url: The URL of the logo's primary web portal. + discord: Discord server or contact for the subnet. + description: A textual description of the subnet. + additional: Any additional metadata or information related to the subnet. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - tuple[bool, str]: A tuple where the first element indicates success or failure (True/False), and the second - element contains a descriptive message. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. """ if not (unlock := unlock_key(wallet)).success: @@ -462,6 +467,7 @@ async def set_subnet_identity_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if not wait_for_finalization and not wait_for_inclusion: diff --git a/bittensor/core/extrinsics/asyncex/root.py b/bittensor/core/extrinsics/asyncex/root.py index bab6f0b230..bb318cdb90 100644 --- a/bittensor/core/extrinsics/asyncex/root.py +++ b/bittensor/core/extrinsics/asyncex/root.py @@ -37,26 +37,26 @@ async def _get_limits(subtensor: "AsyncSubtensor") -> tuple[int, float]: async def root_register_extrinsic( subtensor: "AsyncSubtensor", wallet: "Wallet", + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = True, - period: Optional[int] = None, ) -> bool: - """Registers the wallet to the root network. + """ + Registers the neuron to the root network. Arguments: - subtensor (bittensor.core.async_subtensor.AsyncSubtensor): The AsyncSubtensor object - wallet (bittensor_wallet.Wallet): Bittensor wallet object. - wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning `True`, or returns - `False` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning - `True`, or returns `False` if the extrinsic fails to be finalized within the timeout. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + subtensor: Subtensor instance to interact with the blockchain. + wallet: Bittensor Wallet instance. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - `True` if extrinsic was finalized or included in the block. If we did not wait for finalization/inclusion, - the response is `True`. + bool: True if the subnet registration was successful, False otherwise. """ netuid = 0 logging.info( @@ -114,6 +114,7 @@ async def root_register_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if not success: diff --git a/bittensor/core/extrinsics/asyncex/serving.py b/bittensor/core/extrinsics/asyncex/serving.py index ffd952e049..6a511718d1 100644 --- a/bittensor/core/extrinsics/asyncex/serving.py +++ b/bittensor/core/extrinsics/asyncex/serving.py @@ -76,35 +76,34 @@ async def serve_extrinsic( netuid: int, placeholder1: int = 0, placeholder2: int = 0, - wait_for_inclusion: bool = False, - wait_for_finalization=True, certificate: Optional[Certificate] = None, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: - """Subscribes a Bittensor endpoint to the subtensor chain. - - Args: - subtensor (bittensor.core.async_subtensor.AsyncSubtensor): Subtensor instance object. - wallet (bittensor_wallet.Wallet): Bittensor wallet object. - ip (str): Endpoint host port i.e., ``192.122.31.4``. - port (int): Endpoint port number i.e., ``9221``. - protocol (int): An ``int`` representation of the protocol. - netuid (int): The network uid to serve on. - placeholder1 (int): A placeholder for future use. - placeholder2 (int): A placeholder for future use. - wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning ``True``, or - returns ``False`` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning - ``True``, or returns ``False`` if the extrinsic fails to be finalized within the timeout. - certificate (bittensor.utils.Certificate): Certificate to use for TLS. If ``None``, no TLS will be used. - Defaults to ``None``. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + """ + Subscribes a Bittensor endpoint to the subtensor chain. + + Parameters: + subtensor: Subtensor instance object. + wallet: Bittensor wallet object. + ip: Endpoint host port i.e., ``192.122.31.4``. + port: Endpoint port number i.e., ``9221``. + protocol: An ``int`` representation of the protocol. + netuid: The network uid to serve on. + placeholder1: A placeholder for future use. + placeholder2: A placeholder for future use. + certificate: Certificate to use for TLS. If ``None``, no TLS will be used. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - success (bool): Flag is ``True`` if extrinsic was finalized or included in the block. If we did not wait for - finalization / inclusion, the response is ``True``. + bool: True if the subnet registration was successful, False otherwise. """ # Decrypt hotkey if not (unlock := unlock_key(wallet, "hotkey")).success: @@ -141,13 +140,25 @@ async def serve_extrinsic( f"Serving axon with: [blue]AxonInfo({wallet.hotkey.ss58_address}, {ip}:{port})[/blue] -> " f"[green]{subtensor.network}:{netuid}[/green]" ) - success, message = await do_serve_axon( - subtensor=subtensor, + + if params.certificate is None: + call_function = "serve_axon" + else: + call_function = "serve_axon_tls" + + call = await subtensor.substrate.compose_call( + call_module="SubtensorModule", + call_function=call_function, + call_params=params.dict(), + ) + success, message = await subtensor.sign_and_send_extrinsic( + call=call, wallet=wallet, - call_params=params, - wait_for_finalization=wait_for_finalization, wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + sign_with="hotkey", period=period, + raise_error=raise_error, ) if success: @@ -165,30 +176,30 @@ async def serve_axon_extrinsic( subtensor: "AsyncSubtensor", netuid: int, axon: "Axon", - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, certificate: Optional[Certificate] = None, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: - """Serves the axon to the network. + """ + Serves the axon to the network. - Args: - subtensor (bittensor.core.async_subtensor.AsyncSubtensor): Subtensor instance object. + Parameters: + subtensor: AsyncSubtensor instance object. netuid (int): The ``netuid`` being served on. axon (bittensor.core.axon.Axon): Axon to serve. - wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning ``True``, or - returns ``False`` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning - ``True``, or returns ``False`` if the extrinsic fails to be finalized within the timeout. certificate (bittensor.utils.Certificate): Certificate to use for TLS. If ``None``, no TLS will be used. Defaults to ``None``. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - success (bool): Flag is ``True`` if extrinsic was finalized or included in the block. If we did not wait for - finalization / inclusion, the response is ``True``. + bool: True if the subnet registration was successful, False otherwise. """ if not (unlock := unlock_key(axon.wallet, "hotkey")).success: logging.error(unlock.message) @@ -219,10 +230,11 @@ async def serve_axon_extrinsic( port=external_port, protocol=4, netuid=netuid, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, certificate=certificate, period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) return serve_success @@ -233,34 +245,34 @@ async def publish_metadata( netuid: int, data_type: str, data: Union[bytes, dict], - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, reset_bonds: bool = False, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Publishes metadata on the Bittensor network using the specified wallet and network identifier. - Args: - subtensor (bittensor.subtensor): The subtensor instance representing the Bittensor blockchain connection. - wallet (bittensor.wallet): The wallet object used for authentication in the transaction. - netuid (int): Network UID on which the metadata is to be published. - data_type (str): The data type of the information being submitted. It should be one of the following: + Parameters: + subtensor: The subtensor instance representing the Bittensor blockchain connection. + wallet: The wallet object used for authentication in the transaction. + netuid: Network UID on which the metadata is to be published. + data_type: The data type of the information being submitted. It should be one of the following: ``'Sha256'``, ``'Blake256'``, ``'Keccak256'``, or ``'Raw0-128'``. This specifies the format or hashing algorithm used for the data. - data (Union[bytes, dict]): The actual metadata content to be published. This should be formatted or hashed + data: The actual metadata content to be published. This should be formatted or hashed according to the ``type`` specified. (Note: max ``str`` length is 128 bytes for ``'Raw0-128'``.) - wait_for_inclusion (bool, optional): If ``True``, the function will wait for the extrinsic to be included in a - block before returning. Defaults to ``False``. - wait_for_finalization (bool, optional): If ``True``, the function will wait for the extrinsic to be finalized - on the chain before returning. Defaults to ``True``. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. - reset_bonds (bool): If `True`, the function will reset the bonds for the neuron. Defaults to `False`. + reset_bonds: If `True`, the function will reset the bonds for the neuron. Defaults to `False`. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - bool: ``True`` if the metadata was successfully published (and finalized if specified). ``False`` otherwise. + bool: True if the subnet registration was successful, False otherwise. Raises: MetadataError: If there is an error in submitting the extrinsic, or if the response from the blockchain indicates @@ -292,6 +304,7 @@ async def publish_metadata( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if success: @@ -330,7 +343,20 @@ async def get_last_bonds_reset( block_hash: Optional[str] = None, reuse_block: bool = False, ) -> bytes: - """Fetches the last bonds reset triggered at commitment from the blockchain for a given hotkey and netuid.""" + """ + Fetches the last bonds reset triggered at commitment from the blockchain for a given hotkey and netuid. + + Parameters: + subtensor: Subtensor instance object. + netuid: The network uid to fetch from. + hotkey: The hotkey of the neuron for which to fetch the last bonds reset. + block: The block number to query. If ``None``, the latest block is used. + block_hash: The hash of the block to retrieve the parameter from. Do not specify if using block or reuse_block. + reuse_block: Whether to use the last-used block. Do not set if using block_hash or block. + + Returns: + bytes: The last bonds reset data for the specified hotkey and netuid. + """ block_hash = await subtensor.determine_block_hash(block, block_hash, reuse_block) block = await subtensor.substrate.query( module="Commitments", diff --git a/bittensor/core/extrinsics/asyncex/staking.py b/bittensor/core/extrinsics/asyncex/staking.py index 76ffe73285..c06c58cd78 100644 --- a/bittensor/core/extrinsics/asyncex/staking.py +++ b/bittensor/core/extrinsics/asyncex/staking.py @@ -16,43 +16,40 @@ async def add_stake_extrinsic( subtensor: "AsyncSubtensor", wallet: "Wallet", - old_balance: Optional[Balance] = None, - hotkey_ss58: Optional[str] = None, - netuid: Optional[int] = None, - amount: Optional[Balance] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, + netuid: int, + hotkey_ss58: str, + amount: Balance, safe_staking: bool = False, allow_partial_stake: bool = False, rate_tolerance: float = 0.005, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Adds a stake from the specified wallet to the neuron identified by the SS58 address of its hotkey in specified subnet. - Staking is a fundamental process in the Bittensor network that enables neurons to participate actively and earn incentives. + Staking is a fundamental process in the Bittensor network that enables neurons to participate actively and earn + incentives. - Arguments: + Parameters: subtensor: Subtensor instance with the connection to the chain. wallet: Bittensor wallet object. - old_balance: the balance prior to the staking - hotkey_ss58: The `ss58` address of the hotkey account to stake to default to the wallet's hotkey. If not - specified, the wallet's hotkey will be used. Defaults to ``None``. netuid: The unique identifier of the subnet to which the neuron belongs. - amount: Amount to stake as Bittensor balance in TAO always, `None` if staking all. Defaults is ``None``. - wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning `True`, or returns - `False` if the extrinsic fails to enter the block within the timeout. Defaults to ``True``. - wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning `True`, - or returns `False` if the extrinsic fails to be finalized within the timeout. Defaults to ``False``. + hotkey_ss58: The `ss58` address of the hotkey account to stake to default to the wallet's hotkey. + amount: Amount to stake as Bittensor balance in TAO always. safe_staking: If True, enables price safety checks. Default is ``False``. allow_partial_stake: If True, allows partial unstaking if price tolerance exceeded. Default is ``False``. rate_tolerance: Maximum allowed price increase percentage (0.005 = 0.5%). Default is ``0.005``. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. Defaults to ``None``. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - success: Flag is `True` if extrinsic was finalized or included in the block. If we did not wait for - finalization/inclusion, the response is `True`. + bool: True if the subnet registration was successful, False otherwise. Raises: SubstrateRequestException: Raised if the extrinsic fails to be included in the block within the timeout. @@ -63,15 +60,10 @@ async def add_stake_extrinsic( logging.error(unlock.message) return False - # Default to wallet's own hotkey if the value is not passed. - if hotkey_ss58 is None: - hotkey_ss58 = wallet.hotkey.ss58_address - logging.info( f":satellite: [magenta]Syncing with chain:[/magenta] [blue]{subtensor.network}[/blue] [magenta]...[/magenta]" ) - if not old_balance: - old_balance = await subtensor.get_balance(wallet.coldkeypub.ss58_address) + old_balance = await subtensor.get_balance(wallet.coldkeypub.ss58_address) block_hash = await subtensor.substrate.get_chain_head() # Get current stake and existential deposit @@ -85,134 +77,116 @@ async def add_stake_extrinsic( subtensor.get_existential_deposit(block_hash=block_hash), ) - # Convert to bittensor.Balance - if amount is None: - # Stake it all. - staking_balance = Balance.from_tao(old_balance.tao) - logging.warning( - f"Didn't receive any staking amount. Staking all available balance: [blue]{staking_balance}[/blue] " - f"from wallet: [blue]{wallet.name}[/blue]" - ) - else: - staking_balance = amount - # Leave existential balance to keep key alive. - if staking_balance > old_balance - existential_deposit: + if amount > old_balance - existential_deposit: # If we are staking all, we need to leave at least the existential deposit. - staking_balance = old_balance - existential_deposit + amount = old_balance - existential_deposit else: - staking_balance = staking_balance + amount = amount # Check enough to stake. - if staking_balance > old_balance: + if amount > old_balance: logging.error(":cross_mark: [red]Not enough stake:[/red]") logging.error(f"\t\tbalance:{old_balance}") - logging.error(f"\t\tamount: {staking_balance}") + logging.error(f"\t\tamount: {amount}") logging.error(f"\t\twallet: {wallet.name}") return False - try: - call_params = { - "hotkey": hotkey_ss58, - "netuid": netuid, - "amount_staked": staking_balance.rao, - } - - if safe_staking: - pool = await subtensor.subnet(netuid=netuid) - base_price = pool.price.tao + call_params = { + "hotkey": hotkey_ss58, + "netuid": netuid, + "amount_staked": amount.rao, + } - if pool.netuid == 0: - price_with_tolerance = base_price - else: - price_with_tolerance = base_price * (1 + rate_tolerance) + if safe_staking: + pool = await subtensor.subnet(netuid=netuid) + base_price = pool.price.tao - logging.info( - f":satellite: [magenta]Safe Staking to:[/magenta] " - f"[blue]netuid: [green]{netuid}[/green], amount: [green]{staking_balance}[/green], " - f"tolerance percentage: [green]{rate_tolerance * 100}%[/green], " - f"price limit: [green]{price_with_tolerance}[/green], " - f"original price: [green]{base_price}[/green], " - f"with partial stake: [green]{allow_partial_stake}[/green] " - f"on [blue]{subtensor.network}[/blue][/magenta]...[/magenta]" - ) + price_with_tolerance = ( + base_price if pool.netuid == 0 else base_price * (1 + rate_tolerance) + ) - limit_price = Balance.from_tao(price_with_tolerance).rao - call_params.update( - { - "limit_price": limit_price, - "allow_partial": allow_partial_stake, - } - ) - call_function = "add_stake_limit" - else: - logging.info( - f":satellite: [magenta]Staking to:[/magenta] " - f"[blue]netuid: [green]{netuid}[/green], amount: [green]{staking_balance}[/green] " - f"on [blue]{subtensor.network}[/blue][magenta]...[/magenta]" - ) - call_function = "add_stake" + logging.info( + f":satellite: [magenta]Safe Staking to:[/magenta] " + f"[blue]netuid: [green]{netuid}[/green], amount: [green]{amount}[/green], " + f"tolerance percentage: [green]{rate_tolerance * 100}%[/green], " + f"price limit: [green]{price_with_tolerance}[/green], " + f"original price: [green]{base_price}[/green], " + f"with partial stake: [green]{allow_partial_stake}[/green] " + f"on [blue]{subtensor.network}[/blue][/magenta]...[/magenta]" + ) - call = await subtensor.substrate.compose_call( - call_module="SubtensorModule", - call_function=call_function, - call_params=call_params, + limit_price = Balance.from_tao(price_with_tolerance).rao + call_params.update( + { + "limit_price": limit_price, + "allow_partial": allow_partial_stake, + } ) - staking_response, err_msg = await subtensor.sign_and_send_extrinsic( - call=call, - wallet=wallet, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - nonce_key="coldkeypub", - sign_with="coldkey", - use_nonce=True, - period=period, + call_function = "add_stake_limit" + else: + logging.info( + f":satellite: [magenta]Staking to:[/magenta] " + f"[blue]netuid: [green]{netuid}[/green], amount: [green]{amount}[/green] " + f"on [blue]{subtensor.network}[/blue][magenta]...[/magenta]" ) - if staking_response is True: # If we successfully staked. - # We only wait here if we expect finalization. - if not wait_for_finalization and not wait_for_inclusion: - return True + call_function = "add_stake" - logging.success(":white_heavy_check_mark: [green]Finalized[/green]") + call = await subtensor.substrate.compose_call( + call_module="SubtensorModule", + call_function=call_function, + call_params=call_params, + ) + success, message = await subtensor.sign_and_send_extrinsic( + call=call, + wallet=wallet, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + nonce_key="coldkeypub", + sign_with="coldkey", + use_nonce=True, + period=period, + raise_error=raise_error, + ) + if success: # If we successfully staked. + # We only wait here if we expect finalization. + if not wait_for_finalization and not wait_for_inclusion: + return True - logging.info( - f":satellite: [magenta]Checking Balance on:[/magenta] " - f"[blue]{subtensor.network}[/blue] [magenta]...[/magenta]" - ) - new_block_hash = await subtensor.substrate.get_chain_head() - new_balance, new_stake = await asyncio.gather( - subtensor.get_balance( - wallet.coldkeypub.ss58_address, block_hash=new_block_hash - ), - subtensor.get_stake( - coldkey_ss58=wallet.coldkeypub.ss58_address, - hotkey_ss58=hotkey_ss58, - netuid=netuid, - block_hash=new_block_hash, - ), - ) + logging.success(":white_heavy_check_mark: [green]Finalized[/green]") - logging.info( - f"Balance: [blue]{old_balance}[/blue] :arrow_right: [green]{new_balance}[/green]" - ) - logging.info( - f"Stake: [blue]{old_stake}[/blue] :arrow_right: [green]{new_stake}[/green]" - ) - return True - else: - if safe_staking and "Custom error: 8" in err_msg: - logging.error( - ":cross_mark: [red]Failed[/red]: Price exceeded tolerance limit. Either increase price tolerance or enable partial staking." - ) - else: - logging.error(f":cross_mark: [red]Failed: {err_msg}.[/red]") - return False + logging.info( + f":satellite: [magenta]Checking Balance on:[/magenta] " + f"[blue]{subtensor.network}[/blue] [magenta]...[/magenta]" + ) + new_block_hash = await subtensor.substrate.get_chain_head() + new_balance, new_stake = await asyncio.gather( + subtensor.get_balance( + wallet.coldkeypub.ss58_address, block_hash=new_block_hash + ), + subtensor.get_stake( + coldkey_ss58=wallet.coldkeypub.ss58_address, + hotkey_ss58=hotkey_ss58, + netuid=netuid, + block_hash=new_block_hash, + ), + ) - except SubstrateRequestException as error: + logging.info( + f"Balance: [blue]{old_balance}[/blue] :arrow_right: [green]{new_balance}[/green]" + ) + logging.info( + f"Stake: [blue]{old_stake}[/blue] :arrow_right: [green]{new_stake}[/green]" + ) + return True + + if safe_staking and "Custom error: 8" in message: logging.error( - f":cross_mark: [red]Add Stake Error: {format_error_message(error)}[/red]" + ":cross_mark: [red]Failed[/red]: Price exceeded tolerance limit. Either increase price tolerance or enable partial staking." ) - return False + else: + logging.error(f":cross_mark: [red]Failed: {message}.[/red]") + return False async def add_stake_multiple_extrinsic( @@ -220,62 +194,62 @@ async def add_stake_multiple_extrinsic( wallet: "Wallet", hotkey_ss58s: list[str], netuids: list[int], - old_balance: Optional[Balance] = None, - amounts: Optional[list[Balance]] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, + amounts: list[Balance], period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: - """Adds a stake to each ``hotkey_ss58`` in the list, using each amount, from a common coldkey. + """ + Adds stake to each ``hotkey_ss58`` in the list, using each amount, from a common coldkey on subnet with + corresponding netuid. - Arguments: - subtensor: The initialized SubtensorInterface object. + Parameters: + subtensor: Subtensor instance with the connection to the chain. wallet: Bittensor wallet object for the coldkey. - old_balance: The balance of the wallet prior to staking. - hotkey_ss58s: List of hotkeys to stake to. netuids: List of netuids to stake to. - amounts: List of amounts to stake. If `None`, stake all to the first hotkey. - wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning `True`, or returns `False` - if the extrinsic fails to enter the block within the timeout. - wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning `True`, or - returns `False` if the extrinsic fails to be finalized within the timeout. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + hotkey_ss58s: List of hotkeys to stake to. + amounts: List of corresponding TAO amounts to bet for each netuid and hotkey. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - success: `True` if extrinsic was finalized or included in the block. `True` if any wallet was staked. If we did - not wait for finalization/inclusion, the response is `True`. + bool: True if the subnet registration was successful, False otherwise. """ - if not isinstance(hotkey_ss58s, list) or not all( - isinstance(hotkey_ss58, str) for hotkey_ss58 in hotkey_ss58s - ): - raise TypeError("hotkey_ss58s must be a list of str") + # Decrypt keys, + if not (unlock := unlock_key(wallet)).success: + logging.error(unlock.message) + return False + + assert all( + [ + isinstance(netuids, list), + isinstance(hotkey_ss58s, list), + isinstance(amounts, list), + ] + ), "The `netuids`, `hotkey_ss58s` and `amounts` must be lists." if len(hotkey_ss58s) == 0: return True - if amounts is not None and len(amounts) != len(hotkey_ss58s): - raise ValueError("amounts must be a list of the same length as hotkey_ss58s") + assert len(netuids) == len(hotkey_ss58s) == len(amounts), ( + "The number of items in `netuids`, `hotkey_ss58s` and `amounts` must be the same." + ) - if len(netuids) != len(hotkey_ss58s): - raise ValueError("netuids must be a list of the same length as hotkey_ss58s") + if not all(isinstance(hotkey_ss58, str) for hotkey_ss58 in hotkey_ss58s): + raise TypeError("hotkey_ss58s must be a list of str") - new_amounts: Sequence[Optional[Balance]] - if amounts is None: - new_amounts = [None] * len(hotkey_ss58s) - else: - new_amounts = [ - amount.set_unit(netuid=netuid) for amount, netuid in zip(amounts, netuids) - ] - if sum(amount.tao for amount in new_amounts) == 0: - # Staking 0 tao - return True + new_amounts: Sequence[Optional[Balance]] = [ + amount.set_unit(netuid) for amount, netuid in zip(amounts, netuids) + ] - # Decrypt keys, - if not (unlock := unlock_key(wallet)).success: - logging.error(unlock.message) - return False + if sum(amount.tao for amount in new_amounts) == 0: + # Staking 0 tao + return True logging.info( f":satellite: [magenta]Syncing with chain:[/magenta] [blue]{subtensor.network}[/blue] [magenta]...[/magenta]" @@ -294,11 +268,9 @@ async def add_stake_multiple_extrinsic( total_staking_rao = sum( [amount.rao if amount is not None else 0 for amount in new_amounts] ) - if old_balance is None: - old_balance = await subtensor.get_balance( - wallet.coldkeypub.ss58_address, block_hash=block_hash - ) - initial_balance = old_balance + old_balance = initial_balance = await subtensor.get_balance( + wallet.coldkeypub.ss58_address, block_hash=block_hash + ) if total_staking_rao == 0: # Staking all to the first wallet. @@ -320,28 +292,17 @@ async def add_stake_multiple_extrinsic( for idx, (hotkey_ss58, amount, old_stake, netuid) in enumerate( zip(hotkey_ss58s, new_amounts, old_stakes, netuids) ): - staking_all = False - # Convert to bittensor.Balance - if amount is None: - # Stake it all. - staking_balance = Balance.from_tao(old_balance.tao) - staking_all = True - else: - # Amounts are cast to balance earlier in the function - assert isinstance(amount, Balance) - staking_balance = amount - # Check enough to stake - if staking_balance > old_balance: + if amount > old_balance: logging.error( f":cross_mark: [red]Not enough balance[/red]: [green]{old_balance}[/green] to stake: " - f"[blue]{staking_balance}[/blue] from wallet: [white]{wallet.name}[/white]" + f"[blue]{amount}[/blue] from wallet: [white]{wallet.name}[/white]" ) continue try: logging.info( - f"Staking [blue]{staking_balance}[/blue] to hotkey: [magenta]{hotkey_ss58}[/magenta] on netuid: " + f"Staking [blue]{amount}[/blue] to hotkey: [magenta]{hotkey_ss58}[/magenta] on netuid: " f"[blue]{netuid}[/blue]" ) call = await subtensor.substrate.compose_call( @@ -349,7 +310,7 @@ async def add_stake_multiple_extrinsic( call_function="add_stake", call_params={ "hotkey": hotkey_ss58, - "amount_staked": staking_balance.rao, + "amount_staked": amount.rao, "netuid": netuid, }, ) @@ -362,18 +323,14 @@ async def add_stake_multiple_extrinsic( sign_with="coldkey", use_nonce=True, period=period, + raise_error=raise_error, ) - if success is True: # If we successfully staked. - # We only wait here if we expect finalization. - + # If we successfully staked. + if success: if not wait_for_finalization and not wait_for_inclusion: - old_balance -= staking_balance + old_balance -= amount successful_stakes += 1 - if staking_all: - # If staked all, no need to continue - break - continue logging.success(":white_heavy_check_mark: [green]Finalized[/green]") @@ -399,10 +356,6 @@ async def add_stake_multiple_extrinsic( ) old_balance = new_balance successful_stakes += 1 - if staking_all: - # If staked all, no need to continue - break - else: logging.error(f":cross_mark: [red]Failed: {message}.[/red]") continue @@ -411,7 +364,6 @@ async def add_stake_multiple_extrinsic( logging.error( f":cross_mark: [red]Add Stake Multiple error: {format_error_message(error)}[/red]" ) - continue if successful_stakes != 0: logging.info( diff --git a/bittensor/core/extrinsics/asyncex/start_call.py b/bittensor/core/extrinsics/asyncex/start_call.py index 63f6fbc3c1..3a2c64937a 100644 --- a/bittensor/core/extrinsics/asyncex/start_call.py +++ b/bittensor/core/extrinsics/asyncex/start_call.py @@ -12,23 +12,25 @@ async def start_call_extrinsic( subtensor: "AsyncSubtensor", wallet: "Wallet", netuid: int, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = False, - period: Optional[int] = None, ) -> tuple[bool, str]: """ Submits a start_call extrinsic to the blockchain, to trigger the start call process for a subnet (used to start a new subnet's emission mechanism). - Args: - subtensor (Subtensor): The Subtensor client instance used for blockchain interaction. - wallet (Wallet): The wallet used to sign the extrinsic (must be unlocked). - netuid (int): The UID of the target subnet for which the call is being initiated. - wait_for_inclusion (bool, optional): Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization (bool, optional): Whether to wait for finalization of the extrinsic. Defaults to False. + Parameters: + subtensor: The Subtensor client instance used for blockchain interaction. + wallet: The wallet used to sign the extrinsic (must be unlocked). + netuid: The UID of the target subnet for which the call is being initiated. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: Tuple[bool, str]: @@ -52,6 +54,7 @@ async def start_call_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if not wait_for_finalization and not wait_for_inclusion: diff --git a/bittensor/core/extrinsics/asyncex/take.py b/bittensor/core/extrinsics/asyncex/take.py index 543d4e72da..3840821c08 100644 --- a/bittensor/core/extrinsics/asyncex/take.py +++ b/bittensor/core/extrinsics/asyncex/take.py @@ -13,27 +13,29 @@ async def increase_take_extrinsic( wallet: Wallet, hotkey_ss58: str, take: int, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = True, - raise_error: bool = False, - period: Optional[int] = None, ) -> tuple[bool, str]: """Sets the delegate 'take' percentage for a neuron identified by its hotkey. - Args: - subtensor (Subtensor): Blockchain connection. - wallet (Wallet): The wallet to sign the extrinsic. - hotkey_ss58 (str): SS58 address of the hotkey to set take for. - take (int): The percentage of rewards that the delegate claims from nominators. - wait_for_inclusion (bool, optional): Wait for inclusion before returning. Defaults to True. - wait_for_finalization (bool, optional): Wait for finalization before returning. Defaults to True. - raise_error (bool, optional): Raise error on failure. Defaults to False. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + Parameters: + subtensor: The Subtensor instance. + wallet: The wallet to sign the extrinsic. + hotkey_ss58: SS58 address of the hotkey to set take for. + take: The percentage of rewards that the delegate claims from nominators. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - tuple[bool, str]: Success flag and status message. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. """ unlock = unlock_key(wallet, raise_error=raise_error) @@ -65,27 +67,30 @@ async def decrease_take_extrinsic( wallet: Wallet, hotkey_ss58: str, take: int, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = True, - raise_error: bool = False, - period: Optional[int] = None, ) -> tuple[bool, str]: - """Sets the delegate 'take' percentage for a neuron identified by its hotkey. - - Args: - subtensor (Subtensor): Blockchain connection. - wallet (Wallet): The wallet to sign the extrinsic. - hotkey_ss58 (str): SS58 address of the hotkey to set take for. - take (int): The percentage of rewards that the delegate claims from nominators. - wait_for_inclusion (bool, optional): Wait for inclusion before returning. Defaults to True. - wait_for_finalization (bool, optional): Wait for finalization before returning. Defaults to True. - raise_error (bool, optional): Raise error on failure. Defaults to False. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + """ + Sets the delegate 'take' percentage for a neuron identified by its hotkey. + + Parameters: + subtensor: The Subtensor instance. + wallet: The wallet to sign the extrinsic. + hotkey_ss58: SS58 address of the hotkey to set take for. + take: The percentage of rewards that the delegate claims from nominators. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - tuple[bool, str]: Success flag and status message. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. """ unlock = unlock_key(wallet, raise_error=raise_error) @@ -104,8 +109,8 @@ async def decrease_take_extrinsic( return await subtensor.sign_and_send_extrinsic( call=call, wallet=wallet, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, period=period, raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) diff --git a/bittensor/core/extrinsics/asyncex/transfer.py b/bittensor/core/extrinsics/asyncex/transfer.py index 365441d51c..3e3d6d7193 100644 --- a/bittensor/core/extrinsics/asyncex/transfer.py +++ b/bittensor/core/extrinsics/asyncex/transfer.py @@ -4,9 +4,9 @@ from bittensor.core.settings import NETWORK_EXPLORER_MAP from bittensor.utils import ( get_explorer_url_for_network, + get_transfer_fn_params, is_valid_bittensor_address_or_public_key, unlock_key, - get_transfer_fn_params, ) from bittensor.utils.balance import Balance from bittensor.utils.btlogging import logging @@ -21,33 +21,31 @@ async def transfer_extrinsic( wallet: "Wallet", destination: str, amount: Optional[Balance], - transfer_all: bool = False, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, keep_alive: bool = True, + transfer_all: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """Transfers funds from this wallet to the destination public key address. - Args: - subtensor (bittensor.core.async_subtensor.AsyncSubtensor): initialized AsyncSubtensor object used for transfer - wallet (bittensor_wallet.Wallet): Bittensor wallet object to make transfer from. - destination (str): Destination public key address (ss58_address or ed25519) of recipient. - amount (Optional[bittensor.utils.balance.Balance]): Amount to stake as Bittensor balance. `None` if - transferring all. - transfer_all (bool): Whether to transfer all funds from this wallet to the destination address. - wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning `True`, or returns - `False` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning - `True`, or returns `False` if the extrinsic fails to be finalized within the timeout. - keep_alive (bool): If set, keeps the account alive by keeping the balance above the existential deposit. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. - If the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + Parameters: + subtensor: The Subtensor instance. + wallet: The wallet to sign the extrinsic. + destination: Destination public key address (ss58_address or ed25519) of recipient. + amount: Amount to stake as Bittensor balance. `None` if transferring all. + transfer_all: Whether to transfer all funds from this wallet to the destination address. + keep_alive: If set, keeps the account alive by keeping the balance above the existential deposit. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - success (bool): Flag is `True` if extrinsic was finalized or included in the block. If we did not wait for - finalization / inclusion, the response is `True`, regardless of its inclusion. + bool: True if the subnet registration was successful, False otherwise. """ if amount is None and not transfer_all: logging.error("If not transferring all, `amount` must be specified.") @@ -114,6 +112,7 @@ async def transfer_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if success: diff --git a/bittensor/core/extrinsics/asyncex/unstaking.py b/bittensor/core/extrinsics/asyncex/unstaking.py index fcc0416dd5..bda16a0835 100644 --- a/bittensor/core/extrinsics/asyncex/unstaking.py +++ b/bittensor/core/extrinsics/asyncex/unstaking.py @@ -16,54 +16,44 @@ async def unstake_extrinsic( subtensor: "AsyncSubtensor", wallet: "Wallet", - hotkey_ss58: Optional[str] = None, - netuid: Optional[int] = None, - amount: Optional[Balance] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - safe_staking: bool = False, + netuid: int, + hotkey_ss58: str, + amount: Balance, allow_partial_stake: bool = False, rate_tolerance: float = 0.005, + safe_unstaking: bool = False, period: Optional[int] = None, - unstake_all: bool = False, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: - """Removes stake into the wallet coldkey from the specified hotkey ``uid``. + """ + Removes stake into the wallet coldkey from the specified hotkey ``uid``. - Args: - subtensor: AsyncSubtensor instance. + Parameters: + subtensor: Subtensor instance. wallet: Bittensor wallet object. - hotkey_ss58: The ``ss58`` address of the hotkey to unstake from. By default, the wallet hotkey is used. - netuid: The subnet uid to unstake from. - amount: Amount to stake as Bittensor balance, or ``float`` interpreted as Tao. - wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning ``True``, or returns - ``False`` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning ``True``, - or returns ``False`` if the extrinsic fails to be finalized within the timeout. - safe_staking: If true, enables price safety checks - allow_partial_stake: If true, allows partial unstaking if price tolerance exceeded - rate_tolerance: Maximum allowed price decrease percentage (0.005 = 0.5%) + netuid: Subnet unique id. + hotkey_ss58: The ``ss58`` address of the hotkey to unstake from. + amount: Amount to stake as Bittensor balance. + allow_partial_stake: If true, allows partial unstaking if price tolerance exceeded. + safe_unstaking: If true, enables price safety checks. + rate_tolerance: Maximum allowed price decrease percentage (0.005 = 0.5%). period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - unstake_all: If true, unstakes all tokens. Default is ``False``. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - tuple[bool, str]: - A tuple containing: - - `True` and a success message if the unstake operation succeeded; - - `False` and an error message otherwise. + bool: True if the subnet registration was successful, False otherwise. """ - if amount and unstake_all: - raise ValueError("Cannot specify both `amount` and `unstake_all`.") - # Decrypt keys, if not (unlock := unlock_key(wallet)).success: logging.error(unlock.message) return False - if hotkey_ss58 is None: - hotkey_ss58 = wallet.hotkey.ss58_address # Default to wallet's own hotkey. - logging.info( f":satellite: [magenta]Syncing with chain:[/magenta] [blue]{subtensor.network}[/blue] [magenta]...[/magenta]" ) @@ -78,24 +68,13 @@ async def unstake_extrinsic( ), ) - # Convert to bittensor.Balance - if amount is None: - # Unstake it all. - unstaking_balance = old_stake - logging.warning( - f"Didn't receive any unstaking amount. Unstaking all existing stake: [blue]{old_stake}[/blue] " - f"from hotkey: [blue]{hotkey_ss58}[/blue]" - ) - else: - unstaking_balance = amount - unstaking_balance.set_unit(netuid) + amount.set_unit(netuid) # Check enough to unstake. - stake_on_uid = old_stake - if unstaking_balance > stake_on_uid: + if amount > old_stake: logging.error( - f":cross_mark: [red]Not enough stake[/red]: [green]{stake_on_uid}[/green] to unstake: " - f"[blue]{unstaking_balance}[/blue] from hotkey: [yellow]{wallet.hotkey_str}[/yellow]" + f":cross_mark: [red]Not enough stake[/red]: [green]{old_stake}[/green] to unstake: " + f"[blue]{amount}[/blue] from hotkey: [yellow]{wallet.hotkey_str}[/yellow]" ) return False @@ -103,9 +82,9 @@ async def unstake_extrinsic( call_params = { "hotkey": hotkey_ss58, "netuid": netuid, - "amount_unstaked": unstaking_balance.rao, + "amount_unstaked": amount.rao, } - if safe_staking: + if safe_unstaking: pool = await subtensor.subnet(netuid=netuid) base_price = pool.price.tao @@ -116,7 +95,7 @@ async def unstake_extrinsic( logging_info = ( f":satellite: [magenta]Safe Unstaking from:[/magenta] " - f"netuid: [green]{netuid}[/green], amount: [green]{unstaking_balance}[/green], " + f"netuid: [green]{netuid}[/green], amount: [green]{amount}[/green], " f"tolerance percentage: [green]{rate_tolerance * 100}%[/green], " f"price limit: [green]{price_with_tolerance}[/green], " f"original price: [green]{base_price}[/green], " @@ -135,7 +114,7 @@ async def unstake_extrinsic( else: logging_info = ( f":satellite: [magenta]Unstaking from:[/magenta] " - f"netuid: [green]{netuid}[/green], amount: [green]{unstaking_balance}[/green] " + f"netuid: [green]{netuid}[/green], amount: [green]{amount}[/green] " f"on [blue]{subtensor.network}[/blue]" ) call_function = "remove_stake" @@ -158,9 +137,10 @@ async def unstake_extrinsic( sign_with="coldkey", use_nonce=True, period=period, + raise_error=raise_error, ) - if success is True: # If we successfully unstaked. + if success: # If we successfully unstaked. # We only wait here if we expect finalization. if not wait_for_finalization and not wait_for_inclusion: return True @@ -190,14 +170,14 @@ async def unstake_extrinsic( f"Stake: [blue]{old_stake}[/blue] :arrow_right: [green]{new_stake}[/green]" ) return True + + if safe_unstaking and "Custom error: 8" in message: + logging.error( + ":cross_mark: [red]Failed[/red]: Price exceeded tolerance limit. Either increase price tolerance or enable partial staking." + ) else: - if safe_staking and "Custom error: 8" in message: - logging.error( - ":cross_mark: [red]Failed[/red]: Price exceeded tolerance limit. Either increase price tolerance or enable partial staking." - ) - else: - logging.error(f":cross_mark: [red]Failed: {message}.[/red]") - return False + logging.error(f":cross_mark: [red]Failed: {message}.[/red]") + return False except SubstrateRequestException as error: logging.error( @@ -212,24 +192,26 @@ async def unstake_all_extrinsic( hotkey: str, netuid: int, rate_tolerance: Optional[float] = 0.005, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Unstakes all TAO/Alpha associated with a hotkey from the specified subnets on the Bittensor network. - Arguments: + Parameters: subtensor: Subtensor instance. wallet: The wallet of the stake owner. hotkey: The SS58 address of the hotkey to unstake from. netuid: The unique identifier of the subnet. rate_tolerance: The maximum allowed price change ratio when unstaking. For example, 0.005 = 0.5% maximum price decrease. If not passed (None), then unstaking goes without price limit. Default is `0.005`. - wait_for_inclusion: Waits for the transaction to be included in a block. Default is `True`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Default is `False`. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can - think of it as an expiration date for the transaction. Default is `None`. + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: tuple[bool, str]: @@ -268,66 +250,55 @@ async def unstake_all_extrinsic( sign_with="coldkey", use_nonce=True, period=period, + raise_error=raise_error, ) async def unstake_multiple_extrinsic( subtensor: "AsyncSubtensor", wallet: "Wallet", - hotkey_ss58s: list[str], netuids: list[int], + hotkey_ss58s: list[str], amounts: Optional[list[Balance]] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - period: Optional[int] = None, unstake_all: bool = False, + period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: - """Removes stake from each ``hotkey_ss58`` in the list, using each amount, to a common coldkey. + """ + Removes stake from each ``hotkey_ss58`` in the list, using each amount, to a common coldkey. - Args: - subtensor: Subtensor instance. + Parameters: + subtensor: AsyncSubtensor instance. wallet: The wallet with the coldkey to unstake to. + netuids: List of subnets unique IDs to unstake from. hotkey_ss58s: List of hotkeys to unstake from. - netuids: List of netuids to unstake from. amounts: List of amounts to unstake. If ``None``, unstake all. - wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning ``True``, or - returns ``False`` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning - ``True``, or returns ``False`` if the extrinsic fails to be finalized within the timeout. + unstake_all: If true, unstakes all tokens. Default is ``False``. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - unstake_all: If true, unstakes all tokens. Default is ``False``. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - tuple[bool, str]: - A tuple containing: - - `True` and a success message if the unstake operation succeeded; - - `False` and an error message otherwise. + bool: True if the subnet registration was successful, False otherwise. """ + # Unlock coldkey. + if not (unlock := unlock_key(wallet)).success: + logging.error(unlock.message) + return False + + # or amounts or unstake_all (no both) if amounts and unstake_all: raise ValueError("Cannot specify both `amounts` and `unstake_all`.") - if not isinstance(hotkey_ss58s, list) or not all( - isinstance(hotkey_ss58, str) for hotkey_ss58 in hotkey_ss58s - ): - raise TypeError("hotkey_ss58s must be a list of str") - - if len(hotkey_ss58s) == 0: - return True - - if amounts is not None and len(amounts) != len(hotkey_ss58s): - raise ValueError("amounts must be a list of the same length as hotkey_ss58s") - - if netuids is not None and len(netuids) != len(hotkey_ss58s): - raise ValueError("netuids must be a list of the same length as hotkey_ss58s") - if amounts is not None and not all( - isinstance(amount, (Balance, float)) for amount in amounts + isinstance(amount, Balance) for amount in amounts ): - raise TypeError( - "amounts must be a [list of bittensor.Balance or float] or None" - ) + raise TypeError("amounts must be a [list of bittensor.Balance] or None") if amounts is None: amounts = [None] * len(hotkey_ss58s) @@ -338,10 +309,29 @@ async def unstake_multiple_extrinsic( # Staking 0 tao return True - # Unlock coldkey. - if not (unlock := unlock_key(wallet)).success: - logging.error(unlock.message) - return False + assert all( + [ + isinstance(netuids, list), + isinstance(hotkey_ss58s, list), + isinstance(amounts, list), + ] + ), "The `netuids`, `hotkey_ss58s` and `amounts` must be lists." + + if len(hotkey_ss58s) == 0: + return True + + assert len(netuids) == len(hotkey_ss58s) == len(amounts), ( + "The number of items in `netuids`, `hotkey_ss58s` and `amounts` must be the same." + ) + + if not all(isinstance(hotkey_ss58, str) for hotkey_ss58 in hotkey_ss58s): + raise TypeError("hotkey_ss58s must be a list of str") + + if amounts is not None and len(amounts) != len(hotkey_ss58s): + raise ValueError("amounts must be a list of the same length as hotkey_ss58s") + + if netuids is not None and len(netuids) != len(hotkey_ss58s): + raise ValueError("netuids must be a list of the same length as hotkey_ss58s") logging.info( f":satellite: [magenta]Syncing with chain:[/magenta] [blue]{subtensor.network}[/blue] [magenta]...[/magenta]" @@ -411,6 +401,7 @@ async def unstake_multiple_extrinsic( sign_with="coldkey", use_nonce=True, period=period, + raise_error=raise_error, ) if staking_response is True: # If we successfully unstaked. diff --git a/bittensor/core/extrinsics/asyncex/weights.py b/bittensor/core/extrinsics/asyncex/weights.py index 8717bf638d..53aa650f2d 100644 --- a/bittensor/core/extrinsics/asyncex/weights.py +++ b/bittensor/core/extrinsics/asyncex/weights.py @@ -24,26 +24,26 @@ async def commit_weights_extrinsic( wallet: "Wallet", netuid: int, commit_hash: str, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = False, period: Optional[int] = None, raise_error: bool = False, + wait_for_inclusion: bool = False, + wait_for_finalization: bool = False, ) -> tuple[bool, str]: """ Commits a hash of the neuron's weights to the Bittensor blockchain using the provided wallet. This function is a wrapper around the `do_commit_weights` method. - Args: + Parameters: subtensor: The subtensor instance used for blockchain interaction. wallet: The wallet associated with the neuron committing the weights. netuid: The unique identifier of the subnet. commit_hash: The hash of the neuron's weights to be committed. - wait_for_inclusion: Waits for the transaction to be included in a block. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - raise_error: raises the relevant exception rather than returning `False` if unsuccessful. + raise_error: Whether to raise an error if the transaction fails. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: tuple[bool, str]: @@ -51,7 +51,7 @@ async def commit_weights_extrinsic( `msg` is a string value describing the success or potential error. This function provides a user-friendly interface for committing weights to the Bittensor blockchain, ensuring proper - error handling and user interaction when required. + error handling and user interaction when required. """ call = await subtensor.substrate.compose_call( call_module="SubtensorModule", @@ -88,16 +88,16 @@ async def reveal_weights_extrinsic( weights: list[int], salt: list[int], version_key: int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = False, period: Optional[int] = None, raise_error: bool = False, + wait_for_inclusion: bool = False, + wait_for_finalization: bool = False, ) -> tuple[bool, str]: """ Reveals the weights for a specific subnet on the Bittensor blockchain using the provided wallet. This function is a wrapper around the `_do_reveal_weights` method. - Args: + Parameters: subtensor: The subtensor instance used for blockchain interaction. wallet: The wallet associated with the neuron revealing the weights. netuid: The unique identifier of the subnet. @@ -105,12 +105,12 @@ async def reveal_weights_extrinsic( weights: List of weight values corresponding to each UID. salt: List of salt values corresponding to the hash function. version_key: Version key for compatibility with the network. - wait_for_inclusion: Waits for the transaction to be included in a block. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - raise_error: raises the relevant exception rather than returning `False` if unsuccessful. + raise_error: Whether to raise an error if the transaction fails. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: tuple[bool, str]: @@ -157,28 +157,27 @@ async def set_weights_extrinsic( uids: Union[NDArray[np.int64], "torch.LongTensor", list], weights: Union[NDArray[np.float32], "torch.FloatTensor", list], version_key: int = version_as_int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = False, period: Optional[int] = 8, raise_error: bool = False, + wait_for_inclusion: bool = False, + wait_for_finalization: bool = False, ) -> tuple[bool, str]: - """Sets the given weights and values on chain for a given wallet hotkey account. + """ + Sets the given weights and values on chain for a given wallet hotkey account. - Args: + Parameters: subtensor: Bittensor subtensor object. wallet: Bittensor wallet object. netuid: The ``netuid`` of the subnet to set weights for. uids: The ``uint64`` uids of destination neurons. weights: The weights to set. These must be ``float``s and correspond to the passed ``uid``s. version_key: The version key of the validator. - wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning ``True``, or returns - ``False`` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning ``True``, - or returns ``False`` if the extrinsic fails to be finalized within the timeout. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - raise_error: raises the relevant exception rather than returning `False` if unsuccessful. + raise_error: Whether to raise an error if the transaction fails. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: tuple[bool, str]: @@ -223,4 +222,5 @@ async def set_weights_extrinsic( logging.info("Successfully set weights and Finalized.") else: logging.error(f"{get_function_name}: {message}") + return success, message diff --git a/bittensor/core/extrinsics/children.py b/bittensor/core/extrinsics/children.py index dd91fbe97b..5f7c1a9d84 100644 --- a/bittensor/core/extrinsics/children.py +++ b/bittensor/core/extrinsics/children.py @@ -12,30 +12,31 @@ def set_children_extrinsic( hotkey: str, netuid: int, children: list[tuple[float, str]], - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - raise_error: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ): """ Allows a coldkey to set children-keys. - Arguments: - subtensor: bittensor subtensor. + Parameters: + subtensor: The Subtensor client instance used for blockchain interaction. wallet: bittensor wallet instance. hotkey: The ``SS58`` address of the neuron's hotkey. netuid: The netuid value. children: A list of children with their proportions. - wait_for_inclusion: Waits for the transaction to be included in a block. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. - raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure of the operation, - and the second element is a message providing additional information. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. Raises: DuplicateChild: There are duplicates in the list of children. @@ -74,10 +75,10 @@ def set_children_extrinsic( success, message = subtensor.sign_and_send_extrinsic( call=call, wallet=wallet, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - raise_error=raise_error, - period=period, ) if not wait_for_finalization and not wait_for_inclusion: @@ -93,12 +94,29 @@ def root_set_pending_childkey_cooldown_extrinsic( subtensor: "Subtensor", wallet: "Wallet", cooldown: int, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = False, - period: Optional[int] = None, ) -> tuple[bool, str]: """ - Allows a coldkey to set children-keys. + Allows a root coldkey to set children-keys. + + Parameters: + subtensor: The Subtensor client instance used for blockchain interaction. + wallet: The wallet used to sign the extrinsic (must be unlocked). + cooldown: The cooldown period in blocks. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. + + Returns: + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. """ unlock = unlock_key(wallet) @@ -120,9 +138,10 @@ def root_set_pending_childkey_cooldown_extrinsic( success, message = subtensor.sign_and_send_extrinsic( call=sudo_call, wallet=wallet, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) if not wait_for_finalization and not wait_for_inclusion: diff --git a/bittensor/core/extrinsics/commit_reveal.py b/bittensor/core/extrinsics/commit_reveal.py index 2f83229b33..d0997605b4 100644 --- a/bittensor/core/extrinsics/commit_reveal.py +++ b/bittensor/core/extrinsics/commit_reveal.py @@ -22,91 +22,90 @@ def commit_reveal_extrinsic( netuid: int, uids: Union[NDArray[np.int64], "torch.LongTensor", list], weights: Union[NDArray[np.float32], "torch.FloatTensor", list], + block_time: Union[int, float] = 12.0, + commit_reveal_version: int = 4, version_key: int = version_as_int, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = False, wait_for_finalization: bool = False, - block_time: Union[int, float] = 12.0, - period: Optional[int] = None, - commit_reveal_version: int = 4, ) -> tuple[bool, str]: """ Commits and reveals weights for a given subtensor and wallet with provided uids and weights. - Arguments: + Parameters: subtensor: The Subtensor instance. wallet: The wallet to use for committing and revealing. netuid: The id of the network. uids: The uids to commit. weights: The weights associated with the uids. - version_key: The version key to use for committing and revealing. Default is version_as_int. - wait_for_inclusion: Whether to wait for the inclusion of the transaction. Default is False. - wait_for_finalization: Whether to wait for the finalization of the transaction. Default is False. - block_time (float): The number of seconds for block duration. Default is 12.0 seconds. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. - If the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. - commit_reveal_version: The version of the chain commit-reveal protocol to use. Default is ``4``. + block_time: The number of seconds for block duration. + commit_reveal_version: The version of the chain commit-reveal protocol to use. + version_key: The version key to use for committing and revealing. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure, and the second - element is a message associated with the result + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. """ - try: - uids, weights = convert_and_normalize_weights_and_uids(uids, weights) - - current_block = subtensor.get_current_block() - subnet_hyperparameters = subtensor.get_subnet_hyperparameters( - netuid, block=current_block - ) - tempo = subnet_hyperparameters.tempo - subnet_reveal_period_epochs = subnet_hyperparameters.commit_reveal_period + uids, weights = convert_and_normalize_weights_and_uids(uids, weights) - # Encrypt `commit_hash` with t-lock and `get reveal_round` - commit_for_reveal, reveal_round = get_encrypted_commit( - uids=uids, - weights=weights, - version_key=version_key, - tempo=tempo, - current_block=current_block, - netuid=netuid, - subnet_reveal_period_epochs=subnet_reveal_period_epochs, - block_time=block_time, - hotkey=wallet.hotkey.public_key, - ) + current_block = subtensor.get_current_block() + subnet_hyperparameters = subtensor.get_subnet_hyperparameters( + netuid, block=current_block + ) + tempo = subnet_hyperparameters.tempo + subnet_reveal_period_epochs = subnet_hyperparameters.commit_reveal_period - logging.info( - f"Committing weights hash [blue]{commit_for_reveal.hex()}[/blue] for subnet #[blue]{netuid}[/blue] with " - f"reveal round [blue]{reveal_round}[/blue]..." - ) + # Encrypt `commit_hash` with t-lock and `get reveal_round` + commit_for_reveal, reveal_round = get_encrypted_commit( + uids=uids, + weights=weights, + version_key=version_key, + tempo=tempo, + current_block=current_block, + netuid=netuid, + subnet_reveal_period_epochs=subnet_reveal_period_epochs, + block_time=block_time, + hotkey=wallet.hotkey.public_key, + ) - call = subtensor.substrate.compose_call( - call_module="SubtensorModule", - call_function="commit_timelocked_weights", - call_params={ - "netuid": netuid, - "commit": commit_for_reveal, - "reveal_round": reveal_round, - "commit_reveal_version": commit_reveal_version, - }, - ) - success, message = subtensor.sign_and_send_extrinsic( - call=call, - wallet=wallet, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - sign_with="hotkey", - period=period, - ) + logging.info( + f"Committing weights hash [blue]{commit_for_reveal.hex()}[/blue] for subnet #[blue]{netuid}[/blue] with " + f"reveal round [blue]{reveal_round}[/blue]..." + ) - if not success: - logging.error(message) - return False, message + call = subtensor.substrate.compose_call( + call_module="SubtensorModule", + call_function="commit_timelocked_weights", + call_params={ + "netuid": netuid, + "commit": commit_for_reveal, + "reveal_round": reveal_round, + "commit_reveal_version": commit_reveal_version, + }, + ) + success, message = subtensor.sign_and_send_extrinsic( + call=call, + wallet=wallet, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + sign_with="hotkey", + period=period, + raise_error=raise_error, + ) - logging.success( - f"[green]Finalized![/green] Weights committed with reveal round [blue]{reveal_round}[/blue]." - ) - return True, f"reveal_round:{reveal_round}" + if not success: + logging.error(message) + return False, message - except Exception as e: - logging.error(f":cross_mark: [red]Failed. Error:[/red] {e}") - return False, str(e) + logging.success( + f"[green]Finalized![/green] Weights committed with reveal round [blue]{reveal_round}[/blue]." + ) + return True, f"reveal_round:{reveal_round}" diff --git a/bittensor/core/extrinsics/liquidity.py b/bittensor/core/extrinsics/liquidity.py index 96e502692c..dbb974082a 100644 --- a/bittensor/core/extrinsics/liquidity.py +++ b/bittensor/core/extrinsics/liquidity.py @@ -18,26 +18,28 @@ def add_liquidity_extrinsic( price_low: Balance, price_high: Balance, hotkey: Optional[str] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """ Adds liquidity to the specified price range. - Arguments: + Parameters: subtensor: The Subtensor client instance used for blockchain interaction. wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. liquidity: The amount of liquidity to be added. price_low: The lower bound of the price tick range. price_high: The upper bound of the price tick range. - hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. Defaults to `None`. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: Tuple[bool, str]: @@ -45,7 +47,7 @@ def add_liquidity_extrinsic( - False and an error message if the submission fails or the wallet cannot be unlocked. Note: Adding is allowed even when user liquidity is enabled in specified subnet. Call - `toggle_user_liquidity_extrinsic` to enable/disable user liquidity. + `toggle_user_liquidity_extrinsic` to enable/disable user liquidity. """ if not (unlock := unlock_key(wallet)).success: logging.error(unlock.message) @@ -73,6 +75,7 @@ def add_liquidity_extrinsic( wait_for_finalization=wait_for_finalization, use_nonce=True, period=period, + raise_error=raise_error, ) @@ -83,24 +86,26 @@ def modify_liquidity_extrinsic( position_id: int, liquidity_delta: Balance, hotkey: Optional[str] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Modifies liquidity in liquidity position by adding or removing liquidity from it. - Arguments: + Parameters: subtensor: The Subtensor client instance used for blockchain interaction. wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. position_id: The id of the position record in the pool. liquidity_delta: The amount of liquidity to be added or removed (add if positive or remove if negative). hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. Defaults to `None`. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: Tuple[bool, str]: @@ -108,7 +113,7 @@ def modify_liquidity_extrinsic( - False and an error message if the submission fails or the wallet cannot be unlocked. Note: Modifying is allowed even when user liquidity is enabled in specified subnet. Call - `toggle_user_liquidity_extrinsic` to enable/disable user liquidity. + `toggle_user_liquidity_extrinsic` to enable/disable user liquidity. """ if not (unlock := unlock_key(wallet)).success: logging.error(unlock.message) @@ -132,6 +137,7 @@ def modify_liquidity_extrinsic( wait_for_finalization=wait_for_finalization, use_nonce=True, period=period, + raise_error=raise_error, ) @@ -141,31 +147,33 @@ def remove_liquidity_extrinsic( netuid: int, position_id: int, hotkey: Optional[str] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Remove liquidity and credit balances back to wallet's hotkey stake. - Arguments: + Parameters: subtensor: The Subtensor client instance used for blockchain interaction. wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. position_id: The id of the position record in the pool. hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. Defaults to `None`. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: Tuple[bool, str]: - True and a success message if the extrinsic is successfully submitted or processed. - False and an error message if the submission fails or the wallet cannot be unlocked. - Note: Adding is allowed even when user liquidity is enabled in specified subnet. - Call `toggle_user_liquidity_extrinsic` to enable/disable user liquidity. + Note: Adding is allowed even when user liquidity is enabled in specified subnet. Call + `toggle_user_liquidity_extrinsic` to enable/disable user liquidity. """ if not (unlock := unlock_key(wallet)).success: logging.error(unlock.message) @@ -188,6 +196,7 @@ def remove_liquidity_extrinsic( wait_for_finalization=wait_for_finalization, use_nonce=True, period=period, + raise_error=raise_error, ) @@ -196,22 +205,24 @@ def toggle_user_liquidity_extrinsic( wallet: "Wallet", netuid: int, enable: bool, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Allow to toggle user liquidity for specified subnet. - Arguments: + Parameters: subtensor: The Subtensor client instance used for blockchain interaction. wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. enable: Boolean indicating whether to enable user liquidity. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: Tuple[bool, str]: @@ -234,4 +245,5 @@ def toggle_user_liquidity_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) diff --git a/bittensor/core/extrinsics/move_stake.py b/bittensor/core/extrinsics/move_stake.py index f3aae363ce..b3a9d54e95 100644 --- a/bittensor/core/extrinsics/move_stake.py +++ b/bittensor/core/extrinsics/move_stake.py @@ -41,27 +41,29 @@ def transfer_stake_extrinsic( hotkey_ss58: str, origin_netuid: int, destination_netuid: int, - amount: Optional[Balance] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, + amount: Balance, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Transfers stake from one subnet to another while changing the coldkey owner. - Args: - subtensor (Subtensor): Subtensor instance. - wallet (bittensor.wallet): The wallet to transfer stake from. - destination_coldkey_ss58 (str): The destination coldkey SS58 address. - hotkey_ss58 (str): The hotkey SS58 address associated with the stake. - origin_netuid (int): The source subnet UID. - destination_netuid (int): The destination subnet UID. - amount (Union[Balance, float, int]): Amount to transfer. - wait_for_inclusion (bool): If true, waits for inclusion before returning. - wait_for_finalization (bool): If true, waits for finalization before returning. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + Parameters: + subtensor: The subtensor instance to interact with the blockchain. + wallet: The wallet containing the coldkey to authorize the transfer. + destination_coldkey_ss58: SS58 address of the destination coldkey. + hotkey_ss58: SS58 address of the hotkey associated with the stake. + origin_netuid: Network UID of the origin subnet. + destination_netuid: Network UID of the destination subnet. + amount: The amount of stake to transfer as a `Balance` object. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: success (bool): True if the transfer was successful. @@ -105,12 +107,13 @@ def transfer_stake_extrinsic( }, ) - success, err_msg = subtensor.sign_and_send_extrinsic( + success, message = subtensor.sign_and_send_extrinsic( call=call, wallet=wallet, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if success: @@ -121,7 +124,7 @@ def transfer_stake_extrinsic( # Get updated stakes origin_stake, dest_stake = _get_stake_in_origin_and_dest( - subtensor, + subtensor=subtensor, origin_hotkey_ss58=hotkey_ss58, destination_hotkey_ss58=hotkey_ss58, origin_netuid=origin_netuid, @@ -138,7 +141,7 @@ def transfer_stake_extrinsic( return True else: - logging.error(f":cross_mark: [red]Failed[/red]: {err_msg}") + logging.error(f":cross_mark: [red]Failed[/red]: {message}") return False except Exception as e: @@ -152,32 +155,35 @@ def swap_stake_extrinsic( hotkey_ss58: str, origin_netuid: int, destination_netuid: int, - amount: Optional[Balance] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - safe_staking: bool = False, + amount: Balance, + safe_swapping: bool = False, allow_partial_stake: bool = False, rate_tolerance: float = 0.005, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Moves stake between subnets while keeping the same coldkey-hotkey pair ownership. - Args: - subtensor (Subtensor): Subtensor instance. - wallet (bittensor.wallet): The wallet to swap stake from. - hotkey_ss58 (str): The hotkey SS58 address associated with the stake. - origin_netuid (int): The source subnet UID. - destination_netuid (int): The destination subnet UID. - amount (Union[Balance, float]): Amount to swap. - wait_for_inclusion (bool): If true, waits for inclusion before returning. - wait_for_finalization (bool): If true, waits for finalization before returning. - safe_staking (bool): If true, enables price safety checks to protect against price impact. - allow_partial_stake (bool): If true, allows partial stake swaps when the full amount would exceed the price tolerance. - rate_tolerance (float): Maximum allowed increase in a price ratio (0.005 = 0.5%). - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + Parameters: + subtensor: Subtensor instance. + wallet: The wallet to swap stake from. + hotkey_ss58: The hotkey SS58 address associated with the stake. + origin_netuid: The source subnet UID. + destination_netuid: The destination subnet UID. + amount: Amount to swap. + safe_swapping: If true, enables price safety checks to protect against price impact. + allow_partial_stake: If true, allows partial stake swaps when the full amount would exceed the price tolerance. + rate_tolerance: Maximum allowed increase in a price ratio (0.005 = 0.5%). + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. + Returns: success (bool): True if the swap was successful. @@ -210,7 +216,7 @@ def swap_stake_extrinsic( "alpha_amount": amount.rao, } - if safe_staking: + if safe_swapping: origin_pool = subtensor.subnet(netuid=origin_netuid) destination_pool = subtensor.subnet(netuid=destination_netuid) swap_rate_ratio = origin_pool.price.rao / destination_pool.price.rao @@ -250,6 +256,7 @@ def swap_stake_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if success: @@ -277,7 +284,7 @@ def swap_stake_extrinsic( return True else: - if safe_staking and "Custom error: 8" in err_msg: + if safe_swapping and "Custom error: 8" in err_msg: logging.error( ":cross_mark: [red]Failed[/red]: Price ratio exceeded tolerance limit. Either increase price tolerance or enable partial staking." ) @@ -293,33 +300,35 @@ def swap_stake_extrinsic( def move_stake_extrinsic( subtensor: "Subtensor", wallet: "Wallet", - origin_hotkey: str, + origin_hotkey_ss58: str, origin_netuid: int, - destination_hotkey: str, + destination_hotkey_ss58: str, destination_netuid: int, amount: Optional[Balance] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - period: Optional[int] = None, move_all_stake: bool = False, + period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Moves stake to a different hotkey and/or subnet while keeping the same coldkey owner. - Args: + Parameters: subtensor: Subtensor instance. wallet: The wallet to move stake from. - origin_hotkey: The SS58 address of the source hotkey. + origin_hotkey_ss58: The SS58 address of the source hotkey. origin_netuid: The netuid of the source subnet. - destination_hotkey: The SS58 address of the destination hotkey. + destination_hotkey_ss58: The SS58 address of the destination hotkey. destination_netuid: The netuid of the destination subnet. amount: Amount to move. - wait_for_inclusion: If true, waits for inclusion before returning. - wait_for_finalization: If true, waits for finalization before returning. + move_all_stake: If true, moves all stake from the source hotkey to the destination hotkey. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - move_all_stake: If true, moves all stake from the source hotkey to the destination hotkey. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: success: True if the move was successful. Otherwise, False. @@ -333,8 +342,8 @@ def move_stake_extrinsic( # Check sufficient stake stake_in_origin, stake_in_destination = _get_stake_in_origin_and_dest( subtensor=subtensor, - origin_hotkey_ss58=origin_hotkey, - destination_hotkey_ss58=destination_hotkey, + origin_hotkey_ss58=origin_hotkey_ss58, + destination_hotkey_ss58=destination_hotkey_ss58, origin_netuid=origin_netuid, destination_netuid=destination_netuid, origin_coldkey_ss58=wallet.coldkeypub.ss58_address, @@ -345,7 +354,7 @@ def move_stake_extrinsic( elif stake_in_origin < amount: logging.error( - f":cross_mark: [red]Failed[/red]: Insufficient stake in origin hotkey: {origin_hotkey}. " + f":cross_mark: [red]Failed[/red]: Insufficient stake in origin hotkey: {origin_hotkey_ss58}. " f"Stake: {stake_in_origin}, amount: {amount}" ) return False @@ -354,27 +363,28 @@ def move_stake_extrinsic( try: logging.info( - f"Moving stake from hotkey [blue]{origin_hotkey}[/blue] to hotkey [blue]{destination_hotkey}[/blue]\n" + f"Moving stake from hotkey [blue]{origin_hotkey_ss58}[/blue] to hotkey [blue]{destination_hotkey_ss58}[/blue]\n" f"Amount: [green]{amount}[/green] from netuid [yellow]{origin_netuid}[/yellow] to netuid [yellow]{destination_netuid}[/yellow]" ) call = subtensor.substrate.compose_call( call_module="SubtensorModule", call_function="move_stake", call_params={ - "origin_hotkey": origin_hotkey, + "origin_hotkey": origin_hotkey_ss58, "origin_netuid": origin_netuid, - "destination_hotkey": destination_hotkey, + "destination_hotkey": destination_hotkey_ss58, "destination_netuid": destination_netuid, "alpha_amount": amount.rao, }, ) - success, err_msg = subtensor.sign_and_send_extrinsic( + success, message = subtensor.sign_and_send_extrinsic( call=call, wallet=wallet, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if success: @@ -386,8 +396,8 @@ def move_stake_extrinsic( # Get updated stakes origin_stake, dest_stake = _get_stake_in_origin_and_dest( subtensor=subtensor, - origin_hotkey_ss58=origin_hotkey, - destination_hotkey_ss58=destination_hotkey, + origin_hotkey_ss58=origin_hotkey_ss58, + destination_hotkey_ss58=destination_hotkey_ss58, origin_netuid=origin_netuid, destination_netuid=destination_netuid, origin_coldkey_ss58=wallet.coldkeypub.ss58_address, @@ -402,7 +412,7 @@ def move_stake_extrinsic( return True else: - logging.error(f":cross_mark: [red]Failed[/red]: {err_msg}") + logging.error(f":cross_mark: [red]Failed[/red]: {message}") return False except Exception as e: diff --git a/bittensor/core/extrinsics/registration.py b/bittensor/core/extrinsics/registration.py index 730aeee2e6..6f667ff7b6 100644 --- a/bittensor/core/extrinsics/registration.py +++ b/bittensor/core/extrinsics/registration.py @@ -23,29 +23,26 @@ def burned_register_extrinsic( subtensor: "Subtensor", wallet: "Wallet", netuid: int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """Registers the wallet to chain by recycling TAO. - Args: + Parameters: subtensor: Subtensor instance. wallet: Bittensor wallet object. netuid: The ``netuid`` of the subnet to register on. - wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning ``True``, or returns - ``False`` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning ``True``, - or returns ``False`` if the extrinsic fails to be finalized within the timeout. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - raise_error: raises the relevant exception rather than returning `False` if unsuccessful. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - success (bool): Flag is ``True`` if extrinsic was finalized or included in the block. If we did not wait for - finalization / inclusion, the response is ``True``. + success: True if the extrinsic was successful. Otherwise, False. """ block = subtensor.get_current_block() if not subtensor.subnet_exists(netuid, block=block): @@ -131,21 +128,23 @@ def burned_register_extrinsic( def register_subnet_extrinsic( subtensor: "Subtensor", wallet: "Wallet", - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Registers a new subnetwork on the Bittensor blockchain. - Args: - subtensor (Subtensor): The subtensor interface to send the extrinsic. - wallet (Wallet): The wallet to be used for subnet registration. - wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning true. - wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning true. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + Parameters: + subtensor: The subtensor interface to send the extrinsic. + wallet: The wallet to be used for subnet registration. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: bool: True if the subnet registration was successful, False otherwise. @@ -174,6 +173,7 @@ def register_subnet_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if not wait_for_finalization and not wait_for_inclusion: @@ -193,8 +193,6 @@ def register_extrinsic( subtensor: "Subtensor", wallet: "Wallet", netuid: int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, max_allowed_attempts: int = 3, output_in_place: bool = True, cuda: bool = False, @@ -204,32 +202,33 @@ def register_extrinsic( update_interval: Optional[int] = None, log_verbose: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: - """Registers the wallet to the chain. - - Args: - subtensor (bittensor.core.subtensor.Subtensor): Subtensor object to use for chain interactions - wallet (bittensor_wallet.Wallet): Bittensor wallet object. - netuid (int): The ``netuid`` of the subnet to register on. - wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning `True`, or returns - `False` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning - `True`, or returns `False` if the extrinsic fails to be finalized within the timeout. - max_allowed_attempts (int): Maximum number of attempts to register the wallet. - output_in_place (bool): Whether the POW solving should be outputted to the console as it goes along. - cuda (bool): If `True`, the wallet should be registered using CUDA device(s). + """Registers a neuron on the Bittensor subnet with provided netuid using the provided wallet. + + Parameters: + subtensor: Subtensor object to use for chain interactions + wallet: Bittensor wallet object. + netuid: The ``netuid`` of the subnet to register on. + max_allowed_attempts: Maximum number of attempts to register the wallet. + output_in_place: Whether the POW solving should be outputted to the console as it goes along. + cuda: If `True`, the wallet should be registered using CUDA device(s). dev_id: The CUDA device id to use, or a list of device ids. tpb: The number of threads per block (CUDA). num_processes: The number of processes to use to register. update_interval: The number of nonces to solve between updates. log_verbose: If `True`, the registration process will log more information. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - `True` if extrinsic was finalized or included in the block. If we did not wait for finalization/inclusion, the - response is `True`. + bool: True if the subnet registration was successful, False otherwise. """ logging.debug("[magenta]Checking subnet status... [/magenta]") @@ -339,6 +338,7 @@ def register_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if not success: @@ -401,34 +401,37 @@ def set_subnet_identity_extrinsic( discord: str, description: str, additional: str, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """ Set the identity information for a given subnet. - Arguments: - subtensor (Subtensor): An instance of the Subtensor class to interact with the blockchain. - wallet (Wallet): A wallet instance used to sign and submit the extrinsic. - netuid (int): The unique ID for the subnet. - subnet_name (str): The name of the subnet to assign the identity information. - github_repo (str): URL of the GitHub repository related to the subnet. - subnet_contact (str): Subnet's contact information, e.g., email or contact link. - subnet_url (str): The URL of the subnet's primary web portal. - logo_url (str): The URL of the logo's primary web portal. - discord (str): Discord server or contact for the subnet. - description (str): A textual description of the subnet. - additional (str): Any additional metadata or information related to the subnet. - wait_for_inclusion (bool): Whether to wait for the extrinsic inclusion in a block (default: False). - wait_for_finalization (bool): Whether to wait for the extrinsic finalization in a block (default: True). - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + Parameters: + subtensor: An instance of the Subtensor class to interact with the blockchain. + wallet: A wallet instance used to sign and submit the extrinsic. + netuid: The unique ID for the subnet. + subnet_name: The name of the subnet to assign the identity information. + github_repo: URL of the GitHub repository related to the subnet. + subnet_contact: Subnet's contact information, e.g., email or contact link. + subnet_url: The URL of the subnet's primary web portal. + logo_url: The URL of the logo's primary web portal. + discord: Discord server or contact for the subnet. + description: A textual description of the subnet. + additional: Any additional metadata or information related to the subnet. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - tuple[bool, str]: A tuple where the first element indicates success or failure (True/False), and the second - element contains a descriptive message. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. """ if not (unlock := unlock_key(wallet)).success: @@ -458,6 +461,7 @@ def set_subnet_identity_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if not wait_for_finalization and not wait_for_inclusion: diff --git a/bittensor/core/extrinsics/root.py b/bittensor/core/extrinsics/root.py index 1606bf76da..161ca53fd0 100644 --- a/bittensor/core/extrinsics/root.py +++ b/bittensor/core/extrinsics/root.py @@ -38,26 +38,26 @@ def _get_limits(subtensor: "Subtensor") -> tuple[int, float]: def root_register_extrinsic( subtensor: "Subtensor", wallet: "Wallet", - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: - """Registers the wallet to the root network. - - Arguments: - subtensor (bittensor.core.subtensor.Subtensor): The Subtensor object - wallet (bittensor_wallet.Wallet): Bittensor wallet object. - wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning `True`, or returns - `False` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning - `True`, or returns `False` if the extrinsic fails to be finalized within the timeout. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + """ + Registers the neuron to the root network. + + Parameters: + subtensor: Subtensor instance to interact with the blockchain. + wallet: Bittensor Wallet instance. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - `True` if extrinsic was finalized or included in the block. If we did not wait for finalization/inclusion, the - response is `True`. + bool: True if the subnet registration was successful, False otherwise. """ netuid = 0 logging.info( @@ -113,6 +113,7 @@ def root_register_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if not success: diff --git a/bittensor/core/extrinsics/serving.py b/bittensor/core/extrinsics/serving.py index 09903d763e..dd62fa3669 100644 --- a/bittensor/core/extrinsics/serving.py +++ b/bittensor/core/extrinsics/serving.py @@ -16,56 +16,6 @@ from bittensor.core.subtensor import Subtensor -def do_serve_axon( - subtensor: "Subtensor", - wallet: "Wallet", - call_params: "AxonServeCallParams", - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, - period: Optional[int] = None, -) -> tuple[bool, str]: - """ - Internal method to submit a serve axon transaction to the Bittensor blockchain. This method creates and submits a - transaction, enabling a neuron's ``Axon`` to serve requests on the network. - - Args: - subtensor (bittensor.core.subtensor.Subtensor): Subtensor instance object. - wallet (bittensor_wallet.Wallet): The wallet associated with the neuron. - call_params (bittensor.core.types.AxonServeCallParams): Parameters required for the serve axon call. - wait_for_inclusion (bool): Waits for the transaction to be included in a block. - wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. - - Returns: - tuple[bool, Optional[str]]: A tuple containing a success flag and an optional error message. - - This function is crucial for initializing and announcing a neuron's ``Axon`` service on the network, enhancing the - decentralized computation capabilities of Bittensor. - """ - if call_params.certificate is None: - call_function = "serve_axon" - else: - call_function = "serve_axon_tls" - - call = subtensor.substrate.compose_call( - call_module="SubtensorModule", - call_function=call_function, - call_params=call_params.dict(), - ) - - success, message = subtensor.sign_and_send_extrinsic( - call=call, - wallet=wallet, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - sign_with="hotkey", - period=period, - ) - return success, message - - def serve_extrinsic( subtensor: "Subtensor", wallet: "Wallet", @@ -75,35 +25,34 @@ def serve_extrinsic( netuid: int, placeholder1: int = 0, placeholder2: int = 0, - wait_for_inclusion: bool = False, - wait_for_finalization=True, certificate: Optional[Certificate] = None, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: - """Subscribes a Bittensor endpoint to the subtensor chain. - - Args: - subtensor (bittensor.core.subtensor.Subtensor): Subtensor instance object. - wallet (bittensor_wallet.Wallet): Bittensor wallet object. - ip (str): Endpoint host port i.e., ``192.122.31.4``. - port (int): Endpoint port number i.e., ``9221``. - protocol (int): An ``int`` representation of the protocol. - netuid (int): The network uid to serve on. - placeholder1 (int): A placeholder for future use. - placeholder2 (int): A placeholder for future use. - wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning ``True``, or - returns ``False`` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning - ``True``, or returns ``False`` if the extrinsic fails to be finalized within the timeout. - certificate (bittensor.utils.Certificate): Certificate to use for TLS. If ``None``, no TLS will be used. - Defaults to ``None``. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + """ + Subscribes a Bittensor endpoint to the subtensor chain. + + Parameters: + subtensor: Subtensor instance object. + wallet: Bittensor wallet object. + ip: Endpoint host port i.e., ``192.122.31.4``. + port: Endpoint port number i.e., ``9221``. + protocol: An ``int`` representation of the protocol. + netuid: The network uid to serve on. + placeholder1: A placeholder for future use. + placeholder2: A placeholder for future use. + certificate: Certificate to use for TLS. If ``None``, no TLS will be used. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - success (bool): Flag is ``True`` if extrinsic was finalized or included in the block. If we did not wait for - finalization / inclusion, the response is ``True``. + bool: True if the subnet registration was successful, False otherwise. """ # Decrypt hotkey if not (unlock := unlock_key(wallet, "hotkey")).success: @@ -140,13 +89,26 @@ def serve_extrinsic( f"Serving axon with: [blue]AxonInfo({wallet.hotkey.ss58_address}, {ip}:{port})[/blue] -> " f"[green]{subtensor.network}:{netuid}[/green]" ) - success, message = do_serve_axon( - subtensor=subtensor, + + if params.certificate is None: + call_function = "serve_axon" + else: + call_function = "serve_axon_tls" + + call = subtensor.substrate.compose_call( + call_module="SubtensorModule", + call_function=call_function, + call_params=params.dict(), + ) + + success, message = subtensor.sign_and_send_extrinsic( + call=call, wallet=wallet, - call_params=params, - wait_for_finalization=wait_for_finalization, wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + sign_with="hotkey", period=period, + raise_error=raise_error, ) if success: @@ -164,30 +126,30 @@ def serve_axon_extrinsic( subtensor: "Subtensor", netuid: int, axon: "Axon", - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, certificate: Optional["Certificate"] = None, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: - """Serves the axon to the network. + """ + Serves the axon to the network. - Args: - subtensor (bittensor.core.subtensor.Subtensor): Subtensor instance object. + Parameters: + subtensor: Subtensor instance object. netuid (int): The ``netuid`` being served on. axon (bittensor.core.axon.Axon): Axon to serve. - wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning ``True``, or - returns ``False`` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning - ``True``, or returns ``False`` if the extrinsic fails to be finalized within the timeout. certificate (bittensor.utils.Certificate): Certificate to use for TLS. If ``None``, no TLS will be used. Defaults to ``None``. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - success (bool): Flag is ``True`` if extrinsic was finalized or included in the block. If we did not wait for - finalization / inclusion, the response is ``true``. + bool: True if the subnet registration was successful, False otherwise. """ if not (unlock := unlock_key(axon.wallet, "hotkey")).success: logging.error(unlock.message) @@ -216,10 +178,11 @@ def serve_axon_extrinsic( port=external_port, protocol=4, netuid=netuid, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, certificate=certificate, period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) return serve_success @@ -230,34 +193,34 @@ def publish_metadata( netuid: int, data_type: str, data: Union[bytes, dict], - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, - period: Optional[int] = None, reset_bonds: bool = False, + period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Publishes metadata on the Bittensor network using the specified wallet and network identifier. - Args: - subtensor (bittensor.subtensor): The subtensor instance representing the Bittensor blockchain connection. - wallet (bittensor.wallet): The wallet object used for authentication in the transaction. - netuid (int): Network UID on which the metadata is to be published. - data_type (str): The data type of the information being submitted. It should be one of the following: + Parameters: + subtensor: The subtensor instance representing the Bittensor blockchain connection. + wallet: The wallet object used for authentication in the transaction. + netuid: Network UID on which the metadata is to be published. + data_type: The data type of the information being submitted. It should be one of the following: ``'Sha256'``, ``'Blake256'``, ``'Keccak256'``, or ``'Raw0-128'``. This specifies the format or hashing algorithm used for the data. - data (Union[bytes, dict]): The actual metadata content to be published. This should be formatted or hashed + data: The actual metadata content to be published. This should be formatted or hashed according to the ``type`` specified. (Note: max ``str`` length is 128 bytes for ``'Raw0-128'``.) - wait_for_inclusion (bool, optional): If ``True``, the function will wait for the extrinsic to be included in a - block before returning. Defaults to ``False``. - wait_for_finalization (bool, optional): If ``True``, the function will wait for the extrinsic to be finalized - on the chain before returning. Defaults to ``True``. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. - reset_bonds (bool): If `True`, the function will reset the bonds for the neuron. Defaults to `False`. + reset_bonds: If `True`, the function will reset the bonds for the neuron. Defaults to `False`. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - bool: ``True`` if the metadata was successfully published (and finalized if specified). ``False`` otherwise. + bool: True if the subnet registration was successful, False otherwise. Raises: MetadataError: If there is an error in submitting the extrinsic, or if the response from the blockchain indicates @@ -288,6 +251,7 @@ def publish_metadata( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if success: @@ -314,11 +278,11 @@ def get_last_bonds_reset( """ Fetches the last bonds reset triggered at commitment from the blockchain for a given hotkey and netuid. - Args: - subtensor (bittensor.core.subtensor.Subtensor): Subtensor instance object. - netuid (int): The network uid to fetch from. - hotkey (str): The hotkey of the neuron for which to fetch the last bonds reset. - block (Optional[int]): The block number to query. If ``None``, the latest block is used. + Parameters: + subtensor: Subtensor instance object. + netuid: The network uid to fetch from. + hotkey: The hotkey of the neuron for which to fetch the last bonds reset. + block: The block number to query. If ``None``, the latest block is used. Returns: bytes: The last bonds reset data for the specified hotkey and netuid. diff --git a/bittensor/core/extrinsics/staking.py b/bittensor/core/extrinsics/staking.py index fc8b69c48b..eefe5ea65d 100644 --- a/bittensor/core/extrinsics/staking.py +++ b/bittensor/core/extrinsics/staking.py @@ -15,41 +15,40 @@ def add_stake_extrinsic( subtensor: "Subtensor", wallet: "Wallet", - hotkey_ss58: Optional[str] = None, - netuid: Optional[int] = None, - amount: Optional[Balance] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, + netuid: int, + hotkey_ss58: str, + amount: Balance, safe_staking: bool = False, allow_partial_stake: bool = False, rate_tolerance: float = 0.005, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Adds a stake from the specified wallet to the neuron identified by the SS58 address of its hotkey in specified subnet. - Staking is a fundamental process in the Bittensor network that enables neurons to participate actively and earn incentives. + Staking is a fundamental process in the Bittensor network that enables neurons to participate actively and earn + incentives. - Arguments: + Parameters: subtensor: Subtensor instance with the connection to the chain. wallet: Bittensor wallet object. - hotkey_ss58: The `ss58` address of the hotkey account to stake to default to the wallet's hotkey. If not - specified, the wallet's hotkey will be used. Defaults to ``None``. netuid: The unique identifier of the subnet to which the neuron belongs. - amount: Amount to stake as Bittensor balance in TAO always, `None` if staking all. Defaults is ``None``. - wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning `True`, or returns - `False` if the extrinsic fails to enter the block within the timeout. Defaults to ``True``. - wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning `True`, - or returns `False` if the extrinsic fails to be finalized within the timeout. Defaults to ``False``. + hotkey_ss58: The `ss58` address of the hotkey account to stake to default to the wallet's hotkey. + amount: Amount to stake as Bittensor balance in TAO always. safe_staking: If True, enables price safety checks. Default is ``False``. allow_partial_stake: If True, allows partial unstaking if price tolerance exceeded. Default is ``False``. rate_tolerance: Maximum allowed price increase percentage (0.005 = 0.5%). Default is ``0.005``. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. Defaults to ``None``. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - success: Flag is `True` if extrinsic was finalized or included in the block. If we did not wait for - finalization/inclusion, the response is `True`. + bool: True if the subnet registration was successful, False otherwise. Raises: SubstrateRequestException: Raised if the extrinsic fails to be included in the block within the timeout. @@ -60,10 +59,6 @@ def add_stake_extrinsic( logging.error(unlock.message) return False - # Default to wallet's own hotkey if the value is not passed. - if hotkey_ss58 is None: - hotkey_ss58 = wallet.hotkey.ss58_address - logging.info( f":satellite: [magenta]Syncing with chain:[/magenta] [blue]{subtensor.network}[/blue] [magenta]...[/magenta]" ) @@ -79,130 +74,113 @@ def add_stake_extrinsic( ) existential_deposit = subtensor.get_existential_deposit(block=block) - # Convert to bittensor.Balance - if amount is None: - # Stake it all. - staking_balance = Balance.from_tao(old_balance.tao) - logging.warning( - f"Didn't receive any staking amount. Staking all available balance: [blue]{staking_balance}[/blue] " - f"from wallet: [blue]{wallet.name}[/blue]" - ) - else: - staking_balance = amount - # Leave existential balance to keep key alive. - if staking_balance > old_balance - existential_deposit: + if amount > old_balance - existential_deposit: # If we are staking all, we need to leave at least the existential deposit. - staking_balance = old_balance - existential_deposit + amount = old_balance - existential_deposit # Check enough to stake. - if staking_balance > old_balance: + if amount > old_balance: logging.error(":cross_mark: [red]Not enough stake:[/red]") logging.error(f"\t\tbalance:{old_balance}") - logging.error(f"\t\tamount: {staking_balance}") + logging.error(f"\t\tamount: {amount}") logging.error(f"\t\twallet: {wallet.name}") return False - try: - call_params = { - "hotkey": hotkey_ss58, - "netuid": netuid, - "amount_staked": staking_balance.rao, - } - - if safe_staking: - pool = subtensor.subnet(netuid=netuid) - base_price = pool.price.tao + call_params = { + "hotkey": hotkey_ss58, + "netuid": netuid, + "amount_staked": amount.rao, + } - if pool.netuid == 0: - price_with_tolerance = base_price - else: - price_with_tolerance = base_price * (1 + rate_tolerance) + if safe_staking: + pool = subtensor.subnet(netuid=netuid) + base_price = pool.price.tao - logging.info( - f":satellite: [magenta]Safe Staking to:[/magenta] " - f"[blue]netuid: [green]{netuid}[/green], amount: [green]{staking_balance}[/green], " - f"tolerance percentage: [green]{rate_tolerance * 100}%[/green], " - f"price limit: [green]{price_with_tolerance}[/green], " - f"original price: [green]{base_price}[/green], " - f"with partial stake: [green]{allow_partial_stake}[/green] " - f"on [blue]{subtensor.network}[/blue][/magenta]...[/magenta]" - ) - - limit_price = Balance.from_tao(price_with_tolerance).rao - call_params.update( - { - "limit_price": limit_price, - "allow_partial": allow_partial_stake, - } - ) - call_function = "add_stake_limit" - else: - logging.info( - f":satellite: [magenta]Staking to:[/magenta] " - f"[blue]netuid: [green]{netuid}[/green], amount: [green]{staking_balance}[/green] " - f"on [blue]{subtensor.network}[/blue][magenta]...[/magenta]" - ) - call_function = "add_stake" + price_with_tolerance = ( + base_price if pool.netuid == 0 else base_price * (1 + rate_tolerance) + ) - call = subtensor.substrate.compose_call( - call_module="SubtensorModule", - call_function=call_function, - call_params=call_params, + logging.info( + f":satellite: [magenta]Safe Staking to:[/magenta] " + f"[blue]netuid: [green]{netuid}[/green], amount: [green]{amount}[/green], " + f"tolerance percentage: [green]{rate_tolerance * 100}%[/green], " + f"price limit: [green]{price_with_tolerance}[/green], " + f"original price: [green]{base_price}[/green], " + f"with partial stake: [green]{allow_partial_stake}[/green] " + f"on [blue]{subtensor.network}[/blue][/magenta]...[/magenta]" ) - success, message = subtensor.sign_and_send_extrinsic( - call=call, - wallet=wallet, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - use_nonce=True, - sign_with="coldkey", - nonce_key="coldkeypub", - period=period, + limit_price = Balance.from_tao(price_with_tolerance).rao + call_params.update( + { + "limit_price": limit_price, + "allow_partial": allow_partial_stake, + } + ) + call_function = "add_stake_limit" + else: + logging.info( + f":satellite: [magenta]Staking to:[/magenta] " + f"[blue]netuid: [green]{netuid}[/green], amount: [green]{amount}[/green] " + f"on [blue]{subtensor.network}[/blue][magenta]...[/magenta]" ) - if success is True: # If we successfully staked. - # We only wait here if we expect finalization. - if not wait_for_finalization and not wait_for_inclusion: - return True + call_function = "add_stake" - logging.success(":white_heavy_check_mark: [green]Finalized[/green]") + call = subtensor.substrate.compose_call( + call_module="SubtensorModule", + call_function=call_function, + call_params=call_params, + ) - logging.info( - f":satellite: [magenta]Checking Balance on:[/magenta] " - f"[blue]{subtensor.network}[/blue] [magenta]...[/magenta]" - ) - new_block = subtensor.get_current_block() - new_balance = subtensor.get_balance( - wallet.coldkeypub.ss58_address, block=new_block - ) - new_stake = subtensor.get_stake( - coldkey_ss58=wallet.coldkeypub.ss58_address, - hotkey_ss58=hotkey_ss58, - netuid=netuid, - block=new_block, - ) - logging.info( - f"Balance: [blue]{old_balance}[/blue] :arrow_right: {new_balance}[/green]" - ) - logging.info( - f"Stake: [blue]{old_stake}[/blue] :arrow_right: [green]{new_stake}[/green]" - ) + success, message = subtensor.sign_and_send_extrinsic( + call=call, + wallet=wallet, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + use_nonce=True, + sign_with="coldkey", + nonce_key="coldkeypub", + period=period, + raise_error=raise_error, + ) + # If we successfully staked. + if success: + # We only wait here if we expect finalization. + if not wait_for_finalization and not wait_for_inclusion: return True - else: - if safe_staking and "Custom error: 8" in message: - logging.error( - ":cross_mark: [red]Failed[/red]: Price exceeded tolerance limit. Either increase price tolerance or enable partial staking." - ) - else: - logging.error(f":cross_mark: [red]Failed: {message}.[/red]") - return False - except SubstrateRequestException as error: + logging.success(":white_heavy_check_mark: [green]Finalized[/green]") + + logging.info( + f":satellite: [magenta]Checking Balance on:[/magenta] " + f"[blue]{subtensor.network}[/blue] [magenta]...[/magenta]" + ) + new_block = subtensor.get_current_block() + new_balance = subtensor.get_balance( + wallet.coldkeypub.ss58_address, block=new_block + ) + new_stake = subtensor.get_stake( + coldkey_ss58=wallet.coldkeypub.ss58_address, + hotkey_ss58=hotkey_ss58, + netuid=netuid, + block=new_block, + ) + logging.info( + f"Balance: [blue]{old_balance}[/blue] :arrow_right: {new_balance}[/green]" + ) + logging.info( + f"Stake: [blue]{old_stake}[/blue] :arrow_right: [green]{new_stake}[/green]" + ) + return True + + if safe_staking and "Custom error: 8" in message: logging.error( - f":cross_mark: [red]Add Stake Error: {format_error_message(error)}[/red]" + ":cross_mark: [red]Failed[/red]: Price exceeded tolerance limit. Either increase price tolerance or enable partial staking." ) - return False + else: + logging.error(f":cross_mark: [red]Failed: {message}.[/red]") + return False def add_stake_multiple_extrinsic( @@ -210,62 +188,62 @@ def add_stake_multiple_extrinsic( wallet: "Wallet", hotkey_ss58s: list[str], netuids: list[int], - amounts: Optional[list[Balance]] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, + amounts: list[Balance], period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: - """Adds stake to each ``hotkey_ss58`` in the list, using each amount, from a common coldkey. + """ + Adds stake to each ``hotkey_ss58`` in the list, using each amount, from a common coldkey on subnet with + corresponding netuid. - Arguments: - subtensor: The initialized SubtensorInterface object. + Parameters: + subtensor: Subtensor instance with the connection to the chain. wallet: Bittensor wallet object for the coldkey. - hotkey_ss58s: List of hotkeys to stake to. netuids: List of netuids to stake to. - amounts: List of amounts to stake. If `None`, stake all to the first hotkey. - wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning `True`, or returns `False` - if the extrinsic fails to enter the block within the timeout. - wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning `True`, or - returns `False` if the extrinsic fails to be finalized within the timeout. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + hotkey_ss58s: List of hotkeys to stake to. + amounts: List of corresponding TAO amounts to bet for each netuid and hotkey. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - success: `True` if extrinsic was finalized or included in the block. `True` if any wallet was staked. If we did - not wait for finalization/inclusion, the response is `True`. + bool: True if the subnet registration was successful, False otherwise. """ + # Decrypt keys, + if not (unlock := unlock_key(wallet)).success: + logging.error(unlock.message) + return False - if not isinstance(hotkey_ss58s, list) or not all( - isinstance(hotkey_ss58, str) for hotkey_ss58 in hotkey_ss58s - ): - raise TypeError("hotkey_ss58s must be a list of str") + assert all( + [ + isinstance(netuids, list), + isinstance(hotkey_ss58s, list), + isinstance(amounts, list), + ] + ), "The `netuids`, `hotkey_ss58s` and `amounts` must be lists." if len(hotkey_ss58s) == 0: return True - if amounts is not None and len(amounts) != len(hotkey_ss58s): - raise ValueError("amounts must be a list of the same length as hotkey_ss58s") + assert len(netuids) == len(hotkey_ss58s) == len(amounts), ( + "The number of items in `netuids`, `hotkey_ss58s` and `amounts` must be the same." + ) - if netuids is not None and len(netuids) != len(hotkey_ss58s): - raise ValueError("netuids must be a list of the same length as hotkey_ss58s") + if not all(isinstance(hotkey_ss58, str) for hotkey_ss58 in hotkey_ss58s): + raise TypeError("hotkey_ss58s must be a list of str") - new_amounts: Sequence[Optional[Balance]] + new_amounts: Sequence[Optional[Balance]] = [ + amount.set_unit(netuid) for amount, netuid in zip(amounts, netuids) + ] - if amounts is None: - new_amounts = [None] * len(hotkey_ss58s) - else: - new_amounts = [ - amount.set_unit(netuid) for amount, netuid in zip(amounts, netuids) - ] - if sum(amount.tao for amount in new_amounts) == 0: - # Staking 0 tao - return True - - # Decrypt keys, - if not (unlock := unlock_key(wallet)).success: - logging.error(unlock.message) - return False + if sum(amount.tao for amount in new_amounts) == 0: + # Staking 0 tao + return True logging.info( f":satellite: [magenta]Syncing with chain:[/magenta] [blue]{subtensor.network}[/blue] [magenta]...[/magenta]" @@ -284,7 +262,7 @@ def add_stake_multiple_extrinsic( [amount.rao if amount is not None else 0 for amount in new_amounts] ) old_balance = initial_balance = subtensor.get_balance( - wallet.coldkeypub.ss58_address, block=block + address=wallet.coldkeypub.ss58_address, block=block ) if total_staking_rao == 0: # Staking all to the first wallet. @@ -306,32 +284,25 @@ def add_stake_multiple_extrinsic( for idx, (hotkey_ss58, amount, old_stake, netuid) in enumerate( zip(hotkey_ss58s, new_amounts, old_stakes, netuids) ): - staking_all = False - if amount is None: - # Stake it all. - staking_balance = Balance.from_tao(old_balance.tao) - staking_all = True - else: - staking_balance = amount - # Check enough to stake - if staking_balance > old_balance: + if amount > old_balance: logging.error( f":cross_mark: [red]Not enough balance[/red]: [green]{old_balance}[/green] to stake: " - f"[blue]{staking_balance}[/blue] from wallet: [white]{wallet.name}[/white]" + f"[blue]{amount}[/blue] from wallet: [white]{wallet.name}[/white]" ) continue try: logging.info( - f"Staking [blue]{staking_balance}[/blue] to [magenta]{hotkey_ss58}[/magenta] on netuid [blue]{netuid}[/blue]" + f"Staking [blue]{amount}[/blue] to hotkey: [magenta]{hotkey_ss58}[/magenta] on netuid: " + f"[blue]{netuid}[/blue]" ) call = subtensor.substrate.compose_call( call_module="SubtensorModule", call_function="add_stake", call_params={ "hotkey": hotkey_ss58, - "amount_staked": staking_balance.rao, + "amount_staked": amount.rao, "netuid": netuid, }, ) @@ -344,18 +315,15 @@ def add_stake_multiple_extrinsic( nonce_key="coldkeypub", sign_with="coldkey", period=period, + raise_error=raise_error, ) - if success is True: # If we successfully staked. + # If we successfully staked. + if success: # We only wait here if we expect finalization. - if not wait_for_finalization and not wait_for_inclusion: - old_balance -= staking_balance + old_balance -= amount successful_stakes += 1 - if staking_all: - # If staked all, no need to continue - break - continue logging.success(":white_heavy_check_mark: [green]Finalized[/green]") @@ -378,10 +346,6 @@ def add_stake_multiple_extrinsic( ) old_balance = new_balance successful_stakes += 1 - if staking_all: - # If staked all, no need to continue - break - else: logging.error(f":cross_mark: [red]Failed[/red]: {message}") continue @@ -390,7 +354,6 @@ def add_stake_multiple_extrinsic( logging.error( f":cross_mark: [red]Add Stake Multiple error: {format_error_message(error)}[/red]" ) - continue if successful_stakes != 0: logging.info( diff --git a/bittensor/core/extrinsics/start_call.py b/bittensor/core/extrinsics/start_call.py index 2788bb88f1..4a0b37e382 100644 --- a/bittensor/core/extrinsics/start_call.py +++ b/bittensor/core/extrinsics/start_call.py @@ -12,23 +12,25 @@ def start_call_extrinsic( subtensor: "Subtensor", wallet: "Wallet", netuid: int, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = False, - period: Optional[int] = None, ) -> tuple[bool, str]: """ Submits a start_call extrinsic to the blockchain, to trigger the start call process for a subnet (used to start a new subnet's emission mechanism). - Args: + Parameters: subtensor (Subtensor): The Subtensor client instance used for blockchain interaction. wallet (Wallet): The wallet used to sign the extrinsic (must be unlocked). netuid (int): The UID of the target subnet for which the call is being initiated. - wait_for_inclusion (bool, optional): Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization (bool, optional): Whether to wait for finalization of the extrinsic. Defaults to False. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: Tuple[bool, str]: @@ -51,6 +53,7 @@ def start_call_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if not wait_for_finalization and not wait_for_inclusion: diff --git a/bittensor/core/extrinsics/take.py b/bittensor/core/extrinsics/take.py index 968338d8a9..3effd7699b 100644 --- a/bittensor/core/extrinsics/take.py +++ b/bittensor/core/extrinsics/take.py @@ -13,27 +13,29 @@ def increase_take_extrinsic( wallet: Wallet, hotkey_ss58: str, take: int, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = True, - raise_error: bool = False, - period: Optional[int] = None, ) -> tuple[bool, str]: """Sets the delegate 'take' percentage for a neuron identified by its hotkey. - Args: - subtensor (Subtensor): Blockchain connection. - wallet (Wallet): The wallet to sign the extrinsic. - hotkey_ss58 (str): SS58 address of the hotkey to set take for. - take (int): The percentage of rewards that the delegate claims from nominators. - wait_for_inclusion (bool, optional): Wait for inclusion before returning. Defaults to True. - wait_for_finalization (bool, optional): Wait for finalization before returning. Defaults to True. - raise_error (bool, optional): Raise error on failure. Defaults to False. - period: The number of blocks during which the transaction will remain valid after it's submitted. If - the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + Parameters: + subtensor: The Subtensor instance. + wallet: The wallet to sign the extrinsic. + hotkey_ss58: SS58 address of the hotkey to set take for. + take: The percentage of rewards that the delegate claims from nominators. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - tuple[bool, str]: Success flag and status message. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. """ unlock = unlock_key(wallet, raise_error=raise_error) @@ -64,27 +66,30 @@ def decrease_take_extrinsic( wallet: Wallet, hotkey_ss58: str, take: int, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = True, - raise_error: bool = False, - period: Optional[int] = None, ) -> tuple[bool, str]: - """Sets the delegate `take` percentage for a neuron identified by its hotkey. - - Args: - subtensor (Subtensor): Blockchain connection. - wallet (Wallet): The wallet to sign the extrinsic. - hotkey_ss58 (str): SS58 address of the hotkey to set take for. - take (int): The percentage of rewards that the delegate claims from nominators. - wait_for_inclusion (bool, optional): Wait for inclusion before returning. Defaults to True. - wait_for_finalization (bool, optional): Wait for finalization before returning. Defaults to True. - raise_error (bool, optional): Raise error on failure. Defaults to False. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. - If the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + """ + Sets the delegate `take` percentage for a neuron identified by its hotkey. + + Parameters: + subtensor: The Subtensor instance. + wallet: The wallet to sign the extrinsic. + hotkey_ss58: SS58 address of the hotkey to set take for. + take: The percentage of rewards that the delegate claims from nominators. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - tuple[bool, str]: Success flag and status message. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. """ unlock = unlock_key(wallet, raise_error=raise_error) @@ -103,8 +108,8 @@ def decrease_take_extrinsic( return subtensor.sign_and_send_extrinsic( call=call, wallet=wallet, - wait_for_inclusion=wait_for_inclusion, + period=period, raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) diff --git a/bittensor/core/extrinsics/transfer.py b/bittensor/core/extrinsics/transfer.py index 0d0a8377b5..7d2a28ad9f 100644 --- a/bittensor/core/extrinsics/transfer.py +++ b/bittensor/core/extrinsics/transfer.py @@ -2,10 +2,10 @@ from bittensor.core.settings import NETWORK_EXPLORER_MAP from bittensor.utils import ( - is_valid_bittensor_address_or_public_key, - unlock_key, get_explorer_url_for_network, get_transfer_fn_params, + is_valid_bittensor_address_or_public_key, + unlock_key, ) from bittensor.utils.balance import Balance from bittensor.utils.btlogging import logging @@ -20,32 +20,31 @@ def transfer_extrinsic( wallet: "Wallet", destination: str, amount: Optional[Balance], - transfer_all: bool = False, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, keep_alive: bool = True, + transfer_all: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """Transfers funds from this wallet to the destination public key address. - Args: - subtensor (bittensor.core.subtensor.Subtensor): the Subtensor object used for transfer - wallet (bittensor_wallet.Wallet): Bittensor wallet object to make transfer from. - destination (str): Destination public key address (ss58_address or ed25519) of recipient. - amount (bittensor.utils.balance.Balance): Amount to stake as Bittensor balance. `None` if transferring all. - transfer_all (bool): Whether to transfer all funds from this wallet to the destination address. - wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning `True`, or returns - `False` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning - `True`, or returns `False` if the extrinsic fails to be finalized within the timeout. - keep_alive (bool): If set, keeps the account alive by keeping the balance above the existential deposit. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. - If the transaction is not included in a block within that number of blocks, it will expire and be rejected. - You can think of it as an expiration date for the transaction. + Parameters: + subtensor: the Subtensor object used for transfer + wallet: The wallet to sign the extrinsic. + destination: Destination public key address (ss58_address or ed25519) of recipient. + amount: Amount to stake as Bittensor balance. `None` if transferring all. + transfer_all: Whether to transfer all funds from this wallet to the destination address. + keep_alive: If set, keeps the account alive by keeping the balance above the existential deposit. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You can + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - success (bool): Flag is `True` if extrinsic was finalized or included in the block. If we did not wait for - finalization / inclusion, the response is `True`, regardless of its inclusion. + bool: True if the subnet registration was successful, False otherwise. """ if amount is None and not transfer_all: logging.error("If not transferring all, `amount` must be specified.") @@ -110,6 +109,7 @@ def transfer_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, + raise_error=raise_error, ) if success: diff --git a/bittensor/core/extrinsics/unstaking.py b/bittensor/core/extrinsics/unstaking.py index 8f0ce3329d..d9539a8268 100644 --- a/bittensor/core/extrinsics/unstaking.py +++ b/bittensor/core/extrinsics/unstaking.py @@ -16,54 +16,44 @@ def unstake_extrinsic( subtensor: "Subtensor", wallet: "Wallet", - hotkey_ss58: Optional[str] = None, - netuid: Optional[int] = None, - amount: Optional[Balance] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - safe_staking: bool = False, + netuid: int, + hotkey_ss58: str, + amount: Balance, allow_partial_stake: bool = False, rate_tolerance: float = 0.005, + safe_unstaking: bool = False, period: Optional[int] = None, - unstake_all: bool = False, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: - """Removes stake into the wallet coldkey from the specified hotkey ``uid``. + """ + Removes stake into the wallet coldkey from the specified hotkey ``uid``. - Args: + Parameters: subtensor: Subtensor instance. wallet: Bittensor wallet object. - hotkey_ss58: The ``ss58`` address of the hotkey to unstake from. By default, the wallet hotkey is used. + hotkey_ss58: The ``ss58`` address of the hotkey to unstake from. netuid: Subnet unique id. amount: Amount to stake as Bittensor balance. - wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning ``True``, or returns - ``False`` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning ``True``, - or returns ``False`` if the extrinsic fails to be finalized within the timeout. - safe_staking: If true, enables price safety checks. - allow_partial_stake: If true, allows partial unstaking if price tolerance exceeded - rate_tolerance: Maximum allowed price decrease percentage (0.005 = 0.5%) + allow_partial_stake: If true, allows partial unstaking if price tolerance exceeded. + rate_tolerance: Maximum allowed price decrease percentage (0.005 = 0.5%). + safe_unstaking: If true, enables price safety checks. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - unstake_all: If true, unstakes all tokens. Default is ``False``. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - tuple[bool, str]: - A tuple containing: - - `True` and a success message if the unstake operation succeeded; - - `False` and an error message otherwise. + bool: True if the subnet registration was successful, False otherwise. """ - if amount and unstake_all: - raise ValueError("Cannot specify both `amount` and `unstake_all`.") - # Decrypt keys, if not (unlock := unlock_key(wallet)).success: logging.error(unlock.message) return False - if hotkey_ss58 is None: - hotkey_ss58 = wallet.hotkey.ss58_address # Default to wallet's own hotkey. - logging.info( f":satellite: [magenta]Syncing with chain:[/magenta] [blue]{subtensor.network}[/blue] [magenta]...[/magenta]" ) @@ -76,24 +66,14 @@ def unstake_extrinsic( block=block, ) - # Convert to bittensor.Balance - if amount is None: - # Unstake it all. - logging.warning( - f"Didn't receive any unstaking amount. Unstaking all existing stake: [blue]{old_stake}[/blue] " - f"from hotkey: [blue]{hotkey_ss58}[/blue]" - ) - unstaking_balance = old_stake - else: - unstaking_balance = amount - unstaking_balance.set_unit(netuid) + # unstaking_balance = amount + amount.set_unit(netuid) # Check enough to unstake. - stake_on_uid = old_stake - if unstaking_balance > stake_on_uid: + if amount > old_stake: logging.error( - f":cross_mark: [red]Not enough stake[/red]: [green]{stake_on_uid}[/green] to unstake: " - f"[blue]{unstaking_balance}[/blue] from hotkey: [yellow]{wallet.hotkey_str}[/yellow]" + f":cross_mark: [red]Not enough stake[/red]: [green]{old_stake}[/green] to unstake: " + f"[blue]{amount}[/blue] from hotkey: [yellow]{wallet.hotkey_str}[/yellow]" ) return False @@ -101,10 +81,10 @@ def unstake_extrinsic( call_params = { "hotkey": hotkey_ss58, "netuid": netuid, - "amount_unstaked": unstaking_balance.rao, + "amount_unstaked": amount.rao, } - if safe_staking: + if safe_unstaking: pool = subtensor.subnet(netuid=netuid) base_price = pool.price.tao @@ -115,7 +95,7 @@ def unstake_extrinsic( logging_info = ( f":satellite: [magenta]Safe Unstaking from:[/magenta] " - f"netuid: [green]{netuid}[/green], amount: [green]{unstaking_balance}[/green], " + f"netuid: [green]{netuid}[/green], amount: [green]{amount}[/green], " f"tolerance percentage: [green]{rate_tolerance * 100}%[/green], " f"price limit: [green]{price_with_tolerance}[/green], " f"original price: [green]{base_price}[/green], " @@ -134,7 +114,7 @@ def unstake_extrinsic( else: logging_info = ( f":satellite: [magenta]Unstaking from:[/magenta] " - f"netuid: [green]{netuid}[/green], amount: [green]{unstaking_balance}[/green] " + f"netuid: [green]{netuid}[/green], amount: [green]{amount}[/green] " f"on [blue]{subtensor.network}[/blue]" ) call_function = "remove_stake" @@ -158,6 +138,7 @@ def unstake_extrinsic( sign_with="coldkey", use_nonce=True, period=period, + raise_error=raise_error, ) if success: # If we successfully unstaked. @@ -188,14 +169,15 @@ def unstake_extrinsic( f"Stake: [blue]{old_stake}[/blue] :arrow_right: [green]{new_stake}[/green]" ) return True + + if safe_unstaking and "Custom error: 8" in message: + logging.error( + ":cross_mark: [red]Failed[/red]: Price exceeded tolerance limit. Either increase price tolerance or" + " enable partial staking." + ) else: - if safe_staking and "Custom error: 8" in message: - logging.error( - ":cross_mark: [red]Failed[/red]: Price exceeded tolerance limit. Either increase price tolerance or enable partial staking." - ) - else: - logging.error(f":cross_mark: [red]Failed: {message}.[/red]") - return False + logging.error(f":cross_mark: [red]Failed: {message}.[/red]") + return False except SubstrateRequestException as error: logging.error( @@ -210,24 +192,26 @@ def unstake_all_extrinsic( hotkey: str, netuid: int, rate_tolerance: Optional[float] = 0.005, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Unstakes all TAO/Alpha associated with a hotkey from the specified subnets on the Bittensor network. - Arguments: + Parameters: subtensor: Subtensor instance. wallet: The wallet of the stake owner. hotkey: The SS58 address of the hotkey to unstake from. netuid: The unique identifier of the subnet. rate_tolerance: The maximum allowed price change ratio when unstaking. For example, 0.005 = 0.5% maximum price decrease. If not passed (None), then unstaking goes without price limit. Default is `0.005`. - wait_for_inclusion: Waits for the transaction to be included in a block. Default is `True`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Default is `False`. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can - think of it as an expiration date for the transaction. Default is `None`. + think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: tuple[bool, str]: @@ -265,6 +249,7 @@ def unstake_all_extrinsic( sign_with="coldkey", use_nonce=True, period=period, + raise_error=raise_error, ) return success, message @@ -273,54 +258,44 @@ def unstake_all_extrinsic( def unstake_multiple_extrinsic( subtensor: "Subtensor", wallet: "Wallet", - hotkey_ss58s: list[str], netuids: list[int], + hotkey_ss58s: list[str], amounts: Optional[list[Balance]] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - period: Optional[int] = None, unstake_all: bool = False, + period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: - """Removes stake from each ``hotkey_ss58`` in the list, using each amount, to a common coldkey. + """ + Removes stake from each ``hotkey_ss58`` in the list, using each amount, to a common coldkey. - Args: + Parameters: subtensor: Subtensor instance. wallet: The wallet with the coldkey to unstake to. - hotkey_ss58s: List of hotkeys to unstake from. netuids: List of subnets unique IDs to unstake from. + hotkey_ss58s: List of hotkeys to unstake from. amounts: List of amounts to unstake. If ``None``, unstake all. - wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning ``True``, or - returns ``False`` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning ``True``, - or returns ``False`` if the extrinsic fails to be finalized within the timeout. + unstake_all: If true, unstakes all tokens. Default is ``False``. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - unstake_all: If true, unstakes all tokens. Default is ``False``. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - tuple[bool, str]: - A tuple containing: - - `True` and a success message if the unstake operation succeeded; - - `False` and an error message otherwise. + bool: True if the subnet registration was successful, False otherwise. """ + # Unlock coldkey. + if not (unlock := unlock_key(wallet)).success: + logging.error(unlock.message) + return False + + # or amounts or unstake_all (no both) if amounts and unstake_all: raise ValueError("Cannot specify both `amounts` and `unstake_all`.") - if not isinstance(hotkey_ss58s, list) or not all( - isinstance(hotkey_ss58, str) for hotkey_ss58 in hotkey_ss58s - ): - raise TypeError("hotkey_ss58s must be a list of str") - - if len(hotkey_ss58s) == 0: - return True - - if netuids is not None and len(netuids) != len(hotkey_ss58s): - raise ValueError("netuids must be a list of the same length as hotkey_ss58s") - - if amounts is not None and len(amounts) != len(hotkey_ss58s): - raise ValueError("amounts must be a list of the same length as hotkey_ss58s") - if amounts is not None and not all( isinstance(amount, Balance) for amount in amounts ): @@ -335,10 +310,29 @@ def unstake_multiple_extrinsic( # Staking 0 tao return True - # Unlock coldkey. - if not (unlock := unlock_key(wallet)).success: - logging.error(unlock.message) - return False + assert all( + [ + isinstance(netuids, list), + isinstance(hotkey_ss58s, list), + isinstance(amounts, list), + ] + ), "The `netuids`, `hotkey_ss58s` and `amounts` must be lists." + + if len(hotkey_ss58s) == 0: + return True + + assert len(netuids) == len(hotkey_ss58s) == len(amounts), ( + "The number of items in `netuids`, `hotkey_ss58s` and `amounts` must be the same." + ) + + if not all(isinstance(hotkey_ss58, str) for hotkey_ss58 in hotkey_ss58s): + raise TypeError("hotkey_ss58s must be a list of str") + + if amounts is not None and len(amounts) != len(hotkey_ss58s): + raise ValueError("amounts must be a list of the same length as hotkey_ss58s") + + if netuids is not None and len(netuids) != len(hotkey_ss58s): + raise ValueError("netuids must be a list of the same length as hotkey_ss58s") logging.info( f":satellite: [magenta]Syncing with chain:[/magenta] [blue]{subtensor.network}[/blue] [magenta]...[/magenta]" @@ -394,7 +388,7 @@ def unstake_multiple_extrinsic( f"[blue]{netuid}[/blue] for fee [blue]{fee}[/blue]" ) - staking_response, err_msg = subtensor.sign_and_send_extrinsic( + success, message = subtensor.sign_and_send_extrinsic( call=call, wallet=wallet, wait_for_inclusion=wait_for_inclusion, @@ -403,9 +397,10 @@ def unstake_multiple_extrinsic( sign_with="coldkey", use_nonce=True, period=period, + raise_error=raise_error, ) - if staking_response is True: # If we successfully unstaked. + if success: # If we successfully unstaked. # We only wait here if we expect finalization. if not wait_for_finalization and not wait_for_inclusion: @@ -429,7 +424,7 @@ def unstake_multiple_extrinsic( ) successful_unstakes += 1 else: - logging.error(f":cross_mark: [red]Failed: {err_msg}.[/red]") + logging.error(f":cross_mark: [red]Failed: {message}.[/red]") continue except SubstrateRequestException as error: diff --git a/bittensor/core/extrinsics/weights.py b/bittensor/core/extrinsics/weights.py index fec8e36b70..0a3aa8e264 100644 --- a/bittensor/core/extrinsics/weights.py +++ b/bittensor/core/extrinsics/weights.py @@ -24,26 +24,26 @@ def commit_weights_extrinsic( wallet: "Wallet", netuid: int, commit_hash: str, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = False, period: Optional[int] = None, raise_error: bool = False, + wait_for_inclusion: bool = False, + wait_for_finalization: bool = False, ) -> tuple[bool, str]: """ Commits a hash of the neuron's weights to the Bittensor blockchain using the provided wallet. This function is a wrapper around the `do_commit_weights` method. - Args: + Parameters: subtensor: The subtensor instance used for blockchain interaction. wallet: The wallet associated with the neuron committing the weights. netuid: The unique identifier of the subnet. commit_hash: The hash of the neuron's weights to be committed. - wait_for_inclusion: Waits for the transaction to be included in a block. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - raise_error (bool): Whether to raise an error if the transaction fails. + raise_error: Whether to raise an error if the transaction fails. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: tuple[bool, str]: @@ -51,7 +51,7 @@ def commit_weights_extrinsic( `msg` is a string value describing the success or potential error. This function provides a user-friendly interface for committing weights to the Bittensor blockchain, ensuring proper - error handling and user interaction when required. + error handling and user interaction when required. """ call = subtensor.substrate.compose_call( @@ -89,16 +89,16 @@ def reveal_weights_extrinsic( weights: list[int], salt: list[int], version_key: int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = False, period: Optional[int] = None, raise_error: bool = False, + wait_for_inclusion: bool = False, + wait_for_finalization: bool = False, ) -> tuple[bool, str]: """ Reveals the weights for a specific subnet on the Bittensor blockchain using the provided wallet. This function is a wrapper around the `_do_reveal_weights` method. - Args: + Parameters: subtensor: The subtensor instance used for blockchain interaction. wallet: The wallet associated with the neuron revealing the weights. netuid: The unique identifier of the subnet. @@ -106,12 +106,12 @@ def reveal_weights_extrinsic( weights: List of weight values corresponding to each UID. salt: List of salt values corresponding to the hash function. version_key: Version key for compatibility with the network. - wait_for_inclusion: Waits for the transaction to be included in a block. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - raise_error: raises the relevant exception rather than returning `False` if unsuccessful. + raise_error: Whether to raise an error if the transaction fails. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: tuple[bool, str]: @@ -160,28 +160,27 @@ def set_weights_extrinsic( uids: Union[NDArray[np.int64], "torch.LongTensor", list], weights: Union[NDArray[np.float32], "torch.FloatTensor", list], version_key: int = version_as_int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = False, period: Optional[int] = 8, raise_error: bool = False, + wait_for_inclusion: bool = False, + wait_for_finalization: bool = False, ) -> tuple[bool, str]: - """Sets the given weights and values on a chain for a wallet hotkey account. + """ + Sets the given weights and values on a chain for a wallet hotkey account. - Args: + Parameters: subtensor: Bittensor subtensor object. wallet: Bittensor wallet object. netuid: The ``netuid`` of the subnet to set weights for. uids: The ``uint64`` uids of destination neurons. weights: The weights to set. These must be ``float``s and correspond to the passed ``uid``s. version_key: The version key of the validator. - wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning ``True``, or returns - ``False`` if the extrinsic fails to enter the block within the timeout. - wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning ``True``, - or returns ``False`` if the extrinsic fails to be finalized within the timeout. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. - raise_error: raises the relevant exception rather than returning `False` if unsuccessful. + raise_error: Whether to raise an error if the transaction fails. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: tuple[bool, str]: diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 7696eebeb9..435498038c 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -530,35 +530,6 @@ def bonds( return b_map - def commit( - self, wallet, netuid: int, data: str, period: Optional[int] = None - ) -> bool: - """ - Commits arbitrary data to the Bittensor network by publishing metadata. - - Arguments: - wallet (bittensor_wallet.Wallet): The wallet associated with the neuron committing the data. - netuid (int): The unique identifier of the subnetwork. - data (str): The data to be committed to the network. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. - - Returns: - bool: `True` if the commitment was successful, `False` otherwise. - """ - return publish_metadata( - subtensor=self, - wallet=wallet, - netuid=netuid, - data_type=f"Raw{len(data)}", - data=data.encode(), - period=period, - ) - - # add explicit alias - set_commitment = commit - def commit_reveal_enabled( self, netuid: int, block: Optional[int] = None ) -> Optional[bool]: @@ -2772,20 +2743,27 @@ def set_reveal_commitment( blocks_until_reveal: int = 360, block_time: Union[int, float] = 12, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, int]: """ Commits arbitrary data to the Bittensor network by publishing metadata. - Arguments: - wallet (bittensor_wallet.Wallet): The wallet associated with the neuron committing the data. - netuid (int): The unique identifier of the subnetwork. - data (str): The data to be committed to the network. - blocks_until_reveal (int): The number of blocks from now after which the data will be revealed. Defaults to - `360`. Then number of blocks in one epoch. - block_time (Union[int, float]): The number of seconds between each block. Defaults to `12`. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + Parameters: + wallet: The wallet associated with the neuron committing the data. + netuid: The unique identifier of the subnetwork. + data: The data to be committed to the network. + blocks_until_reveal: The number of blocks from now after which the data will be revealed. Then number of + blocks in one epoch. + block_time: The number of seconds between each block. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. + Returns: bool: `True` if the commitment was successful, `False` otherwise. @@ -2806,6 +2784,9 @@ def set_reveal_commitment( data_type="TimelockEncrypted", data=data_, period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ), reveal_round def subnet(self, netuid: int, block: Optional[int] = None) -> Optional[DynamicInfo]: @@ -3136,47 +3117,47 @@ def sign_and_send_extrinsic( def add_stake( self, wallet: "Wallet", - hotkey_ss58: Optional[str] = None, - netuid: Optional[int] = None, - amount: Optional[Balance] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, + netuid: int, + hotkey_ss58: str, + amount: Balance, safe_staking: bool = False, allow_partial_stake: bool = False, rate_tolerance: float = 0.005, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Adds a stake from the specified wallet to the neuron identified by the SS58 address of its hotkey in specified - subnet. Staking is a fundamental process in the Bittensor network that enables neurons to participate - actively and earn incentives. + subnet. Staking is a fundamental process in the Bittensor network that enables neurons to participate actively + and earn incentives. - Args: + Parameters: wallet: The wallet to be used for staking. - hotkey_ss58: The SS58 address of the hotkey associated with the neuron to which you intend to delegate your - stake. If not specified, the wallet's hotkey will be used. Defaults to ``None``. netuid: The unique identifier of the subnet to which the neuron belongs. + hotkey_ss58: The `ss58` address of the hotkey account to stake to default to the wallet's hotkey. amount: The amount of TAO to stake. - wait_for_inclusion: Waits for the transaction to be included in a block. Defaults to ``True``. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Defaults to ``False``. safe_staking: If true, enables price safety checks to protect against fluctuating prices. The stake will only execute if the price change doesn't exceed the rate tolerance. Default is ``False``. allow_partial_stake: If true and safe_staking is enabled, allows partial staking when the full amount would exceed the price tolerance. If false, the entire stake fails if it would exceed the tolerance. Default is ``False``. - rate_tolerance: The maximum allowed price change ratio when staking. For example, - 0.005 = 0.5% maximum price increase. Only used when safe_staking is True. Default is ``0.005``. - period: The number of blocks during which the transaction will remain valid after it's submitted. If the - transaction is not included in a block within that number of blocks, it will expire and be rejected. You - can think of it as an expiration date for the transaction. Defaults to ``None``. + rate_tolerance: The maximum allowed price change ratio when staking. For example, 0.005 = 0.5% maximum price + increase. Only used when safe_staking is True. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: - bool: True if the staking is successful, False otherwise. + bool: ``True`` if the staking is successful, ``False`` otherwise. - This function enables neurons to increase their stake in the network, enhancing their influence and potential - rewards in line with Bittensor's consensus and reward mechanisms. - When safe_staking is enabled, it provides protection against price fluctuations during the time stake is - executed and the time it is actually processed by the chain. + This function enables neurons to increase their stake in the network, enhancing their influence and potential. + When safe_staking is enabled, it provides protection against price fluctuations during the time stake is + executed and the time it is actually processed by the chain. """ amount = check_and_convert_to_balance(amount) return add_stake_extrinsic( @@ -3185,12 +3166,13 @@ def add_stake( hotkey_ss58=hotkey_ss58, netuid=netuid, amount=amount, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, safe_staking=safe_staking, allow_partial_stake=allow_partial_stake, rate_tolerance=rate_tolerance, period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) def add_liquidity( @@ -3201,26 +3183,27 @@ def add_liquidity( price_low: Balance, price_high: Balance, hotkey: Optional[str] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """ Adds liquidity to the specified price range. - Arguments: + Parameters: wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. liquidity: The amount of liquidity to be added. price_low: The lower bound of the price tick range. In TAO. price_high: The upper bound of the price tick range. In TAO. - hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. Defaults to - `None`. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. + hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: Tuple[bool, str]: @@ -3228,7 +3211,7 @@ def add_liquidity( - False and an error message if the submission fails or the wallet cannot be unlocked. Note: Adding is allowed even when user liquidity is enabled in specified subnet. Call `toggle_user_liquidity` - method to enable/disable user liquidity. + method to enable/disable user liquidity. """ return add_liquidity_extrinsic( subtensor=self, @@ -3238,9 +3221,10 @@ def add_liquidity( price_low=price_low, price_high=price_high, hotkey=hotkey, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) def add_stake_multiple( @@ -3248,65 +3232,68 @@ def add_stake_multiple( wallet: "Wallet", hotkey_ss58s: list[str], netuids: list[int], - amounts: Optional[list[Balance]] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, + amounts: list[Balance], period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Adds stakes to multiple neurons identified by their hotkey SS58 addresses. This bulk operation allows for efficient staking across different neurons from a single wallet. - Args: - wallet (bittensor_wallet.Wallet): The wallet used for staking. - hotkey_ss58s (list[str]): List of ``SS58`` addresses of hotkeys to stake to. - netuids (list[int]): List of network UIDs to stake to. - amounts (list[Balance]): Corresponding amounts of TAO to stake for each hotkey. - wait_for_inclusion (bool): Waits for the transaction to be included in a block. - wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + Parameters: + wallet: The wallet used for staking. + hotkey_ss58s: List of ``SS58`` addresses of hotkeys to stake to. + netuids: List of subnet UIDs. + amounts: List of corresponding TAO amounts to bet for each netuid and hotkey. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - bool: ``True`` if the staking is successful for all specified neurons, False otherwise. + bool: ``True`` if the staking is successful for all specified neurons, ``False`` otherwise. This function is essential for managing stakes across multiple neurons, reflecting the dynamic and collaborative - nature of the Bittensor network. + nature of the Bittensor network. """ return add_stake_multiple_extrinsic( subtensor=self, wallet=wallet, - hotkey_ss58s=hotkey_ss58s, netuids=netuids, + hotkey_ss58s=hotkey_ss58s, amounts=amounts, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) def burned_register( self, wallet: "Wallet", netuid: int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Registers a neuron on the Bittensor network by recycling TAO. This method of registration involves recycling - TAO tokens, allowing them to be re-mined by performing work on the network. + TAO tokens, allowing them to be re-mined by performing work on the network. - Args: - wallet (bittensor_wallet.Wallet): The wallet associated with the neuron to be registered. - netuid (int): The unique identifier of the subnet. - wait_for_inclusion (bool, optional): Waits for the transaction to be included in a block. Defaults to - `False`. - wait_for_finalization (bool, optional): Waits for the transaction to be finalized on the blockchain. - Defaults to `True`. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + Parameters: + wallet: The wallet associated with the neuron to be registered. + netuid: The unique identifier of the subnet. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: bool: ``True`` if the registration is successful, False otherwise. @@ -3316,18 +3303,20 @@ def burned_register( return root_register_extrinsic( subtensor=self, wallet=wallet, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) return burned_register_extrinsic( subtensor=self, wallet=wallet, netuid=netuid, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) def commit_weights( @@ -3338,38 +3327,38 @@ def commit_weights( uids: Union[NDArray[np.int64], list], weights: Union[NDArray[np.int64], list], version_key: int = version_as_int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = False, max_retries: int = 5, period: Optional[int] = 16, + raise_error: bool = True, + wait_for_inclusion: bool = False, + wait_for_finalization: bool = False, ) -> tuple[bool, str]: """ Commits a hash of the neuron's weights to the Bittensor blockchain using the provided wallet. This action serves as a commitment or snapshot of the neuron's current weight distribution. - Arguments: - wallet (bittensor_wallet.Wallet): The wallet associated with the neuron committing the weights. - netuid (int): The unique identifier of the subnet. - salt (list[int]): list of randomly generated integers as salt to generated weighted hash. - uids (np.ndarray): NumPy array of neuron UIDs for which weights are being committed. - weights (np.ndarray): NumPy array of weight values corresponding to each UID. - version_key (int): Version key for compatibility with the network. Default is ``int representation of - a Bittensor version.``. - wait_for_inclusion (bool): Waits for the transaction to be included in a block. Default is ``False``. - wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. Default is - ``False``. - max_retries (int): The number of maximum attempts to commit weights. Default is ``5``. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + Parameters: + wallet: The wallet associated with the neuron committing the weights. + netuid: The unique identifier of the subnet. + salt: list of randomly generated integers as salt to generated weighted hash. + uids: NumPy array of neuron UIDs for which weights are being committed. + weights: NumPy array of weight values corresponding to each UID. + version_key: Version key for compatibility with the network. + max_retries: The number of maximum attempts to commit weights. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: tuple[bool, str]: `True` if the weight commitment is successful, False otherwise. `msg` is a string value describing the success or potential error. - This function allows neurons to create a tamper-proof record of their weight distribution at a specific point - in time, enhancing transparency and accountability within the Bittensor network. + This function allows neurons to create a tamper-proof record of their weight distribution at a specific point in + time, enhancing transparency and accountability within the Bittensor network. """ retries = 0 success = False @@ -3398,10 +3387,10 @@ def commit_weights( wallet=wallet, netuid=netuid, commit_hash=commit_hash, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, - raise_error=True, ) if success: break @@ -3418,24 +3407,25 @@ def modify_liquidity( position_id: int, liquidity_delta: Balance, hotkey: Optional[str] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Modifies liquidity in liquidity position by adding or removing liquidity from it. - Arguments: + Parameters: wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. position_id: The id of the position record in the pool. liquidity_delta: The amount of liquidity to be added or removed (add if positive or remove if negative). - hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. Defaults to - `None`. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. + hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: Tuple[bool, str]: @@ -3469,7 +3459,7 @@ def modify_liquidity( ) Note: Modifying is allowed even when user liquidity is enabled in specified subnet. Call `toggle_user_liquidity` - to enable/disable user liquidity. + to enable/disable user liquidity. """ return modify_liquidity_extrinsic( subtensor=self, @@ -3478,65 +3468,67 @@ def modify_liquidity( position_id=position_id, liquidity_delta=liquidity_delta, hotkey=hotkey, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) def move_stake( self, wallet: "Wallet", - origin_hotkey: str, + origin_hotkey_ss58: str, origin_netuid: int, - destination_hotkey: str, + destination_hotkey_ss58: str, destination_netuid: int, amount: Optional[Balance] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - period: Optional[int] = None, move_all_stake: bool = False, + period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Moves stake to a different hotkey and/or subnet. - Args: - wallet (bittensor.wallet): The wallet to move stake from. - origin_hotkey (str): The SS58 address of the source hotkey. - origin_netuid (int): The netuid of the source subnet. - destination_hotkey (str): The SS58 address of the destination hotkey. - destination_netuid (int): The netuid of the destination subnet. - amount (Balance): Amount of stake to move. - wait_for_inclusion (bool): Waits for the transaction to be included in a block. - wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + Parameters: + wallet: The wallet to move stake from. + origin_hotkey_ss58: The SS58 address of the source hotkey. + origin_netuid: The netuid of the source subnet. + destination_hotkey_ss58: The SS58 address of the destination hotkey. + destination_netuid: The netuid of the destination subnet. + amount: Amount of stake to move. move_all_stake: If true, moves all stake from the source hotkey to the destination hotkey. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - success (bool): True if the stake movement was successful. + success: True if the stake movement was successful. """ amount = check_and_convert_to_balance(amount) return move_stake_extrinsic( subtensor=self, wallet=wallet, - origin_hotkey=origin_hotkey, + origin_hotkey_ss58=origin_hotkey_ss58, origin_netuid=origin_netuid, - destination_hotkey=destination_hotkey, + destination_hotkey_ss58=destination_hotkey_ss58, destination_netuid=destination_netuid, amount=amount, + move_all_stake=move_all_stake, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, - move_all_stake=move_all_stake, ) def register( self, wallet: "Wallet", netuid: int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, max_allowed_attempts: int = 3, output_in_place: bool = True, cuda: bool = False, @@ -3546,44 +3538,45 @@ def register( update_interval: Optional[int] = None, log_verbose: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ - Registers a neuron on the Bittensor network using the provided wallet. + Registers a neuron on the Bittensor subnet with provided netuid using the provided wallet. Registration is a critical step for a neuron to become an active participant in the network, enabling it to - stake, set weights, and receive incentives. + stake, set weights, and receive incentives. - Args: - wallet (bittensor_wallet.Wallet): The wallet associated with the neuron to be registered. - netuid (int): The unique identifier of the subnet. - wait_for_inclusion (bool): Waits for the transaction to be included in a block. Defaults to `False`. - wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. Defaults to - `True`. - max_allowed_attempts (int): Maximum number of attempts to register the wallet. - output_in_place (bool): If true, prints the progress of the proof of work to the console in-place. Meaning - the progress is printed on the same lines. Defaults to `True`. - cuda (bool): If ``true``, the wallet should be registered using CUDA device(s). Defaults to `False`. - dev_id (Union[List[int], int]): The CUDA device id to use, or a list of device ids. Defaults to `0` (zero). - tpb (int): The number of threads per block (CUDA). Default to `256`. - num_processes (Optional[int]): The number of processes to use to register. Default to `None`. - update_interval (Optional[int]): The number of nonces to solve between updates. Default to `None`. - log_verbose (bool): If ``true``, the registration process will log more information. Default to `False`. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + Parameters: + wallet: The wallet associated with the neuron to be registered. + netuid: The unique identifier of the subnet. + max_allowed_attempts: Maximum number of attempts to register the wallet. + output_in_place: If true, prints the progress of the proof of work to the console in-place. Meaning the + progress is printed on the same lines. + cuda: If ``true``, the wallet should be registered using CUDA device(s). + dev_id: The CUDA device id to use, or a list of device ids. + tpb: The number of threads per block (CUDA). + num_processes: The number of processes to use to register. + update_interval: The number of nonces to solve between updates. + log_verbose: If ``true``, the registration process will log more information. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: bool: ``True`` if the registration is successful, False otherwise. - This function facilitates the entry of new neurons into the network, supporting the decentralized - growth and scalability of the Bittensor ecosystem. + This function facilitates the entry of new neurons into the network, supporting the decentralized growth and + scalability of the Bittensor ecosystem. """ return register_extrinsic( subtensor=self, wallet=wallet, netuid=netuid, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, max_allowed_attempts=max_allowed_attempts, tpb=tpb, update_interval=update_interval, @@ -3593,27 +3586,30 @@ def register( output_in_place=output_in_place, log_verbose=log_verbose, period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) def register_subnet( self, wallet: "Wallet", - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Registers a new subnetwork on the Bittensor network. - Args: - wallet (bittensor_wallet.Wallet): The wallet to be used for subnet registration. - wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning `True`, or - returns `False` if the extrinsic fails to enter the block within the timeout. Default is `False`. - wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning - `True`, or returns `False` if the extrinsic fails to be finalized within the timeout. Default is `True`. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + Parameters: + wallet: The wallet to be used for subnet registration. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: bool: True if the subnet registration was successful, False otherwise. @@ -3621,9 +3617,10 @@ def register_subnet( return register_subnet_extrinsic( subtensor=self, wallet=wallet, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) def remove_liquidity( @@ -3632,23 +3629,24 @@ def remove_liquidity( netuid: int, position_id: int, hotkey: Optional[str] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Remove liquidity and credit balances back to wallet's hotkey stake. - Arguments: + Parameters: wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. position_id: The id of the position record in the pool. - hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. Defaults to - `None`. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. + hotkey: The hotkey with staked TAO in Alpha. If not passed then the wallet hotkey is used. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: Tuple[bool, str]: @@ -3657,7 +3655,7 @@ def remove_liquidity( Note: - Adding is allowed even when user liquidity is enabled in specified subnet. Call `toggle_user_liquidity` - extrinsic to enable/disable user liquidity. + extrinsic to enable/disable user liquidity. - To get the `position_id` use `get_liquidity_list` method. """ return remove_liquidity_extrinsic( @@ -3666,9 +3664,10 @@ def remove_liquidity( netuid=netuid, position_id=position_id, hotkey=hotkey, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) def reveal_weights( @@ -3678,38 +3677,40 @@ def reveal_weights( uids: Union[NDArray[np.int64], list], weights: Union[NDArray[np.int64], list], salt: Union[NDArray[np.int64], list], + max_retries: int = 5, version_key: int = version_as_int, + period: Optional[int] = 16, + raise_error: bool = True, wait_for_inclusion: bool = False, wait_for_finalization: bool = False, - max_retries: int = 5, - period: Optional[int] = 16, ) -> tuple[bool, str]: """ Reveals the weights for a specific subnet on the Bittensor blockchain using the provided wallet. This action serves as a revelation of the neuron's previously committed weight distribution. - Args: - wallet (bittensor_wallet.Wallet): The wallet associated with the neuron revealing the weights. - netuid (int): The unique identifier of the subnet. - uids (np.ndarray): NumPy array of neuron UIDs for which weights are being revealed. - weights (np.ndarray): NumPy array of weight values corresponding to each UID. - salt (np.ndarray): NumPy array of salt values corresponding to the hash function. - version_key (int): Version key for compatibility with the network. Default is ``int representation of - the Bittensor version``. - wait_for_inclusion (bool): Waits for the transaction to be included in a block. Default is ``False``. - wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. Default is - ``False``. - max_retries (int): The number of maximum attempts to reveal weights. Default is ``5``. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + Parameters: + wallet: The wallet associated with the subnet validator revealing the weights. + netuid: unique identifier of the subnet. + uids: NumPy array of subnet miner neuron UIDs for which weights are being revealed. + weights: NumPy array of weight values corresponding to each UID. + salt: NumPy array of salt values + max_retries: The number of maximum attempts to reveal weights. + version_key: Version key for compatibility with the network. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: - tuple[bool, str]: ``True`` if the weight revelation is successful, False otherwise. And `msg`, a string - value describing the success or potential error. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. - This function allows neurons to reveal their previously committed weight distribution, ensuring transparency - and accountability within the Bittensor network. + This function allows subnet validators to reveal their previously committed weight vector. + + See also: , """ retries = 0 success = False @@ -3728,7 +3729,7 @@ def reveal_weights( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=period, - raise_error=True, + raise_error=raise_error, ) if success: break @@ -3741,57 +3742,61 @@ def reveal_weights( def root_register( self, wallet: "Wallet", - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Register neuron by recycling some TAO. - Arguments: + Parameters: wallet (bittensor_wallet.Wallet): Bittensor wallet instance. - wait_for_inclusion (bool): Waits for the transaction to be included in a block. Default is ``False``. - wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. Default is - ``False``. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - `True` if registration was successful, otherwise `False`. + bool: ``True`` if the registration is successful, False otherwise. """ return root_register_extrinsic( subtensor=self, wallet=wallet, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) def root_set_pending_childkey_cooldown( self, wallet: "Wallet", cooldown: int, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = True, - period: Optional[int] = None, ) -> tuple[bool, str]: """Sets the pending childkey cooldown. - Arguments: + Parameters: wallet: bittensor wallet instance. cooldown: the number of blocks to setting pending childkey cooldown. - wait_for_inclusion (bool): Waits for the transaction to be included in a block. Default is ``False``. - wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. Default is - ``False``. period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion (bool): Waits for the transaction to be included in a block. + wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. Returns: - tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure of the - operation, and the second element is a message providing additional information. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. Note: This operation can only be successfully performed if your wallet has root privileges. """ @@ -3799,9 +3804,10 @@ def root_set_pending_childkey_cooldown( subtensor=self, wallet=wallet, cooldown=cooldown, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) def set_children( @@ -3810,30 +3816,30 @@ def set_children( hotkey: str, netuid: int, children: list[tuple[float, str]], + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = True, - raise_error: bool = False, - period: Optional[int] = None, ) -> tuple[bool, str]: """ Allows a coldkey to set children-keys. - Arguments: + Parameters: wallet: bittensor wallet instance. hotkey: The ``SS58`` address of the neuron's hotkey. netuid: The netuid value. children: A list of children with their proportions. - wait_for_inclusion: Waits for the transaction to be included in a block. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. - raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure of the - operation, and the second element is a message providing additional information. - + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. """ return set_children_extrinsic( subtensor=self, @@ -3841,10 +3847,10 @@ def set_children( hotkey=hotkey, netuid=netuid, children=children, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - raise_error=raise_error, - period=period, ) def set_delegate_take( @@ -3861,20 +3867,21 @@ def set_delegate_take( Sets the delegate 'take' percentage for a neuron identified by its hotkey. The 'take' represents the percentage of rewards that the delegate claims from its nominators' stakes. - Arguments: - wallet (bittensor_wallet.Wallet): bittensor wallet instance. - hotkey_ss58 (str): The ``SS58`` address of the neuron's hotkey. - take (float): Percentage reward for the delegate. - wait_for_inclusion (bool): Waits for the transaction to be included in a block. - wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. - raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's + Parameters: + wallet: bittensor wallet instance. + hotkey_ss58: The ``SS58`` address of the neuron's hotkey. + take: Percentage reward for the delegate. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure of the - operation, and the second element is a message providing additional information. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. Raises: DelegateTakeTooHigh: Delegate take is too high. @@ -3889,7 +3896,6 @@ def set_delegate_take( The delegate take is a critical parameter in the network's incentive structure, influencing the distribution of rewards among neurons and their nominators. """ - # u16 representation of the take take_u16 = int(take * 0xFFFF) @@ -3902,62 +3908,57 @@ def set_delegate_take( logging.info(f"Updating {hotkey_ss58} take: current={current_take} new={take}") - if current_take_u16 < take_u16: - success, error = increase_take_extrinsic( - self, - wallet, - hotkey_ss58, - take_u16, - wait_for_finalization=wait_for_finalization, - wait_for_inclusion=wait_for_inclusion, - raise_error=raise_error, - period=period, - ) - else: - success, error = decrease_take_extrinsic( - self, - wallet, - hotkey_ss58, - take_u16, - wait_for_finalization=wait_for_finalization, - wait_for_inclusion=wait_for_inclusion, - raise_error=raise_error, - period=period, - ) + extrinsic_call = ( + increase_take_extrinsic + if current_take_u16 < take_u16 + else decrease_take_extrinsic + ) + + success, message = extrinsic_call( + subtensor=self, + wallet=wallet, + hotkey_ss58=hotkey_ss58, + take=take_u16, + period=period, + raise_error=raise_error, + wait_for_finalization=wait_for_finalization, + wait_for_inclusion=wait_for_inclusion, + ) if success: logging.info(":white_heavy_check_mark: [green]Take Updated[/green]") - return success, error + return success, message def set_subnet_identity( self, wallet: "Wallet", netuid: int, subnet_identity: SubnetIdentity, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """ Sets the identity of a subnet for a specific wallet and network. - Arguments: - wallet (Wallet): The wallet instance that will authorize the transaction. - netuid (int): The unique ID of the network on which the operation takes place. - subnet_identity (SubnetIdentity): The identity data of the subnet including attributes like name, GitHub - repository, contact, URL, discord, description, and any additional metadata. - wait_for_inclusion (bool): Indicates if the function should wait for the transaction to be included in the - block. - wait_for_finalization (bool): Indicates if the function should wait for the transaction to reach - finalization. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's + Parameters: + wallet: The wallet instance that will authorize the transaction. + netuid: The unique ID of the network on which the operation takes place. + subnet_identity: The identity data of the subnet including attributes like name, GitHub repository, contact, + URL, discord, description, and any additional metadata. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure of the - operation, and the second element is a message providing additional information. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. """ return set_subnet_identity_extrinsic( subtensor=self, @@ -3971,9 +3972,10 @@ def set_subnet_identity( discord=subnet_identity.discord, description=subnet_identity.description, additional=subnet_identity.additional, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) def set_weights( @@ -3982,40 +3984,47 @@ def set_weights( netuid: int, uids: Union[NDArray[np.int64], "torch.LongTensor", list], weights: Union[NDArray[np.float32], "torch.FloatTensor", list], - version_key: int = version_as_int, - wait_for_inclusion: bool = False, - wait_for_finalization: bool = False, - max_retries: int = 5, block_time: float = 12.0, + commit_reveal_version: int = 4, + max_retries: int = 5, + version_key: int = version_as_int, period: Optional[int] = 8, + raise_error: bool = True, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """ - Sets the interneuronal weights for the specified neuron. This process involves specifying the influence or - trust a neuron places on other neurons in the network, which is a fundamental aspect of Bittensor's - decentralized learning architecture. + Sets the interneuronal weights for the specified neuron. This process involves specifying the influence or trust + a neuron places on other neurons in the network, which is a fundamental aspect of Bittensor's decentralized + learning architecture. - Arguments: - wallet: The wallet associated with the neuron setting the weights. + Parameters: + wallet: The wallet associated with the subnet validator setting the weights. netuid: The unique identifier of the subnet. - uids: The list of neuron UIDs that the weights are being set for. - weights: The corresponding weights to be set for each UID. - version_key: Version key for compatibility with the network. Default is int representation of a Bittensor - version. - wait_for_inclusion: Waits for the transaction to be included in a block. Default is ``False``. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Default is ``False``. - max_retries: The number of maximum attempts to set weights. Default is ``5``. - block_time: The number of seconds for block duration. Default is 12.0 seconds. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's + uids: The list of subnet miner neuron UIDs that the weights are being set for. + weights: The corresponding weights to be set for each UID, representing the validator's evaluation of each + miner's performance. + block_time: The number of seconds for block duration. + commit_reveal_version: The version of the chain commit-reveal protocol to use. + max_retries: The number of maximum attempts to set weights. + version_key: Version key for compatibility with the network. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. Default is 8. + and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: - tuple: - `True` if the setting of weights is successful, `False` otherwise. - `msg` is a string value describing the success or potential error. + Tuple[bool, str]: + - True and a success message if the extrinsic is successfully submitted or processed. + - False and an error message if the submission fails or the wallet cannot be unlocked. This function is crucial in shaping the network's collective intelligence, where each neuron's learning and - contribution are influenced by the weights it sets towards others. + contribution are influenced by the weights it sets towards others. + + Notes: + See """ def _blocks_weight_limit() -> bool: @@ -4042,19 +4051,25 @@ def _blocks_weight_limit() -> bool: f"Committing weights for subnet [blue]{netuid}[/blue]. " f"Attempt [blue]{retries + 1}[blue] of [green]{max_retries}[/green]." ) - success, message = commit_reveal_extrinsic( - subtensor=self, - wallet=wallet, - netuid=netuid, - uids=uids, - weights=weights, - version_key=version_key, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - block_time=block_time, - period=period, - ) + try: + success, message = commit_reveal_extrinsic( + subtensor=self, + wallet=wallet, + netuid=netuid, + uids=uids, + weights=weights, + block_time=block_time, + commit_reveal_version=commit_reveal_version, + version_key=version_key, + period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, + ) + except Exception as e: + logging.error(f"Error setting weights: {e}") retries += 1 + return success, message else: # go with classic `set_weights_extrinsic` @@ -4072,9 +4087,10 @@ def _blocks_weight_limit() -> bool: uids=uids, weights=weights, version_key=version_key, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) except Exception as e: logging.error(f"Error setting weights: {e}") @@ -4086,65 +4102,120 @@ def serve_axon( self, netuid: int, axon: "Axon", - wait_for_inclusion: bool = False, - wait_for_finalization: bool = True, certificate: Optional[Certificate] = None, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ - Registers an ``Axon`` serving endpoint on the Bittensor network for a specific neuron. This function is used to - set up the Axon, a key component of a neuron that handles incoming queries and data processing tasks. + Registers an ``Axon`` serving endpoint on the Bittensor network for a specific neuron. - Args: - netuid (int): The unique identifier of the subnetwork. - axon (bittensor.core.axon.Axon): The Axon instance to be registered for serving. - wait_for_inclusion (bool): Waits for the transaction to be included in a block. Default is ``False``. - wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. Default is - ``True``. - certificate (bittensor.utils.Certificate): Certificate to use for TLS. If ``None``, no TLS will be used. - Defaults to ``None``. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's + This function is used to set up the Axon, a key component of a neuron that handles incoming queries and data + processing tasks. + + Parameters: + netuid: The unique identifier of the subnetwork. + axon: The Axon instance to be registered for serving. + certificate: Certificate to use for TLS. If ``None``, no TLS will be used. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Waits for the transaction to be included in a block. + wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Returns: bool: ``True`` if the Axon serve registration is successful, False otherwise. By registering an Axon, the neuron becomes an active part of the network's distributed computing infrastructure, - contributing to the collective intelligence of Bittensor. + contributing to the collective intelligence of Bittensor. """ return serve_axon_extrinsic( subtensor=self, netuid=netuid, axon=axon, + certificate=certificate, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - certificate=certificate, + ) + + def set_commitment( + self, + wallet: "Wallet", + netuid: int, + data: str, + period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, + ) -> bool: + """ + Commits arbitrary data to the Bittensor network by publishing metadata. + + This method allows neurons to publish arbitrary data to the blockchain, which can be used for various purposes + such as sharing model updates, configuration data, or other network-relevant information. + + + Parameters: + wallet (bittensor_wallet.Wallet): The wallet associated with the neuron committing the data. + netuid (int): The unique identifier of the subnetwork. + data (str): The data to be committed to the network. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. + + Returns: + bool: `True` if the commitment was successful, `False` otherwise. + + Example: + # Commit some data to subnet 1 + success = await subtensor.commit(wallet=my_wallet, netuid=1, data="Hello Bittensor!") + + # Commit with custom period + success = await subtensor.commit(wallet=my_wallet, netuid=1, data="Model update v2.0", period=100) + + Note: See + """ + return publish_metadata( + subtensor=self, + wallet=wallet, + netuid=netuid, + data_type=f"Raw{len(data)}", + data=data.encode(), period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) def start_call( self, wallet: "Wallet", netuid: int, + period: Optional[int] = None, + raise_error: bool = False, wait_for_inclusion: bool = True, wait_for_finalization: bool = False, - period: Optional[int] = None, ) -> tuple[bool, str]: """ Submits a start_call extrinsic to the blockchain, to trigger the start call process for a subnet (used to start a new subnet's emission mechanism). - Args: - wallet (Wallet): The wallet used to sign the extrinsic (must be unlocked). - netuid (int): The UID of the target subnet for which the call is being initiated. - wait_for_inclusion (bool, optional): Whether to wait for the extrinsic to be included in a block. - Defaults to `True`. - wait_for_finalization (bool, optional): Whether to wait for finalization of the extrinsic. - Defaults to `False`. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + Parameters: + wallet: The wallet used to sign the extrinsic (must be unlocked). + netuid: The UID of the target subnet for which the call is being initiated. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: Tuple[bool, str]: @@ -4155,9 +4226,10 @@ def start_call( subtensor=self, wallet=wallet, netuid=netuid, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) def swap_stake( @@ -4167,40 +4239,40 @@ def swap_stake( origin_netuid: int, destination_netuid: int, amount: Balance, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - safe_staking: bool = False, + safe_swapping: bool = False, allow_partial_stake: bool = False, rate_tolerance: float = 0.005, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Moves stake between subnets while keeping the same coldkey-hotkey pair ownership. Like subnet hopping - same owner, same hotkey, just changing which subnet the stake is in. - Args: - wallet (bittensor.wallet): The wallet to swap stake from. - hotkey_ss58 (str): The SS58 address of the hotkey whose stake is being swapped. - origin_netuid (int): The netuid from which stake is removed. - destination_netuid (int): The netuid to which stake is added. - amount (Union[Balance, float]): The amount to swap. - wait_for_inclusion (bool): Waits for the transaction to be included in a block. - wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. - safe_staking (bool): If true, enables price safety checks to protect against fluctuating prices. The swap + Parameters: + wallet: The wallet to swap stake from. + hotkey_ss58: The SS58 address of the hotkey whose stake is being swapped. + origin_netuid: The netuid from which stake is removed. + destination_netuid: The netuid to which stake is added. + amount: The amount to swap. + safe_swapping: If true, enables price safety checks to protect against fluctuating prices. The swap will only execute if the price ratio between subnets doesn't exceed the rate tolerance. - Default is False. - allow_partial_stake (bool): If true and safe_staking is enabled, allows partial stake swaps when - the full amount would exceed the price tolerance. If false, the entire swap fails if it would - exceed the tolerance. Default is False. - rate_tolerance (float): The maximum allowed increase in the price ratio between subnets - (origin_price/destination_price). For example, 0.005 = 0.5% maximum increase. Only used - when safe_staking is True. Default is 0.005. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + allow_partial_stake: If true and safe_staking is enabled, allows partial stake swaps when the full amount + would exceed the price tolerance. If false, the entire swap fails if it would exceed the tolerance. + rate_tolerance: The maximum allowed increase in the price ratio between subnets + (origin_price/destination_price). For example, 0.005 = 0.5% maximum increase. Only used when + safe_staking is True. + period: The number of blocks during which the transaction will remain valid after it's submitted. If the + transaction is not included in a block within that number of blocks, it will expire and be rejected. You + can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the inclusion of the transaction. + wait_for_finalization: Whether to wait for the finalization of the transaction. Returns: - success (bool): True if the extrinsic was successful. + success: True if the extrinsic was successful. The price ratio for swap_stake in safe mode is calculated as: origin_subnet_price / destination_subnet_price When safe_staking is enabled, the swap will only execute if: @@ -4217,12 +4289,13 @@ def swap_stake( origin_netuid=origin_netuid, destination_netuid=destination_netuid, amount=amount, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - safe_staking=safe_staking, + safe_swapping=safe_swapping, allow_partial_stake=allow_partial_stake, rate_tolerance=rate_tolerance, period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) def toggle_user_liquidity( @@ -4230,21 +4303,23 @@ def toggle_user_liquidity( wallet: "Wallet", netuid: int, enable: bool, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Allow to toggle user liquidity for specified subnet. - Arguments: + Parameters: wallet: The wallet used to sign the extrinsic (must be unlocked). netuid: The UID of the target subnet for which the call is being initiated. enable: Boolean indicating whether to enable user liquidity. - wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. Defaults to True. - wait_for_finalization: Whether to wait for finalization of the extrinsic. Defaults to False. period: The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: Tuple[bool, str]: @@ -4258,9 +4333,10 @@ def toggle_user_liquidity( wallet=wallet, netuid=netuid, enable=enable, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) def transfer( @@ -4268,27 +4344,28 @@ def transfer( wallet: "Wallet", destination: str, amount: Optional[Balance], - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, transfer_all: bool = False, keep_alive: bool = True, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = False, ) -> bool: """ Transfer token of amount to destination. - Arguments: - wallet (bittensor_wallet.Wallet): Source wallet for the transfer. - destination (str): Destination address for the transfer. - amount (float): Amount of tao to transfer. - transfer_all (bool): Flag to transfer all tokens. Default is ``False``. - wait_for_inclusion (bool): Waits for the transaction to be included in a block. Default is ``True``. - wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. Default is - ``False``. - keep_alive (bool): Flag to keep the connection alive. Default is ``True``. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + Parameters: + wallet: Source wallet for the transfer. + destination: Destination address for the transfer. + amount: Number of tokens to transfer. `None` is transferring all. + transfer_all: Flag to transfer all tokens. Default is `False`. + keep_alive: Flag to keep the connection alive. Default is `True`. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: `True` if the transferring was successful, otherwise `False`. @@ -4301,10 +4378,11 @@ def transfer( destination=destination, amount=amount, transfer_all=transfer_all, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, keep_alive=keep_alive, period=period, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) def transfer_stake( @@ -4315,28 +4393,30 @@ def transfer_stake( origin_netuid: int, destination_netuid: int, amount: Balance, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Transfers stake from one subnet to another while changing the coldkey owner. - Args: - wallet (bittensor.wallet): The wallet to transfer stake from. - destination_coldkey_ss58 (str): The destination coldkey SS58 address. - hotkey_ss58 (str): The hotkey SS58 address associated with the stake. - origin_netuid (int): The source subnet UID. - destination_netuid (int): The destination subnet UID. - amount (Union[Balance, float, int]): Amount to transfer. - wait_for_inclusion (bool): If true, waits for inclusion before returning. - wait_for_finalization (bool): If true, waits for finalization before returning. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. + Parameters: + wallet: The wallet to transfer stake from. + destination_coldkey_ss58: The destination coldkey SS58 address. + hotkey_ss58: The hotkey SS58 address associated with the stake. + origin_netuid: The source subnet UID. + destination_netuid: The destination subnet UID. + amount: Amount to transfer. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: - success (bool): True if the transfer was successful. + success: True if the transfer was successful. """ amount = check_and_convert_to_balance(amount) return transfer_stake_extrinsic( @@ -4347,69 +4427,70 @@ def transfer_stake( origin_netuid=origin_netuid, destination_netuid=destination_netuid, amount=amount, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) def unstake( self, wallet: "Wallet", - hotkey_ss58: Optional[str] = None, - netuid: Optional[int] = None, # TODO why is this optional? - amount: Optional[Balance] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - safe_staking: bool = False, + netuid: int, + hotkey_ss58: str, + amount: Balance, allow_partial_stake: bool = False, rate_tolerance: float = 0.005, + safe_unstaking: bool = False, period: Optional[int] = None, - unstake_all: bool = False, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Removes a specified amount of stake from a single hotkey account. This function is critical for adjusting - individual neuron stakes within the Bittensor network. + individual neuron stakes within the Bittensor network. - Args: + Parameters: wallet: The wallet associated with the neuron from which the stake is being removed. - hotkey_ss58: The ``SS58`` address of the hotkey account to unstake from. netuid: The unique identifier of the subnet. + hotkey_ss58: The ``SS58`` address of the hotkey account to unstake from. amount: The amount of alpha to unstake. If not specified, unstakes all. Alpha amount. - wait_for_inclusion: Waits for the transaction to be included in a block. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. - safe_staking: If true, enables price safety checks to protect against fluctuating prices. The unstake - will only execute if the price change doesn't exceed the rate tolerance. Default is False. - allow_partial_stake (bool): If true and safe_staking is enabled, allows partial unstaking when + allow_partial_stake: If true and safe_staking is enabled, allows partial unstaking when the full amount would exceed the price tolerance. If false, the entire unstake fails if it would - exceed the tolerance. Default is False. - rate_tolerance (float): The maximum allowed price change ratio when unstaking. For example, - 0.005 = 0.5% maximum price decrease. Only used when safe_staking is True. Default is 0.005. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. - unstake_all: If `True`, unstakes all tokens, and `amount` is ignored. Default is `False`. + exceed the tolerance. + rate_tolerance: The maximum allowed price change ratio when unstaking. For example, + 0.005 = 0.5% maximum price decrease. Only used when safe_staking is True. + safe_unstaking: If true, enables price safety checks to protect against fluctuating prices. The unstake + will only execute if the price change doesn't exceed the rate tolerance. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: bool: ``True`` if the unstaking process is successful, False otherwise. This function supports flexible stake management, allowing neurons to adjust their network participation and - potential reward accruals. When safe_staking is enabled, it provides protection against price fluctuations - during the time unstake is executed and the time it is actually processed by the chain. + potential reward accruals. When safe_staking is enabled, it provides protection against price fluctuations + during the time unstake is executed and the time it is actually processed by the chain. """ amount = check_and_convert_to_balance(amount) return unstake_extrinsic( subtensor=self, wallet=wallet, - hotkey_ss58=hotkey_ss58, netuid=netuid, + hotkey_ss58=hotkey_ss58, amount=amount, - wait_for_inclusion=wait_for_inclusion, - wait_for_finalization=wait_for_finalization, - safe_staking=safe_staking, allow_partial_stake=allow_partial_stake, rate_tolerance=rate_tolerance, + safe_unstaking=safe_unstaking, period=period, - unstake_all=unstake_all, + raise_error=raise_error, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) def unstake_all( @@ -4418,23 +4499,25 @@ def unstake_all( hotkey: str, netuid: int, rate_tolerance: Optional[float] = 0.005, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> tuple[bool, str]: """Unstakes all TAO/Alpha associated with a hotkey from the specified subnets on the Bittensor network. - Arguments: + Parameters: wallet: The wallet of the stake owner. hotkey: The SS58 address of the hotkey to unstake from. netuid: The unique identifier of the subnet. rate_tolerance: The maximum allowed price change ratio when unstaking. For example, 0.005 = 0.5% maximum price decrease. If not passed (None), then unstaking goes without price limit. Default is 0.005. - wait_for_inclusion: Waits for the transaction to be included in a block. Default is `True`. - wait_for_finalization: Waits for the transaction to be finalized on the blockchain. Default is `False`. - period: The number of blocks during which the transaction will remain valid after it's submitted. If the - transaction is not included in a block within that number of blocks, it will expire and be rejected. You - can think of it as an expiration date for the transaction. Default is `None`. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: tuple[bool, str]: @@ -4490,54 +4573,56 @@ def unstake_all( hotkey=hotkey, netuid=netuid, rate_tolerance=rate_tolerance, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, ) def unstake_multiple( self, wallet: "Wallet", - hotkey_ss58s: list[str], netuids: list[int], + hotkey_ss58s: list[str], amounts: Optional[list[Balance]] = None, - wait_for_inclusion: bool = True, - wait_for_finalization: bool = False, - period: Optional[int] = None, unstake_all: bool = False, + period: Optional[int] = None, + raise_error: bool = False, + wait_for_inclusion: bool = True, + wait_for_finalization: bool = True, ) -> bool: """ Performs batch unstaking from multiple hotkey accounts, allowing a neuron to reduce its staked amounts efficiently. This function is useful for managing the distribution of stakes across multiple neurons. - Args: - wallet: The wallet linked to the coldkey from which the stakes are being - withdrawn. - hotkey_ss58s (List[str]): A list of hotkey ``SS58`` addresses to unstake from. - netuids (List[int]): The list of subnet uids. - amounts (List[Balance]): The amounts of TAO to unstake from each hotkey. If not provided, - unstakes all available stakes. - wait_for_inclusion (bool): Waits for the transaction to be included in a block. - wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain. - period (Optional[int]): The number of blocks during which the transaction will remain valid after it's - submitted. If the transaction is not included in a block within that number of blocks, it will expire - and be rejected. You can think of it as an expiration date for the transaction. - unstake_all: If `True`, unstakes all tokens, and `amounts` is ignored. Default is `False`. + Parameters: + wallet: The wallet linked to the coldkey from which the stakes are being withdrawn. + netuids: Subnets unique IDs. + hotkey_ss58s: A list of hotkey `SS58` addresses to unstake from. + amounts: The amounts of TAO to unstake from each hotkey. If not provided, unstakes all. + unstake_all: If true, unstakes all tokens. Default is `False`. If `True` amounts are ignored. + period: The number of blocks during which the transaction will remain valid after it's submitted. If + the transaction is not included in a block within that number of blocks, it will expire and be rejected. + You can think of it as an expiration date for the transaction. + raise_error: Raises a relevant exception rather than returning `False` if unsuccessful. + wait_for_inclusion: Whether to wait for the extrinsic to be included in a block. + wait_for_finalization: Whether to wait for finalization of the extrinsic. Returns: bool: ``True`` if the batch unstaking is successful, False otherwise. This function allows for strategic reallocation or withdrawal of stakes, aligning with the dynamic stake - management aspect of the Bittensor network. + management aspect of the Bittensor network. """ return unstake_multiple_extrinsic( subtensor=self, wallet=wallet, - hotkey_ss58s=hotkey_ss58s, netuids=netuids, + hotkey_ss58s=hotkey_ss58s, amounts=amounts, + unstake_all=unstake_all, + period=period, + raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, - period=period, - unstake_all=unstake_all, ) diff --git a/bittensor/core/subtensor_api/extrinsics.py b/bittensor/core/subtensor_api/extrinsics.py index c2acf078e5..62c6c5c1b4 100644 --- a/bittensor/core/subtensor_api/extrinsics.py +++ b/bittensor/core/subtensor_api/extrinsics.py @@ -26,6 +26,7 @@ def __init__(self, subtensor: Union["_Subtensor", "_AsyncSubtensor"]): self.set_subnet_identity = subtensor.set_subnet_identity self.set_weights = subtensor.set_weights self.serve_axon = subtensor.serve_axon + self.set_commitment = subtensor.set_commitment self.start_call = subtensor.start_call self.swap_stake = subtensor.swap_stake self.toggle_user_liquidity = subtensor.toggle_user_liquidity diff --git a/bittensor/core/subtensor_api/utils.py b/bittensor/core/subtensor_api/utils.py index b8383a3f62..34cc48502a 100644 --- a/bittensor/core/subtensor_api/utils.py +++ b/bittensor/core/subtensor_api/utils.py @@ -15,7 +15,6 @@ def add_legacy_methods(subtensor: "SubtensorApi"): subtensor.bonds = subtensor._subtensor.bonds subtensor.burned_register = subtensor._subtensor.burned_register subtensor.chain_endpoint = subtensor._subtensor.chain_endpoint - subtensor.commit = subtensor._subtensor.commit subtensor.commit_reveal_enabled = subtensor._subtensor.commit_reveal_enabled subtensor.commit_weights = subtensor._subtensor.commit_weights subtensor.determine_block_hash = subtensor._subtensor.determine_block_hash diff --git a/migration.md b/migration.md index 25edf20b71..3e4b0a7a1a 100644 --- a/migration.md +++ b/migration.md @@ -1,7 +1,7 @@ # Plan ## Extrinsics and related -1. Standardize parameter order across all extrinsics and related calls. Pass extrinsic-specific arguments first (e.g., wallet, hotkey, netuid, amount), followed by optional general flags (e.g., wait_for_inclusion, wait_for_finalization) +1. ✅ Standardize parameter order across all extrinsics and related calls. Pass extrinsic-specific arguments first (e.g., wallet, hotkey, netuid, amount), followed by optional general flags (e.g., wait_for_inclusion, wait_for_finalization)
Example @@ -33,11 +33,11 @@ amount: Optional[Balance] = None, rate_tolerance: float = 0.005, allow_partial_stake: bool = False, - safe_staking: bool = False, + safe_swapping: bool = False, period: Optional[int] = None, + raise_error: bool = True, wait_for_inclusion: bool = True, wait_for_finalization: bool = False, - raise_error: bool = True, ) -> bool: ```
@@ -48,14 +48,14 @@ - Ease of processing - This class should contain success, message, and optionally data and logs. (to save all logs during the extrinsic) -3. Set `wait_for_inclusion` and `wait_for_finalization` to `True` by default in extrinsics and their related calls. Then we will guarantee the correct/expected extrinsic call response is consistent with the chain response. If the user changes those values, then it is the user's responsibility. -4. Make the internal logic of extrinsics the same. There are extrinsics that are slightly different in implementation. +3. ✅ Set `wait_for_inclusion` and `wait_for_finalization` to `True` by default in extrinsics and their related calls. Then we will guarantee the correct/expected extrinsic call response is consistent with the chain response. If the user changes those values, then it is the user's responsibility. +4. ✅ Make the internal logic of extrinsics the same. There are extrinsics that are slightly different in implementation. 5. Since SDK is not a responsible tool, try to remove all calculations inside extrinsics that do not affect the result, but are only used in logging. Actually, this should be applied not to extrinsics only but for all codebase. -6. Remove `unstake_all` parameter from `unstake_extrinsic` since we have `unstake_all_extrinsic`which is calles another subtensor function. +6. ✅ Remove `unstake_all` parameter from `unstake_extrinsic` since we have `unstake_all_extrinsic`which is calles another subtensor function. -7. `unstake` and `unstake_multiple` extrinsics should have `safe_unstaking` parameters instead of `safe_staking`. +7. ✅ `unstake` and `unstake_multiple` extrinsics should have `safe_unstaking` parameters instead of `safe_staking`. 8. ✅ Remove `_do*` extrinsic calls and combine them with extrinsic logic. @@ -106,7 +106,9 @@ rename this variable in documentation. 11. Remove `bittensor.utils.version.version_checking` 12. Find and process all `TODOs` across the entire code base. If in doubt, discuss each one with the team separately. SDK has 29 TODOs. -13. ✅ The SDK is dropping support for `Python 3.9` starting with this release.~~ +13. ✅ The SDK is dropping support for `Python 3.9` starting with this release. +14. Remove `Default is` and `Default to` in docstrings bc parameters enough. +15. camfairchild: TODO, but we should have a grab_metadata if we don't already. Maybe don't decode, but can have a call that removes the Raw prefix, and another just doing grab_metadata_raw (no decoding) ## New features 1. Add `bittensor.utils.hex_to_ss58` function. SDK still doesn't have it. (Probably inner import `from scalecodec import ss58_encode, ss58_decode`) @@ -159,4 +161,66 @@ It must include: - [x] `._do_set_root_weights` logic is included in the main code `.set_root_weights_extrinsic` - [x] `._do_transfer` logic is included in the main code `.transfer_extrinsic` - [x] `dest` parameter has been renamed to `destination` in `transfer_extrinsic` function and `subtensor.transfer` method. -- [x]] obsolete extrinsic `set_root_weights_extrinsic` removed. Also related subtensor calls `subtensor.set_root_weights_extrinsic` removed too. \ No newline at end of file +- [x] obsolete extrinsic `set_root_weights_extrinsic` removed. Also related subtensor calls `subtensor.set_root_weights_extrinsic` removed too. + +# Standardize parameter order is applied for (extrinsics and related calls): + +These parameters will now exist in all extrinsics and related calls (default values could be different depends by extrinsic): + +```py +period: Optional[int] = None, +raise_error: bool = False, +wait_for_inclusion: bool = False, +wait_for_finalization: bool = False, +``` +- [x] `.set_children_extrinsic` and `.root_set_pending_childkey_cooldown_extrinsic`. `subtensor.set_children` and `subtensor.root_set_pending_childkey_cooldown` methods. +- [x] `.commit_reveal_extrinsic` and `subtensor.set_weights` +- [x] `.add_liquidity_extrinsic` and `subtensor.add_liquidity` +- [x] `.modify_liquidity_extrinsic` and `subtensor.modify_liquidity` +- [x] `.remove_liquidity_extrinsic` and `subtensor.remove_liquidity` +- [x] `.toggle_user_liquidity_extrinsic` and `subtensor.toggle_user_liquidity` +- [x] `.transfer_stake_extrinsic` and `subtensor.transfer_stake` +- [x] `.swap_stake_extrinsic` and `subtensor.swap_stake` + - Changes in `swap_stake_extrinsic` and `subtensor.swap_stake`: + - parameter `safe_staking: bool` renamed to `safe_swapping: bool` +- [x] `.move_stake_extrinsic` and `subtensor.move_stake` + - Changes in `move_stake_extrinsic` and `subtensor.move_stake`: + - parameter `origin_hotkey` renamed to `origin_hotkey_ss58` + - parameter `destination_hotkey` renamed to `destination_hotkey_ss58` +- [x] `.burned_register_extrinsic` and `subtensor.burned_register` +- [x] `.register_subnet_extrinsic` and `subtensor.register_subnet` +- [x] `.register_extrinsic` and `subtensor.register` +- [x] `.set_subnet_identity_extrinsic` and `subtensor.set_subnet_identity` +- [x] `.root_register_extrinsic`, `subtensor.burned_register` and `subtensor.root_register` +- [x] `.serve_extrinsic` +- [x] `.serve_axon_extrinsic` and `subtensor.serve_axon` +- [x] alias `subtensor.set_commitment` removed +- [x] `subtensor.comit` renamed to `subtensor.set_commitment` +- [x] `.publish_metadata`, `subtensor.set_commitment` and `subtenor.set_reveal_commitment` +- [x] `.add_stake_extrinsic` and `subtensor.add_stake` + - Changes in `.add_stake_extrinsic` and `subtensor.add_stake`: + - parameter `old_balance` removed from async version + - parameter `netuid` required (no Optional anymore) + - parameter `hotkey_ss58` required (no Optional anymore) + - parameter `amount` required (no Optional anymore) +- [x] `.add_stake_multiple_extrinsic` and `subtensor.add_stake_multiple` + - Changes in `.add_stake_multiple_extrinsic` and `subtensor.add_stake_multiple`: + - parameter `old_balance` removed from async version + - parameter `amounts` required (no Optional anymore) +- [x] `.start_call_extrinsic` and `subtensor.start_call` +- [x] `.increase_take_extrinsic`, `.decrease_take_extrinsic` and `subtenor.set_reveal_commitment` +- [x] `.transfer_extrinsic` and `subtensor.transfer` +- [x] `.unstake_extrinsic` and `subtensor.unstake` + - Changes in `unstake_extrinsic` and `subtensor.unstake`: + - parameter `netuid: Optional[int]` is now required -> `netuid: int` + - parameter `hotkey_ss58: Optional[str]` is now required -> `hotkey_ss58: str` + - parameter `amount: Optional[Balance]` is now required -> `amount: Balance` + - parameter `safe_staking: bool` renamed to `safe_unstaking: bool` + - parameter `unstake_all: bool` removed (use `unstake_all_extrinsic` for unstake all stake) +- [x] `.unstake_all_extrinsic` and `subtensor.unstake_all` +- [x] `.unstake_multiple_extrinsic` and `subtensor.unstake_multiple` + - Changes in `.unstake_multiple_extrinsic` and `subtensor.unstake_multiple`: + - parameter `amounts` is now required (no Optional anymore) +- [x] `.commit_weights_extrinsic` and `subtensor.commit_weights` +- [x] `.reveal_weights_extrinsic` and `subtensor.reveal_weights` +- [x] `.set_weights_extrinsic` and `subtensor.set_weights` \ No newline at end of file diff --git a/tests/e2e_tests/test_commitment.py b/tests/e2e_tests/test_commitment.py index 860601f075..d31bf739ef 100644 --- a/tests/e2e_tests/test_commitment.py +++ b/tests/e2e_tests/test_commitment.py @@ -16,7 +16,7 @@ def test_commitment(subtensor, alice_wallet, dave_wallet): dave_subnet_netuid = 2 - assert subtensor.subnets.register_subnet(dave_wallet, True, True) + assert subtensor.subnets.register_subnet(dave_wallet) assert subtensor.subnets.subnet_exists(dave_subnet_netuid), ( "Subnet wasn't created successfully" ) @@ -31,12 +31,12 @@ def test_commitment(subtensor, alice_wallet, dave_wallet): ) assert subtensor.subnets.burned_register( - alice_wallet, + wallet=alice_wallet, netuid=dave_subnet_netuid, ) uid = subtensor.subnets.get_uid_for_hotkey_on_subnet( - alice_wallet.hotkey.ss58_address, + hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=dave_subnet_netuid, ) @@ -110,7 +110,7 @@ async def test_commitment_async(async_subtensor, alice_wallet, dave_wallet): ) assert await sub.subnets.burned_register( - alice_wallet, + wallet=alice_wallet, netuid=dave_subnet_netuid, ) diff --git a/tests/e2e_tests/test_delegate.py b/tests/e2e_tests/test_delegate.py index a63bfaab39..04417f6615 100644 --- a/tests/e2e_tests/test_delegate.py +++ b/tests/e2e_tests/test_delegate.py @@ -452,11 +452,9 @@ def test_delegates(subtensor, alice_wallet, bob_wallet): subtensor.staking.add_stake( wallet=bob_wallet, - hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=Balance.from_tao(10_000), - wait_for_inclusion=True, - wait_for_finalization=True, ) # let chain update validator_permits @@ -619,11 +617,9 @@ async def test_delegates_async(async_subtensor, alice_wallet, bob_wallet): await async_subtensor.staking.add_stake( wallet=bob_wallet, - hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=Balance.from_tao(10_000), - wait_for_inclusion=True, - wait_for_finalization=True, ) # let chain update validator_permits @@ -663,11 +659,7 @@ def test_nominator_min_required_stake(subtensor, alice_wallet, bob_wallet, dave_ alice_subnet_netuid = subtensor.subnets.get_total_subnets() # 2 # Register a subnet, netuid 2 - assert subtensor.subnets.register_subnet( - alice_wallet, - wait_for_inclusion=True, - wait_for_finalization=True, - ), "Subnet wasn't created" + assert subtensor.subnets.register_subnet(alice_wallet), "Subnet wasn't created" # Verify subnet created successfully assert subtensor.subnets.subnet_exists(alice_subnet_netuid), ( @@ -681,24 +673,18 @@ def test_nominator_min_required_stake(subtensor, alice_wallet, bob_wallet, dave_ subtensor.subnets.burned_register( wallet=bob_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) subtensor.subnets.burned_register( wallet=dave_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) success = subtensor.staking.add_stake( wallet=dave_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=Balance.from_tao(1000), - wait_for_inclusion=True, - wait_for_finalization=True, ) assert success is True @@ -752,11 +738,9 @@ async def test_nominator_min_required_stake_async( alice_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 2 # Register a subnet, netuid 2 - assert await async_subtensor.subnets.register_subnet( - alice_wallet, - wait_for_inclusion=True, - wait_for_finalization=True, - ), "Subnet wasn't created" + assert await async_subtensor.subnets.register_subnet(alice_wallet), ( + "Subnet wasn't created" + ) # Verify subnet created successfully assert await async_subtensor.subnets.subnet_exists(alice_subnet_netuid), ( @@ -772,24 +756,18 @@ async def test_nominator_min_required_stake_async( await async_subtensor.subnets.burned_register( wallet=bob_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) await async_subtensor.subnets.burned_register( wallet=dave_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) success = await async_subtensor.staking.add_stake( wallet=dave_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=Balance.from_tao(1000), - wait_for_inclusion=True, - wait_for_finalization=True, ) assert success is True diff --git a/tests/e2e_tests/test_dendrite.py b/tests/e2e_tests/test_dendrite.py index 841e349557..73d646aadf 100644 --- a/tests/e2e_tests/test_dendrite.py +++ b/tests/e2e_tests/test_dendrite.py @@ -15,6 +15,11 @@ wait_to_start_call, ) +logging.on() +logging.set_debug() + +NON_FAST_RUNTIME_TEMPO = 10 + @pytest.mark.asyncio async def test_dendrite(subtensor, templates, alice_wallet, bob_wallet): @@ -35,9 +40,7 @@ async def test_dendrite(subtensor, templates, alice_wallet, bob_wallet): alice_subnet_netuid = subtensor.subnets.get_total_subnets() # 2 # Register a subnet, netuid 2 - assert subtensor.subnets.register_subnet(alice_wallet, True, True), ( - "Subnet wasn't created." - ) + assert subtensor.subnets.register_subnet(alice_wallet), "Subnet wasn't created." # Verify subnet created successfully assert subtensor.subnets.subnet_exists(alice_subnet_netuid), ( @@ -51,12 +54,24 @@ async def test_dendrite(subtensor, templates, alice_wallet, bob_wallet): "Subnet is not active." ) - # Make sure Alice is Top Validator - assert subtensor.staking.add_stake( - wallet=alice_wallet, - netuid=alice_subnet_netuid, - amount=Balance.from_tao(1), - ) + if not subtensor.chain.is_fast_blocks(): + # Make sure Alice is Top Validator (for non-fast-runtime only) + assert subtensor.staking.add_stake( + wallet=alice_wallet, + netuid=alice_subnet_netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, + amount=Balance.from_tao(1), + ) + # set tempo to 10 block for non-fast-runtime + assert sudo_set_admin_utils( + substrate=subtensor.substrate, + wallet=alice_wallet, + call_function="sudo_set_tempo", + call_params={ + "netuid": alice_subnet_netuid, + "tempo": NON_FAST_RUNTIME_TEMPO, + }, + ) # update max_allowed_validators so only one neuron can get validator_permit assert sudo_set_admin_utils( @@ -110,8 +125,9 @@ async def test_dendrite(subtensor, templates, alice_wallet, bob_wallet): ) assert subtensor.staking.add_stake( - bob_wallet, + wallet=bob_wallet, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=tao, ) @@ -168,9 +184,9 @@ async def test_dendrite_async(async_subtensor, templates, alice_wallet, bob_wall alice_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 2 # Register a subnet, netuid 2 - assert await async_subtensor.subnets.register_subnet( - alice_wallet, wait_for_inclusion=True, wait_for_finalization=True - ), "Subnet wasn't created" + assert await async_subtensor.subnets.register_subnet(alice_wallet), ( + "Subnet wasn't created" + ) # Verify subnet created successfully assert await async_subtensor.subnets.subnet_exists(alice_subnet_netuid), ( @@ -185,12 +201,26 @@ async def test_dendrite_async(async_subtensor, templates, alice_wallet, bob_wall "Subnet is not active." ) - # Make sure Alice is Top Validator - assert await async_subtensor.staking.add_stake( - wallet=alice_wallet, - netuid=alice_subnet_netuid, - amount=Balance.from_tao(1), - ) + if not await async_subtensor.chain.is_fast_blocks(): + # Make sure Alice is Top Validator (for non-fast-runtime only) + assert await async_subtensor.staking.add_stake( + wallet=alice_wallet, + netuid=alice_subnet_netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, + amount=Balance.from_tao(5), + wait_for_inclusion=False, + wait_for_finalization=False, + ) + # set tempo to 10 block for non-fast-runtime + assert await async_sudo_set_admin_utils( + substrate=async_subtensor.substrate, + wallet=alice_wallet, + call_function="sudo_set_tempo", + call_params={ + "netuid": alice_subnet_netuid, + "tempo": NON_FAST_RUNTIME_TEMPO, + }, + ) # update max_allowed_validators so only one neuron can get validator_permit assert await async_sudo_set_admin_utils( @@ -244,9 +274,12 @@ async def test_dendrite_async(async_subtensor, templates, alice_wallet, bob_wall ).tao_to_alpha_with_slippage(tao) assert await async_subtensor.staking.add_stake( - bob_wallet, + wallet=bob_wallet, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=tao, + wait_for_inclusion=False, + wait_for_finalization=False, ) # Refresh metagraph diff --git a/tests/e2e_tests/test_hotkeys.py b/tests/e2e_tests/test_hotkeys.py index 47c2b94ce6..f9fde7a37f 100644 --- a/tests/e2e_tests/test_hotkeys.py +++ b/tests/e2e_tests/test_hotkeys.py @@ -34,7 +34,7 @@ def test_hotkeys(subtensor, alice_wallet, dave_wallet): logging.console.info("Testing [green]test_hotkeys[/green].") dave_subnet_netuid = subtensor.subnets.get_total_subnets() # 2 - assert subtensor.subnets.register_subnet(dave_wallet, True, True) + assert subtensor.subnets.register_subnet(dave_wallet) assert subtensor.subnets.subnet_exists(dave_subnet_netuid), ( f"Subnet #{dave_subnet_netuid} does not exist." ) @@ -60,8 +60,8 @@ def test_hotkeys(subtensor, alice_wallet, dave_wallet): is False ) - subtensor.subnets.burned_register( - alice_wallet, + assert subtensor.subnets.burned_register( + wallet=alice_wallet, netuid=dave_subnet_netuid, ) @@ -90,7 +90,7 @@ async def test_hotkeys_async(async_subtensor, alice_wallet, dave_wallet): logging.console.info("Testing [green]test_hotkeys_async[/green].") dave_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 2 - assert await async_subtensor.subnets.register_subnet(dave_wallet, True, True) + assert await async_subtensor.subnets.register_subnet(dave_wallet) assert await async_subtensor.subnets.subnet_exists(dave_subnet_netuid), ( f"Subnet #{dave_subnet_netuid} does not exist." ) @@ -119,7 +119,7 @@ async def test_hotkeys_async(async_subtensor, alice_wallet, dave_wallet): ) assert await async_subtensor.subnets.burned_register( - alice_wallet, + wallet=alice_wallet, netuid=dave_subnet_netuid, ) @@ -165,7 +165,7 @@ def test_children(subtensor, alice_wallet, bob_wallet, dave_wallet): == "Success with `root_set_pending_childkey_cooldown_extrinsic` response." ) - assert subtensor.subnets.register_subnet(dave_wallet, True, True) + assert subtensor.subnets.register_subnet(dave_wallet) assert subtensor.subnets.subnet_exists(dave_subnet_netuid), ( f"Subnet #{dave_subnet_netuid} does not exist." ) @@ -490,7 +490,7 @@ async def test_children_async(async_subtensor, alice_wallet, bob_wallet, dave_wa == "Success with `root_set_pending_childkey_cooldown_extrinsic` response." ) - assert await async_subtensor.subnets.register_subnet(dave_wallet, True, True) + assert await async_subtensor.subnets.register_subnet(dave_wallet) assert await async_subtensor.subnets.subnet_exists(dave_subnet_netuid), ( f"Subnet #{dave_subnet_netuid} does not exist." ) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 70cda9b48b..0cee9beb8f 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -35,9 +35,7 @@ async def test_incentive(subtensor, templates, alice_wallet, bob_wallet): alice_subnet_netuid = subtensor.subnets.get_total_subnets() # 2 # Register root as Alice - the subnet owner and validator - assert subtensor.subnets.register_subnet(alice_wallet, True, True), ( - "Subnet wasn't created" - ) + assert subtensor.subnets.register_subnet(alice_wallet), "Subnet wasn't created" # Verify subnet created successfully assert subtensor.subnets.subnet_exists(alice_subnet_netuid), ( @@ -208,7 +206,7 @@ async def test_incentive_async(async_subtensor, templates, alice_wallet, bob_wal alice_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 2 # Register root as Alice - the subnet owner and validator - assert await async_subtensor.subnets.register_subnet(alice_wallet, True, True), ( + assert await async_subtensor.subnets.register_subnet(alice_wallet), ( "Subnet wasn't created" ) diff --git a/tests/e2e_tests/test_liquid_alpha.py b/tests/e2e_tests/test_liquid_alpha.py index 3306deb072..e31a852933 100644 --- a/tests/e2e_tests/test_liquid_alpha.py +++ b/tests/e2e_tests/test_liquid_alpha.py @@ -60,6 +60,7 @@ def test_liquid_alpha(subtensor, alice_wallet): assert subtensor.staking.add_stake( wallet=alice_wallet, netuid=netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=Balance.from_tao(10_000), ), "Unable to stake to Alice neuron" @@ -241,6 +242,7 @@ async def test_liquid_alpha_async(async_subtensor, alice_wallet): assert await async_subtensor.staking.add_stake( wallet=alice_wallet, netuid=netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=Balance.from_tao(10_000), ), "Unable to stake to Alice neuron" diff --git a/tests/e2e_tests/test_liquidity.py b/tests/e2e_tests/test_liquidity.py index c99b23338d..2617a6259c 100644 --- a/tests/e2e_tests/test_liquidity.py +++ b/tests/e2e_tests/test_liquidity.py @@ -76,13 +76,11 @@ async def test_liquidity(subtensor, alice_wallet, bob_wallet): assert message == "", "❌ Cannot enable user liquidity." # Add steak to call add_liquidity - assert subtensor.extrinsics.add_stake( + assert subtensor.staking.add_stake( wallet=alice_wallet, hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, amount=Balance.from_tao(1), - wait_for_inclusion=True, - wait_for_finalization=True, ), "❌ Cannot cannot add stake to Alice from Alice." # wait for the next block to give the chain time to update the stake @@ -193,13 +191,11 @@ async def test_liquidity(subtensor, alice_wallet, bob_wallet): ) # Add stake from Bob to Alice - assert subtensor.extrinsics.add_stake( + assert subtensor.staking.add_stake( wallet=bob_wallet, hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, amount=Balance.from_tao(1000), - wait_for_inclusion=True, - wait_for_finalization=True, ), "❌ Cannot add stake from Bob to Alice." # wait for the next block to give the chain time to update the stake @@ -371,13 +367,11 @@ async def test_liquidity_async(async_subtensor, alice_wallet, bob_wallet): assert message == "", "❌ Cannot enable user liquidity." # Add steak to call add_liquidity - assert await async_subtensor.extrinsics.add_stake( + assert await async_subtensor.staking.add_stake( wallet=alice_wallet, hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, amount=Balance.from_tao(1), - wait_for_inclusion=True, - wait_for_finalization=True, ), "❌ Cannot cannot add stake to Alice from Alice." # wait for the next block to give the chain time to update the stake @@ -490,13 +484,11 @@ async def test_liquidity_async(async_subtensor, alice_wallet, bob_wallet): ) # Add stake from Bob to Alice - assert await async_subtensor.extrinsics.add_stake( + assert await async_subtensor.staking.add_stake( wallet=bob_wallet, hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, amount=Balance.from_tao(1000), - wait_for_inclusion=True, - wait_for_finalization=True, ), "❌ Cannot add stake from Bob to Alice." # wait for the next block to give the chain time to update the stake diff --git a/tests/e2e_tests/test_metagraph.py b/tests/e2e_tests/test_metagraph.py index fba4e6fea7..d59b944162 100644 --- a/tests/e2e_tests/test_metagraph.py +++ b/tests/e2e_tests/test_metagraph.py @@ -56,7 +56,7 @@ def test_metagraph(subtensor, alice_wallet, bob_wallet, dave_wallet): alice_subnet_netuid = subtensor.subnets.get_total_subnets() # 2 logging.console.info("Register the subnet through Alice") - assert subtensor.subnets.register_subnet(alice_wallet, True, True), ( + assert subtensor.subnets.register_subnet(alice_wallet), ( "Unable to register the subnet" ) @@ -143,9 +143,8 @@ def test_metagraph(subtensor, alice_wallet, bob_wallet, dave_wallet): assert subtensor.staking.add_stake( wallet=bob_wallet, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=tao, - wait_for_inclusion=True, - wait_for_finalization=True, ), "Failed to add stake for Bob" logging.console.info("Assert stake is added after updating metagraph") @@ -216,9 +215,9 @@ async def test_metagraph_async(async_subtensor, alice_wallet, bob_wallet, dave_w alice_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 2 logging.console.info("Register the subnet through Alice") - assert await async_subtensor.subnets.register_subnet( - alice_wallet, True, True - ), "Unable to register the subnet" + assert await async_subtensor.subnets.register_subnet(alice_wallet), ( + "Unable to register the subnet" + ) logging.console.info("Verify subnet was created successfully") assert await async_subtensor.subnets.subnet_exists(alice_subnet_netuid), ( @@ -313,9 +312,8 @@ async def test_metagraph_async(async_subtensor, alice_wallet, bob_wallet, dave_w assert await async_subtensor.staking.add_stake( wallet=bob_wallet, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=tao, - wait_for_inclusion=True, - wait_for_finalization=True, ), "Failed to add stake for Bob" logging.console.info("Assert stake is added after updating metagraph") @@ -375,7 +373,7 @@ def test_metagraph_info(subtensor, alice_wallet, bob_wallet): logging.console.info("Testing [blue]test_metagraph_info[/blue]") alice_subnet_netuid = subtensor.subnets.get_total_subnets() # 2 - assert subtensor.subnets.register_subnet(alice_wallet, True, True) + assert subtensor.subnets.register_subnet(alice_wallet) metagraph_info = subtensor.metagraphs.get_metagraph_info(netuid=1, block=1) @@ -560,8 +558,6 @@ def test_metagraph_info(subtensor, alice_wallet, bob_wallet): assert subtensor.subnets.burned_register( bob_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) metagraph_info = subtensor.metagraphs.get_metagraph_info(netuid=alice_subnet_netuid) @@ -594,11 +590,7 @@ def test_metagraph_info(subtensor, alice_wallet, bob_wallet): ] alice_subnet_netuid = subtensor.subnets.get_total_subnets() # 3 - assert subtensor.subnets.register_subnet( - alice_wallet, - wait_for_inclusion=True, - wait_for_finalization=True, - ) + assert subtensor.subnets.register_subnet(alice_wallet) block = subtensor.chain.get_current_block() metagraph_info = subtensor.metagraphs.get_metagraph_info( @@ -635,7 +627,7 @@ async def test_metagraph_info_async(async_subtensor, alice_wallet, bob_wallet): logging.console.info("Testing [blue]test_metagraph_info_async[/blue]") alice_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 2 - assert await async_subtensor.subnets.register_subnet(alice_wallet, True, True) + assert await async_subtensor.subnets.register_subnet(alice_wallet) metagraph_info = await async_subtensor.metagraphs.get_metagraph_info( netuid=1, block=1 @@ -824,8 +816,6 @@ async def test_metagraph_info_async(async_subtensor, alice_wallet, bob_wallet): assert await async_subtensor.subnets.burned_register( bob_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) metagraph_info = await async_subtensor.metagraphs.get_metagraph_info( @@ -860,11 +850,7 @@ async def test_metagraph_info_async(async_subtensor, alice_wallet, bob_wallet): ] alice_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 3 - assert await async_subtensor.subnets.register_subnet( - alice_wallet, - wait_for_inclusion=True, - wait_for_finalization=True, - ) + assert await async_subtensor.subnets.register_subnet(alice_wallet) block = await async_subtensor.chain.get_current_block() metagraph_info = await async_subtensor.metagraphs.get_metagraph_info( @@ -900,7 +886,7 @@ def test_metagraph_info_with_indexes(subtensor, alice_wallet, bob_wallet): logging.console.info("Testing [blue]test_metagraph_info_with_indexes[/blue]") alice_subnet_netuid = subtensor.subnets.get_total_subnets() # 2 - assert subtensor.subnets.register_subnet(alice_wallet, True, True) + assert subtensor.subnets.register_subnet(alice_wallet) field_indices = [ SelectiveMetagraphIndex.Name, @@ -1004,10 +990,8 @@ def test_metagraph_info_with_indexes(subtensor, alice_wallet, bob_wallet): assert wait_to_start_call(subtensor, alice_wallet, alice_subnet_netuid) assert subtensor.subnets.burned_register( - bob_wallet, + wallet=bob_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) fields = [ @@ -1136,7 +1120,7 @@ async def test_metagraph_info_with_indexes_async( logging.console.info("Testing [blue]test_metagraph_info_with_indexes_async[/blue]") alice_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 2 - assert await async_subtensor.subnets.register_subnet(alice_wallet, True, True) + assert await async_subtensor.subnets.register_subnet(alice_wallet) field_indices = [ SelectiveMetagraphIndex.Name, @@ -1242,10 +1226,8 @@ async def test_metagraph_info_with_indexes_async( ) assert await async_subtensor.subnets.burned_register( - bob_wallet, + wallet=bob_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) fields = [ diff --git a/tests/e2e_tests/test_reveal_commitments.py b/tests/e2e_tests/test_reveal_commitments.py index 97b60373fd..9ad12eaa76 100644 --- a/tests/e2e_tests/test_reveal_commitments.py +++ b/tests/e2e_tests/test_reveal_commitments.py @@ -38,7 +38,7 @@ def test_set_reveal_commitment(subtensor, alice_wallet, bob_wallet): logging.console.info("Testing Drand encrypted commitments.") # Register subnet as Alice - assert subtensor.subnets.register_subnet(alice_wallet, True, True), ( + assert subtensor.subnets.register_subnet(alice_wallet), ( "Unable to register the subnet" ) @@ -46,7 +46,8 @@ def test_set_reveal_commitment(subtensor, alice_wallet, bob_wallet): # Register Bob's neuron assert subtensor.subnets.burned_register( - bob_wallet, alice_subnet_netuid, True, True + wallet=bob_wallet, + netuid=alice_subnet_netuid, ), "Bob's neuron was not register." # Verify subnet 2 created successfully @@ -152,7 +153,7 @@ async def test_set_reveal_commitment(async_subtensor, alice_wallet, bob_wallet): logging.console.info("Testing Drand encrypted commitments.") # Register subnet as Alice - assert await async_subtensor.subnets.register_subnet(alice_wallet, True, True), ( + assert await async_subtensor.subnets.register_subnet(alice_wallet), ( "Unable to register the subnet" ) @@ -162,7 +163,7 @@ async def test_set_reveal_commitment(async_subtensor, alice_wallet, bob_wallet): # Register Bob's neuron assert await async_subtensor.subnets.burned_register( - bob_wallet, alice_subnet_netuid, True, True + bob_wallet, alice_subnet_netuid ), "Bob's neuron was not register." # Verify subnet 2 created successfully diff --git a/tests/e2e_tests/test_root_set_weights.py b/tests/e2e_tests/test_root_set_weights.py index 7ce08d9f47..7d18dccfcf 100644 --- a/tests/e2e_tests/test_root_set_weights.py +++ b/tests/e2e_tests/test_root_set_weights.py @@ -88,11 +88,9 @@ async def test_root_reg_hyperparams(subtensor, templates, alice_wallet, bob_wall assert subtensor.staking.add_stake( wallet=bob_wallet, - hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=Balance.from_tao(1), - wait_for_inclusion=True, - wait_for_finalization=True, period=16, ), "Unable to stake from Bob to Alice" @@ -213,11 +211,9 @@ async def test_root_reg_hyperparams_async( assert await async_subtensor.staking.add_stake( wallet=bob_wallet, - hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=Balance.from_tao(1), - wait_for_inclusion=True, - wait_for_finalization=True, period=16, ), "Unable to stake from Bob to Alice" diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index 0e153b804e..ea754b68c8 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -54,11 +54,9 @@ def test_set_weights_uses_next_nonce(subtensor, alice_wallet): for netuid in netuids: # Register the subnets - assert subtensor.subnets.register_subnet( - wallet=alice_wallet, - wait_for_inclusion=True, - wait_for_finalization=True, - ), "Unable to register the subnet" + assert subtensor.subnets.register_subnet(alice_wallet), ( + "Unable to register the subnet" + ) # Verify all subnets created successfully assert subtensor.subnets.subnet_exists(netuid), ( @@ -85,11 +83,9 @@ def test_set_weights_uses_next_nonce(subtensor, alice_wallet): for netuid in netuids: assert subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=Balance.from_tao(10_000), - wait_for_inclusion=True, - wait_for_finalization=True, ) # Set weight hyperparameters per subnet @@ -222,11 +218,9 @@ async def test_set_weights_uses_next_nonce_async(async_subtensor, alice_wallet): for netuid in netuids: # Register the subnets - assert await async_subtensor.subnets.register_subnet( - wallet=alice_wallet, - wait_for_inclusion=True, - wait_for_finalization=True, - ), "Unable to register the subnet" + assert await async_subtensor.subnets.register_subnet(alice_wallet), ( + "Unable to register the subnet" + ) # Verify all subnets created successfully assert await async_subtensor.subnets.subnet_exists(netuid), ( @@ -253,11 +247,9 @@ async def test_set_weights_uses_next_nonce_async(async_subtensor, alice_wallet): for netuid in netuids: assert await async_subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=Balance.from_tao(10_000), - wait_for_inclusion=True, - wait_for_finalization=True, ) # Set weight hyperparameters per subnet diff --git a/tests/e2e_tests/test_staking.py b/tests/e2e_tests/test_staking.py index f9f86adc5b..b3847bb507 100644 --- a/tests/e2e_tests/test_staking.py +++ b/tests/e2e_tests/test_staking.py @@ -29,7 +29,7 @@ def test_single_operation(subtensor, alice_wallet, bob_wallet): alice_subnet_netuid = subtensor.subnets.get_total_subnets() # 2 # Register root as Alice - the subnet owner and validator - assert subtensor.subnets.register_subnet(alice_wallet, True, True) + assert subtensor.subnets.register_subnet(alice_wallet) # Verify subnet created successfully assert subtensor.subnets.subnet_exists(alice_subnet_netuid), ( @@ -41,15 +41,11 @@ def test_single_operation(subtensor, alice_wallet, bob_wallet): subtensor.subnets.burned_register( wallet=alice_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) logging.console.success(f"Alice is registered in subnet {alice_subnet_netuid}") subtensor.subnets.burned_register( wallet=bob_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) logging.console.success(f"Bob is registered in subnet {alice_subnet_netuid}") @@ -63,11 +59,9 @@ def test_single_operation(subtensor, alice_wallet, bob_wallet): success = subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=Balance.from_tao(1), - wait_for_inclusion=True, - wait_for_finalization=True, period=16, ) @@ -169,13 +163,19 @@ def test_single_operation(subtensor, alice_wallet, bob_wallet): ), } + stake = subtensor.staking.get_stake( + coldkey_ss58=alice_wallet.coldkey.ss58_address, + hotkey_ss58=bob_wallet.hotkey.ss58_address, + netuid=alice_subnet_netuid, + ) + logging.console.info(f"Alice stake before unstake: {stake}") + # unstale all to check in later success = subtensor.staking.unstake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, + hotkey_ss58=bob_wallet.hotkey.ss58_address, + amount=stake, period=16, ) @@ -205,7 +205,7 @@ async def test_single_operation_async(async_subtensor, alice_wallet, bob_wallet) alice_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 2 # Register root as Alice - the subnet owner and validator - assert await async_subtensor.subnets.register_subnet(alice_wallet, True, True) + assert await async_subtensor.subnets.register_subnet(alice_wallet) # Verify subnet created successfully assert await async_subtensor.subnets.subnet_exists(alice_subnet_netuid), ( @@ -219,15 +219,11 @@ async def test_single_operation_async(async_subtensor, alice_wallet, bob_wallet) await async_subtensor.subnets.burned_register( wallet=alice_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) logging.console.success(f"Alice is registered in subnet {alice_subnet_netuid}") await async_subtensor.subnets.burned_register( wallet=bob_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) logging.console.success(f"Bob is registered in subnet {alice_subnet_netuid}") @@ -241,11 +237,9 @@ async def test_single_operation_async(async_subtensor, alice_wallet, bob_wallet) success = await async_subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=Balance.from_tao(1), - wait_for_inclusion=True, - wait_for_finalization=True, period=16, ) @@ -359,10 +353,8 @@ async def test_single_operation_async(async_subtensor, alice_wallet, bob_wallet) # unstale all to check in later success, message = await async_subtensor.staking.unstake_all( wallet=alice_wallet, - hotkey=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, + hotkey=bob_wallet.hotkey.ss58_address, period=16, ) assert success is True, message @@ -396,11 +388,7 @@ def test_batch_operations(subtensor, alice_wallet, bob_wallet): ] for _ in netuids: - subtensor.subnets.register_subnet( - alice_wallet, - wait_for_inclusion=True, - wait_for_finalization=True, - ) + subtensor.subnets.register_subnet(alice_wallet) # make sure we passed start_call limit for both subnets for netuid in netuids: @@ -408,10 +396,8 @@ def test_batch_operations(subtensor, alice_wallet, bob_wallet): for netuid in netuids: subtensor.subnets.burned_register( - bob_wallet, - netuid, - wait_for_inclusion=True, - wait_for_finalization=True, + wallet=bob_wallet, + netuid=netuid, ) for netuid in netuids: @@ -442,7 +428,7 @@ def test_batch_operations(subtensor, alice_wallet, bob_wallet): alice_balance = balances[alice_wallet.coldkey.ss58_address] success = subtensor.staking.add_stake_multiple( - alice_wallet, + wallet=alice_wallet, hotkey_ss58s=[bob_wallet.hotkey.ss58_address for _ in netuids], netuids=netuids, amounts=[Balance.from_tao(10_000) for _ in netuids], @@ -452,8 +438,8 @@ def test_batch_operations(subtensor, alice_wallet, bob_wallet): stakes = [ subtensor.staking.get_stake( - alice_wallet.coldkey.ss58_address, - bob_wallet.hotkey.ss58_address, + coldkey_ss58=alice_wallet.coldkey.ss58_address, + hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=netuid, ) for netuid in netuids @@ -500,9 +486,9 @@ def test_batch_operations(subtensor, alice_wallet, bob_wallet): expected_fee_paid += fee_tao success = subtensor.staking.unstake_multiple( - alice_wallet, - hotkey_ss58s=[bob_wallet.hotkey.ss58_address for _ in netuids], + wallet=alice_wallet, netuids=netuids, + hotkey_ss58s=[bob_wallet.hotkey.ss58_address for _ in netuids], amounts=[Balance.from_tao(100) for _ in netuids], ) @@ -510,8 +496,8 @@ def test_batch_operations(subtensor, alice_wallet, bob_wallet): for netuid, old_stake in zip(netuids, stakes): stake = subtensor.staking.get_stake( - alice_wallet.coldkey.ss58_address, - bob_wallet.hotkey.ss58_address, + coldkey_ss58=alice_wallet.coldkey.ss58_address, + hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=netuid, ) @@ -547,11 +533,7 @@ async def test_batch_operations_async(async_subtensor, alice_wallet, bob_wallet) ] for _ in netuids: - await async_subtensor.subnets.register_subnet( - wallet=alice_wallet, - wait_for_inclusion=True, - wait_for_finalization=True, - ) + await async_subtensor.subnets.register_subnet(alice_wallet) # make sure we passed start_call limit for both subnets for netuid in netuids: @@ -561,8 +543,6 @@ async def test_batch_operations_async(async_subtensor, alice_wallet, bob_wallet) await async_subtensor.subnets.burned_register( wallet=bob_wallet, netuid=netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) for netuid in netuids: @@ -651,9 +631,9 @@ async def test_batch_operations_async(async_subtensor, alice_wallet, bob_wallet) expected_fee_paid += fee_tao success = await async_subtensor.staking.unstake_multiple( - alice_wallet, - hotkey_ss58s=[bob_wallet.hotkey.ss58_address for _ in netuids], + wallet=alice_wallet, netuids=netuids, + hotkey_ss58s=[bob_wallet.hotkey.ss58_address for _ in netuids], amounts=[Balance.from_tao(100) for _ in netuids], ) @@ -661,8 +641,8 @@ async def test_batch_operations_async(async_subtensor, alice_wallet, bob_wallet) for netuid, old_stake in zip(netuids, stakes): stake = await async_subtensor.staking.get_stake( - alice_wallet.coldkey.ss58_address, - bob_wallet.hotkey.ss58_address, + coldkey_ss58=alice_wallet.coldkey.ss58_address, + hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=netuid, ) @@ -694,7 +674,7 @@ def test_safe_staking_scenarios(subtensor, alice_wallet, bob_wallet, eve_wallet) alice_subnet_netuid = subtensor.subnets.get_total_subnets() # 2 # Register root as Alice - the subnet owner and validator - assert subtensor.extrinsics.register_subnet(alice_wallet, True, True) + assert subtensor.extrinsics.register_subnet(alice_wallet) # Verify subnet created successfully assert subtensor.subnets.subnet_exists(alice_subnet_netuid), ( @@ -741,11 +721,9 @@ def test_safe_staking_scenarios(subtensor, alice_wallet, bob_wallet, eve_wallet) # 1. Strict params - should fail success = subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=stake_amount, - wait_for_inclusion=True, - wait_for_finalization=True, safe_staking=True, rate_tolerance=0.005, # 0.5% allow_partial_stake=False, @@ -765,11 +743,9 @@ def test_safe_staking_scenarios(subtensor, alice_wallet, bob_wallet, eve_wallet) # 2. Partial allowed - should succeed partially success = subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=stake_amount, - wait_for_inclusion=True, - wait_for_finalization=True, safe_staking=True, rate_tolerance=0.005, # 0.5% allow_partial_stake=True, @@ -792,11 +768,9 @@ def test_safe_staking_scenarios(subtensor, alice_wallet, bob_wallet, eve_wallet) amount = Balance.from_tao(100) success = subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=amount, - wait_for_inclusion=True, - wait_for_finalization=True, safe_staking=True, rate_tolerance=0.22, # 22% allow_partial_stake=False, @@ -813,12 +787,10 @@ def test_safe_staking_scenarios(subtensor, alice_wallet, bob_wallet, eve_wallet) # 1. Strict params - should fail success = subtensor.staking.unstake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=full_stake, - wait_for_inclusion=True, - wait_for_finalization=True, - safe_staking=True, + safe_unstaking=True, rate_tolerance=0.005, # 0.5% allow_partial_stake=False, ) @@ -840,12 +812,10 @@ def test_safe_staking_scenarios(subtensor, alice_wallet, bob_wallet, eve_wallet) # 2. Partial allowed - should succeed partially success = subtensor.staking.unstake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=current_stake, - wait_for_inclusion=True, - wait_for_finalization=True, - safe_staking=True, + safe_unstaking=True, rate_tolerance=0.005, # 0.5% allow_partial_stake=True, ) @@ -864,12 +834,10 @@ def test_safe_staking_scenarios(subtensor, alice_wallet, bob_wallet, eve_wallet) # 3. Higher threshold - should succeed fully success = subtensor.staking.unstake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=partial_unstake, - wait_for_inclusion=True, - wait_for_finalization=True, - safe_staking=True, + safe_unstaking=True, rate_tolerance=0.3, # 30% allow_partial_stake=False, ) @@ -893,7 +861,7 @@ async def test_safe_staking_scenarios_async( alice_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 2 # Register root as Alice - the subnet owner and validator - assert await async_subtensor.extrinsics.register_subnet(alice_wallet, True, True) + assert await async_subtensor.extrinsics.register_subnet(alice_wallet) # Verify subnet created successfully assert await async_subtensor.subnets.subnet_exists(alice_subnet_netuid), ( @@ -943,11 +911,9 @@ async def test_safe_staking_scenarios_async( # 1. Strict params - should fail success = await async_subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=stake_amount, - wait_for_inclusion=True, - wait_for_finalization=True, safe_staking=True, rate_tolerance=0.005, # 0.5% allow_partial_stake=False, @@ -967,11 +933,9 @@ async def test_safe_staking_scenarios_async( # 2. Partial allowed - should succeed partially success = await async_subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=stake_amount, - wait_for_inclusion=True, - wait_for_finalization=True, safe_staking=True, rate_tolerance=0.005, # 0.5% allow_partial_stake=True, @@ -994,11 +958,9 @@ async def test_safe_staking_scenarios_async( amount = Balance.from_tao(100) success = await async_subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=amount, - wait_for_inclusion=True, - wait_for_finalization=True, safe_staking=True, rate_tolerance=0.22, # 22% allow_partial_stake=False, @@ -1015,12 +977,10 @@ async def test_safe_staking_scenarios_async( # 1. Strict params - should fail success = await async_subtensor.staking.unstake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=full_stake, - wait_for_inclusion=True, - wait_for_finalization=True, - safe_staking=True, + safe_unstaking=True, rate_tolerance=0.005, # 0.5% allow_partial_stake=False, ) @@ -1042,12 +1002,10 @@ async def test_safe_staking_scenarios_async( # 2. Partial allowed - should succeed partially success = await async_subtensor.staking.unstake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=current_stake, - wait_for_inclusion=True, - wait_for_finalization=True, - safe_staking=True, + safe_unstaking=True, rate_tolerance=0.005, # 0.5% allow_partial_stake=True, ) @@ -1066,12 +1024,10 @@ async def test_safe_staking_scenarios_async( # 3. Higher threshold - should succeed fully success = await async_subtensor.staking.unstake( wallet=alice_wallet, - hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=bob_wallet.hotkey.ss58_address, amount=partial_unstake, - wait_for_inclusion=True, - wait_for_finalization=True, - safe_staking=True, + safe_unstaking=True, rate_tolerance=0.3, # 30% allow_partial_stake=False, ) @@ -1093,12 +1049,12 @@ def test_safe_swap_stake_scenarios(subtensor, alice_wallet, bob_wallet): # Create new subnet (netuid 2) and register Alice origin_netuid = 2 - assert subtensor.subnets.register_subnet(bob_wallet, True, True) + assert subtensor.subnets.register_subnet(bob_wallet) assert subtensor.subnets.subnet_exists(origin_netuid), ( "Subnet wasn't created successfully" ) dest_netuid = 3 - assert subtensor.subnets.register_subnet(bob_wallet, True, True) + assert subtensor.subnets.register_subnet(bob_wallet) assert subtensor.subnets.subnet_exists(dest_netuid), ( "Subnet wasn't created successfully" ) @@ -1111,25 +1067,19 @@ def test_safe_swap_stake_scenarios(subtensor, alice_wallet, bob_wallet): subtensor.subnets.burned_register( wallet=alice_wallet, netuid=origin_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) subtensor.subnets.burned_register( wallet=alice_wallet, netuid=dest_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) # Add initial stake to swap from initial_stake_amount = Balance.from_tao(10_000) success = subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=origin_netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=initial_stake_amount, - wait_for_inclusion=True, - wait_for_finalization=True, ) assert success is True @@ -1152,7 +1102,7 @@ def test_safe_swap_stake_scenarios(subtensor, alice_wallet, bob_wallet): amount=stake_swap_amount, wait_for_inclusion=True, wait_for_finalization=True, - safe_staking=True, + safe_swapping=True, rate_tolerance=0.005, # 0.5% allow_partial_stake=False, ) @@ -1178,7 +1128,7 @@ def test_safe_swap_stake_scenarios(subtensor, alice_wallet, bob_wallet): amount=stake_swap_amount, wait_for_inclusion=True, wait_for_finalization=True, - safe_staking=True, + safe_swapping=True, rate_tolerance=0.3, # 30% allow_partial_stake=True, ) @@ -1213,12 +1163,12 @@ async def test_safe_swap_stake_scenarios_async( # Create new subnet (netuid 2) and register Alice origin_netuid = 2 - assert await async_subtensor.subnets.register_subnet(bob_wallet, True, True) + assert await async_subtensor.subnets.register_subnet(bob_wallet) assert await async_subtensor.subnets.subnet_exists(origin_netuid), ( "Subnet wasn't created successfully" ) dest_netuid = 3 - assert await async_subtensor.subnets.register_subnet(bob_wallet, True, True) + assert await async_subtensor.subnets.register_subnet(bob_wallet) assert await async_subtensor.subnets.subnet_exists(dest_netuid), ( "Subnet wasn't created successfully" ) @@ -1231,25 +1181,19 @@ async def test_safe_swap_stake_scenarios_async( await async_subtensor.subnets.burned_register( wallet=alice_wallet, netuid=origin_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) await async_subtensor.subnets.burned_register( wallet=alice_wallet, netuid=dest_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) # Add initial stake to swap from initial_stake_amount = Balance.from_tao(10_000) success = await async_subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=origin_netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=initial_stake_amount, - wait_for_inclusion=True, - wait_for_finalization=True, ) assert success is True @@ -1272,7 +1216,7 @@ async def test_safe_swap_stake_scenarios_async( amount=stake_swap_amount, wait_for_inclusion=True, wait_for_finalization=True, - safe_staking=True, + safe_swapping=True, rate_tolerance=0.005, # 0.5% allow_partial_stake=False, ) @@ -1298,7 +1242,7 @@ async def test_safe_swap_stake_scenarios_async( amount=stake_swap_amount, wait_for_inclusion=True, wait_for_finalization=True, - safe_staking=True, + safe_swapping=True, rate_tolerance=0.3, # 30% allow_partial_stake=True, ) @@ -1328,7 +1272,7 @@ def test_move_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): logging.console.info("Testing [blue]test_move_stake[/blue]") alice_subnet_netuid = subtensor.subnets.get_total_subnets() # 2 - assert subtensor.subnets.register_subnet(alice_wallet, True, True) + assert subtensor.subnets.register_subnet(alice_wallet) assert subtensor.subnets.subnet_exists(alice_subnet_netuid), ( "Subnet wasn't created successfully" ) @@ -1337,11 +1281,9 @@ def test_move_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): assert subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=Balance.from_tao(1_000), - wait_for_inclusion=True, - wait_for_finalization=True, ) stakes = subtensor.staking.get_stake_for_coldkey(alice_wallet.coldkey.ss58_address) @@ -1360,7 +1302,7 @@ def test_move_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): ] bob_subnet_netuid = subtensor.subnets.get_total_subnets() # 3 - subtensor.subnets.register_subnet(bob_wallet, True, True) + subtensor.subnets.register_subnet(bob_wallet) assert subtensor.subnets.subnet_exists(bob_subnet_netuid), ( "Subnet wasn't created successfully" ) @@ -1370,22 +1312,18 @@ def test_move_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): subtensor.subnets.burned_register( wallet=bob_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) subtensor.subnets.burned_register( wallet=dave_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) assert subtensor.staking.move_stake( wallet=alice_wallet, - origin_hotkey=alice_wallet.hotkey.ss58_address, + origin_hotkey_ss58=alice_wallet.hotkey.ss58_address, origin_netuid=alice_subnet_netuid, - destination_hotkey=bob_wallet.hotkey.ss58_address, + destination_hotkey_ss58=bob_wallet.hotkey.ss58_address, destination_netuid=bob_subnet_netuid, amount=stakes[0].stake, wait_for_finalization=True, @@ -1439,11 +1377,9 @@ def test_move_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): assert subtensor.staking.add_stake( wallet=dave_wallet, - hotkey_ss58=dave_wallet.hotkey.ss58_address, netuid=bob_subnet_netuid, + hotkey_ss58=dave_wallet.hotkey.ss58_address, amount=Balance.from_tao(1000), - wait_for_inclusion=True, - wait_for_finalization=True, allow_partial_stake=True, ) @@ -1461,9 +1397,9 @@ def test_move_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): assert subtensor.staking.move_stake( wallet=dave_wallet, - origin_hotkey=dave_wallet.hotkey.ss58_address, + origin_hotkey_ss58=dave_wallet.hotkey.ss58_address, origin_netuid=bob_subnet_netuid, - destination_hotkey=bob_wallet.hotkey.ss58_address, + destination_hotkey_ss58=bob_wallet.hotkey.ss58_address, destination_netuid=bob_subnet_netuid, wait_for_inclusion=True, wait_for_finalization=True, @@ -1493,7 +1429,7 @@ async def test_move_stake_async(async_subtensor, alice_wallet, bob_wallet, dave_ logging.console.info("Testing [blue]test_move_stake_async[/blue]") alice_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 2 - assert await async_subtensor.subnets.register_subnet(alice_wallet, True, True) + assert await async_subtensor.subnets.register_subnet(alice_wallet) assert await async_subtensor.subnets.subnet_exists(alice_subnet_netuid), ( "Subnet wasn't created successfully" ) @@ -1504,11 +1440,9 @@ async def test_move_stake_async(async_subtensor, alice_wallet, bob_wallet, dave_ assert await async_subtensor.staking.add_stake( wallet=alice_wallet, - hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=Balance.from_tao(1_000), - wait_for_inclusion=True, - wait_for_finalization=True, ) stakes = await async_subtensor.staking.get_stake_for_coldkey( @@ -1529,7 +1463,7 @@ async def test_move_stake_async(async_subtensor, alice_wallet, bob_wallet, dave_ ] bob_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 3 - await async_subtensor.subnets.register_subnet(bob_wallet, True, True) + await async_subtensor.subnets.register_subnet(bob_wallet) assert await async_subtensor.subnets.subnet_exists(bob_subnet_netuid), ( "Subnet wasn't created successfully" ) @@ -1541,22 +1475,18 @@ async def test_move_stake_async(async_subtensor, alice_wallet, bob_wallet, dave_ await async_subtensor.subnets.burned_register( wallet=bob_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) await async_subtensor.subnets.burned_register( wallet=dave_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) assert await async_subtensor.staking.move_stake( wallet=alice_wallet, - origin_hotkey=alice_wallet.hotkey.ss58_address, + origin_hotkey_ss58=alice_wallet.hotkey.ss58_address, origin_netuid=alice_subnet_netuid, - destination_hotkey=bob_wallet.hotkey.ss58_address, + destination_hotkey_ss58=bob_wallet.hotkey.ss58_address, destination_netuid=bob_subnet_netuid, amount=stakes[0].stake, wait_for_finalization=True, @@ -1615,8 +1545,6 @@ async def test_move_stake_async(async_subtensor, alice_wallet, bob_wallet, dave_ hotkey_ss58=dave_wallet.hotkey.ss58_address, netuid=bob_subnet_netuid, amount=Balance.from_tao(1000), - wait_for_inclusion=True, - wait_for_finalization=True, allow_partial_stake=True, ) @@ -1635,9 +1563,9 @@ async def test_move_stake_async(async_subtensor, alice_wallet, bob_wallet, dave_ assert await async_subtensor.staking.move_stake( wallet=dave_wallet, - origin_hotkey=dave_wallet.hotkey.ss58_address, + origin_hotkey_ss58=dave_wallet.hotkey.ss58_address, origin_netuid=bob_subnet_netuid, - destination_hotkey=bob_wallet.hotkey.ss58_address, + destination_hotkey_ss58=bob_wallet.hotkey.ss58_address, destination_netuid=bob_subnet_netuid, wait_for_inclusion=True, wait_for_finalization=True, @@ -1666,7 +1594,7 @@ def test_transfer_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): alice_subnet_netuid = subtensor.subnets.get_total_subnets() # 2 - assert subtensor.subnets.register_subnet(alice_wallet, True, True) + assert subtensor.subnets.register_subnet(alice_wallet) assert subtensor.subnets.subnet_exists(alice_subnet_netuid), ( "Subnet wasn't created successfully" ) @@ -1674,19 +1602,15 @@ def test_transfer_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): assert wait_to_start_call(subtensor, alice_wallet, alice_subnet_netuid) subtensor.subnets.burned_register( - alice_wallet, + wallet=alice_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) assert subtensor.staking.add_stake( - alice_wallet, - alice_wallet.hotkey.ss58_address, + wallet=alice_wallet, netuid=alice_subnet_netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=Balance.from_tao(1_000), - wait_for_inclusion=True, - wait_for_finalization=True, ) alice_stakes = subtensor.staking.get_stake_for_coldkey( @@ -1715,15 +1639,13 @@ def test_transfer_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): assert bob_stakes == [] dave_subnet_netuid = subtensor.subnets.get_total_subnets() # 3 - subtensor.subnets.register_subnet(dave_wallet, True, True) + subtensor.subnets.register_subnet(dave_wallet) assert wait_to_start_call(subtensor, dave_wallet, dave_subnet_netuid) subtensor.subnets.burned_register( - bob_wallet, + wallet=bob_wallet, netuid=dave_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) assert subtensor.staking.transfer_stake( @@ -1799,7 +1721,7 @@ async def test_transfer_stake_async( alice_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 2 - assert await async_subtensor.subnets.register_subnet(alice_wallet, True, True) + assert await async_subtensor.subnets.register_subnet(alice_wallet) assert await async_subtensor.subnets.subnet_exists(alice_subnet_netuid), ( "Subnet wasn't created successfully" ) @@ -1809,19 +1731,15 @@ async def test_transfer_stake_async( ) await async_subtensor.subnets.burned_register( - alice_wallet, + wallet=alice_wallet, netuid=alice_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) assert await async_subtensor.staking.add_stake( - alice_wallet, - alice_wallet.hotkey.ss58_address, + wallet=alice_wallet, netuid=alice_subnet_netuid, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=Balance.from_tao(1_000), - wait_for_inclusion=True, - wait_for_finalization=True, ) alice_stakes = await async_subtensor.staking.get_stake_for_coldkey( @@ -1850,17 +1768,15 @@ async def test_transfer_stake_async( assert bob_stakes == [] dave_subnet_netuid = await async_subtensor.subnets.get_total_subnets() # 3 - await async_subtensor.subnets.register_subnet(dave_wallet, True, True) + await async_subtensor.subnets.register_subnet(dave_wallet) assert await async_wait_to_start_call( async_subtensor, dave_wallet, dave_subnet_netuid ) await async_subtensor.subnets.burned_register( - bob_wallet, + wallet=bob_wallet, netuid=dave_subnet_netuid, - wait_for_inclusion=True, - wait_for_finalization=True, ) assert await async_subtensor.staking.transfer_stake( @@ -1942,7 +1858,7 @@ def test_unstaking_with_limit( # Register first SN alice_subnet_netuid_2 = subtensor.subnets.get_total_subnets() # 2 - assert subtensor.subnets.register_subnet(alice_wallet, True, True) + assert subtensor.subnets.register_subnet(alice_wallet) assert subtensor.subnets.subnet_exists(alice_subnet_netuid_2), ( "Subnet wasn't created successfully" ) @@ -1953,20 +1869,16 @@ def test_unstaking_with_limit( assert subtensor.subnets.burned_register( wallet=bob_wallet, netuid=alice_subnet_netuid_2, - wait_for_inclusion=True, - wait_for_finalization=True, ) assert subtensor.subnets.burned_register( wallet=dave_wallet, netuid=alice_subnet_netuid_2, - wait_for_inclusion=True, - wait_for_finalization=True, ) # Register second SN alice_subnet_netuid_3 = subtensor.subnets.get_total_subnets() # 3 - assert subtensor.subnets.register_subnet(alice_wallet, True, True) + assert subtensor.subnets.register_subnet(alice_wallet) assert subtensor.subnets.subnet_exists(alice_subnet_netuid_3), ( "Subnet wasn't created successfully" ) @@ -1977,15 +1889,11 @@ def test_unstaking_with_limit( assert subtensor.subnets.burned_register( wallet=bob_wallet, netuid=alice_subnet_netuid_3, - wait_for_inclusion=True, - wait_for_finalization=True, ) assert subtensor.subnets.burned_register( wallet=dave_wallet, netuid=alice_subnet_netuid_3, - wait_for_inclusion=True, - wait_for_finalization=True, ) # Check Bob's stakes are empty. @@ -2001,8 +1909,6 @@ def test_unstaking_with_limit( hotkey_ss58=dave_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid_2, amount=Balance.from_tao(10000), - wait_for_inclusion=True, - wait_for_finalization=True, period=16, ), f"Cant add stake to dave in SN {alice_subnet_netuid_2}" assert subtensor.staking.add_stake( @@ -2010,8 +1916,6 @@ def test_unstaking_with_limit( hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid_3, amount=Balance.from_tao(15000), - wait_for_inclusion=True, - wait_for_finalization=True, period=16, ), f"Cant add stake to dave in SN {alice_subnet_netuid_3}" @@ -2031,8 +1935,6 @@ def test_unstaking_with_limit( hotkey=bob_stakes[0].hotkey_ss58, netuid=bob_stakes[0].netuid, rate_tolerance=rate_tolerance, - wait_for_inclusion=True, - wait_for_finalization=True, ) else: # Successful cases @@ -2042,8 +1944,6 @@ def test_unstaking_with_limit( hotkey=si.hotkey_ss58, netuid=si.netuid, rate_tolerance=rate_tolerance, - wait_for_inclusion=True, - wait_for_finalization=True, )[0] # Make sure both unstake were successful. @@ -2070,7 +1970,7 @@ async def test_unstaking_with_limit_async( # Register first SN alice_subnet_netuid_2 = await async_subtensor.subnets.get_total_subnets() # 2 - assert await async_subtensor.subnets.register_subnet(alice_wallet, True, True) + assert await async_subtensor.subnets.register_subnet(alice_wallet) assert await async_subtensor.subnets.subnet_exists(alice_subnet_netuid_2), ( "Subnet wasn't created successfully" ) @@ -2083,20 +1983,16 @@ async def test_unstaking_with_limit_async( assert await async_subtensor.subnets.burned_register( wallet=bob_wallet, netuid=alice_subnet_netuid_2, - wait_for_inclusion=True, - wait_for_finalization=True, ) assert await async_subtensor.subnets.burned_register( wallet=dave_wallet, netuid=alice_subnet_netuid_2, - wait_for_inclusion=True, - wait_for_finalization=True, ) # Register second SN alice_subnet_netuid_3 = await async_subtensor.subnets.get_total_subnets() # 3 - assert await async_subtensor.subnets.register_subnet(alice_wallet, True, True) + assert await async_subtensor.subnets.register_subnet(alice_wallet) assert await async_subtensor.subnets.subnet_exists(alice_subnet_netuid_3), ( "Subnet wasn't created successfully" ) @@ -2107,15 +2003,11 @@ async def test_unstaking_with_limit_async( assert await async_subtensor.subnets.burned_register( wallet=bob_wallet, netuid=alice_subnet_netuid_3, - wait_for_inclusion=True, - wait_for_finalization=True, ) assert await async_subtensor.subnets.burned_register( wallet=dave_wallet, netuid=alice_subnet_netuid_3, - wait_for_inclusion=True, - wait_for_finalization=True, ) # Check Bob's stakes are empty. @@ -2130,20 +2022,16 @@ async def test_unstaking_with_limit_async( assert await async_subtensor.staking.add_stake( wallet=bob_wallet, - hotkey_ss58=dave_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid_2, + hotkey_ss58=dave_wallet.hotkey.ss58_address, amount=Balance.from_tao(10000), - wait_for_inclusion=True, - wait_for_finalization=True, period=16, ), f"Cant add stake to dave in SN {alice_subnet_netuid_2}" assert await async_subtensor.staking.add_stake( wallet=bob_wallet, - hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid_3, + hotkey_ss58=alice_wallet.hotkey.ss58_address, amount=Balance.from_tao(15000), - wait_for_inclusion=True, - wait_for_finalization=True, period=16, ), f"Cant add stake to dave in SN {alice_subnet_netuid_3}" @@ -2160,11 +2048,9 @@ async def test_unstaking_with_limit_async( ): await async_subtensor.staking.unstake_all( wallet=bob_wallet, - hotkey=bob_stakes[0].hotkey_ss58, netuid=bob_stakes[0].netuid, + hotkey=bob_stakes[0].hotkey_ss58, rate_tolerance=rate_tolerance, - wait_for_inclusion=True, - wait_for_finalization=True, ) else: # Successful cases @@ -2172,11 +2058,9 @@ async def test_unstaking_with_limit_async( assert ( await async_subtensor.staking.unstake_all( wallet=bob_wallet, - hotkey=si.hotkey_ss58, netuid=si.netuid, + hotkey=si.hotkey_ss58, rate_tolerance=rate_tolerance, - wait_for_inclusion=True, - wait_for_finalization=True, ) )[0] diff --git a/tests/e2e_tests/test_subnets.py b/tests/e2e_tests/test_subnets.py index 8b28206fdc..89028d2d06 100644 --- a/tests/e2e_tests/test_subnets.py +++ b/tests/e2e_tests/test_subnets.py @@ -14,11 +14,7 @@ def test_subnets(subtensor, alice_wallet): subnets = subtensor.subnets.all_subnets() assert len(subnets) == 2 - subtensor.subnets.register_subnet( - alice_wallet, - wait_for_inclusion=True, - wait_for_finalization=True, - ) + subtensor.subnets.register_subnet(alice_wallet) subnets = subtensor.subnets.all_subnets() assert len(subnets) == 3 @@ -50,11 +46,7 @@ async def test_subnets_async(async_subtensor, alice_wallet): subnets = await async_subtensor.subnets.all_subnets() assert len(subnets) == 2 - assert await async_subtensor.subnets.register_subnet( - alice_wallet, - wait_for_inclusion=True, - wait_for_finalization=True, - ) + assert await async_subtensor.subnets.register_subnet(alice_wallet) subnets = await async_subtensor.subnets.all_subnets() assert len(subnets) == 3 diff --git a/tests/e2e_tests/test_subtensor_functions.py b/tests/e2e_tests/test_subtensor_functions.py index 11342caec5..669b929d3f 100644 --- a/tests/e2e_tests/test_subtensor_functions.py +++ b/tests/e2e_tests/test_subtensor_functions.py @@ -68,7 +68,7 @@ async def test_subtensor_extrinsics(subtensor, templates, alice_wallet, bob_wall pre_subnet_creation_cost = subtensor.subnets.get_subnet_burn_cost() # Register subnet - assert subtensor.subnets.register_subnet(alice_wallet, True, True), ( + assert subtensor.subnets.register_subnet(alice_wallet), ( "Unable to register the subnet" ) @@ -259,7 +259,7 @@ async def test_subtensor_extrinsics_async( pre_subnet_creation_cost = await async_subtensor.subnets.get_subnet_burn_cost() # Register subnet - assert await async_subtensor.subnets.register_subnet(alice_wallet, True, True), ( + assert await async_subtensor.subnets.register_subnet(alice_wallet), ( "Unable to register the subnet" ) diff --git a/tests/helpers/helpers.py b/tests/helpers/helpers.py index eccf716811..6f94196273 100644 --- a/tests/helpers/helpers.py +++ b/tests/helpers/helpers.py @@ -84,7 +84,7 @@ def assert_submit_signed_extrinsic( call_params: Optional[dict] = None, era: Optional[dict] = None, nonce: Optional[int] = None, - wait_for_inclusion: bool = False, + wait_for_inclusion: bool = True, wait_for_finalization: bool = True, ): substrate.compose_call.assert_called_with( diff --git a/tests/unit_tests/extrinsics/asyncex/test_children.py b/tests/unit_tests/extrinsics/asyncex/test_children.py index da107dfad4..48c0940170 100644 --- a/tests/unit_tests/extrinsics/asyncex/test_children.py +++ b/tests/unit_tests/extrinsics/asyncex/test_children.py @@ -50,10 +50,10 @@ async def test_set_children_extrinsic(subtensor, mocker, fake_wallet): mocked_sign_and_send_extrinsic.assert_awaited_once_with( call=substrate.compose_call.return_value, wallet=fake_wallet, - wait_for_inclusion=True, - wait_for_finalization=False, period=None, raise_error=False, + wait_for_inclusion=True, + wait_for_finalization=True, ) assert success is True @@ -86,9 +86,10 @@ async def test_root_set_pending_childkey_cooldown_extrinsic( mocked_sign_and_send_extrinsic.assert_awaited_once_with( call=substrate.compose_call.return_value, wallet=fake_wallet, - wait_for_inclusion=True, - wait_for_finalization=False, period=None, + raise_error=False, + wait_for_inclusion=True, + wait_for_finalization=True, ) assert success is True assert "Success" in message diff --git a/tests/unit_tests/extrinsics/asyncex/test_commit_reveal.py b/tests/unit_tests/extrinsics/asyncex/test_commit_reveal.py index 7b2a74aeb9..7e46e436be 100644 --- a/tests/unit_tests/extrinsics/asyncex/test_commit_reveal.py +++ b/tests/unit_tests/extrinsics/asyncex/test_commit_reveal.py @@ -121,6 +121,7 @@ async def test_commit_reveal_v3_extrinsic_success_with_torch( wait_for_finalization=True, sign_with="hotkey", period=None, + raise_error=False, ) @@ -176,6 +177,7 @@ async def test_commit_reveal_v3_extrinsic_success_with_numpy( wait_for_finalization=False, sign_with="hotkey", period=None, + raise_error=False, ) @@ -234,6 +236,7 @@ async def test_commit_reveal_v3_extrinsic_response_false( wait_for_finalization=True, sign_with="hotkey", period=None, + raise_error=False, ) diff --git a/tests/unit_tests/extrinsics/asyncex/test_liquidity.py b/tests/unit_tests/extrinsics/asyncex/test_liquidity.py index ae780e6c4b..c572a518a9 100644 --- a/tests/unit_tests/extrinsics/asyncex/test_liquidity.py +++ b/tests/unit_tests/extrinsics/asyncex/test_liquidity.py @@ -43,9 +43,10 @@ async def test_add_liquidity_extrinsic(subtensor, fake_wallet, mocker): call=mocked_compose_call.return_value, wallet=fake_wallet, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, use_nonce=True, period=None, + raise_error=False, ) assert result == mocked_sign_and_send_extrinsic.return_value @@ -87,9 +88,10 @@ async def test_modify_liquidity_extrinsic(subtensor, fake_wallet, mocker): call=mocked_compose_call.return_value, wallet=fake_wallet, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, use_nonce=True, period=None, + raise_error=False, ) assert result == mocked_sign_and_send_extrinsic.return_value @@ -128,9 +130,10 @@ async def test_remove_liquidity_extrinsic(subtensor, fake_wallet, mocker): call=mocked_compose_call.return_value, wallet=fake_wallet, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, use_nonce=True, period=None, + raise_error=False, ) assert result == mocked_sign_and_send_extrinsic.return_value @@ -168,7 +171,8 @@ async def test_toggle_user_liquidity_extrinsic(subtensor, fake_wallet, mocker): call=mocked_compose_call.return_value, wallet=fake_wallet, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, period=None, + raise_error=False, ) assert result == mocked_sign_and_send_extrinsic.return_value diff --git a/tests/unit_tests/extrinsics/asyncex/test_registration.py b/tests/unit_tests/extrinsics/asyncex/test_registration.py index 181394a8bb..03f00aab82 100644 --- a/tests/unit_tests/extrinsics/asyncex/test_registration.py +++ b/tests/unit_tests/extrinsics/asyncex/test_registration.py @@ -59,6 +59,7 @@ async def test_register_extrinsic_success(subtensor, fake_wallet, mocker): wait_for_inclusion=True, wait_for_finalization=True, period=None, + raise_error=False, ) mocked_is_hotkey_registered.assert_called_once_with( netuid=1, hotkey_ss58="hotkey_ss58" @@ -124,6 +125,7 @@ async def test_register_extrinsic_success_with_cuda(subtensor, fake_wallet, mock wait_for_inclusion=True, wait_for_finalization=True, period=None, + raise_error=False, ) mocked_is_hotkey_registered.assert_called_once_with( netuid=1, hotkey_ss58="hotkey_ss58" @@ -281,6 +283,7 @@ async def is_stale_side_effect(*_, **__): wait_for_inclusion=True, wait_for_finalization=True, period=None, + raise_error=False, ) assert result is False @@ -342,9 +345,10 @@ async def test_set_subnet_identity_extrinsic_is_success(subtensor, fake_wallet, mocked_sign_and_send_extrinsic.assert_awaited_once_with( call=mocked_compose_call.return_value, wallet=fake_wallet, - wait_for_inclusion=False, + wait_for_inclusion=True, wait_for_finalization=True, period=None, + raise_error=False, ) assert result == (True, "Identities for subnet 123 are set.") @@ -413,6 +417,7 @@ async def test_set_subnet_identity_extrinsic_is_failed(subtensor, fake_wallet, m wait_for_inclusion=True, wait_for_finalization=True, period=None, + raise_error=False, ) assert result == ( diff --git a/tests/unit_tests/extrinsics/asyncex/test_start_call.py b/tests/unit_tests/extrinsics/asyncex/test_start_call.py index d99295195e..68507acbd2 100644 --- a/tests/unit_tests/extrinsics/asyncex/test_start_call.py +++ b/tests/unit_tests/extrinsics/asyncex/test_start_call.py @@ -36,6 +36,7 @@ async def test_start_call_extrinsics(subtensor, mocker, fake_wallet): wait_for_inclusion=True, wait_for_finalization=False, period=None, + raise_error=False, ) assert success is True diff --git a/tests/unit_tests/extrinsics/asyncex/test_transfer.py b/tests/unit_tests/extrinsics/asyncex/test_transfer.py index a755c8c894..3992fa33bb 100644 --- a/tests/unit_tests/extrinsics/asyncex/test_transfer.py +++ b/tests/unit_tests/extrinsics/asyncex/test_transfer.py @@ -68,6 +68,7 @@ async def test_transfer_extrinsic_success(subtensor, fake_wallet, mocker): wait_for_inclusion=True, wait_for_finalization=True, period=None, + raise_error=False, ) assert result is True @@ -140,6 +141,7 @@ async def test_transfer_extrinsic_call_successful_with_failed_response( wait_for_inclusion=True, wait_for_finalization=True, period=None, + raise_error=False, ) assert result is False diff --git a/tests/unit_tests/extrinsics/asyncex/test_unstaking.py b/tests/unit_tests/extrinsics/asyncex/test_unstaking.py index 24857e0261..2f70f9bc68 100644 --- a/tests/unit_tests/extrinsics/asyncex/test_unstaking.py +++ b/tests/unit_tests/extrinsics/asyncex/test_unstaking.py @@ -59,6 +59,7 @@ async def test_unstake_extrinsic(fake_wallet, mocker): nonce_key="coldkeypub", use_nonce=True, period=None, + raise_error=False, ) @@ -100,11 +101,12 @@ async def test_unstake_all_extrinsic(fake_wallet, mocker): call=fake_substrate.compose_call.return_value, wallet=fake_wallet, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, sign_with="coldkey", nonce_key="coldkeypub", use_nonce=True, period=None, + raise_error=False, ) @@ -177,4 +179,5 @@ async def test_unstake_multiple_extrinsic(fake_wallet, mocker): nonce_key="coldkeypub", use_nonce=True, period=None, + raise_error=False, ) diff --git a/tests/unit_tests/extrinsics/test_children.py b/tests/unit_tests/extrinsics/test_children.py index 2af3517fff..12bb96f09b 100644 --- a/tests/unit_tests/extrinsics/test_children.py +++ b/tests/unit_tests/extrinsics/test_children.py @@ -46,10 +46,10 @@ def test_set_children_extrinsic(subtensor, mocker, fake_wallet): mocked_sign_and_send_extrinsic.assert_called_once_with( call=subtensor.substrate.compose_call.return_value, wallet=fake_wallet, - wait_for_inclusion=True, - wait_for_finalization=False, period=None, raise_error=False, + wait_for_inclusion=True, + wait_for_finalization=True, ) assert success is True @@ -78,9 +78,10 @@ def test_root_set_pending_childkey_cooldown_extrinsic(subtensor, mocker, fake_wa mocked_sign_and_send_extrinsic.assert_called_once_with( call=subtensor.substrate.compose_call.return_value, wallet=fake_wallet, + period=None, + raise_error=False, wait_for_inclusion=True, wait_for_finalization=False, - period=None, ) assert success is True assert "Success" in message diff --git a/tests/unit_tests/extrinsics/test_commit_reveal.py b/tests/unit_tests/extrinsics/test_commit_reveal.py index b0c2da977c..92dc926f51 100644 --- a/tests/unit_tests/extrinsics/test_commit_reveal.py +++ b/tests/unit_tests/extrinsics/test_commit_reveal.py @@ -119,6 +119,7 @@ def test_commit_reveal_v3_extrinsic_success_with_torch( wait_for_finalization=True, sign_with="hotkey", period=None, + raise_error=False, ) @@ -173,6 +174,7 @@ def test_commit_reveal_v3_extrinsic_success_with_numpy( wait_for_finalization=False, sign_with="hotkey", period=None, + raise_error=False, ) @@ -230,6 +232,7 @@ def test_commit_reveal_v3_extrinsic_response_false( wait_for_finalization=True, sign_with="hotkey", period=None, + raise_error=False, ) @@ -246,15 +249,12 @@ def test_commit_reveal_v3_extrinsic_exception(mocker, subtensor, fake_wallet): side_effect=Exception("Test Error"), ) - # Call - success, message = commit_reveal.commit_reveal_extrinsic( - subtensor=subtensor, - wallet=fake_wallet, - netuid=fake_netuid, - uids=fake_uids, - weights=fake_weights, - ) - - # Asserts - assert success is False - assert "Test Error" in message + # Call + Asserts + with pytest.raises(Exception): + commit_reveal.commit_reveal_extrinsic( + subtensor=subtensor, + wallet=fake_wallet, + netuid=fake_netuid, + uids=fake_uids, + weights=fake_weights, + ) diff --git a/tests/unit_tests/extrinsics/test_liquidity.py b/tests/unit_tests/extrinsics/test_liquidity.py index 7d3942909e..ce60b34bd3 100644 --- a/tests/unit_tests/extrinsics/test_liquidity.py +++ b/tests/unit_tests/extrinsics/test_liquidity.py @@ -41,9 +41,10 @@ def test_add_liquidity_extrinsic(subtensor, fake_wallet, mocker): call=mocked_compose_call.return_value, wallet=fake_wallet, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, use_nonce=True, period=None, + raise_error=False, ) assert result == mocked_sign_and_send_extrinsic.return_value @@ -84,9 +85,10 @@ def test_modify_liquidity_extrinsic(subtensor, fake_wallet, mocker): call=mocked_compose_call.return_value, wallet=fake_wallet, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, use_nonce=True, period=None, + raise_error=False, ) assert result == mocked_sign_and_send_extrinsic.return_value @@ -124,9 +126,10 @@ def test_remove_liquidity_extrinsic(subtensor, fake_wallet, mocker): call=mocked_compose_call.return_value, wallet=fake_wallet, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, use_nonce=True, period=None, + raise_error=False, ) assert result == mocked_sign_and_send_extrinsic.return_value @@ -163,7 +166,8 @@ def test_toggle_user_liquidity_extrinsic(subtensor, fake_wallet, mocker): call=mocked_compose_call.return_value, wallet=fake_wallet, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, period=None, + raise_error=False, ) assert result == mocked_sign_and_send_extrinsic.return_value diff --git a/tests/unit_tests/extrinsics/test_registration.py b/tests/unit_tests/extrinsics/test_registration.py index 97b0fb785f..796c3d45f0 100644 --- a/tests/unit_tests/extrinsics/test_registration.py +++ b/tests/unit_tests/extrinsics/test_registration.py @@ -270,9 +270,10 @@ def test_set_subnet_identity_extrinsic_is_success(mock_subtensor, mock_wallet, m mocked_sign_and_send_extrinsic.assert_called_once_with( call=mocked_compose_call.return_value, wallet=mock_wallet, - wait_for_inclusion=False, + wait_for_inclusion=True, wait_for_finalization=True, period=None, + raise_error=False, ) assert result == (True, "Identities for subnet 123 are set.") @@ -335,9 +336,10 @@ def test_set_subnet_identity_extrinsic_is_failed(mock_subtensor, mock_wallet, mo mocked_sign_and_send_extrinsic.assert_called_once_with( call=mocked_compose_call.return_value, wallet=mock_wallet, - wait_for_inclusion=False, + wait_for_inclusion=True, wait_for_finalization=True, period=None, + raise_error=False, ) assert result == ( diff --git a/tests/unit_tests/extrinsics/test_root.py b/tests/unit_tests/extrinsics/test_root.py index 5a16a10909..4a4c11e8e8 100644 --- a/tests/unit_tests/extrinsics/test_root.py +++ b/tests/unit_tests/extrinsics/test_root.py @@ -104,6 +104,7 @@ def test_root_register_extrinsic( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=None, + raise_error=False, ) diff --git a/tests/unit_tests/extrinsics/test_serving.py b/tests/unit_tests/extrinsics/test_serving.py index 7095ea0bc1..3964df1cd2 100644 --- a/tests/unit_tests/extrinsics/test_serving.py +++ b/tests/unit_tests/extrinsics/test_serving.py @@ -110,20 +110,22 @@ def test_serve_extrinsic_happy_path( test_id, mocker, ): - # Arrange - serving.do_serve_axon = mocker.MagicMock(return_value=(True, "")) - # Act + # Prep + mocker.patch.object( + mock_subtensor, "sign_and_send_extrinsic", return_value=(True, "") + ) + # Call result = serving.serve_extrinsic( - mock_subtensor, - mock_wallet, - ip, - port, - protocol, - netuid, - placeholder1, - placeholder2, - wait_for_inclusion, - wait_for_finalization, + subtensor=mock_subtensor, + wallet=mock_wallet, + ip=ip, + port=port, + protocol=protocol, + netuid=netuid, + placeholder1=placeholder1, + placeholder2=placeholder2, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) # Assert @@ -164,20 +166,23 @@ def test_serve_extrinsic_edge_cases( test_id, mocker, ): - # Arrange - serving.do_serve_axon = mocker.MagicMock(return_value=(True, "")) - # Act + # Prep + mocker.patch.object( + mock_subtensor, "sign_and_send_extrinsic", return_value=(True, "") + ) + + # Call result = serving.serve_extrinsic( - mock_subtensor, - mock_wallet, - ip, - port, - protocol, - netuid, - placeholder1, - placeholder2, - wait_for_inclusion, - wait_for_finalization, + subtensor=mock_subtensor, + wallet=mock_wallet, + ip=ip, + port=port, + protocol=protocol, + netuid=netuid, + placeholder1=placeholder1, + placeholder2=placeholder2, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) # Assert @@ -218,20 +223,22 @@ def test_serve_extrinsic_error_cases( test_id, mocker, ): - # Arrange - serving.do_serve_axon = mocker.MagicMock(return_value=(False, "Error serving axon")) - # Act + # Prep + mocker.patch.object( + mock_subtensor, "sign_and_send_extrinsic", return_value=(False, "") + ) + # Call result = serving.serve_extrinsic( - mock_subtensor, - mock_wallet, - ip, - port, - protocol, - netuid, - placeholder1, - placeholder2, - wait_for_inclusion, - wait_for_finalization, + subtensor=mock_subtensor, + wallet=mock_wallet, + ip=ip, + port=port, + protocol=protocol, + netuid=netuid, + placeholder1=placeholder1, + placeholder2=placeholder2, + wait_for_inclusion=wait_for_inclusion, + wait_for_finalization=wait_for_finalization, ) # Assert @@ -281,29 +288,32 @@ def test_serve_axon_extrinsic( mocker, ): mock_axon.external_ip = external_ip - # Arrange + # Preps with patch( "bittensor.utils.networking.get_external_ip", side_effect=Exception("Failed to fetch IP") if not external_ip_success else MagicMock(return_value="192.168.1.1"), ): - serving.do_serve_axon = mocker.MagicMock(return_value=(serve_success, "")) - # Act + mocker.patch.object( + mock_subtensor, "sign_and_send_extrinsic", return_value=(serve_success, "") + ) + + # Calls if not external_ip_success: with pytest.raises(ConnectionError): serving.serve_axon_extrinsic( - mock_subtensor, - netuid, - mock_axon, + subtensor=mock_subtensor, + netuid=netuid, + axon=mock_axon, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, ) else: result = serving.serve_axon_extrinsic( - mock_subtensor, - netuid, - mock_axon, + subtensor=mock_subtensor, + netuid=netuid, + axon=mock_axon, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, ) @@ -376,4 +386,5 @@ def test_publish_metadata( wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, period=None, + raise_error=False, ) diff --git a/tests/unit_tests/extrinsics/test_staking.py b/tests/unit_tests/extrinsics/test_staking.py index 80ecb5c240..9ba6fe71a6 100644 --- a/tests/unit_tests/extrinsics/test_staking.py +++ b/tests/unit_tests/extrinsics/test_staking.py @@ -52,6 +52,7 @@ def test_add_stake_extrinsic(mocker): sign_with="coldkey", use_nonce=True, period=None, + raise_error=False, ) @@ -134,10 +135,11 @@ def test_add_stake_multiple_extrinsic(mocker): fake_subtensor.sign_and_send_extrinsic.assert_called_with( call=fake_subtensor.substrate.compose_call.return_value, wallet=fake_wallet_, - wait_for_inclusion=True, - wait_for_finalization=True, nonce_key="coldkeypub", sign_with="coldkey", use_nonce=True, period=None, + raise_error=False, + wait_for_inclusion=True, + wait_for_finalization=True, ) diff --git a/tests/unit_tests/extrinsics/test_start_call.py b/tests/unit_tests/extrinsics/test_start_call.py index ece0e6cf42..03373fa955 100644 --- a/tests/unit_tests/extrinsics/test_start_call.py +++ b/tests/unit_tests/extrinsics/test_start_call.py @@ -34,6 +34,7 @@ def test_start_call_extrinsics(subtensor, mocker, fake_wallet): wait_for_inclusion=True, wait_for_finalization=False, period=None, + raise_error=False, ) assert success is True diff --git a/tests/unit_tests/extrinsics/test_transfer.py b/tests/unit_tests/extrinsics/test_transfer.py index b4ceee33f8..b885977de8 100644 --- a/tests/unit_tests/extrinsics/test_transfer.py +++ b/tests/unit_tests/extrinsics/test_transfer.py @@ -67,6 +67,7 @@ def test_transfer_extrinsic_success(subtensor, fake_wallet, mocker): wait_for_inclusion=True, wait_for_finalization=True, period=None, + raise_error=False, ) assert result is True @@ -137,6 +138,7 @@ def test_transfer_extrinsic_call_successful_with_failed_response( wait_for_inclusion=True, wait_for_finalization=True, period=None, + raise_error=False, ) assert result is False diff --git a/tests/unit_tests/extrinsics/test_unstaking.py b/tests/unit_tests/extrinsics/test_unstaking.py index 69e020854f..f4719cdbb2 100644 --- a/tests/unit_tests/extrinsics/test_unstaking.py +++ b/tests/unit_tests/extrinsics/test_unstaking.py @@ -55,6 +55,7 @@ def test_unstake_extrinsic(fake_wallet, mocker): nonce_key="coldkeypub", use_nonce=True, period=None, + raise_error=False, ) @@ -95,11 +96,12 @@ def test_unstake_all_extrinsic(fake_wallet, mocker): call=fake_subtensor.substrate.compose_call.return_value, wallet=fake_wallet, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, sign_with="coldkey", nonce_key="coldkeypub", use_nonce=True, period=None, + raise_error=False, ) @@ -171,4 +173,5 @@ def test_unstake_multiple_extrinsic(fake_wallet, mocker): nonce_key="coldkeypub", use_nonce=True, period=None, + raise_error=False, ) diff --git a/tests/unit_tests/test_async_subtensor.py b/tests/unit_tests/test_async_subtensor.py index d75c5c3604..28decac35a 100644 --- a/tests/unit_tests/test_async_subtensor.py +++ b/tests/unit_tests/test_async_subtensor.py @@ -203,7 +203,7 @@ async def test_burned_register(mock_substrate, subtensor, fake_wallet, mocker): "hotkey": fake_wallet.hotkey.ss58_address, }, wait_for_finalization=True, - wait_for_inclusion=False, + wait_for_inclusion=True, ) @@ -244,7 +244,7 @@ async def test_burned_register_on_root(mock_substrate, subtensor, fake_wallet, m "hotkey": fake_wallet.hotkey.ss58_address, }, wait_for_finalization=True, - wait_for_inclusion=False, + wait_for_inclusion=True, ) @@ -2604,6 +2604,7 @@ async def test_transfer_success(subtensor, fake_wallet, mocker): wait_for_finalization=False, keep_alive=True, period=None, + raise_error=False, ) assert result == mocked_transfer_extrinsic.return_value @@ -2624,6 +2625,7 @@ async def test_register_success(subtensor, fake_wallet, mocker): # Asserts mocked_register_extrinsic.assert_awaited_once_with( + wallet=fake_wallet, cuda=False, dev_id=0, log_verbose=False, @@ -2634,10 +2636,10 @@ async def test_register_success(subtensor, fake_wallet, mocker): subtensor=subtensor, tpb=256, update_interval=None, - wait_for_finalization=True, - wait_for_inclusion=False, - wallet=fake_wallet, period=None, + raise_error=False, + wait_for_finalization=True, + wait_for_inclusion=True, ) assert result == mocked_register_extrinsic.return_value @@ -2799,10 +2801,11 @@ async def test_set_weights_success(subtensor, fake_wallet, mocker): netuid=fake_netuid, uids=fake_uids, version_key=async_subtensor.version_as_int, - wait_for_finalization=False, - wait_for_inclusion=False, + wait_for_finalization=True, + wait_for_inclusion=True, weights=fake_weights, period=8, + raise_error=True, ) mocked_weights_rate_limit.assert_called_once_with(fake_netuid) assert result is True @@ -3002,9 +3005,10 @@ async def test_set_subnet_identity(mocker, subtensor, fake_wallet): discord=fake_subnet_identity.discord, description=fake_subnet_identity.description, additional=fake_subnet_identity.additional, - wait_for_finalization=True, - wait_for_inclusion=False, period=None, + raise_error=False, + wait_for_finalization=True, + wait_for_inclusion=True, ) assert result == mocked_extrinsic.return_value @@ -3111,6 +3115,7 @@ async def test_start_call(subtensor, mocker): wait_for_inclusion=True, wait_for_finalization=False, period=None, + raise_error=False, ) assert result == mocked_extrinsic.return_value @@ -3475,8 +3480,9 @@ async def test_unstake_all(subtensor, fake_wallet, mocker): netuid=1, rate_tolerance=0.005, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, period=None, + raise_error=False, ) assert result == fake_unstake_all_extrinsic.return_value @@ -3698,8 +3704,9 @@ async def test_add_liquidity(subtensor, fake_wallet, mocker): price_high=Balance.from_tao(130).rao, hotkey=None, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, period=None, + raise_error=False, ) assert result == mocked_extrinsic.return_value @@ -3731,8 +3738,9 @@ async def test_modify_liquidity(subtensor, fake_wallet, mocker): liquidity_delta=Balance.from_tao(150), hotkey=None, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, period=None, + raise_error=False, ) assert result == mocked_extrinsic.return_value @@ -3762,8 +3770,9 @@ async def test_remove_liquidity(subtensor, fake_wallet, mocker): position_id=position_id, hotkey=None, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, period=None, + raise_error=False, ) assert result == mocked_extrinsic.return_value @@ -3792,8 +3801,9 @@ async def test_toggle_user_liquidity(subtensor, fake_wallet, mocker): netuid=netuid, enable=enable, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, period=None, + raise_error=False, ) assert result == mocked_extrinsic.return_value diff --git a/tests/unit_tests/test_subtensor.py b/tests/unit_tests/test_subtensor.py index 76a211b782..a8882e9897 100644 --- a/tests/unit_tests/test_subtensor.py +++ b/tests/unit_tests/test_subtensor.py @@ -15,7 +15,6 @@ from bittensor.core.async_subtensor import AsyncSubtensor, logging from bittensor.core.axon import Axon from bittensor.core.chain_data import SubnetHyperparameters, SelectiveMetagraphIndex -from bittensor.core.extrinsics.serving import do_serve_axon from bittensor.core.settings import version_as_int from bittensor.core.subtensor import Subtensor from bittensor.core.types import AxonServeCallParams @@ -1203,6 +1202,7 @@ def test_set_weights(subtensor, mocker, fake_wallet): wait_for_inclusion=fake_wait_for_inclusion, wait_for_finalization=fake_wait_for_finalization, period=8, + raise_error=True, ) assert result == expected_result @@ -1222,7 +1222,10 @@ def test_serve_axon(subtensor, mocker): # Call result = subtensor.serve_axon( - fake_netuid, fake_axon, fake_wait_for_inclusion, fake_wait_for_finalization + netuid=fake_netuid, + axon=fake_axon, + wait_for_inclusion=fake_wait_for_inclusion, + wait_for_finalization=fake_wait_for_finalization, ) # Asserts @@ -1230,10 +1233,11 @@ def test_serve_axon(subtensor, mocker): subtensor=subtensor, netuid=fake_netuid, axon=fake_axon, - wait_for_inclusion=fake_wait_for_inclusion, - wait_for_finalization=fake_wait_for_finalization, certificate=fake_certificate, period=None, + raise_error=False, + wait_for_inclusion=fake_wait_for_inclusion, + wait_for_finalization=fake_wait_for_finalization, ) assert result == mocked_serve_axon_extrinsic.return_value @@ -1259,7 +1263,7 @@ def test_commit(subtensor, fake_wallet, mocker): mocked_publish_metadata = mocker.patch.object(subtensor_module, "publish_metadata") # Call - result = subtensor.commit(fake_wallet, fake_netuid, fake_data) + result = subtensor.set_commitment(fake_wallet, fake_netuid, fake_data) # Asserts mocked_publish_metadata.assert_called_once_with( @@ -1269,6 +1273,9 @@ def test_commit(subtensor, fake_wallet, mocker): data_type=f"Raw{len(fake_data)}", data=fake_data.encode(), period=None, + raise_error=False, + wait_for_inclusion=True, + wait_for_finalization=True, ) assert result is mocked_publish_metadata.return_value @@ -1327,6 +1334,7 @@ def test_transfer(subtensor, fake_wallet, mocker): wait_for_finalization=fake_wait_for_finalization, keep_alive=True, period=None, + raise_error=False, ) assert result == mocked_transfer_extrinsic.return_value @@ -1453,128 +1461,6 @@ def test_neuron_for_uid_success(subtensor, mocker): assert result == mocked_neuron_from_dict.return_value -@pytest.mark.parametrize( - ["fake_call_params", "expected_call_function"], - [ - (call_params(), "serve_axon"), - (call_params_with_certificate(), "serve_axon_tls"), - ], -) -def test_do_serve_axon_is_success( - subtensor, fake_wallet, mocker, fake_call_params, expected_call_function -): - """Successful do_serve_axon call.""" - # Prep - fake_wait_for_inclusion = True - fake_wait_for_finalization = True - - mocker.patch.object(subtensor, "sign_and_send_extrinsic", return_value=(True, "")) - - # Call - result = do_serve_axon( - subtensor=subtensor, - wallet=fake_wallet, - call_params=fake_call_params, - wait_for_inclusion=fake_wait_for_inclusion, - wait_for_finalization=fake_wait_for_finalization, - ) - - # Asserts - subtensor.substrate.compose_call.assert_called_once_with( - call_module="SubtensorModule", - call_function=expected_call_function, - call_params=fake_call_params, - ) - - subtensor.sign_and_send_extrinsic.assert_called_once_with( - call=subtensor.substrate.compose_call.return_value, - wallet=fake_wallet, - wait_for_inclusion=fake_wait_for_inclusion, - wait_for_finalization=fake_wait_for_finalization, - sign_with="hotkey", - period=None, - ) - - assert result[0] is True - assert result[1] == "" - - -def test_do_serve_axon_is_not_success(subtensor, fake_wallet, mocker, fake_call_params): - """Unsuccessful do_serve_axon call.""" - # Prep - fake_wait_for_inclusion = True - fake_wait_for_finalization = True - - mocker.patch.object( - subtensor, "sign_and_send_extrinsic", return_value=(False, None) - ) - - # Call - result = do_serve_axon( - subtensor=subtensor, - wallet=fake_wallet, - call_params=fake_call_params, - wait_for_inclusion=fake_wait_for_inclusion, - wait_for_finalization=fake_wait_for_finalization, - ) - - # Asserts - subtensor.substrate.compose_call.assert_called_once_with( - call_module="SubtensorModule", - call_function="serve_axon", - call_params=fake_call_params, - ) - - subtensor.sign_and_send_extrinsic.assert_called_once_with( - call=subtensor.substrate.compose_call.return_value, - wallet=fake_wallet, - wait_for_inclusion=fake_wait_for_inclusion, - wait_for_finalization=fake_wait_for_finalization, - sign_with="hotkey", - period=None, - ) - - assert result == (False, None) - - -def test_do_serve_axon_no_waits(subtensor, fake_wallet, mocker, fake_call_params): - """Unsuccessful do_serve_axon call.""" - # Prep - fake_wait_for_inclusion = False - fake_wait_for_finalization = False - - mocked_sign_and_send_extrinsic = mocker.Mock(return_value=(True, "")) - mocker.patch.object( - subtensor, "sign_and_send_extrinsic", new=mocked_sign_and_send_extrinsic - ) - - # Call - result = do_serve_axon( - subtensor=subtensor, - wallet=fake_wallet, - call_params=fake_call_params, - wait_for_inclusion=fake_wait_for_inclusion, - wait_for_finalization=fake_wait_for_finalization, - ) - - # Asserts - subtensor.substrate.compose_call.assert_called_once_with( - call_module="SubtensorModule", - call_function="serve_axon", - call_params=fake_call_params, - ) - - mocked_sign_and_send_extrinsic.assert_called_once_with( - call=subtensor.substrate.compose_call.return_value, - wallet=fake_wallet, - wait_for_inclusion=fake_wait_for_inclusion, - wait_for_finalization=fake_wait_for_finalization, - sign_with="hotkey", - period=None, - ) - assert result == (True, "") - - def test_immunity_period(subtensor, mocker): """Successful immunity_period call.""" # Preps @@ -2831,7 +2717,8 @@ def test_add_stake_success(mocker, fake_wallet, subtensor): """Test add_stake returns True on successful staking.""" # Prep fake_hotkey_ss58 = "fake_hotkey" - fake_amount = 10.0 + fake_amount = Balance.from_tao(10.0) + fake_netuid = 14 mock_add_stake_extrinsic = mocker.patch.object( subtensor_module, "add_stake_extrinsic" @@ -2840,6 +2727,7 @@ def test_add_stake_success(mocker, fake_wallet, subtensor): # Call result = subtensor.add_stake( wallet=fake_wallet, + netuid=fake_netuid, hotkey_ss58=fake_hotkey_ss58, amount=fake_amount, wait_for_inclusion=True, @@ -2854,14 +2742,15 @@ def test_add_stake_success(mocker, fake_wallet, subtensor): subtensor=subtensor, wallet=fake_wallet, hotkey_ss58=fake_hotkey_ss58, - netuid=None, - amount=Balance.from_rao(fake_amount), + netuid=14, + amount=fake_amount.rao, wait_for_inclusion=True, wait_for_finalization=False, safe_staking=False, allow_partial_stake=False, rate_tolerance=0.005, period=None, + raise_error=False, ) assert result == mock_add_stake_extrinsic.return_value @@ -2869,8 +2758,9 @@ def test_add_stake_success(mocker, fake_wallet, subtensor): def test_add_stake_with_safe_staking(mocker, fake_wallet, subtensor): """Test add_stake with safe staking parameters enabled.""" # Prep + fake_netuid = 14 fake_hotkey_ss58 = "fake_hotkey" - fake_amount = 10.0 + fake_amount = Balance.from_tao(10.0) fake_rate_tolerance = 0.01 # 1% threshold mock_add_stake_extrinsic = mocker.patch.object( @@ -2880,6 +2770,7 @@ def test_add_stake_with_safe_staking(mocker, fake_wallet, subtensor): # Call result = subtensor.add_stake( wallet=fake_wallet, + netuid=fake_netuid, hotkey_ss58=fake_hotkey_ss58, amount=fake_amount, wait_for_inclusion=True, @@ -2894,14 +2785,15 @@ def test_add_stake_with_safe_staking(mocker, fake_wallet, subtensor): subtensor=subtensor, wallet=fake_wallet, hotkey_ss58=fake_hotkey_ss58, - netuid=None, - amount=Balance.from_rao(fake_amount), + netuid=14, + amount=fake_amount.rao, wait_for_inclusion=True, wait_for_finalization=False, safe_staking=True, allow_partial_stake=False, rate_tolerance=fake_rate_tolerance, period=None, + raise_error=False, ) assert result == mock_add_stake_extrinsic.return_value @@ -2936,6 +2828,7 @@ def test_add_stake_multiple_success(mocker, fake_wallet, subtensor): wait_for_inclusion=True, wait_for_finalization=False, period=None, + raise_error=False, ) assert result == mock_add_stake_multiple_extrinsic.return_value @@ -2944,6 +2837,7 @@ def test_unstake_success(mocker, subtensor, fake_wallet): """Test unstake operation is successful.""" # Preps fake_hotkey_ss58 = "hotkey_1" + fake_netuid = 1 fake_amount = 10.0 mock_unstake_extrinsic = mocker.patch.object(subtensor_module, "unstake_extrinsic") @@ -2951,11 +2845,12 @@ def test_unstake_success(mocker, subtensor, fake_wallet): # Call result = subtensor.unstake( wallet=fake_wallet, + netuid=fake_netuid, hotkey_ss58=fake_hotkey_ss58, amount=fake_amount, wait_for_inclusion=True, wait_for_finalization=False, - safe_staking=False, + safe_unstaking=False, allow_partial_stake=False, rate_tolerance=0.005, ) @@ -2964,24 +2859,25 @@ def test_unstake_success(mocker, subtensor, fake_wallet): mock_unstake_extrinsic.assert_called_once_with( subtensor=subtensor, wallet=fake_wallet, + netuid=fake_netuid, hotkey_ss58=fake_hotkey_ss58, - netuid=None, amount=Balance.from_rao(fake_amount), - wait_for_inclusion=True, - wait_for_finalization=False, - safe_staking=False, + safe_unstaking=False, allow_partial_stake=False, rate_tolerance=0.005, period=None, - unstake_all=False, + wait_for_inclusion=True, + wait_for_finalization=False, + raise_error=False, ) assert result == mock_unstake_extrinsic.return_value -def test_unstake_with_safe_staking(mocker, subtensor, fake_wallet): - """Test unstake with safe staking parameters enabled.""" +def test_unstake_with_safe_unstaking(mocker, subtensor, fake_wallet): + """Test unstake with `safe_unstaking` parameters enabled.""" fake_hotkey_ss58 = "hotkey_1" fake_amount = 10.0 + fake_netuid = 14 fake_rate_tolerance = 0.01 # 1% threshold mock_unstake_extrinsic = mocker.patch.object(subtensor_module, "unstake_extrinsic") @@ -2989,11 +2885,12 @@ def test_unstake_with_safe_staking(mocker, subtensor, fake_wallet): # Call result = subtensor.unstake( wallet=fake_wallet, + netuid=fake_netuid, hotkey_ss58=fake_hotkey_ss58, amount=fake_amount, wait_for_inclusion=True, wait_for_finalization=False, - safe_staking=True, + safe_unstaking=True, allow_partial_stake=True, rate_tolerance=fake_rate_tolerance, ) @@ -3002,16 +2899,16 @@ def test_unstake_with_safe_staking(mocker, subtensor, fake_wallet): mock_unstake_extrinsic.assert_called_once_with( subtensor=subtensor, wallet=fake_wallet, + netuid=fake_netuid, hotkey_ss58=fake_hotkey_ss58, - netuid=None, amount=Balance.from_rao(fake_amount), - wait_for_inclusion=True, - wait_for_finalization=False, - safe_staking=True, + safe_unstaking=True, allow_partial_stake=True, rate_tolerance=fake_rate_tolerance, period=None, - unstake_all=False, + raise_error=False, + wait_for_inclusion=True, + wait_for_finalization=False, ) assert result == mock_unstake_extrinsic.return_value @@ -3037,7 +2934,7 @@ def test_swap_stake_success(mocker, subtensor, fake_wallet): amount=fake_amount, wait_for_inclusion=True, wait_for_finalization=False, - safe_staking=False, + safe_swapping=False, allow_partial_stake=False, rate_tolerance=0.005, ) @@ -3052,10 +2949,11 @@ def test_swap_stake_success(mocker, subtensor, fake_wallet): amount=Balance.from_rao(fake_amount), wait_for_inclusion=True, wait_for_finalization=False, - safe_staking=False, + safe_swapping=False, allow_partial_stake=False, rate_tolerance=0.005, period=None, + raise_error=False, ) assert result == mock_swap_stake_extrinsic.return_value @@ -3082,7 +2980,7 @@ def test_swap_stake_with_safe_staking(mocker, subtensor, fake_wallet): amount=fake_amount, wait_for_inclusion=True, wait_for_finalization=False, - safe_staking=True, + safe_swapping=True, allow_partial_stake=True, rate_tolerance=fake_rate_tolerance, ) @@ -3097,10 +2995,11 @@ def test_swap_stake_with_safe_staking(mocker, subtensor, fake_wallet): amount=Balance.from_rao(fake_amount), wait_for_inclusion=True, wait_for_finalization=False, - safe_staking=True, + safe_swapping=True, allow_partial_stake=True, rate_tolerance=fake_rate_tolerance, period=None, + raise_error=False, ) assert result == mock_swap_stake_extrinsic.return_value @@ -3136,6 +3035,7 @@ def test_unstake_multiple_success(mocker, subtensor, fake_wallet): wait_for_finalization=False, period=None, unstake_all=False, + raise_error=False, ) assert result == mock_unstake_multiple_extrinsic.return_value @@ -3180,11 +3080,13 @@ def test_set_weights_with_commit_reveal_enabled(subtensor, fake_wallet, mocker): netuid=fake_netuid, uids=fake_uids, weights=fake_weights, + commit_reveal_version=4, version_key=subtensor_module.version_as_int, wait_for_inclusion=fake_wait_for_inclusion, wait_for_finalization=fake_wait_for_finalization, block_time=12.0, period=8, + raise_error=True, ) assert result == mocked_commit_reveal_v3_extrinsic.return_value @@ -3241,9 +3143,10 @@ def test_set_subnet_identity(mocker, subtensor, fake_wallet): discord=fake_subnet_identity.discord, description=fake_subnet_identity.description, additional=fake_subnet_identity.additional, - wait_for_finalization=True, - wait_for_inclusion=False, period=None, + raise_error=False, + wait_for_finalization=True, + wait_for_inclusion=True, ) assert result == mocked_extrinsic.return_value @@ -3344,6 +3247,7 @@ def test_start_call(subtensor, mocker): wait_for_inclusion=True, wait_for_finalization=False, period=None, + raise_error=False, ) assert result == mocked_extrinsic.return_value @@ -3810,8 +3714,9 @@ def test_unstake_all(subtensor, fake_wallet, mocker): netuid=1, rate_tolerance=0.005, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, period=None, + raise_error=False, ) assert result == fake_unstake_all_extrinsic.return_value @@ -3956,8 +3861,9 @@ def test_add_liquidity(subtensor, fake_wallet, mocker): price_high=Balance.from_tao(130).rao, hotkey=None, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, period=None, + raise_error=False, ) assert result == mocked_extrinsic.return_value @@ -3988,8 +3894,9 @@ def test_modify_liquidity(subtensor, fake_wallet, mocker): liquidity_delta=Balance.from_tao(150), hotkey=None, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, period=None, + raise_error=False, ) assert result == mocked_extrinsic.return_value @@ -4018,8 +3925,9 @@ def test_remove_liquidity(subtensor, fake_wallet, mocker): position_id=position_id, hotkey=None, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, period=None, + raise_error=False, ) assert result == mocked_extrinsic.return_value @@ -4047,8 +3955,9 @@ def test_toggle_user_liquidity(subtensor, fake_wallet, mocker): netuid=netuid, enable=enable, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, period=None, + raise_error=False, ) assert result == mocked_extrinsic.return_value diff --git a/tests/unit_tests/test_subtensor_extended.py b/tests/unit_tests/test_subtensor_extended.py index 1a53e4e7ba..01a365bd31 100644 --- a/tests/unit_tests/test_subtensor_extended.py +++ b/tests/unit_tests/test_subtensor_extended.py @@ -15,6 +15,7 @@ from bittensor.utils import U16_MAX, U64_MAX from bittensor.utils.balance import Balance from tests.helpers.helpers import assert_submit_signed_extrinsic +from bittensor.core.extrinsics import move_stake @pytest.fixture @@ -199,7 +200,7 @@ def test_burned_register(mock_substrate, subtensor, fake_wallet, mocker): "hotkey": fake_wallet.hotkey.ss58_address, }, wait_for_finalization=True, - wait_for_inclusion=False, + wait_for_inclusion=True, ) @@ -236,7 +237,7 @@ def test_burned_register_on_root(mock_substrate, subtensor, fake_wallet, mocker) "hotkey": fake_wallet.hotkey.ss58_address, }, wait_for_finalization=True, - wait_for_inclusion=False, + wait_for_inclusion=True, ) @@ -695,10 +696,10 @@ def test_last_drand_round(mock_substrate, subtensor): ) def test_move_stake(mock_substrate, subtensor, fake_wallet, wait): success = subtensor.move_stake( - fake_wallet, - origin_hotkey="origin_hotkey", + wallet=fake_wallet, + origin_hotkey_ss58="origin_hotkey", origin_netuid=1, - destination_hotkey="destination_hotkey", + destination_hotkey_ss58="destination_hotkey", destination_netuid=2, amount=Balance(1), wait_for_finalization=wait, @@ -729,9 +730,9 @@ def test_move_stake_insufficient_stake(mock_substrate, subtensor, fake_wallet, m success = subtensor.move_stake( fake_wallet, - origin_hotkey="origin_hotkey", + origin_hotkey_ss58="origin_hotkey", origin_netuid=1, - destination_hotkey="destination_hotkey", + destination_hotkey_ss58="destination_hotkey", destination_netuid=2, amount=Balance(1), ) @@ -749,9 +750,9 @@ def test_move_stake_error(mock_substrate, subtensor, fake_wallet, mocker): success = subtensor.move_stake( fake_wallet, - origin_hotkey="origin_hotkey", + origin_hotkey_ss58="origin_hotkey", origin_netuid=1, - destination_hotkey="destination_hotkey", + destination_hotkey_ss58="destination_hotkey", destination_netuid=2, amount=Balance(1), ) @@ -770,7 +771,7 @@ def test_move_stake_error(mock_substrate, subtensor, fake_wallet, mocker): "destination_netuid": 2, "alpha_amount": 1, }, - wait_for_finalization=False, + wait_for_finalization=True, wait_for_inclusion=True, ) @@ -780,9 +781,9 @@ def test_move_stake_exception(mock_substrate, subtensor, fake_wallet): success = subtensor.move_stake( fake_wallet, - origin_hotkey="origin_hotkey", + origin_hotkey_ss58="origin_hotkey", origin_netuid=1, - destination_hotkey="destination_hotkey", + destination_hotkey_ss58="destination_hotkey", destination_netuid=2, amount=Balance(1), ) @@ -801,7 +802,7 @@ def test_move_stake_exception(mock_substrate, subtensor, fake_wallet): "destination_netuid": 2, "alpha_amount": 1, }, - wait_for_finalization=False, + wait_for_finalization=True, wait_for_inclusion=True, ) @@ -1085,7 +1086,7 @@ def test_swap_stake(mock_substrate, subtensor, fake_wallet, mocker): "alpha_amount": 999, }, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, ) @@ -1205,15 +1206,13 @@ def test_register_subnet(mock_substrate, subtensor, fake_wallet, mocker, success is_success=success, ) - result = subtensor.register_subnet( - fake_wallet, - ) + result = subtensor.register_subnet(fake_wallet) assert result is success assert_submit_signed_extrinsic( - mock_substrate, - fake_wallet.coldkey, + substrate=mock_substrate, + keypair=fake_wallet.coldkey, call_module="SubtensorModule", call_function="register_network", call_params={ @@ -1229,9 +1228,7 @@ def test_register_subnet_insufficient_funds( mocker.patch.object(subtensor, "get_balance", return_value=Balance(0)) mocker.patch.object(subtensor, "get_subnet_burn_cost", return_value=Balance(10)) - success = subtensor.register_subnet( - fake_wallet, - ) + success = subtensor.register_subnet(fake_wallet) assert success is False @@ -1263,8 +1260,8 @@ def test_root_register(mock_substrate, subtensor, fake_wallet, mocker): ) assert_submit_signed_extrinsic( - mock_substrate, - fake_wallet.coldkey, + substrate=mock_substrate, + keypair=fake_wallet.coldkey, call_module="SubtensorModule", call_function="root_register", call_params={ @@ -1436,7 +1433,7 @@ def test_transfer_stake_error( "destination_netuid": 1, "alpha_amount": 1, }, - wait_for_finalization=False, + wait_for_finalization=True, wait_for_inclusion=True, )