diff --git a/MIGRATION.md b/MIGRATION.md index 5065daceaf..b2228798c5 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -24,36 +24,36 @@ 9. ✅ ~~`subtensor.get_transfer_fee` calls extrinsic inside the subtensor module. Actually the method could be updated by using `bittensor.core.extrinsics.utils.get_extrinsic_fee`.~~ `get_transfer_fee` isn't `get_extrinsic_fee` ## Subtensor -1. In the synchronous Subtensor class, the `get_owned_hotkeys` method includes a `reuse_block` parameter that is inconsistent with other methods. Either remove this parameter from `get_owned_hotkeys`, or add it to all other methods that directly call self.substrate.* to maintain a consistent interface. -2. In all methods where we `get_stake_operations_fee` is called, remove unused arguments. Consider combining all methods using `get_stake_operations_fee` into one common one. -3. Delete deprecated `get_current_weight_commit_info` and `get_current_weight_commit_info_v2`. Rename `get_timelocked_weight_commits` to get_current_weight_commit_info. -4. Remove references like `get_stake_info_for_coldkey = get_stake_for_coldkey`. -5. Reconsider some methods naming across the entire subtensor module. -6. Add `hotkey_ss58` parameter to `get_liquidity_list` method. One wallet can have many HKs. Currently, the mentioned method uses default HK only. +1. ✅ In the synchronous Subtensor class, the `get_owned_hotkeys` method includes a `reuse_block` parameter that is inconsistent with other methods. Either remove this parameter from `get_owned_hotkeys`, or add it to all other methods that directly call self.substrate.* to maintain a consistent interface. +2. ✅ In all methods where we `get_stake_operations_fee` is called, remove unused arguments. Consider combining all methods using `get_stake_operations_fee` into one common one. +3. ✅ Delete deprecated `get_current_weight_commit_info` and `get_current_weight_commit_info_v2`. ~~Rename `get_timelocked_weight_commits` to `get_current_weight_commit_info`.~~ +4. ✅ Remove references like `get_stake_info_for_coldkey = get_stake_for_coldkey`. +5. ✅ Reconsider some methods naming across the entire subtensor module. +6. ~~Add `hotkey_ss58` parameter to `get_liquidity_list` method. One wallet can have many HKs. Currently, the mentioned method uses default HK only.~~ wrong idea ## Metagraph -1. Remove verbose archival node warnings for blocks older than 300. Some users complained about many messages for them. -2. Reconsider entire metagraph module logic. +1. ✅ Remove verbose archival node warnings for blocks older than 300. Some users complained about many messages for them. +2. ✅ Reconsider entire metagraph module logic. ## Balance -1. In `bittensor.utils.balance._check_currencies` raise the error instead of `warnings.warn`. -2. In `bittensor.utils.balance.check_and_convert_to_balance` raise the error instead of `warnings.warn`. +1. ✅ In `bittensor.utils.balance._check_currencies` raise the error instead of `warnings.warn`. +2. ✅ In `bittensor.utils.balance.check_and_convert_to_balance` raise the error instead of `warnings.warn`. This may seem like a harsh decision at first, but ultimately we will push the community to use Balance and there will be fewer errors in their calculations. Confusion with TAO and Alpha in calculations and display/printing/logging will be eliminated. ## Common things -1. Reduce the amount of logging.info or transfer part of logging.info to logging.debug `(in progress)` +1. ✅ Reduce the amount of logging.info or transfer part of logging.info to logging.debug -2. To be consistent across all SDK regarding local environment variables name: +2. ✅ To be consistent across all SDK regarding local environment variables name: remove `BT_CHAIN_ENDPOINT` (settings.py :line 124) and use `BT_SUBTENSOR_CHAIN_ENDPOINT` instead of that. rename this variable in documentation. -3. Move `bittensor.utils.get_transfer_fn_params` to `bittensor.core.extrinsics.utils`. +3. ✅ ~~Move `bittensor.utils.get_transfer_fn_params` to `bittensor.core.extrinsics.utils`.~~ it's on the right place. 4. ✅ Common refactoring (improve type annotations, etc) -5. Rename `non-/fast-blocks` to `non-/fast-runtime` in related places to be consistent with subtensor repo. Related with testing, subtensor scripts, documentation. +5. ✅ ~~Rename `non-/fast-blocks` to `non-/fast-runtime` in related places to be consistent with subtensor repo. Related with testing, subtensor scripts, documentation.~~ done across many PRs. -6. To be consistent throughout the SDK `(in progress)`: +6. ✅ To be consistent throughout the SDK: `hotkey`, `coldkey`, `hotkeypub`, and `coldkeypub` are keypairs `hotkey_ss58`, `coldkey_ss58`, `hotkeypub_ss58`, and `coldkeypub_ss58` are SS58 addresses of keypair. @@ -65,9 +65,9 @@ rename this variable in documentation. - [x] CRv3 extrinsics - [x] CRv3 logic related subtensor's calls -10. Revise `bittensor/utils/easy_imports.py` module to remove deprecated backwards compatibility objects. Use this module as a functionality for exporting existing objects to the package root to keep __init__.py minimal and simple. +10. ✅ Revise `bittensor/utils/easy_imports.py` module to remove deprecated backwards compatibility objects. Use this module as a functionality for exporting existing objects to the package root to keep __init__.py minimal and simple. -11. Remove `bittensor.utils.version.version_checking` +11. ✅ Remove deprecated `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. @@ -75,9 +75,9 @@ rename this variable in documentation. 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`) -2. Implement Crowdloan logic. Issue: https://github.com/opentensor/bittensor/issues/3017 -3. ✅ Implement Sub-subnets logic. Subtensor PR https://github.com/opentensor/subtensor/pull/1984 +1. ✅ Add `bittensor.utils.hex_to_ss58` function. SDK still doesn't have it. (Probably inner import `from scalecodec import ss58_encode, ss58_decode`) +2. ✅ Implement Sub-subnets logic. Subtensor PR https://github.com/opentensor/subtensor/pull/1984 +3. Implement `Crowdloan` logic. Issue: https://github.com/opentensor/bittensor/issues/3017 ## Testing 1. ✅ When running tests via Docker, ensure no lingering processes occupy required ports before launch. @@ -95,23 +95,21 @@ rename this variable in documentation. ## Implementation - To implement the above changes and prepare for the v10 release, the following steps must be taken: - [x] Create a new branch named SDKv10.~~ All breaking changes and refactors should be targeted into this branch to isolate them from staging and maintain backward compatibility during development. -- [ ] Add a `MIGRATION.md` document at the root of the repository and use it as a check list. This file will serve as a changelog and technical reference. +- [x] Add a `MIGRATION.md` document at the root of the repository and use it as a check list. This file will serve as a changelog and technical reference. It must include: - - [ ] All change categories (Extrinsics, Subtensor, Metagraph, etc.) - - [ ] Per-PR breakdown of what was added, removed, renamed, or refactored. - - [ ] Justifications and migration notes for users (if API behavior changed). + - [x] All change categories (Extrinsics, Subtensor, Metagraph, etc.) + - [x] Per-PR breakdown of what was added, removed, renamed, or refactored. + - [x] Justifications and migration notes for users (if API behavior changed). - [ ] Based on the final `MIGRATION.md`, develop migration documentation for the community. - [ ] Once complete, merge SDKv10 into staging and release version 10. # Migration guide - - [x] `._do_commit_reveal_v3` logic is included in the main code `.commit_timelocked_weights_extrinsic` - [x] `commit_reveal_version` parameter with default value `4` added to `commit_timelocked_weights_extrinsic` - [x] `._do_commit_weights` logic is included in the main code `.commit_weights_extrinsic` @@ -126,8 +124,8 @@ It must include: - [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. -# Standardize parameter order is applied for (extrinsics and related calls): +# 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 @@ -216,6 +214,7 @@ Removing deprecated extrinsics and replacing them with consistent ones: - `decrease_take_extrinsic` and `increase_take_extrinsic` have been merged into a single set_take_extrinsic. The API now has a new `action: Literal["increase_take", "decrease_take"]` parameter (DRY rule). + ### Extrinsics has extra data in response's `data` field: - `add_stake_extrinsic` - `add_stake_multiple_extrinsic` @@ -225,15 +224,30 @@ Removing deprecated extrinsics and replacing them with consistent ones: - `unstake_extrinsic` - `unstake_multiple_extrinsic` + ### Subtensor changes - method `all_subnets` has renamed parameter from `block_number` to `block` (consistency in the codebase). -- The `hotkey` parameter, which meant ss58 key address, was renamed to `hotkey_ss58` in all methods (consistency in the codebase). +- The `hotkey` parameter, which meant ss58 key address, was renamed to `hotkey_ss58` in all methods and related extrinsics (consistency in the codebase). - The `coldkey` parameter, which meant ss58 key address, was renamed to `coldkey_ss58` in all methods (consistency in the codebase). - method `query_subtensor` has updated parameters order. - method `query_module` has updated parameters order. - method `query_map_subtensor` has updated parameters order. - method `query_map` has updated parameters order. - method `add_stake_multiple` has updated parameters order. +- method `get_stake_for_coldkey` removed, bc this is the same as `get_stake_info_for_coldkey` +- method `get_subnets` renamed to `get_all_subnets_netuid` (obvious name, consistent with existing names) +- method `get_owned_hotkeys` get rid `reuse_block` parameter to be consistent with other sync methods. +- method `blocks_since_last_update` improved. Currently it can be used to get historical data from archive node. +- methods (async) `get_subnet_validator_permits` and `get_subnet_owner_hotkey` got `block_hash` and `reuse_block` parameters. +- attribute `DelegateInfo/lite.total_daily_return` has been deleted (Vune confirmed that we shouldn't use it) +- `Async/Subtensor` parameter `_mock` renamed to `mock`, also moved to last one in order. Community can use mocked `Async/Subtensor` in their tests in the same way as in we use it in the codebase. +- method `get_traansfer_fee` has renamed parameter `value` to `amount` + +Added sub-package `bittensor.core.addons` to host optional extensions and experimental logic enhancing the core functionality. + - `bittensor.core.subtensor_api` moved to `bittensor.core.addons.subtensor_api` + - `bittensor.core.timelock` moved to `bittensor.core.addons.timelock` + - local env variable `BT_CHAIN_ENDPOINT` replaced with `BT_SUBTENSOR_CHAIN_ENDPOINT`. + ### Mechid related changes: In the next subtensor methods got updated the parameters order: @@ -249,5 +263,44 @@ In the next subtensor methods got updated the parameters order: Additional: - `bittensor.core.chain_data.metagraph_info.MetagraphInfo` got required attribute `mechid: int`. + ### Renames parameters: - `get_metagraph_info`: `field_indices` -> `selected_indices` (to be consistent) + + +### `easy_import.py` module +Added: +- `from bittenosor import extrinsics` +- `from bittenosor import mock` +- `from bittenosor import get_async_subtensor` + +Next variables removed: +- `async_subtensor` not -> `AsyncSubtensor` +- `axon` not -> `Axon` +- `config` not -> `Config` +- `dendrite` not -> `Dendrite` +- `keyfile` not -> `Keyfile` +- `metagraph` not -> `Metagraph` +- `wallet` not -> `Wallet` +- `subtensor` not -> `Subtensor` +- `synapse` not -> `Synapse` + +Links to subpackages removed: +- `bittensor.mock` (available in `bittensor.core.mock`) +- `bittensor.extrinsics` (available in `bittensor.core.extrinsics`) + + +New subpackage `bittensor.extras` created to host optional extensions and experimental logic enhancing the core functionality. +Currently it contains: +- `bittensor.extras.subtensor_api` +- `bittensor.extras.timelock` + + +### Balance (bittensor/utils/balance.py) and related changes +- [x] Added 2 custom errors: + - `bittensor.core.errors.BalanceUnitMismatchError` + - `bittensor.core.errors.BalanceTypeError` +- [x] `check_balance` renamed to `check_balance_amount` +- [x] `check_and_convert_to_balance` renamed to `check_balance_amount` +- [x] `check_balance_amount` raised `BalanceTypeError` error instead of deprecated warning message. +- [x] private function `bittensor.utils.balance._check_currencies` raises `BalanceUnitMismatchError` error instead of deprecated warning message. This function is used inside the Balance class to check if units match during various mathematical and logical operations. diff --git a/bittensor/core/async_subtensor.py b/bittensor/core/async_subtensor.py index 5c572c7d10..a89557f427 100644 --- a/bittensor/core/async_subtensor.py +++ b/bittensor/core/async_subtensor.py @@ -109,7 +109,7 @@ from bittensor.utils.balance import ( Balance, fixed_to_float, - check_and_convert_to_balance, + check_balance_amount, ) from bittensor.utils.btlogging import logging from bittensor.utils.liquidity import ( @@ -146,9 +146,9 @@ def __init__( log_verbose: bool = False, fallback_endpoints: Optional[list[str]] = None, retry_forever: bool = False, - _mock: bool = False, archive_endpoints: Optional[list[str]] = None, websocket_shutdown_timer: float = 5.0, + mock: bool = False, ): """Initializes an AsyncSubtensor instance for blockchain interaction. @@ -159,7 +159,7 @@ def __init__( log_verbose: Enables or disables verbose logging. fallback_endpoints: List of fallback endpoints to use if default or provided network is not available. retry_forever: Whether to retry forever on connection errors. - _mock: Whether this is a mock instance. Mainly for testing purposes. + mock: Whether this is a mock instance. Mainly for testing purposes. archive_endpoints: Similar to fallback_endpoints, but specifically only archive nodes. Will be used in cases where you are requesting a block that is too old for your current (presumably lite) node. websocket_shutdown_timer: Amount of time, in seconds, to wait after the last response from the chain to @@ -198,7 +198,7 @@ async def main(): self.substrate = self._get_substrate( fallback_endpoints=fallback_endpoints, retry_forever=retry_forever, - _mock=_mock, + _mock=mock, archive_endpoints=archive_endpoints, ws_shutdown_timer=websocket_shutdown_timer, ) @@ -846,12 +846,22 @@ async def blocks_since_last_step( ) return query.value if query is not None and hasattr(query, "value") else query - async def blocks_since_last_update(self, netuid: int, uid: int) -> Optional[int]: + async def blocks_since_last_update( + self, + netuid: int, + uid: int, + block: Optional[int] = None, + block_hash: Optional[str] = None, + reuse_block: bool = False, + ) -> Optional[int]: """Returns the number of blocks since the last update, or ``None`` if the subnetwork or UID does not exist. Parameters: netuid: The unique identifier of the subnetwork. uid: The unique identifier of the neuron. + block: The block number for this query. Do not specify if using block_hash or reuse_block. + block_hash: The hash of the block for the query. Do not specify if using reuse_block or block. + reuse_block: Whether to reuse the last-used block hash. Do not set if using block_hash or block. Returns: The number of blocks since the last update, or None if the subnetwork or UID does not exist. @@ -863,8 +873,16 @@ async def blocks_since_last_update(self, netuid: int, uid: int) -> Optional[int] # Check if neuron needs updating blocks_since_update = await subtensor.blocks_since_last_update(netuid=1, uid=10) """ - call = await self.get_hyperparameter(param_name="LastUpdate", netuid=netuid) - return None if call is None else await self.get_current_block() - int(call[uid]) + block_hash = await self.determine_block_hash(block, block_hash, reuse_block) + block = block or await self.substrate.get_block_number(block_hash) + call = await self.get_hyperparameter( + param_name="LastUpdate", + netuid=netuid, + block=block, + block_hash=block_hash, + reuse_block=reuse_block, + ) + return None if call is None else (block - int(call[uid])) async def bonds( self, @@ -2527,6 +2545,7 @@ async def get_stake_add_fee( Returns: The calculated stake fee as a Balance object """ + check_balance_amount(amount) return await self.get_stake_operations_fee( amount=amount, netuid=netuid, block=block ) @@ -2755,6 +2774,7 @@ async def get_unstake_fee( Returns: The calculated stake fee as a Balance object """ + check_balance_amount(amount) return await self.get_stake_operations_fee( amount=amount, netuid=netuid, block=block ) @@ -2777,6 +2797,7 @@ async def get_stake_movement_fee( Returns: The calculated stake fee as a Balance object """ + check_balance_amount(amount) return await self.get_stake_operations_fee( amount=amount, netuid=origin_netuid, block=block ) @@ -2810,7 +2831,7 @@ async def get_stake_for_coldkey_and_hotkey( elif not block_hash: block_hash = await self.substrate.get_chain_head() if netuids is None: - all_netuids = await self.get_subnets(block_hash=block_hash) + all_netuids = await self.get_all_subnets_netuid(block_hash=block_hash) else: all_netuids = netuids results = await asyncio.gather( @@ -2829,7 +2850,7 @@ async def get_stake_for_coldkey_and_hotkey( for (netuid, result) in zip(all_netuids, results) } - async def get_stake_for_coldkey( + async def get_stake_info_for_coldkey( self, coldkey_ss58: str, block: Optional[int] = None, @@ -2863,8 +2884,6 @@ async def get_stake_for_coldkey( stakes: list[StakeInfo] = StakeInfo.list_from_dicts(result) return [stake for stake in stakes if stake.stake > 0] - get_stake_info_for_coldkey = get_stake_for_coldkey - async def get_stake_for_hotkey( self, hotkey_ss58: str, @@ -2916,6 +2935,7 @@ async def get_stake_operations_fee( Returns: The calculated stake fee as a Balance object. """ + check_balance_amount(amount) block_hash = await self.determine_block_hash( block=block, block_hash=block_hash, reuse_block=reuse_block ) @@ -3037,7 +3057,7 @@ async def get_subnet_reveal_period_epochs( param_name="RevealPeriodEpochs", block_hash=block_hash, netuid=netuid ) - async def get_subnets( + async def get_all_subnets_netuid( self, block: Optional[int] = None, block_hash: Optional[str] = None, @@ -3103,7 +3123,7 @@ async def get_total_subnets( # TODO: update related with fee calculation async def get_transfer_fee( - self, wallet: "Wallet", dest: str, value: Balance, keep_alive: bool = True + self, wallet: "Wallet", dest: str, amount: Balance, keep_alive: bool = True ) -> Balance: """ Calculates the transaction fee for transferring tokens from a wallet to a specified destination address. This @@ -3113,7 +3133,7 @@ async def get_transfer_fee( Parameters: wallet: The wallet from which the transfer is initiated. dest: The ``SS58`` address of the destination account. - value: The amount of tokens to be transferred, specified as a Balance object, or in Tao (float) or Rao + amount: The amount of tokens to be transferred, specified as a Balance object, or in Tao (float) or Rao (int) units. keep_alive: Whether the transfer fee should be calculated based on keeping the wallet alive (existential deposit) or not. @@ -3126,10 +3146,9 @@ async def get_transfer_fee( wallet has sufficient funds to cover both the transfer amount and the associated costs. This function provides a crucial tool for managing financial operations within the Bittensor network. """ - if value is not None: - value = check_and_convert_to_balance(value) + check_balance_amount(amount) call_params: dict[str, Union[int, str, bool]] - call_function, call_params = get_transfer_fn_params(value, dest, keep_alive) + call_function, call_params = get_transfer_fn_params(amount, dest, keep_alive) call = await self.substrate.compose_call( call_module="Balances", @@ -4105,7 +4124,11 @@ async def get_timestamp( return datetime.fromtimestamp(unix / 1000, tz=timezone.utc) async def get_subnet_owner_hotkey( - self, netuid: int, block: Optional[int] = None + self, + netuid: int, + block: Optional[int] = None, + block_hash: Optional[str] = None, + reuse_block: bool = False, ) -> Optional[str]: """ Retrieves the hotkey of the subnet owner for a given network UID. @@ -4115,17 +4138,27 @@ async def get_subnet_owner_hotkey( Parameters: netuid: The network UID of the subnet to fetch the owner's hotkey for. - block: The specific block number to query the data from. + block: The blockchain block number for the query. + block_hash: The blockchain block_hash representation of the block id. + reuse_block: Whether to reuse the last-used blockchain block hash. Returns: The hotkey of the subnet owner if available; None otherwise. """ return await self.query_subtensor( - name="SubnetOwnerHotkey", params=[netuid], block=block + name="SubnetOwnerHotkey", + params=[netuid], + block=block, + block_hash=block_hash, + reuse_block=reuse_block, ) async def get_subnet_validator_permits( - self, netuid: int, block: Optional[int] = None + self, + netuid: int, + block: Optional[int] = None, + block_hash: Optional[str] = None, + reuse_block: bool = False, ) -> Optional[list[bool]]: """ Retrieves the list of validator permits for a given subnet as boolean values. @@ -4133,6 +4166,8 @@ async def get_subnet_validator_permits( Parameters: netuid: The unique identifier of the subnetwork. block: The blockchain block number for the query. + block_hash: The blockchain block_hash representation of the block id. + reuse_block: Whether to reuse the last-used blockchain block hash. Returns: A list of boolean values representing validator permits, or None if not available. @@ -4141,6 +4176,8 @@ async def get_subnet_validator_permits( name="ValidatorPermit", params=[netuid], block=block, + block_hash=block_hash, + reuse_block=reuse_block, ) return query.value if query is not None and hasattr(query, "value") else query @@ -4296,7 +4333,7 @@ async def add_stake( 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) + check_balance_amount(amount) return await add_stake_extrinsic( subtensor=self, wallet=wallet, @@ -4319,7 +4356,7 @@ async def add_liquidity( liquidity: Balance, price_low: Balance, price_high: Balance, - hotkey: Optional[str] = None, + hotkey_ss58: Optional[str] = None, period: Optional[int] = None, raise_error: bool = False, wait_for_inclusion: bool = True, @@ -4334,7 +4371,7 @@ async def add_liquidity( 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. + hotkey_ss58: 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. @@ -4355,7 +4392,7 @@ async def add_liquidity( liquidity=liquidity, price_low=price_low, price_high=price_high, - hotkey=hotkey, + hotkey_ss58=hotkey_ss58, period=period, raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, @@ -4541,7 +4578,7 @@ async def modify_liquidity( netuid: int, position_id: int, liquidity_delta: Balance, - hotkey: Optional[str] = None, + hotkey_ss58: Optional[str] = None, period: Optional[int] = None, raise_error: bool = False, wait_for_inclusion: bool = True, @@ -4554,7 +4591,7 @@ async def modify_liquidity( 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. + hotkey_ss58: 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. @@ -4600,7 +4637,7 @@ async def modify_liquidity( netuid=netuid, position_id=position_id, liquidity_delta=liquidity_delta, - hotkey=hotkey, + hotkey_ss58=hotkey_ss58, period=period, raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, @@ -4642,7 +4679,7 @@ async def move_stake( Returns: ExtrinsicResponse: The result object of the extrinsic execution. """ - amount = check_and_convert_to_balance(amount) + check_balance_amount(amount) return await move_stake_extrinsic( subtensor=self, wallet=wallet, @@ -4761,7 +4798,7 @@ async def remove_liquidity( wallet: "Wallet", netuid: int, position_id: int, - hotkey: Optional[str] = None, + hotkey_ss58: Optional[str] = None, period: Optional[int] = None, raise_error: bool = False, wait_for_inclusion: bool = True, @@ -4773,7 +4810,7 @@ async def remove_liquidity( 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. + hotkey_ss58: 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. @@ -4794,7 +4831,7 @@ async def remove_liquidity( wallet=wallet, netuid=netuid, position_id=position_id, - hotkey=hotkey, + hotkey_ss58=hotkey_ss58, period=period, raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, @@ -5493,7 +5530,7 @@ async def swap_stake( - With allow_partial_stake=True: A partial amount will be swapped up to the point where the price ratio would increase by rate_tolerance. """ - amount = check_and_convert_to_balance(amount) + check_balance_amount(amount) return await swap_stake_extrinsic( subtensor=self, wallet=wallet, @@ -5580,8 +5617,7 @@ async def transfer( Returns: ExtrinsicResponse: The result object of the extrinsic execution. """ - if amount is not None: - amount = check_and_convert_to_balance(amount) + check_balance_amount(amount) return await transfer_extrinsic( subtensor=self, wallet=wallet, @@ -5628,7 +5664,7 @@ async def transfer_stake( Returns: ExtrinsicResponse: The result object of the extrinsic execution. """ - amount = check_and_convert_to_balance(amount) + check_balance_amount(amount) return await transfer_stake_extrinsic( subtensor=self, wallet=wallet, @@ -5686,7 +5722,7 @@ async def unstake( This function supports flexible stake management, allowing neurons to adjust their network participation and potential reward accruals. """ - amount = check_and_convert_to_balance(amount) + check_balance_amount(amount) return await unstake_extrinsic( subtensor=self, wallet=wallet, @@ -5834,14 +5870,14 @@ async def unstake_multiple( async def get_async_subtensor( network: Optional[str] = None, config: Optional["Config"] = None, - _mock: bool = False, + mock: bool = False, log_verbose: bool = False, ) -> "AsyncSubtensor": """Factory method to create an initialized AsyncSubtensor. Mainly useful for when you don't want to run `await subtensor.initialize()` after instantiation. """ sub = AsyncSubtensor( - network=network, config=config, _mock=_mock, log_verbose=log_verbose + network=network, config=config, mock=mock, log_verbose=log_verbose ) await sub.initialize() return sub diff --git a/bittensor/core/chain_data/delegate_info.py b/bittensor/core/chain_data/delegate_info.py index cfc4e50654..91301b6034 100644 --- a/bittensor/core/chain_data/delegate_info.py +++ b/bittensor/core/chain_data/delegate_info.py @@ -18,7 +18,6 @@ class DelegateInfoBase(InfoBase): validator_permits: List of subnets that the delegate is allowed to validate on. registrations: List of subnets that the delegate is registered on. return_per_1000: Return per 1000 tao of the delegate over a day. - total_daily_return: Total daily return of the delegate. """ hotkey_ss58: str # Hotkey of delegate @@ -29,7 +28,6 @@ class DelegateInfoBase(InfoBase): ] # List of subnets that the delegate is allowed to validate on registrations: list[int] # list of subnets that the delegate is registered on return_per_1000: Balance # Return per 1000 tao of the delegate over a day - total_daily_return: Balance # Total daily return of the delegate @dataclass @@ -77,7 +75,6 @@ def _from_dict(cls, decoded: dict) -> Optional["DelegateInfo"]: validator_permits=list(decoded.get("validator_permits", [])), registrations=list(decoded.get("registrations", [])), return_per_1000=Balance.from_rao(decoded.get("return_per_1000")), - total_daily_return=Balance.from_rao(decoded.get("total_daily_return")), ) @@ -108,9 +105,6 @@ def _from_dict( validator_permits=list(delegate_info.get("validator_permits", [])), registrations=list(delegate_info.get("registrations", [])), return_per_1000=Balance.from_rao(delegate_info.get("return_per_1000")), - total_daily_return=Balance.from_rao( - delegate_info.get("total_daily_return") - ), netuid=int(netuid), stake=Balance.from_rao(int(stake)).set_unit(int(netuid)), ) diff --git a/bittensor/core/chain_data/delegate_info_lite.py b/bittensor/core/chain_data/delegate_info_lite.py index aa61f44abd..06666769dc 100644 --- a/bittensor/core/chain_data/delegate_info_lite.py +++ b/bittensor/core/chain_data/delegate_info_lite.py @@ -19,7 +19,6 @@ class DelegateInfoLite(InfoBase): registrations: List of subnets that the delegate is registered on. validator_permits: List of subnets that the delegate is allowed to validate on. return_per_1000: Return per 1000 TAO, for the delegate over a day. - total_daily_return: Total daily return of the delegate. """ delegate_ss58: str # Hotkey of delegate @@ -31,7 +30,6 @@ class DelegateInfoLite(InfoBase): int ] # List of subnets that the delegate is allowed to validate on return_per_1000: Balance # Return per 1000 tao for the delegate over a day - total_daily_return: Balance # Total daily return of the delegate @classmethod def _from_dict(cls, decoded: dict) -> "DelegateInfoLite": @@ -43,5 +41,4 @@ def _from_dict(cls, decoded: dict) -> "DelegateInfoLite": registrations=decoded["registrations"], validator_permits=decoded["validator_permits"], return_per_1000=Balance.from_rao(decoded["return_per_1000"]), - total_daily_return=Balance.from_rao(decoded["total_daily_return"]), ) diff --git a/bittensor/core/errors.py b/bittensor/core/errors.py index 15eb9e0446..19e748103f 100644 --- a/bittensor/core/errors.py +++ b/bittensor/core/errors.py @@ -212,3 +212,11 @@ def __init__( ): self.message = message super().__init__(self.message, synapse) + + +class BalanceUnitMismatchError(Exception): + """Raised when operations is attempted between Balance objects with different units (netuid).""" + + +class BalanceTypeError(TypeError): + """Raised when an unsupported type is used instead of Balance amount.""" diff --git a/bittensor/core/extrinsics/asyncex/liquidity.py b/bittensor/core/extrinsics/asyncex/liquidity.py index f655da7a21..eb42ce2679 100644 --- a/bittensor/core/extrinsics/asyncex/liquidity.py +++ b/bittensor/core/extrinsics/asyncex/liquidity.py @@ -16,7 +16,7 @@ async def add_liquidity_extrinsic( liquidity: Balance, price_low: Balance, price_high: Balance, - hotkey: Optional[str] = None, + hotkey_ss58: Optional[str] = None, period: Optional[int] = None, raise_error: bool = False, wait_for_inclusion: bool = True, @@ -32,7 +32,7 @@ async def add_liquidity_extrinsic( 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. + hotkey_ss58: 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. @@ -59,7 +59,7 @@ async def add_liquidity_extrinsic( call_module="Swap", call_function="add_liquidity", call_params={ - "hotkey": hotkey or wallet.hotkey.ss58_address, + "hotkey": hotkey_ss58 or wallet.hotkey.ss58_address, "netuid": netuid, "tick_low": tick_low, "tick_high": tick_high, @@ -85,7 +85,7 @@ async def modify_liquidity_extrinsic( netuid: int, position_id: int, liquidity_delta: Balance, - hotkey: Optional[str] = None, + hotkey_ss58: Optional[str] = None, period: Optional[int] = None, raise_error: bool = False, wait_for_inclusion: bool = True, @@ -99,7 +99,7 @@ async def modify_liquidity_extrinsic( 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. + hotkey_ss58: 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. @@ -123,7 +123,7 @@ async def modify_liquidity_extrinsic( call_module="Swap", call_function="modify_position", call_params={ - "hotkey": hotkey or wallet.hotkey.ss58_address, + "hotkey": hotkey_ss58 or wallet.hotkey.ss58_address, "netuid": netuid, "position_id": position_id, "liquidity_delta": liquidity_delta.rao, @@ -147,7 +147,7 @@ async def remove_liquidity_extrinsic( wallet: "Wallet", netuid: int, position_id: int, - hotkey: Optional[str] = None, + hotkey_ss58: Optional[str] = None, period: Optional[int] = None, raise_error: bool = False, wait_for_inclusion: bool = True, @@ -160,7 +160,7 @@ async def remove_liquidity_extrinsic( 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. + hotkey_ss58: 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. @@ -184,7 +184,7 @@ async def remove_liquidity_extrinsic( call_module="Swap", call_function="remove_liquidity", call_params={ - "hotkey": hotkey or wallet.hotkey.ss58_address, + "hotkey": hotkey_ss58 or wallet.hotkey.ss58_address, "netuid": netuid, "position_id": position_id, }, diff --git a/bittensor/core/extrinsics/asyncex/staking.py b/bittensor/core/extrinsics/asyncex/staking.py index 9219c903c0..271ced2c99 100644 --- a/bittensor/core/extrinsics/asyncex/staking.py +++ b/bittensor/core/extrinsics/asyncex/staking.py @@ -2,9 +2,11 @@ from typing import Optional, Sequence, TYPE_CHECKING from async_substrate_interface.errors import SubstrateRequestException + +from bittensor.core.errors import BalanceTypeError from bittensor.core.extrinsics.utils import get_old_stakes -from bittensor.utils import format_error_message from bittensor.core.types import ExtrinsicResponse, UIDs +from bittensor.utils import format_error_message from bittensor.utils.balance import Balance from bittensor.utils.btlogging import logging @@ -257,7 +259,7 @@ async def add_stake_multiple_extrinsic( raise TypeError("`hotkey_ss58s` must be a list of str.") if not all(isinstance(a, Balance) for a in amounts): - raise TypeError("Each `amount` must be an instance of Balance.") + raise BalanceTypeError("Each `amount` must be an instance of Balance.") new_amounts: Sequence[Optional[Balance]] = [ amount.set_unit(netuid) for amount, netuid in zip(amounts, netuids) @@ -269,7 +271,7 @@ async def add_stake_multiple_extrinsic( block_hash = await subtensor.substrate.get_chain_head() - all_stakes = await subtensor.get_stake_for_coldkey( + all_stakes = await subtensor.get_stake_info_for_coldkey( coldkey_ss58=wallet.coldkeypub.ss58_address, block_hash=block_hash ) old_stakes: list[Balance] = get_old_stakes( diff --git a/bittensor/core/extrinsics/asyncex/transfer.py b/bittensor/core/extrinsics/asyncex/transfer.py index f8dc6f8b49..3d4b718dfc 100644 --- a/bittensor/core/extrinsics/asyncex/transfer.py +++ b/bittensor/core/extrinsics/asyncex/transfer.py @@ -75,7 +75,7 @@ async def transfer_extrinsic( ) fee = await subtensor.get_transfer_fee( - wallet=wallet, dest=destination, value=amount, keep_alive=keep_alive + wallet=wallet, dest=destination, amount=amount, keep_alive=keep_alive ) if not keep_alive: diff --git a/bittensor/core/extrinsics/asyncex/unstaking.py b/bittensor/core/extrinsics/asyncex/unstaking.py index f6f5fce8bd..d666716b56 100644 --- a/bittensor/core/extrinsics/asyncex/unstaking.py +++ b/bittensor/core/extrinsics/asyncex/unstaking.py @@ -3,6 +3,7 @@ from async_substrate_interface.errors import SubstrateRequestException +from bittensor.core.errors import BalanceTypeError from bittensor.core.extrinsics.utils import get_old_stakes from bittensor.core.types import ExtrinsicResponse from bittensor.core.types import UIDs @@ -305,7 +306,7 @@ async def unstake_multiple_extrinsic( if amounts is not None and not all( isinstance(amount, Balance) for amount in amounts ): - raise TypeError("`amounts` must be a list of Balance or None.") + raise BalanceTypeError("`amounts` must be a list of Balance or None.") if amounts is None: amounts = [None] * len(hotkey_ss58s) @@ -352,7 +353,7 @@ async def unstake_multiple_extrinsic( block_hash = await subtensor.substrate.get_chain_head() all_stakes, old_balance = await asyncio.gather( - subtensor.get_stake_for_coldkey( + subtensor.get_stake_info_for_coldkey( coldkey_ss58=wallet.coldkeypub.ss58_address, block_hash=block_hash ), subtensor.get_balance( diff --git a/bittensor/core/extrinsics/liquidity.py b/bittensor/core/extrinsics/liquidity.py index 64ebc8c674..f86604a202 100644 --- a/bittensor/core/extrinsics/liquidity.py +++ b/bittensor/core/extrinsics/liquidity.py @@ -16,7 +16,7 @@ def add_liquidity_extrinsic( liquidity: Balance, price_low: Balance, price_high: Balance, - hotkey: Optional[str] = None, + hotkey_ss58: Optional[str] = None, period: Optional[int] = None, raise_error: bool = False, wait_for_inclusion: bool = True, @@ -32,7 +32,7 @@ def add_liquidity_extrinsic( 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. + hotkey_ss58: 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. @@ -59,7 +59,7 @@ def add_liquidity_extrinsic( call_module="Swap", call_function="add_liquidity", call_params={ - "hotkey": hotkey or wallet.hotkey.ss58_address, + "hotkey": hotkey_ss58 or wallet.hotkey.ss58_address, "netuid": netuid, "tick_low": tick_low, "tick_high": tick_high, @@ -85,7 +85,7 @@ def modify_liquidity_extrinsic( netuid: int, position_id: int, liquidity_delta: Balance, - hotkey: Optional[str] = None, + hotkey_ss58: Optional[str] = None, period: Optional[int] = None, raise_error: bool = False, wait_for_inclusion: bool = True, @@ -99,7 +99,7 @@ def modify_liquidity_extrinsic( 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. + hotkey_ss58: 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. @@ -123,7 +123,7 @@ def modify_liquidity_extrinsic( call_module="Swap", call_function="modify_position", call_params={ - "hotkey": hotkey or wallet.hotkey.ss58_address, + "hotkey": hotkey_ss58 or wallet.hotkey.ss58_address, "netuid": netuid, "position_id": position_id, "liquidity_delta": liquidity_delta.rao, @@ -147,7 +147,7 @@ def remove_liquidity_extrinsic( wallet: "Wallet", netuid: int, position_id: int, - hotkey: Optional[str] = None, + hotkey_ss58: Optional[str] = None, period: Optional[int] = None, raise_error: bool = False, wait_for_inclusion: bool = True, @@ -160,7 +160,7 @@ def remove_liquidity_extrinsic( 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. + hotkey_ss58: 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. @@ -184,7 +184,7 @@ def remove_liquidity_extrinsic( call_module="Swap", call_function="remove_liquidity", call_params={ - "hotkey": hotkey or wallet.hotkey.ss58_address, + "hotkey": hotkey_ss58 or wallet.hotkey.ss58_address, "netuid": netuid, "position_id": position_id, }, diff --git a/bittensor/core/extrinsics/staking.py b/bittensor/core/extrinsics/staking.py index 949166a994..0cd3f8481b 100644 --- a/bittensor/core/extrinsics/staking.py +++ b/bittensor/core/extrinsics/staking.py @@ -2,6 +2,7 @@ from async_substrate_interface.errors import SubstrateRequestException +from bittensor.core.errors import BalanceTypeError from bittensor.core.extrinsics.utils import get_old_stakes from bittensor.core.types import ExtrinsicResponse, UIDs from bittensor.utils import format_error_message @@ -251,7 +252,7 @@ def add_stake_multiple_extrinsic( raise TypeError("`hotkey_ss58s` must be a list of str.") if not all(isinstance(a, Balance) for a in amounts): - raise TypeError("Each `amount` must be an instance of Balance.") + raise BalanceTypeError("Each `amount` must be an instance of Balance.") new_amounts: Sequence[Optional[Balance]] = [ amount.set_unit(netuid) for amount, netuid in zip(amounts, netuids) @@ -262,7 +263,7 @@ def add_stake_multiple_extrinsic( return ExtrinsicResponse(True, "Success") block = subtensor.get_current_block() - all_stakes = subtensor.get_stake_for_coldkey( + all_stakes = subtensor.get_stake_info_for_coldkey( coldkey_ss58=wallet.coldkeypub.ss58_address, ) old_stakes: list[Balance] = get_old_stakes( diff --git a/bittensor/core/extrinsics/transfer.py b/bittensor/core/extrinsics/transfer.py index 888f9b1ade..56bd44f0e8 100644 --- a/bittensor/core/extrinsics/transfer.py +++ b/bittensor/core/extrinsics/transfer.py @@ -74,7 +74,7 @@ def transfer_extrinsic( existential_deposit = subtensor.get_existential_deposit(block=block) fee = subtensor.get_transfer_fee( - wallet=wallet, dest=destination, value=amount, keep_alive=keep_alive + wallet=wallet, dest=destination, amount=amount, keep_alive=keep_alive ) # Check if we have enough balance. diff --git a/bittensor/core/extrinsics/unstaking.py b/bittensor/core/extrinsics/unstaking.py index 6e2d2bdb27..11c19f1423 100644 --- a/bittensor/core/extrinsics/unstaking.py +++ b/bittensor/core/extrinsics/unstaking.py @@ -2,6 +2,7 @@ from async_substrate_interface.errors import SubstrateRequestException +from bittensor.core.errors import BalanceTypeError from bittensor.core.extrinsics.utils import get_old_stakes from bittensor.core.types import ExtrinsicResponse, UIDs from bittensor.utils import format_error_message @@ -300,7 +301,7 @@ def unstake_multiple_extrinsic( if amounts is not None and not all( isinstance(amount, Balance) for amount in amounts ): - raise TypeError("`amounts` must be a list of Balance or None.") + raise BalanceTypeError("`amounts` must be a list of Balance or None.") if amounts is None: amounts = [None] * len(hotkey_ss58s) @@ -349,7 +350,7 @@ def unstake_multiple_extrinsic( old_balance = subtensor.get_balance( address=wallet.coldkeypub.ss58_address, block=block ) - all_stakes = subtensor.get_stake_for_coldkey( + all_stakes = subtensor.get_stake_info_for_coldkey( coldkey_ss58=wallet.coldkeypub.ss58_address, block=block, ) diff --git a/bittensor/core/metagraph.py b/bittensor/core/metagraph.py index 0231411df5..15f8080107 100644 --- a/bittensor/core/metagraph.py +++ b/bittensor/core/metagraph.py @@ -1412,7 +1412,7 @@ async def sync( ): cur_block = await subtensor.get_current_block() if block and block < (cur_block - 300): - logging.warning( + logging.debug( "Attempting to sync longer than 300 blocks ago on a non-archive node. Please use the 'archive' " "network for subtensor and retry." ) @@ -1556,7 +1556,8 @@ async def _process_root_weights( """ data_array = [] n_subnets_, subnets = await asyncio.gather( - subtensor.get_total_subnets(block=block), subtensor.get_subnets(block=block) + subtensor.get_total_subnets(block=block), + subtensor.get_all_subnets_netuid(block=block), ) n_subnets = n_subnets_ or 0 for item in data: @@ -1729,7 +1730,7 @@ def sync( ): cur_block = subtensor.get_current_block() if block and block < (cur_block - 300): - logging.warning( + logging.debug( "Attempting to sync longer than 300 blocks ago on a non-archive node. Please use the 'archive' " "network for subtensor and retry." ) @@ -1867,7 +1868,7 @@ def _process_root_weights( """ data_array = [] n_subnets = subtensor.get_total_subnets(block=block) or 0 - subnets = subtensor.get_subnets(block=block) + subnets = subtensor.get_all_subnets_netuid(block=block) for item in data: if len(item) == 0: if use_torch(): diff --git a/bittensor/core/settings.py b/bittensor/core/settings.py index 3e5edae0d6..0407e80001 100644 --- a/bittensor/core/settings.py +++ b/bittensor/core/settings.py @@ -121,7 +121,8 @@ "maxsize": int(_BT_PRIORITY_MAXSIZE) if _BT_PRIORITY_MAXSIZE else 10, }, "subtensor": { - "chain_endpoint": os.getenv("BT_CHAIN_ENDPOINT") or DEFAULT_ENDPOINT, + "chain_endpoint": os.getenv("BT_SUBTENSOR_CHAIN_ENDPOINT") + or DEFAULT_ENDPOINT, "network": os.getenv("BT_NETWORK") or DEFAULT_NETWORK, "_mock": False, }, diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index ee70580390..3a7fc2b26f 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -113,7 +113,7 @@ Balance, fixed_to_float, FixedPoint, - check_and_convert_to_balance, + check_balance_amount, ) from bittensor.utils.btlogging import logging from bittensor.utils.liquidity import ( @@ -143,8 +143,8 @@ def __init__( log_verbose: bool = False, fallback_endpoints: Optional[list[str]] = None, retry_forever: bool = False, - _mock: bool = False, archive_endpoints: Optional[list[str]] = None, + mock: bool = False, ): """ Initializes an instance of the Subtensor class. @@ -155,9 +155,9 @@ def __init__( log_verbose: Enables or disables verbose logging. fallback_endpoints: List of fallback endpoints to use if default or provided network is not available. retry_forever: Whether to retry forever on connection errors. - _mock: Whether this is a mock instance. Mainly just for use in testing. archive_endpoints: Similar to fallback_endpoints, but specifically only archive nodes. Will be used in cases where you are requesting a block that is too old for your current (presumably lite) node. + mock: Whether this is a mock instance. Mainly just for use in testing. Raises: Any exceptions raised during the setup, configuration, or connection process. @@ -177,7 +177,7 @@ def __init__( self.substrate = self._get_substrate( fallback_endpoints=fallback_endpoints, retry_forever=retry_forever, - _mock=_mock, + _mock=mock, archive_endpoints=archive_endpoints, ) if self.log_verbose: @@ -485,19 +485,25 @@ def blocks_since_last_step( ) return query.value if query is not None and hasattr(query, "value") else query - def blocks_since_last_update(self, netuid: int, uid: int) -> Optional[int]: + def blocks_since_last_update( + self, netuid: int, uid: int, block: Optional[int] = None + ) -> Optional[int]: """ Returns the number of blocks since the last update for a specific UID in the subnetwork. Parameters: netuid: The unique identifier of the subnetwork. uid: The unique identifier of the neuron. + block: the block number for this query. Returns: The number of blocks since the last update, or ``None`` if the subnetwork or UID does not exist. """ - call = self.get_hyperparameter(param_name="LastUpdate", netuid=netuid) - return None if not call else (self.get_current_block() - int(call[uid])) + block = block or self.get_current_block() + call = self.get_hyperparameter( + param_name="LastUpdate", netuid=netuid, block=block + ) + return None if not call else (block - int(call[uid])) def bonds( self, @@ -1694,7 +1700,6 @@ def get_owned_hotkeys( self, coldkey_ss58: str, block: Optional[int] = None, - reuse_block: bool = False, ) -> list[str]: """ Retrieves all hotkeys owned by a specific coldkey address. @@ -1702,7 +1707,6 @@ def get_owned_hotkeys( Parameters: coldkey_ss58: The SS58 address of the coldkey to query. block: The blockchain block number for the query. - reuse_block: Whether to reuse the last-used blockchain block hash. Returns: list[str]: A list of hotkey SS58 addresses owned by the coldkey. @@ -1713,7 +1717,6 @@ def get_owned_hotkeys( storage_function="OwnedHotkeys", params=[coldkey_ss58], block_hash=block_hash, - reuse_block_hash=reuse_block, ) return [decode_account_id(hotkey[0]) for hotkey in owned_hotkeys or []] @@ -1790,6 +1793,7 @@ def get_stake_add_fee( Returns: The calculated stake fee as a Balance object """ + check_balance_amount(amount) return self.get_stake_operations_fee(amount=amount, netuid=netuid, block=block) def get_mechanism_emission_split( @@ -1980,6 +1984,7 @@ def get_unstake_fee( Returns: The calculated stake fee as a Balance object """ + check_balance_amount(amount) return self.get_stake_operations_fee(amount=amount, netuid=netuid, block=block) # TODO: update related with fee calculation @@ -2000,6 +2005,7 @@ def get_stake_movement_fee( Returns: The calculated stake fee as a Balance object """ + check_balance_amount(amount) return self.get_stake_operations_fee( amount=amount, netuid=origin_netuid, block=block ) @@ -2024,7 +2030,7 @@ def get_stake_for_coldkey_and_hotkey( A {netuid: StakeInfo} pairing of all stakes across all subnets. """ if netuids is None: - all_netuids = self.get_subnets(block=block) + all_netuids = self.get_all_subnets_netuid(block=block) else: all_netuids = netuids results = [ @@ -2041,7 +2047,7 @@ def get_stake_for_coldkey_and_hotkey( for (netuid, result) in zip(all_netuids, results) } - def get_stake_for_coldkey( + def get_stake_info_for_coldkey( self, coldkey_ss58: str, block: Optional[int] = None ) -> list["StakeInfo"]: """ @@ -2066,8 +2072,6 @@ def get_stake_for_coldkey( stakes: list[StakeInfo] = StakeInfo.list_from_dicts(result) return [stake for stake in stakes if stake.stake > 0] - get_stake_info_for_coldkey = get_stake_for_coldkey - def get_stake_for_hotkey( self, hotkey_ss58: str, netuid: int, block: Optional[int] = None ) -> Balance: @@ -2105,6 +2109,7 @@ def get_stake_operations_fee( Returns: The calculated stake fee as a Balance object. """ + check_balance_amount(amount) block_hash = self.determine_block_hash(block=block) result = self.substrate.query( module="Swap", @@ -2200,7 +2205,7 @@ def get_subnet_reveal_period_epochs( ), ) - def get_subnets(self, block: Optional[int] = None) -> UIDs: + def get_all_subnets_netuid(self, block: Optional[int] = None) -> UIDs: """ Retrieves the list of all subnet unique identifiers (netuids) currently present in the Bittensor network. @@ -2251,7 +2256,7 @@ def get_transfer_fee( self, wallet: "Wallet", dest: str, - value: Optional[Balance], + amount: Optional[Balance], keep_alive: bool = True, ) -> Balance: """ @@ -2262,7 +2267,7 @@ def get_transfer_fee( Parameters: wallet: The wallet from which the transfer is initiated. dest: The ``SS58`` address of the destination account. - value: The amount of tokens to be transferred, specified as a Balance object, or in Tao or Rao units. + amount: The amount of tokens to be transferred, specified as a Balance object, or in Tao or Rao units. keep_alive: Whether the transfer fee should be calculated based on keeping the wallet alive (existential deposit) or not. @@ -2273,10 +2278,9 @@ def get_transfer_fee( has sufficient funds to cover both the transfer amount and the associated costs. This function provides a crucial tool for managing financial operations within the Bittensor network. """ - if value is not None: - value = check_and_convert_to_balance(value) + check_balance_amount(amount) call_params: dict[str, Union[int, str, bool]] - call_function, call_params = get_transfer_fn_params(value, dest, keep_alive) + call_function, call_params = get_transfer_fn_params(amount, dest, keep_alive) call = self.substrate.compose_call( call_module="Balances", @@ -3188,7 +3192,7 @@ def add_stake( 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) + check_balance_amount(amount) return add_stake_extrinsic( subtensor=self, wallet=wallet, @@ -3211,7 +3215,7 @@ def add_liquidity( liquidity: Balance, price_low: Balance, price_high: Balance, - hotkey: Optional[str] = None, + hotkey_ss58: Optional[str] = None, period: Optional[int] = None, raise_error: bool = False, wait_for_inclusion: bool = True, @@ -3226,7 +3230,7 @@ def add_liquidity( 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. + hotkey_ss58: 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. @@ -3247,7 +3251,7 @@ def add_liquidity( liquidity=liquidity, price_low=price_low, price_high=price_high, - hotkey=hotkey, + hotkey_ss58=hotkey_ss58, period=period, raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, @@ -3430,7 +3434,7 @@ def modify_liquidity( netuid: int, position_id: int, liquidity_delta: Balance, - hotkey: Optional[str] = None, + hotkey_ss58: Optional[str] = None, period: Optional[int] = None, raise_error: bool = False, wait_for_inclusion: bool = True, @@ -3443,7 +3447,7 @@ def modify_liquidity( 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. + hotkey_ss58: 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. @@ -3489,7 +3493,7 @@ def modify_liquidity( netuid=netuid, position_id=position_id, liquidity_delta=liquidity_delta, - hotkey=hotkey, + hotkey_ss58=hotkey_ss58, period=period, raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, @@ -3531,7 +3535,7 @@ def move_stake( Returns: ExtrinsicResponse: The result object of the extrinsic execution. """ - amount = check_and_convert_to_balance(amount) + check_balance_amount(amount) return move_stake_extrinsic( subtensor=self, wallet=wallet, @@ -3650,7 +3654,7 @@ def remove_liquidity( wallet: "Wallet", netuid: int, position_id: int, - hotkey: Optional[str] = None, + hotkey_ss58: Optional[str] = None, period: Optional[int] = None, raise_error: bool = False, wait_for_inclusion: bool = True, @@ -3662,7 +3666,7 @@ def remove_liquidity( 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. + hotkey_ss58: 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. @@ -3683,7 +3687,7 @@ def remove_liquidity( wallet=wallet, netuid=netuid, position_id=position_id, - hotkey=hotkey, + hotkey_ss58=hotkey_ss58, period=period, raise_error=raise_error, wait_for_inclusion=wait_for_inclusion, @@ -4363,7 +4367,7 @@ def swap_stake( - With allow_partial_stake=True: A partial amount will be swapped up to the point where the price ratio would increase by rate_tolerance """ - amount = check_and_convert_to_balance(amount) + check_balance_amount(amount) return swap_stake_extrinsic( subtensor=self, wallet=wallet, @@ -4450,8 +4454,7 @@ def transfer( Returns: ExtrinsicResponse: The result object of the extrinsic execution. """ - if amount is not None: - amount = check_and_convert_to_balance(amount) + check_balance_amount(amount) return transfer_extrinsic( subtensor=self, wallet=wallet, @@ -4498,7 +4501,7 @@ def transfer_stake( Returns: ExtrinsicResponse: The result object of the extrinsic execution. """ - amount = check_and_convert_to_balance(amount) + check_balance_amount(amount) return transfer_stake_extrinsic( subtensor=self, wallet=wallet, @@ -4557,7 +4560,7 @@ def unstake( 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) + check_balance_amount(amount) return unstake_extrinsic( subtensor=self, wallet=wallet, diff --git a/bittensor/core/subtensor_api/utils.py b/bittensor/core/subtensor_api/utils.py deleted file mode 100644 index 212cdcebcc..0000000000 --- a/bittensor/core/subtensor_api/utils.py +++ /dev/null @@ -1,181 +0,0 @@ -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from bittensor.core.subtensor_api import SubtensorApi - - -def add_legacy_methods(subtensor: "SubtensorApi"): - """If SubtensorApi get `subtensor_fields=True` arguments, then all classic Subtensor fields added to root level.""" - subtensor.add_liquidity = subtensor._subtensor.add_liquidity - subtensor.add_stake = subtensor._subtensor.add_stake - subtensor.add_stake_multiple = subtensor._subtensor.add_stake_multiple - subtensor.all_subnets = subtensor._subtensor.all_subnets - subtensor.blocks_since_last_step = subtensor._subtensor.blocks_since_last_step - subtensor.blocks_since_last_update = subtensor._subtensor.blocks_since_last_update - subtensor.bonds = subtensor._subtensor.bonds - subtensor.burned_register = subtensor._subtensor.burned_register - subtensor.chain_endpoint = subtensor._subtensor.chain_endpoint - 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 - subtensor.difficulty = subtensor._subtensor.difficulty - subtensor.does_hotkey_exist = subtensor._subtensor.does_hotkey_exist - subtensor.encode_params = subtensor._subtensor.encode_params - subtensor.filter_netuids_by_registered_hotkeys = ( - subtensor._subtensor.filter_netuids_by_registered_hotkeys - ) - subtensor.get_admin_freeze_window = subtensor._subtensor.get_admin_freeze_window - subtensor.get_all_commitments = subtensor._subtensor.get_all_commitments - subtensor.get_all_metagraphs_info = subtensor._subtensor.get_all_metagraphs_info - subtensor.get_all_neuron_certificates = ( - subtensor._subtensor.get_all_neuron_certificates - ) - subtensor.get_all_revealed_commitments = ( - subtensor._subtensor.get_all_revealed_commitments - ) - subtensor.get_all_subnets_info = subtensor._subtensor.get_all_subnets_info - subtensor.get_balance = subtensor._subtensor.get_balance - subtensor.get_balances = subtensor._subtensor.get_balances - subtensor.get_block_hash = subtensor._subtensor.get_block_hash - subtensor.get_parents = subtensor._subtensor.get_parents - subtensor.get_children = subtensor._subtensor.get_children - subtensor.get_children_pending = subtensor._subtensor.get_children_pending - subtensor.get_commitment = subtensor._subtensor.get_commitment - subtensor.get_current_block = subtensor._subtensor.get_current_block - subtensor.get_last_commitment_bonds_reset_block = ( - subtensor._subtensor.get_last_commitment_bonds_reset_block - ) - subtensor.get_delegate_by_hotkey = subtensor._subtensor.get_delegate_by_hotkey - subtensor.get_delegate_identities = subtensor._subtensor.get_delegate_identities - subtensor.get_delegate_take = subtensor._subtensor.get_delegate_take - subtensor.get_delegated = subtensor._subtensor.get_delegated - subtensor.get_delegates = subtensor._subtensor.get_delegates - subtensor.get_existential_deposit = subtensor._subtensor.get_existential_deposit - subtensor.get_hotkey_owner = subtensor._subtensor.get_hotkey_owner - subtensor.get_hotkey_stake = subtensor._subtensor.get_hotkey_stake - subtensor.get_hyperparameter = subtensor._subtensor.get_hyperparameter - subtensor.get_liquidity_list = subtensor._subtensor.get_liquidity_list - subtensor.get_metagraph_info = subtensor._subtensor.get_metagraph_info - subtensor.get_minimum_required_stake = ( - subtensor._subtensor.get_minimum_required_stake - ) - subtensor.get_netuids_for_hotkey = subtensor._subtensor.get_netuids_for_hotkey - subtensor.get_neuron_certificate = subtensor._subtensor.get_neuron_certificate - subtensor.get_neuron_for_pubkey_and_subnet = ( - subtensor._subtensor.get_neuron_for_pubkey_and_subnet - ) - subtensor.get_next_epoch_start_block = ( - subtensor._subtensor.get_next_epoch_start_block - ) - subtensor.get_owned_hotkeys = subtensor._subtensor.get_owned_hotkeys - subtensor.get_revealed_commitment = subtensor._subtensor.get_revealed_commitment - subtensor.get_revealed_commitment_by_hotkey = ( - subtensor._subtensor.get_revealed_commitment_by_hotkey - ) - subtensor.get_stake = subtensor._subtensor.get_stake - subtensor.get_stake_add_fee = subtensor._subtensor.get_stake_add_fee - subtensor.get_stake_for_coldkey = subtensor._subtensor.get_stake_for_coldkey - subtensor.get_stake_for_coldkey_and_hotkey = ( - subtensor._subtensor.get_stake_for_coldkey_and_hotkey - ) - subtensor.get_stake_for_hotkey = subtensor._subtensor.get_stake_for_hotkey - subtensor.get_stake_info_for_coldkey = ( - subtensor._subtensor.get_stake_info_for_coldkey - ) - subtensor.get_stake_movement_fee = subtensor._subtensor.get_stake_movement_fee - subtensor.get_stake_operations_fee = subtensor._subtensor.get_stake_operations_fee - subtensor.get_stake_weight = subtensor._subtensor.get_stake_weight - subtensor.get_mechanism_emission_split = ( - subtensor._subtensor.get_mechanism_emission_split - ) - subtensor.get_mechanism_count = subtensor._subtensor.get_mechanism_count - subtensor.get_subnet_burn_cost = subtensor._subtensor.get_subnet_burn_cost - subtensor.get_subnet_hyperparameters = ( - subtensor._subtensor.get_subnet_hyperparameters - ) - subtensor.get_subnet_info = subtensor._subtensor.get_subnet_info - subtensor.get_subnet_price = subtensor._subtensor.get_subnet_price - subtensor.get_subnet_prices = subtensor._subtensor.get_subnet_prices - subtensor.get_subnet_owner_hotkey = subtensor._subtensor.get_subnet_owner_hotkey - subtensor.get_subnet_reveal_period_epochs = ( - subtensor._subtensor.get_subnet_reveal_period_epochs - ) - subtensor.get_subnet_validator_permits = ( - subtensor._subtensor.get_subnet_validator_permits - ) - subtensor.get_subnets = subtensor._subtensor.get_subnets - subtensor.get_timelocked_weight_commits = ( - subtensor._subtensor.get_timelocked_weight_commits - ) - subtensor.get_timestamp = subtensor._subtensor.get_timestamp - subtensor.get_total_subnets = subtensor._subtensor.get_total_subnets - subtensor.get_transfer_fee = subtensor._subtensor.get_transfer_fee - subtensor.get_uid_for_hotkey_on_subnet = ( - subtensor._subtensor.get_uid_for_hotkey_on_subnet - ) - subtensor.get_unstake_fee = subtensor._subtensor.get_unstake_fee - subtensor.get_vote_data = subtensor._subtensor.get_vote_data - subtensor.immunity_period = subtensor._subtensor.immunity_period - subtensor.is_fast_blocks = subtensor._subtensor.is_fast_blocks - subtensor.is_hotkey_delegate = subtensor._subtensor.is_hotkey_delegate - subtensor.is_hotkey_registered = subtensor._subtensor.is_hotkey_registered - subtensor.is_hotkey_registered_any = subtensor._subtensor.is_hotkey_registered_any - subtensor.is_hotkey_registered_on_subnet = ( - subtensor._subtensor.is_hotkey_registered_on_subnet - ) - subtensor.is_in_admin_freeze_window = subtensor._subtensor.is_in_admin_freeze_window - subtensor.is_subnet_active = subtensor._subtensor.is_subnet_active - subtensor.last_drand_round = subtensor._subtensor.last_drand_round - subtensor.log_verbose = subtensor._subtensor.log_verbose - subtensor.max_weight_limit = subtensor._subtensor.max_weight_limit - subtensor.metagraph = subtensor._subtensor.metagraph - subtensor.min_allowed_weights = subtensor._subtensor.min_allowed_weights - subtensor.modify_liquidity = subtensor._subtensor.modify_liquidity - subtensor.move_stake = subtensor._subtensor.move_stake - subtensor.network = subtensor._subtensor.network - subtensor.neurons = subtensor._subtensor.neurons - subtensor.neuron_for_uid = subtensor._subtensor.neuron_for_uid - subtensor.neurons_lite = subtensor._subtensor.neurons_lite - subtensor.query_constant = subtensor._subtensor.query_constant - subtensor.query_identity = subtensor._subtensor.query_identity - subtensor.query_map = subtensor._subtensor.query_map - subtensor.query_map_subtensor = subtensor._subtensor.query_map_subtensor - subtensor.query_module = subtensor._subtensor.query_module - subtensor.query_runtime_api = subtensor._subtensor.query_runtime_api - subtensor.query_subtensor = subtensor._subtensor.query_subtensor - subtensor.recycle = subtensor._subtensor.recycle - subtensor.remove_liquidity = subtensor._subtensor.remove_liquidity - subtensor.register = subtensor._subtensor.register - subtensor.register_subnet = subtensor._subtensor.register_subnet - subtensor.reveal_weights = subtensor._subtensor.reveal_weights - subtensor.root_register = subtensor._subtensor.root_register - subtensor.root_set_pending_childkey_cooldown = ( - subtensor._subtensor.root_set_pending_childkey_cooldown - ) - subtensor.serve_axon = subtensor._subtensor.serve_axon - subtensor.set_children = subtensor._subtensor.set_children - subtensor.set_commitment = subtensor._subtensor.set_commitment - subtensor.set_delegate_take = subtensor._subtensor.set_delegate_take - subtensor.set_reveal_commitment = subtensor._subtensor.set_reveal_commitment - subtensor.set_subnet_identity = subtensor._subtensor.set_subnet_identity - subtensor.set_weights = subtensor._subtensor.set_weights - subtensor.setup_config = subtensor._subtensor.setup_config - subtensor.sign_and_send_extrinsic = subtensor._subtensor.sign_and_send_extrinsic - subtensor.start_call = subtensor._subtensor.start_call - subtensor.state_call = subtensor._subtensor.state_call - subtensor.subnet = subtensor._subtensor.subnet - subtensor.subnet_exists = subtensor._subtensor.subnet_exists - subtensor.subnetwork_n = subtensor._subtensor.subnetwork_n - subtensor.substrate = subtensor._subtensor.substrate - subtensor.swap_stake = subtensor._subtensor.swap_stake - subtensor.tempo = subtensor._subtensor.tempo - subtensor.toggle_user_liquidity = subtensor._subtensor.toggle_user_liquidity - subtensor.transfer = subtensor._subtensor.transfer - subtensor.transfer_stake = subtensor._subtensor.transfer_stake - subtensor.tx_rate_limit = subtensor._subtensor.tx_rate_limit - subtensor.unstake = subtensor._subtensor.unstake - subtensor.unstake_all = subtensor._subtensor.unstake_all - subtensor.unstake_multiple = subtensor._subtensor.unstake_multiple - subtensor.wait_for_block = subtensor._subtensor.wait_for_block - subtensor.weights = subtensor._subtensor.weights - subtensor.weights_rate_limit = subtensor._subtensor.weights_rate_limit diff --git a/bittensor/extras/__init__.py b/bittensor/extras/__init__.py new file mode 100644 index 0000000000..27ccdbaeaf --- /dev/null +++ b/bittensor/extras/__init__.py @@ -0,0 +1,18 @@ +""" +The `addons` sub-package contains optional extensions and logic augmentations for the core functionality of the project. + +Modules placed in this package may include experimental features, alternative implementations, developer tools, or +enhancements that extend or customize core behavior. These components are not always critical for the main application, +but can be enabled or imported as needed for advanced use cases, internal tooling, or feature expansion. + +Use this package to keep optional, modular, or feature-gated logic separate from the primary codebase while maintaining +discoverability and structure. +""" + +from bittensor.extras import timelock +from bittensor.extras.subtensor_api import SubtensorApi + +__all__ = [ + "timelock", + "SubtensorApi", +] diff --git a/bittensor/core/subtensor_api/__init__.py b/bittensor/extras/subtensor_api/__init__.py similarity index 84% rename from bittensor/core/subtensor_api/__init__.py rename to bittensor/extras/subtensor_api/__init__.py index 63bfd137c3..7f9a8e500a 100644 --- a/bittensor/core/subtensor_api/__init__.py +++ b/bittensor/extras/subtensor_api/__init__.py @@ -94,24 +94,24 @@ def __init__( # assigned only for async instance self.initialize = None - self._subtensor = self._get_subtensor() + self.inner_subtensor = self._get_subtensor() # fix naming collision - self._neurons = _Neurons(self._subtensor) + self._neurons = _Neurons(self.inner_subtensor) # define empty fields - self.substrate = self._subtensor.substrate - self.chain_endpoint = self._subtensor.chain_endpoint - self.close = self._subtensor.close - self.config = self._subtensor.config - self.setup_config = self._subtensor.setup_config - self.help = self._subtensor.help - - self.determine_block_hash = self._subtensor.determine_block_hash - self.encode_params = self._subtensor.encode_params - self.sign_and_send_extrinsic = self._subtensor.sign_and_send_extrinsic - self.start_call = self._subtensor.start_call - self.wait_for_block = self._subtensor.wait_for_block + self.substrate = self.inner_subtensor.substrate + self.chain_endpoint = self.inner_subtensor.chain_endpoint + self.close = self.inner_subtensor.close + self.config = self.inner_subtensor.config + self.setup_config = self.inner_subtensor.setup_config + self.help = self.inner_subtensor.help + + self.determine_block_hash = self.inner_subtensor.determine_block_hash + self.encode_params = self.inner_subtensor.encode_params + self.sign_and_send_extrinsic = self.inner_subtensor.sign_and_send_extrinsic + self.start_call = self.inner_subtensor.start_call + self.wait_for_block = self.inner_subtensor.wait_for_block # adds all Subtensor methods into main level os SubtensorApi class if legacy_methods: @@ -126,7 +126,7 @@ def _get_subtensor(self) -> Union["_Subtensor", "_AsyncSubtensor"]: log_verbose=self.log_verbose, fallback_endpoints=self._fallback_endpoints, retry_forever=self._retry_forever, - _mock=self._mock, + mock=self._mock, archive_endpoints=self._archive_endpoints, websocket_shutdown_timer=self._ws_shutdown_timer, ) @@ -139,7 +139,7 @@ def _get_subtensor(self) -> Union["_Subtensor", "_AsyncSubtensor"]: log_verbose=self.log_verbose, fallback_endpoints=self._fallback_endpoints, retry_forever=self._retry_forever, - _mock=self._mock, + mock=self._mock, archive_endpoints=self._archive_endpoints, ) @@ -178,7 +178,7 @@ async def __aenter__(self): raise NotImplementedError( "Sync version of SubtensorApi cannot be used with async context manager." ) - await self._subtensor.__aenter__() + await self.inner_subtensor.__aenter__() return self async def __aexit__(self, exc_type, exc_val, exc_tb): @@ -195,32 +195,32 @@ def add_args(cls, parser): @property def block(self): """Returns current chain block number.""" - return self._subtensor.block + return self.inner_subtensor.block @property def chain(self): """Property of interaction with chain methods.""" - return _Chain(self._subtensor) + return _Chain(self.inner_subtensor) @property def commitments(self): """Property to access commitments methods.""" - return _Commitments(self._subtensor) + return _Commitments(self.inner_subtensor) @property def delegates(self): """Property to access delegates methods.""" - return _Delegates(self._subtensor) + return _Delegates(self.inner_subtensor) @property def extrinsics(self): """Property to access extrinsics methods.""" - return _Extrinsics(self._subtensor) + return _Extrinsics(self.inner_subtensor) @property def metagraphs(self): """Property to access metagraphs methods.""" - return _Metagraphs(self._subtensor) + return _Metagraphs(self.inner_subtensor) @property def neurons(self): @@ -235,19 +235,19 @@ def neurons(self, value): @property def queries(self): """Property to access subtensor queries methods.""" - return _Queries(self._subtensor) + return _Queries(self.inner_subtensor) @property def staking(self): """Property to access staking methods.""" - return _Staking(self._subtensor) + return _Staking(self.inner_subtensor) @property def subnets(self): """Property of interaction with subnets methods.""" - return _Subnets(self._subtensor) + return _Subnets(self.inner_subtensor) @property def wallets(self): """Property of interaction methods with cold/hotkeys, and balances, etc.""" - return _Wallets(self._subtensor) + return _Wallets(self.inner_subtensor) diff --git a/bittensor/core/subtensor_api/chain.py b/bittensor/extras/subtensor_api/chain.py similarity index 100% rename from bittensor/core/subtensor_api/chain.py rename to bittensor/extras/subtensor_api/chain.py index 9f4c312f13..8a45169169 100644 --- a/bittensor/core/subtensor_api/chain.py +++ b/bittensor/extras/subtensor_api/chain.py @@ -13,10 +13,10 @@ def __init__(self, subtensor: Union["_Subtensor", "_AsyncSubtensor"]): self.get_delegate_identities = subtensor.get_delegate_identities self.get_existential_deposit = subtensor.get_existential_deposit self.get_minimum_required_stake = subtensor.get_minimum_required_stake - self.get_vote_data = subtensor.get_vote_data self.get_timestamp = subtensor.get_timestamp - self.is_in_admin_freeze_window = subtensor.is_in_admin_freeze_window + self.get_vote_data = subtensor.get_vote_data self.is_fast_blocks = subtensor.is_fast_blocks + self.is_in_admin_freeze_window = subtensor.is_in_admin_freeze_window self.last_drand_round = subtensor.last_drand_round self.state_call = subtensor.state_call self.tx_rate_limit = subtensor.tx_rate_limit diff --git a/bittensor/core/subtensor_api/commitments.py b/bittensor/extras/subtensor_api/commitments.py similarity index 100% rename from bittensor/core/subtensor_api/commitments.py rename to bittensor/extras/subtensor_api/commitments.py diff --git a/bittensor/core/subtensor_api/delegates.py b/bittensor/extras/subtensor_api/delegates.py similarity index 100% rename from bittensor/core/subtensor_api/delegates.py rename to bittensor/extras/subtensor_api/delegates.py diff --git a/bittensor/core/subtensor_api/extrinsics.py b/bittensor/extras/subtensor_api/extrinsics.py similarity index 100% rename from bittensor/core/subtensor_api/extrinsics.py rename to bittensor/extras/subtensor_api/extrinsics.py diff --git a/bittensor/core/subtensor_api/metagraphs.py b/bittensor/extras/subtensor_api/metagraphs.py similarity index 100% rename from bittensor/core/subtensor_api/metagraphs.py rename to bittensor/extras/subtensor_api/metagraphs.py diff --git a/bittensor/core/subtensor_api/neurons.py b/bittensor/extras/subtensor_api/neurons.py similarity index 100% rename from bittensor/core/subtensor_api/neurons.py rename to bittensor/extras/subtensor_api/neurons.py diff --git a/bittensor/core/subtensor_api/queries.py b/bittensor/extras/subtensor_api/queries.py similarity index 100% rename from bittensor/core/subtensor_api/queries.py rename to bittensor/extras/subtensor_api/queries.py diff --git a/bittensor/core/subtensor_api/staking.py b/bittensor/extras/subtensor_api/staking.py similarity index 95% rename from bittensor/core/subtensor_api/staking.py rename to bittensor/extras/subtensor_api/staking.py index a85d88250e..d84ecc1357 100644 --- a/bittensor/core/subtensor_api/staking.py +++ b/bittensor/extras/subtensor_api/staking.py @@ -13,7 +13,6 @@ def __init__(self, subtensor: Union["_Subtensor", "_AsyncSubtensor"]): self.get_minimum_required_stake = subtensor.get_minimum_required_stake self.get_stake = subtensor.get_stake self.get_stake_add_fee = subtensor.get_stake_add_fee - self.get_stake_for_coldkey = subtensor.get_stake_for_coldkey self.get_stake_for_coldkey_and_hotkey = ( subtensor.get_stake_for_coldkey_and_hotkey ) diff --git a/bittensor/core/subtensor_api/subnets.py b/bittensor/extras/subtensor_api/subnets.py similarity index 97% rename from bittensor/core/subtensor_api/subnets.py rename to bittensor/extras/subtensor_api/subnets.py index 30c31ff7e1..75b8adbf13 100644 --- a/bittensor/core/subtensor_api/subnets.py +++ b/bittensor/extras/subtensor_api/subnets.py @@ -16,6 +16,7 @@ def __init__(self, subtensor: Union["_Subtensor", "_AsyncSubtensor"]): self.commit_reveal_enabled = subtensor.commit_reveal_enabled self.difficulty = subtensor.difficulty self.get_all_subnets_info = subtensor.get_all_subnets_info + self.get_all_subnets_netuid = subtensor.get_all_subnets_netuid self.get_parents = subtensor.get_parents self.get_children = subtensor.get_children self.get_children_pending = subtensor.get_children_pending @@ -35,7 +36,6 @@ def __init__(self, subtensor: Union["_Subtensor", "_AsyncSubtensor"]): self.get_subnet_owner_hotkey = subtensor.get_subnet_owner_hotkey self.get_subnet_reveal_period_epochs = subtensor.get_subnet_reveal_period_epochs self.get_subnet_validator_permits = subtensor.get_subnet_validator_permits - self.get_subnets = subtensor.get_subnets self.get_total_subnets = subtensor.get_total_subnets self.get_uid_for_hotkey_on_subnet = subtensor.get_uid_for_hotkey_on_subnet self.immunity_period = subtensor.immunity_period diff --git a/bittensor/extras/subtensor_api/utils.py b/bittensor/extras/subtensor_api/utils.py new file mode 100644 index 0000000000..b12e18667f --- /dev/null +++ b/bittensor/extras/subtensor_api/utils.py @@ -0,0 +1,202 @@ +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from bittensor.extras import SubtensorApi + + +def add_legacy_methods(subtensor: "SubtensorApi"): + """If SubtensorApi get `subtensor_fields=True` arguments, then all classic Subtensor fields added to root level.""" + subtensor.add_liquidity = subtensor.inner_subtensor.add_liquidity + subtensor.add_stake = subtensor.inner_subtensor.add_stake + subtensor.add_stake_multiple = subtensor.inner_subtensor.add_stake_multiple + subtensor.all_subnets = subtensor.inner_subtensor.all_subnets + subtensor.blocks_since_last_step = subtensor.inner_subtensor.blocks_since_last_step + subtensor.blocks_since_last_update = ( + subtensor.inner_subtensor.blocks_since_last_update + ) + subtensor.bonds = subtensor.inner_subtensor.bonds + subtensor.burned_register = subtensor.inner_subtensor.burned_register + subtensor.chain_endpoint = subtensor.inner_subtensor.chain_endpoint + subtensor.commit_reveal_enabled = subtensor.inner_subtensor.commit_reveal_enabled + subtensor.commit_weights = subtensor.inner_subtensor.commit_weights + subtensor.determine_block_hash = subtensor.inner_subtensor.determine_block_hash + subtensor.difficulty = subtensor.inner_subtensor.difficulty + subtensor.does_hotkey_exist = subtensor.inner_subtensor.does_hotkey_exist + subtensor.encode_params = subtensor.inner_subtensor.encode_params + subtensor.filter_netuids_by_registered_hotkeys = ( + subtensor.inner_subtensor.filter_netuids_by_registered_hotkeys + ) + subtensor.get_admin_freeze_window = ( + subtensor.inner_subtensor.get_admin_freeze_window + ) + subtensor.get_all_commitments = subtensor.inner_subtensor.get_all_commitments + subtensor.get_all_metagraphs_info = ( + subtensor.inner_subtensor.get_all_metagraphs_info + ) + subtensor.get_all_neuron_certificates = ( + subtensor.inner_subtensor.get_all_neuron_certificates + ) + subtensor.get_all_revealed_commitments = ( + subtensor.inner_subtensor.get_all_revealed_commitments + ) + subtensor.get_all_subnets_info = subtensor.inner_subtensor.get_all_subnets_info + subtensor.get_balance = subtensor.inner_subtensor.get_balance + subtensor.get_balances = subtensor.inner_subtensor.get_balances + subtensor.get_block_hash = subtensor.inner_subtensor.get_block_hash + subtensor.get_children = subtensor.inner_subtensor.get_children + subtensor.get_children_pending = subtensor.inner_subtensor.get_children_pending + subtensor.get_commitment = subtensor.inner_subtensor.get_commitment + subtensor.get_current_block = subtensor.inner_subtensor.get_current_block + subtensor.get_delegate_by_hotkey = subtensor.inner_subtensor.get_delegate_by_hotkey + subtensor.get_delegate_identities = ( + subtensor.inner_subtensor.get_delegate_identities + ) + subtensor.get_delegate_take = subtensor.inner_subtensor.get_delegate_take + subtensor.get_delegated = subtensor.inner_subtensor.get_delegated + subtensor.get_delegates = subtensor.inner_subtensor.get_delegates + subtensor.get_existential_deposit = ( + subtensor.inner_subtensor.get_existential_deposit + ) + subtensor.get_hotkey_owner = subtensor.inner_subtensor.get_hotkey_owner + subtensor.get_hotkey_stake = subtensor.inner_subtensor.get_hotkey_stake + subtensor.get_hyperparameter = subtensor.inner_subtensor.get_hyperparameter + subtensor.get_last_commitment_bonds_reset_block = ( + subtensor.inner_subtensor.get_last_commitment_bonds_reset_block + ) + subtensor.get_liquidity_list = subtensor.inner_subtensor.get_liquidity_list + subtensor.get_mechanism_count = subtensor.inner_subtensor.get_mechanism_count + subtensor.get_mechanism_emission_split = ( + subtensor.inner_subtensor.get_mechanism_emission_split + ) + subtensor.get_metagraph_info = subtensor.inner_subtensor.get_metagraph_info + subtensor.get_minimum_required_stake = ( + subtensor.inner_subtensor.get_minimum_required_stake + ) + subtensor.get_netuids_for_hotkey = subtensor.inner_subtensor.get_netuids_for_hotkey + subtensor.get_neuron_certificate = subtensor.inner_subtensor.get_neuron_certificate + subtensor.get_neuron_for_pubkey_and_subnet = ( + subtensor.inner_subtensor.get_neuron_for_pubkey_and_subnet + ) + subtensor.get_next_epoch_start_block = ( + subtensor.inner_subtensor.get_next_epoch_start_block + ) + subtensor.get_owned_hotkeys = subtensor.inner_subtensor.get_owned_hotkeys + subtensor.get_parents = subtensor.inner_subtensor.get_parents + subtensor.get_revealed_commitment = ( + subtensor.inner_subtensor.get_revealed_commitment + ) + subtensor.get_revealed_commitment_by_hotkey = ( + subtensor.inner_subtensor.get_revealed_commitment_by_hotkey + ) + subtensor.get_stake = subtensor.inner_subtensor.get_stake + subtensor.get_stake_add_fee = subtensor.inner_subtensor.get_stake_add_fee + subtensor.get_stake_for_coldkey_and_hotkey = ( + subtensor.inner_subtensor.get_stake_for_coldkey_and_hotkey + ) + subtensor.get_stake_for_hotkey = subtensor.inner_subtensor.get_stake_for_hotkey + subtensor.get_stake_info_for_coldkey = ( + subtensor.inner_subtensor.get_stake_info_for_coldkey + ) + subtensor.get_stake_movement_fee = subtensor.inner_subtensor.get_stake_movement_fee + subtensor.get_stake_operations_fee = ( + subtensor.inner_subtensor.get_stake_operations_fee + ) + subtensor.get_stake_weight = subtensor.inner_subtensor.get_stake_weight + subtensor.get_subnet_burn_cost = subtensor.inner_subtensor.get_subnet_burn_cost + subtensor.get_subnet_hyperparameters = ( + subtensor.inner_subtensor.get_subnet_hyperparameters + ) + subtensor.get_subnet_info = subtensor.inner_subtensor.get_subnet_info + subtensor.get_subnet_owner_hotkey = ( + subtensor.inner_subtensor.get_subnet_owner_hotkey + ) + subtensor.get_subnet_price = subtensor.inner_subtensor.get_subnet_price + subtensor.get_subnet_prices = subtensor.inner_subtensor.get_subnet_prices + subtensor.get_subnet_reveal_period_epochs = ( + subtensor.inner_subtensor.get_subnet_reveal_period_epochs + ) + subtensor.get_subnet_validator_permits = ( + subtensor.inner_subtensor.get_subnet_validator_permits + ) + subtensor.get_all_subnets_netuid = subtensor.inner_subtensor.get_all_subnets_netuid + subtensor.get_timelocked_weight_commits = ( + subtensor.inner_subtensor.get_timelocked_weight_commits + ) + subtensor.get_timestamp = subtensor.inner_subtensor.get_timestamp + subtensor.get_total_subnets = subtensor.inner_subtensor.get_total_subnets + subtensor.get_transfer_fee = subtensor.inner_subtensor.get_transfer_fee + subtensor.get_uid_for_hotkey_on_subnet = ( + subtensor.inner_subtensor.get_uid_for_hotkey_on_subnet + ) + subtensor.get_unstake_fee = subtensor.inner_subtensor.get_unstake_fee + subtensor.get_vote_data = subtensor.inner_subtensor.get_vote_data + subtensor.immunity_period = subtensor.inner_subtensor.immunity_period + subtensor.is_fast_blocks = subtensor.inner_subtensor.is_fast_blocks + subtensor.is_hotkey_delegate = subtensor.inner_subtensor.is_hotkey_delegate + subtensor.is_hotkey_registered = subtensor.inner_subtensor.is_hotkey_registered + subtensor.is_hotkey_registered_any = ( + subtensor.inner_subtensor.is_hotkey_registered_any + ) + subtensor.is_hotkey_registered_on_subnet = ( + subtensor.inner_subtensor.is_hotkey_registered_on_subnet + ) + subtensor.is_in_admin_freeze_window = ( + subtensor.inner_subtensor.is_in_admin_freeze_window + ) + subtensor.is_subnet_active = subtensor.inner_subtensor.is_subnet_active + subtensor.last_drand_round = subtensor.inner_subtensor.last_drand_round + subtensor.log_verbose = subtensor.inner_subtensor.log_verbose + subtensor.max_weight_limit = subtensor.inner_subtensor.max_weight_limit + subtensor.metagraph = subtensor.inner_subtensor.metagraph + subtensor.min_allowed_weights = subtensor.inner_subtensor.min_allowed_weights + subtensor.modify_liquidity = subtensor.inner_subtensor.modify_liquidity + subtensor.move_stake = subtensor.inner_subtensor.move_stake + subtensor.neuron_for_uid = subtensor.inner_subtensor.neuron_for_uid + subtensor.neurons = subtensor.inner_subtensor.neurons + subtensor.neurons_lite = subtensor.inner_subtensor.neurons_lite + subtensor.network = subtensor.inner_subtensor.network + subtensor.query_constant = subtensor.inner_subtensor.query_constant + subtensor.query_identity = subtensor.inner_subtensor.query_identity + subtensor.query_map = subtensor.inner_subtensor.query_map + subtensor.query_map_subtensor = subtensor.inner_subtensor.query_map_subtensor + subtensor.query_module = subtensor.inner_subtensor.query_module + subtensor.query_runtime_api = subtensor.inner_subtensor.query_runtime_api + subtensor.query_subtensor = subtensor.inner_subtensor.query_subtensor + subtensor.recycle = subtensor.inner_subtensor.recycle + subtensor.register = subtensor.inner_subtensor.register + subtensor.register_subnet = subtensor.inner_subtensor.register_subnet + subtensor.remove_liquidity = subtensor.inner_subtensor.remove_liquidity + subtensor.reveal_weights = subtensor.inner_subtensor.reveal_weights + subtensor.root_register = subtensor.inner_subtensor.root_register + subtensor.root_set_pending_childkey_cooldown = ( + subtensor.inner_subtensor.root_set_pending_childkey_cooldown + ) + subtensor.serve_axon = subtensor.inner_subtensor.serve_axon + subtensor.set_children = subtensor.inner_subtensor.set_children + subtensor.set_commitment = subtensor.inner_subtensor.set_commitment + subtensor.set_delegate_take = subtensor.inner_subtensor.set_delegate_take + subtensor.set_reveal_commitment = subtensor.inner_subtensor.set_reveal_commitment + subtensor.set_subnet_identity = subtensor.inner_subtensor.set_subnet_identity + subtensor.set_weights = subtensor.inner_subtensor.set_weights + subtensor.setup_config = subtensor.inner_subtensor.setup_config + subtensor.sign_and_send_extrinsic = ( + subtensor.inner_subtensor.sign_and_send_extrinsic + ) + subtensor.start_call = subtensor.inner_subtensor.start_call + subtensor.state_call = subtensor.inner_subtensor.state_call + subtensor.subnet = subtensor.inner_subtensor.subnet + subtensor.subnet_exists = subtensor.inner_subtensor.subnet_exists + subtensor.subnetwork_n = subtensor.inner_subtensor.subnetwork_n + subtensor.substrate = subtensor.inner_subtensor.substrate + subtensor.swap_stake = subtensor.inner_subtensor.swap_stake + subtensor.tempo = subtensor.inner_subtensor.tempo + subtensor.toggle_user_liquidity = subtensor.inner_subtensor.toggle_user_liquidity + subtensor.transfer = subtensor.inner_subtensor.transfer + subtensor.transfer_stake = subtensor.inner_subtensor.transfer_stake + subtensor.tx_rate_limit = subtensor.inner_subtensor.tx_rate_limit + subtensor.unstake = subtensor.inner_subtensor.unstake + subtensor.unstake_all = subtensor.inner_subtensor.unstake_all + subtensor.unstake_multiple = subtensor.inner_subtensor.unstake_multiple + subtensor.wait_for_block = subtensor.inner_subtensor.wait_for_block + subtensor.weights = subtensor.inner_subtensor.weights + subtensor.weights_rate_limit = subtensor.inner_subtensor.weights_rate_limit diff --git a/bittensor/core/subtensor_api/wallets.py b/bittensor/extras/subtensor_api/wallets.py similarity index 96% rename from bittensor/core/subtensor_api/wallets.py rename to bittensor/extras/subtensor_api/wallets.py index 9b3a3a058b..3ad195ae45 100644 --- a/bittensor/core/subtensor_api/wallets.py +++ b/bittensor/extras/subtensor_api/wallets.py @@ -30,7 +30,6 @@ def __init__(self, subtensor: Union["_Subtensor", "_AsyncSubtensor"]): self.get_parents = subtensor.get_parents self.get_stake = subtensor.get_stake self.get_stake_add_fee = subtensor.get_stake_add_fee - self.get_stake_for_coldkey = subtensor.get_stake_for_coldkey self.get_stake_for_coldkey_and_hotkey = ( subtensor.get_stake_for_coldkey_and_hotkey ) diff --git a/bittensor/core/timelock.py b/bittensor/extras/timelock.py similarity index 100% rename from bittensor/core/timelock.py rename to bittensor/extras/timelock.py diff --git a/bittensor/utils/__init__.py b/bittensor/utils/__init__.py index c75a0b7936..7d58d94de3 100644 --- a/bittensor/utils/__init__.py +++ b/bittensor/utils/__init__.py @@ -1,29 +1,38 @@ import ast import decimal import hashlib +import inspect import warnings from collections import namedtuple from typing import Any, Literal, Union, Optional, TYPE_CHECKING from urllib.parse import urlparse -import inspect + import scalecodec from async_substrate_interface.utils import ( hex_to_bytes, ) from bittensor_wallet import Keypair from bittensor_wallet.errors import KeyFileError, PasswordError -from scalecodec import ss58_decode, is_valid_ss58_address as _is_valid_ss58_address +from scalecodec import ( + ss58_decode, + ss58_encode, + is_valid_ss58_address as _is_valid_ss58_address, +) from bittensor.core import settings from bittensor.core.settings import SS58_FORMAT from bittensor.utils.btlogging import logging from .registration import torch, use_torch -from .version import version_checking, check_version, VersionCheckError +from .version import check_version, VersionCheckError if TYPE_CHECKING: from bittensor_wallet import Wallet from bittensor.utils.balance import Balance +# keep save from import analyzer as obvious aliases +hex_to_ss58 = ss58_encode +ss58_to_hex = ss58_decode + BT_DOCS_LINK = "https://docs.bittensor.com" RAOPERTAO = 1e9 U16_MAX = 65535 @@ -36,7 +45,6 @@ logging = logging torch = torch use_torch = use_torch -version_checking = version_checking check_version = check_version VersionCheckError = VersionCheckError ss58_decode = ss58_decode diff --git a/bittensor/utils/balance.py b/bittensor/utils/balance.py index 5a84960152..f585dd0b11 100644 --- a/bittensor/utils/balance.py +++ b/bittensor/utils/balance.py @@ -1,10 +1,9 @@ -import warnings -from typing import Union, TypedDict, Optional +from typing import Optional, TypedDict, Union from scalecodec import ScaleType from bittensor.core import settings -from bittensor.utils import deprecated_message +from bittensor.core.errors import BalanceTypeError, BalanceUnitMismatchError def _check_currencies(self, other): @@ -13,40 +12,68 @@ def _check_currencies(self, other): A warning is raised if the netuids differ. Example: - >>> balance1 = Balance.from_rao(1000).set_unit(12) - >>> balance2 = Balance.from_rao(500).set_unit(12) - >>> balance1 + balance2 # No warning + balance1 = Balance.from_rao(1000).set_unit(14) + balance2 = Balance.from_tao(500).set_unit(14) + balance1 + balance2 # No error. - >>> balance3 = Balance.from_rao(200).set_unit(15) - >>> balance1 + balance3 # Raises DeprecationWarning + balance3 = Balance.from_tao(200).set_unit(5) + balance1 + balance3 # Raises BalanceUnitMismatchError. In this example: - - `from_rao` creates a Balance instance from the amount in rao (smallest unit). - - `set_unit(12)` sets the unit to correspond to subnet 12 (i.e., Alpha from netuid 12). + - `from_rao` creates a Balance instance from the amount in rao. + - `set_unit(14)` sets the unit to correspond to subnet 14 (i.e., Alpha from netuid 14). """ if self.netuid != other.netuid: - warnings.simplefilter("default", DeprecationWarning) - warnings.warn( - "Balance objects must have the same netuid (Alpha currency) to perform arithmetic operations.\n" - f"First balance is `{self}`. Second balance is `{other}`.\n\n" - "To create a Balance instance with the correct netuid, use:\n" - "Balance.from_rao(1000).set_unit(12) # 1000 rao in subnet 12", - category=DeprecationWarning, - stacklevel=2, + raise BalanceUnitMismatchError( + f"Cannot perform any operations between balances of different currencies: {self} and {other}. " + "Both Balance objects must reference the same netuid (Alpha currency). " + "For example, to create a Balance instance for subnet 12 you can use: " + "Balance.from_tao(10).set_unit(14), which corresponds to 10 TAO in subnet 14." ) class Balance: """ Represents the bittensor balance of the wallet, stored as rao (int). - This class provides a way to interact with balances in two different units: rao and tao. - It provides methods to convert between these units, as well as to perform arithmetic and comparison operations. + + This class provides a way to interact with balances in two different units: rao and tao. It provides methods to + convert between these units, as well as to perform arithmetic and comparison operations. Attributes: unit (str): A string representing the symbol for the tao unit. rao_unit (str): A string representing the symbol for the rao unit. rao (int): An integer that stores the balance in rao units. tao (float): A float property that gives the balance in tao units. + + Note: + To ensure arithmetic operations between `Balance` instances work correctly, they must set the same unit for each + using the `netuid`. + + Examples: + + balance_wallet_default = Balance.from_tao(10, netuid=14) + balance_wallet_secret = Balance.from_tao(2, netuid=14) + total_balance = balance_wallet_default + balance_wallet_secret + + # or + + balance_wallet_default = Balance.from_tao(10).set_unit(netuid=14) + balance_wallet_secret = Balance.from_tao(2).set_unit(netuid=14) + total_balance = balance_wallet_default + balance_wallet_secret + + The `from_tao()` and `from_rao()` methods accept the `netuid` parameter to set the appropriate unit symbol. + + Note: + When performing arithmetic or comparison operations where the first operand is a `Balance` instance and the + second operand is not, the second operand is implicitly interpreted as a raw amount in `rao`, using the same + unit (netuid) as the first operand. This allows interoperability with integer or float values, but may result in + unexpected behavior if the caller assumes the second operand is in `tao`. + + Example: + balance = Balance.from_tao(10, netuid=14) + result = balance + 5000 # 5 will be treated as 5000 rao, not 5 tao + print(result) + output: τ10.000005000 """ unit: str = settings.TAO_SYMBOL # This is the tao unit @@ -349,6 +376,7 @@ class FixedPoint(TypedDict): def fixed_to_float( fixed: Union[FixedPoint, ScaleType], frac_bits: int = 64, total_bits: int = 128 ) -> float: + """Converts a fixed-point value (e.g., U64F64) into a floating-point number.""" # By default, this is a U64F64 # which is 64 bits of integer and 64 bits of fractional data: int = fb.value if isinstance((fb := fixed["bits"]), ScaleType) else fb @@ -823,17 +851,30 @@ def rao(amount: int, netuid: int = 0) -> Balance: return Balance.from_rao(amount).set_unit(netuid) -def check_and_convert_to_balance( - amount: Union[float, int, Optional[Balance]], -) -> Balance: +def check_balance_amount(amount: Optional[Balance]) -> None: """ - Helper function to check and convert the amount type to a Balance object. - This is used to support backwards compatibility while also providing a deprecation notice. + Validate that the provided value is a Balance instance. + + This function ensures that the `amount` argument is a `Balance` object. If a non-Balance type is passed, it raises + a `BalanceTypeError` to enforce consistent usage of Balance objects across arithmetic operations. + + Args: + amount: The value to validate. + + Returns: + None: Always returns None if validation passes. + + Raises: + BalanceTypeError: If amount is not a Balance instance and not None. """ - if isinstance(amount, (float, int)): - deprecated_message( - "Detected a non-balance amount. Converting to Balance from Tao for backwards compatibility." - "Please update your code to use tao(amount) or Balance.from_tao(amount) for the main release 10.0.0." + if amount is None: + return None + + if not isinstance(amount, Balance): + raise BalanceTypeError( + f"Invalid type detected: amount type is {type(amount)}, but expected a Balance instance. " + "Passing non-Balance types may lead to incorrect calculations. " + "Please update your code to explicitly construct Balance instances " + "(e.g., Balance.from_tao(value)) before using this function." ) - amount = tao(amount) - return amount + return None diff --git a/bittensor/utils/btlogging/levels.py b/bittensor/utils/btlogging/levels.py new file mode 100644 index 0000000000..6115de1473 --- /dev/null +++ b/bittensor/utils/btlogging/levels.py @@ -0,0 +1,42 @@ +from bittensor.utils.btlogging import logging + + +# Logging level setup helpers. +def trace(on: bool = True): + """ + Enables or disables trace logging. + + Parameters: + on: If True, enables trace logging. If False, disables trace logging. + """ + logging.set_trace(on) + + +def debug(on: bool = True): + """ + Enables or disables debug logging. + + Parameters: + on: If True, enables debug logging. If False, disables debug logging. + """ + logging.set_debug(on) + + +def warning(on: bool = True): + """ + Enables or disables warning logging. + + Parameters: + on: If True, enables warning logging. If False, disables warning logging and sets default (WARNING) level. + """ + logging.set_warning(on) + + +def info(on: bool = True): + """ + Enables or disables info logging. + + Parameters: + on: If True, enables info logging. If False, disables info logging and sets default (WARNING) level. + """ + logging.set_info(on) diff --git a/bittensor/utils/easy_imports.py b/bittensor/utils/easy_imports.py index de3399aaa5..f4dd89902d 100644 --- a/bittensor/utils/easy_imports.py +++ b/bittensor/utils/easy_imports.py @@ -1,13 +1,15 @@ """ -The Bittensor Compatibility Module is designed to ensure seamless integration and functionality with legacy versions of -the Bittensor framework, specifically up to and including version 7.3.0. This module addresses changes and deprecated -features in recent versions, allowing users to maintain compatibility with older systems and projects. -""" +The Bittensor Compatibility Module serves as a centralized import hub for internal and external classes, functions, +constants, and utilities that are frequently accessed via the top-level `bittensor` namespace +(e.g., `from bittensor import Wallet`). + +It consolidates these widely used symbols into `bittensor/__init__.py`, enabling a cleaner and more intuitive public API +for developers and the broader community. -import importlib -import sys +Note: + Direct imports from their respective submodules are recommended for improved clarity and long-term maintainability. +""" -from bittensor_wallet import Keypair from bittensor_wallet.errors import KeyFileError from bittensor_wallet.keyfile import ( serialized_keypair_to_keyfile_data, @@ -25,10 +27,11 @@ decrypt_keyfile_data, Keyfile, ) +from bittensor_wallet.keypair import Keypair from bittensor_wallet.wallet import Wallet -from bittensor.core import settings, timelock -from bittensor.core.async_subtensor import AsyncSubtensor +from bittensor.core import settings, extrinsics +from bittensor.core.async_subtensor import AsyncSubtensor, get_async_subtensor from bittensor.core.axon import Axon from bittensor.core.chain_data import ( AxonInfo, @@ -58,6 +61,8 @@ from bittensor.core.config import Config from bittensor.core.dendrite import Dendrite from bittensor.core.errors import ( + BalanceTypeError, + BalanceUnitMismatchError, BlacklistedException, ChainConnectionError, ChainError, @@ -99,13 +104,13 @@ from bittensor.core.settings import BLOCKTIME from bittensor.core.stream import StreamingSynapse from bittensor.core.subtensor import Subtensor -from bittensor.core.subtensor_api import SubtensorApi from bittensor.core.synapse import TerminalInfo, Synapse from bittensor.core.tensor import Tensor from bittensor.core.threadpool import PriorityThreadPoolExecutor +from bittensor.extras import timelock, SubtensorApi from bittensor.utils import ( + mock, ss58_to_vec_u8, - version_checking, strtobool, get_explorer_url_for_network, ss58_address_to_bytes, @@ -113,74 +118,12 @@ u64_normalized_float, get_hash, ) -from bittensor.utils.balance import Balance -from bittensor.utils.balance import tao, rao +from bittensor.utils.balance import Balance, tao, rao from bittensor.utils.btlogging import logging +from bittensor.utils.btlogging.levels import trace, debug, warning, info from bittensor.utils.mock.subtensor_mock import MockSubtensor from bittensor.utils.subnets import SubnetsAPI - -# Backwards compatibility with previous bittensor versions. -async_subtensor = AsyncSubtensor -axon = Axon -config = Config -dendrite = Dendrite -keyfile = Keyfile -metagraph = Metagraph -wallet = Wallet -subtensor = Subtensor -synapse = Synapse - -# Makes the `bittensor.utils.mock` subpackage available as `bittensor.mock` for backwards compatibility. -mock_subpackage = importlib.import_module("bittensor.utils.mock") -sys.modules["bittensor.mock"] = mock_subpackage - -# Makes the `bittensor.core.extrinsics` subpackage available as `bittensor.extrinsics` for backwards compatibility. -extrinsics_subpackage = importlib.import_module("bittensor.core.extrinsics") -sys.modules["bittensor.extrinsics"] = extrinsics_subpackage - - -# Logging helpers. -def trace(on: bool = True): - """ - Enables or disables trace logging. - - Parameters: - on: If True, enables trace logging. If False, disables trace logging. - """ - logging.set_trace(on) - - -def debug(on: bool = True): - """ - Enables or disables debug logging. - - Parameters: - on: If True, enables debug logging. If False, disables debug logging. - """ - logging.set_debug(on) - - -def warning(on: bool = True): - """ - Enables or disables warning logging. - - Parameters: - on: If True, enables warning logging. If False, disables warning logging and sets default (WARNING) level. - """ - logging.set_warning(on) - - -def info(on: bool = True): - """ - Enables or disables info logging. - - Parameters: - on: If True, enables info logging. If False, disables info logging and sets default (WARNING) level. - """ - logging.set_info(on) - - __all__ = [ "Keypair", "KeyFileError", @@ -228,6 +171,8 @@ def info(on: bool = True): "WeightCommitInfo", "Config", "Dendrite", + "BalanceTypeError", + "BalanceUnitMismatchError", "BlacklistedException", "ChainConnectionError", "ChainError", @@ -274,7 +219,6 @@ def info(on: bool = True): "Tensor", "PriorityThreadPoolExecutor", "ss58_to_vec_u8", - "version_checking", "strtobool", "get_explorer_url_for_network", "ss58_address_to_bytes", @@ -287,19 +231,11 @@ def info(on: bool = True): "logging", "MockSubtensor", "SubnetsAPI", - "async_subtensor", - "axon", - "config", - "dendrite", - "keyfile", - "metagraph", - "wallet", - "subtensor", - "synapse", "trace", "debug", "warning", "info", - "mock_subpackage", - "extrinsics_subpackage", + "extrinsics", + "mock", + "get_async_subtensor", ] diff --git a/bittensor/utils/version.py b/bittensor/utils/version.py index 3f920e8333..e78fd109e8 100644 --- a/bittensor/utils/version.py +++ b/bittensor/utils/version.py @@ -98,26 +98,6 @@ def check_version(timeout: int = 15): raise VersionCheckError("Version check failed") from e -def version_checking(timeout: int = 15): - """Deprecated, kept for backwards compatibility. Use check_version() instead. - - Parameters: - timeout: The timeout for calling :func:``check_version`` function. - """ - - from warnings import warn - - warn( - "version_checking() is deprecated, please use check_version() instead", - DeprecationWarning, - ) - - try: - check_version(timeout) - except VersionCheckError: - logging.exception("Version check failed") - - def check_latest_version_in_pypi(): """Check for the latest version of the package on PyPI.""" package_name = __name__ diff --git a/tests/e2e_tests/conftest.py b/tests/e2e_tests/conftest.py index 9fa8dfe8d4..8eea338091 100644 --- a/tests/e2e_tests/conftest.py +++ b/tests/e2e_tests/conftest.py @@ -1,4 +1,3 @@ -import asyncio import os import re import shlex @@ -12,9 +11,8 @@ import pytest import pytest_asyncio -from async_substrate_interface import SubstrateInterface -from bittensor.core.subtensor_api import SubtensorApi +from bittensor.extras import SubtensorApi from bittensor.utils.btlogging import logging from tests.e2e_tests.utils.e2e_test_utils import ( Templates, diff --git a/tests/e2e_tests/test_delegate.py b/tests/e2e_tests/test_delegate.py index 176522dea8..3ebb405653 100644 --- a/tests/e2e_tests/test_delegate.py +++ b/tests/e2e_tests/test_delegate.py @@ -389,7 +389,6 @@ def test_delegates(subtensor, alice_wallet, bob_wallet): validator_permits=[], registrations=[0], return_per_1000=Balance(0), - total_daily_return=Balance(0), total_stake={}, nominators={}, ) @@ -405,7 +404,6 @@ def test_delegates(subtensor, alice_wallet, bob_wallet): validator_permits=[], registrations=[0], return_per_1000=Balance(0), - total_daily_return=Balance(0), total_stake={}, nominators={}, ) @@ -461,9 +459,6 @@ def test_delegates(subtensor, alice_wallet, bob_wallet): validator_permits=[alice_subnet_netuid], registrations=[0, alice_subnet_netuid], return_per_1000=Balance(0), - total_daily_return=get_dynamic_balance( - bob_delegated[0].total_daily_return.rao - ), netuid=alice_subnet_netuid, stake=get_dynamic_balance(bob_delegated[0].stake.rao, alice_subnet_netuid), ), @@ -549,7 +544,6 @@ async def test_delegates_async(async_subtensor, alice_wallet, bob_wallet): validator_permits=[], registrations=[0], return_per_1000=Balance(0), - total_daily_return=Balance(0), total_stake={}, nominators={}, ) @@ -565,7 +559,6 @@ async def test_delegates_async(async_subtensor, alice_wallet, bob_wallet): validator_permits=[], registrations=[0], return_per_1000=Balance(0), - total_daily_return=Balance(0), total_stake={}, nominators={}, ) @@ -631,9 +624,6 @@ async def test_delegates_async(async_subtensor, alice_wallet, bob_wallet): validator_permits=[alice_subnet_netuid], registrations=[0, alice_subnet_netuid], return_per_1000=Balance(0), - total_daily_return=get_dynamic_balance( - bob_delegated[0].total_daily_return.rao - ), netuid=alice_subnet_netuid, stake=get_dynamic_balance(bob_delegated[0].stake.rao, alice_subnet_netuid), ), @@ -704,7 +694,7 @@ def test_nominator_min_required_stake(subtensor, alice_wallet, bob_wallet, dave_ hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, ) - assert stake == Balance(0) + assert stake == Balance.from_tao(0, alice_subnet_netuid) @pytest.mark.asyncio @@ -784,7 +774,7 @@ async def test_nominator_min_required_stake_async( hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, ) - assert stake == Balance(0) + assert stake == Balance.from_tao(0, alice_subnet_netuid) def test_get_vote_data(subtensor, alice_wallet): diff --git a/tests/e2e_tests/test_metagraph.py b/tests/e2e_tests/test_metagraph.py index 9553fda968..404c7d91f9 100644 --- a/tests/e2e_tests/test_metagraph.py +++ b/tests/e2e_tests/test_metagraph.py @@ -79,7 +79,7 @@ def test_metagraph(subtensor, alice_wallet, bob_wallet, dave_wallet): ) logging.console.info("Refresh the metagraph") - metagraph.sync(subtensor=subtensor._subtensor) + metagraph.sync(subtensor=subtensor.inner_subtensor) logging.console.info("Assert metagraph has Alice and Bob neurons") assert len(metagraph.uids) == 2, "Metagraph doesn't have exactly 2 neurons" @@ -118,7 +118,7 @@ def test_metagraph(subtensor, alice_wallet, bob_wallet, dave_wallet): dave_wallet, alice_subnet_netuid ).success, "Unable to register Dave as a neuron" - metagraph.sync(subtensor=subtensor._subtensor) + metagraph.sync(subtensor=subtensor.inner_subtensor) logging.console.info("Assert metagraph now includes Dave's neuron") assert len(metagraph.uids) == 3, ( @@ -147,7 +147,7 @@ def test_metagraph(subtensor, alice_wallet, bob_wallet, dave_wallet): ).success, "Failed to add stake for Bob" logging.console.info("Assert stake is added after updating metagraph") - metagraph.sync(subtensor=subtensor._subtensor) + metagraph.sync(subtensor=subtensor.inner_subtensor) assert 0.95 < metagraph.neurons[1].stake.rao / alpha.rao < 1.05, ( "Bob's stake not updated in metagraph" ) @@ -242,7 +242,7 @@ async def test_metagraph_async(async_subtensor, alice_wallet, bob_wallet, dave_w ).success, "Unable to register Bob as a neuron" logging.console.info("Refresh the metagraph") - await metagraph.sync(subtensor=async_subtensor._subtensor) + await metagraph.sync(subtensor=async_subtensor.inner_subtensor) logging.console.info("Assert metagraph has Alice and Bob neurons") assert len(metagraph.uids) == 2, "Metagraph doesn't have exactly 2 neurons" @@ -287,7 +287,7 @@ async def test_metagraph_async(async_subtensor, alice_wallet, bob_wallet, dave_w ) ).success, "Unable to register Dave as a neuron" - await metagraph.sync(subtensor=async_subtensor._subtensor) + await metagraph.sync(subtensor=async_subtensor.inner_subtensor) logging.console.info("Assert metagraph now includes Dave's neuron") assert len(metagraph.uids) == 3, ( @@ -320,7 +320,7 @@ async def test_metagraph_async(async_subtensor, alice_wallet, bob_wallet, dave_w ).success, "Failed to add stake for Bob" logging.console.info("Assert stake is added after updating metagraph") - await metagraph.sync(subtensor=async_subtensor._subtensor) + await metagraph.sync(subtensor=async_subtensor.inner_subtensor) assert 0.95 < metagraph.neurons[1].stake.rao / alpha.rao < 1.05, ( "Bob's stake not updated in metagraph" ) diff --git a/tests/e2e_tests/test_staking.py b/tests/e2e_tests/test_staking.py index cd739fa461..64b093ba8b 100644 --- a/tests/e2e_tests/test_staking.py +++ b/tests/e2e_tests/test_staking.py @@ -80,7 +80,7 @@ def test_single_operation(subtensor, alice_wallet, bob_wallet): logging.console.info(f"Bob stake: {stake_bob}") assert stake_bob > Balance(0).set_unit(alice_subnet_netuid) - stakes = subtensor.staking.get_stake_for_coldkey(alice_wallet.coldkey.ss58_address) + stakes = subtensor.staking.get_stake_info_for_coldkey(alice_wallet.coldkey.ss58_address) expected_stakes = [ StakeInfo( @@ -117,10 +117,6 @@ def test_single_operation(subtensor, alice_wallet, bob_wallet): expected_stakes += fast_blocks_stake assert stakes == expected_stakes - assert ( - subtensor.staking.get_stake_for_coldkey - == subtensor.staking.get_stake_info_for_coldkey - ) stakes = subtensor.staking.get_stake_for_coldkey_and_hotkey( alice_wallet.coldkey.ss58_address, @@ -259,7 +255,7 @@ async def test_single_operation_async(async_subtensor, alice_wallet, bob_wallet) logging.console.info(f"Bob stake: {stake_bob}") assert stake_bob > Balance(0).set_unit(alice_subnet_netuid) - stakes = await async_subtensor.staking.get_stake_for_coldkey( + stakes = await async_subtensor.staking.get_stake_info_for_coldkey( alice_wallet.coldkey.ss58_address ) @@ -298,10 +294,6 @@ async def test_single_operation_async(async_subtensor, alice_wallet, bob_wallet) expected_stakes += fast_blocks_stake assert stakes == expected_stakes - assert ( - async_subtensor.staking.get_stake_for_coldkey - == async_subtensor.staking.get_stake_info_for_coldkey - ) stakes = await async_subtensor.staking.get_stake_for_coldkey_and_hotkey( alice_wallet.coldkey.ss58_address, @@ -759,7 +751,7 @@ def test_safe_staking_scenarios(subtensor, alice_wallet, bob_wallet, eve_wallet) assert partial_stake > Balance(0).set_unit(alice_subnet_netuid), ( "Partial stake should be added" ) - assert partial_stake < stake_amount, ( + assert partial_stake < Balance.from_tao(stake_amount.tao).set_unit(alice_subnet_netuid), ( "Partial stake should be less than requested amount" ) @@ -960,7 +952,7 @@ async def test_safe_staking_scenarios_async( assert partial_stake > Balance(0).set_unit(alice_subnet_netuid), ( "Partial stake should be added" ) - assert partial_stake < stake_amount, ( + assert partial_stake < Balance.from_tao(stake_amount.tao).set_unit(alice_subnet_netuid), ( "Partial stake should be less than requested amount" ) @@ -1287,7 +1279,7 @@ def test_move_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): amount=Balance.from_tao(1_000), ).success - stakes = subtensor.staking.get_stake_for_coldkey(alice_wallet.coldkey.ss58_address) + stakes = subtensor.staking.get_stake_info_for_coldkey(alice_wallet.coldkey.ss58_address) assert stakes == [ StakeInfo( @@ -1332,7 +1324,7 @@ def test_move_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): ) assert response.success is True - stakes = subtensor.staking.get_stake_for_coldkey(alice_wallet.coldkey.ss58_address) + stakes = subtensor.staking.get_stake_info_for_coldkey(alice_wallet.coldkey.ss58_address) expected_stakes = [ StakeInfo( @@ -1341,9 +1333,9 @@ def test_move_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): netuid=alice_subnet_netuid if subtensor.chain.is_fast_blocks() else bob_subnet_netuid, - stake=get_dynamic_balance(stakes[0].stake.rao, bob_subnet_netuid), - locked=Balance(0).set_unit(bob_subnet_netuid), - emission=get_dynamic_balance(stakes[0].emission.rao, bob_subnet_netuid), + stake=get_dynamic_balance(stakes[0].stake.rao, alice_subnet_netuid), + locked=Balance(0).set_unit(alice_subnet_netuid), + emission=get_dynamic_balance(stakes[0].emission.rao, alice_subnet_netuid), drain=0, is_registered=True, ) @@ -1367,6 +1359,9 @@ def test_move_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): ) expected_stakes += fast_block_stake + logging.console.info(f"[orange]FS: {fast_block_stake}[/orange]") + logging.console.info(f"[orange]RS: {stakes}[/orange]") + logging.console.info(f"[orange]ES: {expected_stakes}[/orange]") assert stakes == expected_stakes # test move_stake with move_all_stake=True @@ -1446,7 +1441,7 @@ async def test_move_stake_async(async_subtensor, alice_wallet, bob_wallet, dave_ ) ).success - stakes = await async_subtensor.staking.get_stake_for_coldkey( + stakes = await async_subtensor.staking.get_stake_info_for_coldkey( alice_wallet.coldkey.ss58_address ) @@ -1499,7 +1494,7 @@ async def test_move_stake_async(async_subtensor, alice_wallet, bob_wallet, dave_ ) assert response.success is True - stakes = await async_subtensor.staking.get_stake_for_coldkey( + stakes = await async_subtensor.staking.get_stake_info_for_coldkey( alice_wallet.coldkey.ss58_address ) @@ -1510,9 +1505,9 @@ async def test_move_stake_async(async_subtensor, alice_wallet, bob_wallet, dave_ netuid=alice_subnet_netuid if await async_subtensor.chain.is_fast_blocks() else bob_subnet_netuid, - stake=get_dynamic_balance(stakes[0].stake.rao, bob_subnet_netuid), - locked=Balance(0).set_unit(bob_subnet_netuid), - emission=get_dynamic_balance(stakes[0].emission.rao, bob_subnet_netuid), + stake=get_dynamic_balance(stakes[0].stake.rao, alice_subnet_netuid), + locked=Balance(0).set_unit(alice_subnet_netuid), + emission=get_dynamic_balance(stakes[0].emission.rao, alice_subnet_netuid), drain=0, is_registered=True, ) @@ -1618,7 +1613,7 @@ def test_transfer_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): amount=Balance.from_tao(1_000), ).success - alice_stakes = subtensor.staking.get_stake_for_coldkey( + alice_stakes = subtensor.staking.get_stake_info_for_coldkey( alice_wallet.coldkey.ss58_address ) @@ -1637,7 +1632,7 @@ def test_transfer_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): ), ] - bob_stakes = subtensor.staking.get_stake_for_coldkey( + bob_stakes = subtensor.staking.get_stake_info_for_coldkey( bob_wallet.coldkey.ss58_address ) @@ -1665,7 +1660,7 @@ def test_transfer_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): ) assert response.success is True - alice_stakes = subtensor.staking.get_stake_for_coldkey( + alice_stakes = subtensor.staking.get_stake_info_for_coldkey( alice_wallet.coldkey.ss58_address ) @@ -1692,7 +1687,7 @@ def test_transfer_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): assert alice_stakes == expected_alice_stake - bob_stakes = subtensor.staking.get_stake_for_coldkey( + bob_stakes = subtensor.staking.get_stake_info_for_coldkey( bob_wallet.coldkey.ss58_address ) @@ -1749,7 +1744,7 @@ async def test_transfer_stake_async( ) ).success - alice_stakes = await async_subtensor.staking.get_stake_for_coldkey( + alice_stakes = await async_subtensor.staking.get_stake_info_for_coldkey( alice_wallet.coldkey.ss58_address ) @@ -1768,7 +1763,7 @@ async def test_transfer_stake_async( ), ] - bob_stakes = await async_subtensor.staking.get_stake_for_coldkey( + bob_stakes = await async_subtensor.staking.get_stake_info_for_coldkey( bob_wallet.coldkey.ss58_address ) @@ -1800,7 +1795,7 @@ async def test_transfer_stake_async( ) assert response.success is True - alice_stakes = await async_subtensor.staking.get_stake_for_coldkey( + alice_stakes = await async_subtensor.staking.get_stake_info_for_coldkey( alice_wallet.coldkey.ss58_address ) @@ -1827,7 +1822,7 @@ async def test_transfer_stake_async( assert alice_stakes == expected_alice_stake - bob_stakes = await async_subtensor.staking.get_stake_for_coldkey( + bob_stakes = await async_subtensor.staking.get_stake_info_for_coldkey( bob_wallet.coldkey.ss58_address ) diff --git a/tests/e2e_tests/test_subtensor_functions.py b/tests/e2e_tests/test_subtensor_functions.py index 654f69c035..570171da8c 100644 --- a/tests/e2e_tests/test_subtensor_functions.py +++ b/tests/e2e_tests/test_subtensor_functions.py @@ -20,7 +20,7 @@ """ Verifies: -* get_subnets() +* get_all_subnets_netuid() * get_total_subnets() * subnet_exists() * get_netuids_for_hotkey() @@ -59,7 +59,7 @@ async def test_subtensor_extrinsics(subtensor, templates, alice_wallet, bob_wall existential_deposit = Balance.from_tao(0.000_000_500) # Subnets 0 and 1 are bootstrapped from the start - assert subtensor.subnets.get_subnets() == [0, 1] + assert subtensor.subnets.get_all_subnets_netuid() == [0, 1] assert subtensor.subnets.get_total_subnets() == 2 # Assert correct balance is fetched for Alice @@ -93,7 +93,7 @@ async def test_subtensor_extrinsics(subtensor, templates, alice_wallet, bob_wall ), "Balance is the same even after registering a subnet." # Subnet 2 is added after registration - assert subtensor.subnets.get_subnets() == [0, 1, 2] + assert subtensor.subnets.get_all_subnets_netuid() == [0, 1, 2] assert subtensor.subnets.get_total_subnets() == 3 # Verify subnet 2 created successfully @@ -245,7 +245,7 @@ async def test_subtensor_extrinsics_async( existential_deposit = Balance.from_tao(0.000_000_500) # Subnets 0 and 1 are bootstrapped from the start - assert await async_subtensor.subnets.get_subnets() == [0, 1] + assert await async_subtensor.subnets.get_all_subnets_netuid() == [0, 1] assert await async_subtensor.subnets.get_total_subnets() == 2 # Assert correct balance is fetched for Alice @@ -281,7 +281,7 @@ async def test_subtensor_extrinsics_async( ), "Balance is the same even after registering a subnet." # Subnet 2 is added after registration - assert await async_subtensor.subnets.get_subnets() == [0, 1, 2] + assert await async_subtensor.subnets.get_all_subnets_netuid() == [0, 1, 2] assert await async_subtensor.subnets.get_total_subnets() == 3 # Verify subnet 2 created successfully diff --git a/tests/e2e_tests/test_transfer.py b/tests/e2e_tests/test_transfer.py index 4f65a5828d..dc8e69deb3 100644 --- a/tests/e2e_tests/test_transfer.py +++ b/tests/e2e_tests/test_transfer.py @@ -7,7 +7,7 @@ from bittensor import logging if typing.TYPE_CHECKING: - from bittensor.core.subtensor_api import SubtensorApi + from bittensor.core.addons import SubtensorApi def test_transfer(subtensor, alice_wallet): @@ -27,7 +27,7 @@ def test_transfer(subtensor, alice_wallet): transfer_fee = subtensor.wallets.get_transfer_fee( wallet=alice_wallet, dest=dest_coldkey, - value=transfer_value, + amount=transfer_value, ) # Account details before transfer @@ -68,7 +68,7 @@ async def test_transfer_async(async_subtensor, alice_wallet): transfer_fee = await async_subtensor.wallets.get_transfer_fee( wallet=alice_wallet, dest=dest_coldkey, - value=transfer_value, + amount=transfer_value, ) # Account details before transfer diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index 43af7a1532..87ee70da9d 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -15,7 +15,7 @@ # for typing purposes if TYPE_CHECKING: from bittensor import Wallet - from bittensor.core.subtensor_api import SubtensorApi + from bittensor.extras import SubtensorApi from async_substrate_interface import ( AsyncSubstrateInterface, AsyncExtrinsicReceipt, diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index 3ad0b896c9..3e97bf2ad5 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -6,7 +6,7 @@ from bittensor_wallet import Keypair, Wallet -from bittensor.core.subtensor_api import SubtensorApi +from bittensor.extras import SubtensorApi from bittensor.utils.btlogging import logging template_path = os.getcwd() + "/neurons/" diff --git a/tests/helpers/integration_websocket_data.py b/tests/helpers/integration_websocket_data.py index ce450ad03c..3bbf359819 100644 --- a/tests/helpers/integration_websocket_data.py +++ b/tests/helpers/integration_websocket_data.py @@ -9,48 +9,48 @@ "blocks_since_last_update": { "chain_getHead": { "[]": { - "result": "0xf658002393b00476606e6b6e1eb8c0a2979e53eacb8318b4b5f73fa73ff20398" + "result": "0x2830271e820b419253b79cbafea83f726354bbef26eb318835ffa774288de9ff" } }, "chain_getHeader": { - '["0xf658002393b00476606e6b6e1eb8c0a2979e53eacb8318b4b5f73fa73ff20398"]': { + '["0x2830271e820b419253b79cbafea83f726354bbef26eb318835ffa774288de9ff"]': { "result": { - "parentHash": "0xf620bf7b416a49079f0817a15fe5b1243bb5200416bf1b6c7934114551504517", - "number": "0x63856c", - "stateRoot": "0xb05a9a4ab12adda8c91d63242f9925da3735e5fa79b31094d2c61a6ac85db9a4", - "extrinsicsRoot": "0xedf4302417e5be22e2eff506e624db7807e5c98f1e4941d31d4a4e54527222ec", + "parentHash": "0xb5a3b72cc914b520a12e45e9f73fc3076b86fbae1be20b191fb7da4967c6ac47", + "number": "0x63fe87", + "stateRoot": "0x800d3090504b36e496fc579edf9db972a9cbc7522d52d96d4804e3396b21be7d", + "extrinsicsRoot": "0xe3ccef094f2e6176bc4a2d2f42a2d0b0c5f815c8506cf4299c8390c0eac62d39", "digest": { "logs": [ - "0x066175726120ec74bc0800000000", - "0x0466726f6e88011d87918002e1c26ed6d9a77885b14f77e4077cd9188cf398549cc978a295ad2b00", - "0x05617572610101961dd0050612d51f0aab580ee3ca9c7441ac91a7055716c1db496c418fc9d8431f51fe358b2833d613e6f69d5d783a0e89438511bc848a43845e8daa3d4ed980", + "0x06617572612007eebc0800000000", + "0x0466726f6e8801e4783b7f433d5462d1b84cfc851cbcf2fe886103b02fab1cce30f82cdaf0d37000", + "0x056175726101015e77e14c4e02e720bbd213a708dac67de5ea3494b41b6a87f03eee2d2d71557f2c960bd462e14433e758c6fe2584abec9b22b0d550bd25c76f836b413c526b8d", ] }, } }, "[null]": { "result": { - "parentHash": "0xf620bf7b416a49079f0817a15fe5b1243bb5200416bf1b6c7934114551504517", - "number": "0x63856c", - "stateRoot": "0xb05a9a4ab12adda8c91d63242f9925da3735e5fa79b31094d2c61a6ac85db9a4", - "extrinsicsRoot": "0xedf4302417e5be22e2eff506e624db7807e5c98f1e4941d31d4a4e54527222ec", + "parentHash": "0xb5a3b72cc914b520a12e45e9f73fc3076b86fbae1be20b191fb7da4967c6ac47", + "number": "0x63fe87", + "stateRoot": "0x800d3090504b36e496fc579edf9db972a9cbc7522d52d96d4804e3396b21be7d", + "extrinsicsRoot": "0xe3ccef094f2e6176bc4a2d2f42a2d0b0c5f815c8506cf4299c8390c0eac62d39", "digest": { "logs": [ - "0x066175726120ec74bc0800000000", - "0x0466726f6e88011d87918002e1c26ed6d9a77885b14f77e4077cd9188cf398549cc978a295ad2b00", - "0x05617572610101961dd0050612d51f0aab580ee3ca9c7441ac91a7055716c1db496c418fc9d8431f51fe358b2833d613e6f69d5d783a0e89438511bc848a43845e8daa3d4ed980", + "0x06617572612007eebc0800000000", + "0x0466726f6e8801e4783b7f433d5462d1b84cfc851cbcf2fe886103b02fab1cce30f82cdaf0d37000", + "0x056175726101015e77e14c4e02e720bbd213a708dac67de5ea3494b41b6a87f03eee2d2d71557f2c960bd462e14433e758c6fe2584abec9b22b0d550bd25c76f836b413c526b8d", ] }, } }, }, "state_getRuntimeVersion": { - '["0xf620bf7b416a49079f0817a15fe5b1243bb5200416bf1b6c7934114551504517"]': { + '["0xb5a3b72cc914b520a12e45e9f73fc3076b86fbae1be20b191fb7da4967c6ac47"]': { "result": { "specName": "node-subtensor", "implName": "node-subtensor", "authoringVersion": 1, - "specVersion": 315, + "specVersion": 320, "implVersion": 1, "apis": [ ["0xdf6acb689907609b", 5], @@ -81,12 +81,17 @@ } } }, + "chain_getBlockHash": { + "[6553223]": { + "result": "0x2830271e820b419253b79cbafea83f726354bbef26eb318835ffa774288de9ff" + } + }, "state_getStorageAt": { - '["0x658faa385070e074c85bf6b568cf05550e30450fc4d507a846032a7fa65d9a430100", null]': { + '["0x658faa385070e074c85bf6b568cf05550e30450fc4d507a846032a7fa65d9a430100", "0x2830271e820b419253b79cbafea83f726354bbef26eb318835ffa774288de9ff"]': { "result": "0x01" }, - '["0x658faa385070e074c85bf6b568cf0555696e262a16e52255a69d8acd793541460100", null]': { - "result": "0x0110a1cf2600000000009bc7260000000000b6fc2d0000000000b43c40000000000036b9260000000000e9445e00000000004ec5330000000000a2d02600000000008dc726000000000057d02600000000002ac826000000000069ca260000000000988a470000000000a8812600000000009cce26000000000080d026000000000057ca26000000000060cb26000000000059ce260000000000a9cc2600000000003ad02600000000007fd0260000000000c5c9260000000000fccf260000000000218563000000000011c726000000000015be26000000000039cf260000000000a3d02600000000007bb226000000000057ce2600000000006783260000000000bb093b0000000000b3d026000000000094ce2600000000004a8f2500000000000cc726000000000095c626000000000013b9260000000000fec926000000000070d026000000000078cf26000000000028d026000000000052cb2600000000004aaa240000000000a4c526000000000046ce260000000000c5cd26000000000004ce260000000000f2cc260000000000bcb72b00000000006acc260000000000c7cc260000000000d11c2600000000000dcf2600000000001fcb26000000000000cf26000000000030c1260000000000f3cd2600000000004dd0260000000000ea134b0000000000323d300000000000afcf26000000000016b426000000000087134b000000000094d026000000000012cc2600000000009dc3260000000000c9c3260000000000ecba260000000000f9c6260000000000e0c8260000000000218f25000000000051c8260000000000d2ce2600000000005dce280000000000a2ca260000000000f0cc26000000000089bf260000000000d8cb260000000000ba2526000000000076ab260000000000f8c9260000000000cdc8260000000000b3b32600000000005ed0260000000000f2b4260000000000a4cc26000000000016c926000000000019c6260000000000f1cc260000000000b3d0260000000000f4cc2600000000008db62600000000004fcf2600000000002bc52600000000009a27260000000000848726000000000020c4260000000000ebcb260000000000ea0d290000000000edc4260000000000a2c026000000000078c6260000000000111b2600000000009fc226000000000091d026000000000036c726000000000014c6290000000000a1cc260000000000dfa5260000000000ebc8260000000000ff782600000000001c8f250000000000fe6d260000000000aec0260000000000f5ca260000000000d7cb260000000000a3bd2600000000005dc82600000000009485260000000000c87826000000000090c72600000000002acf260000000000b2c626000000000030ba26000000000010c926000000000035c2260000000000f1c92600000000003acc26000000000095d02600000000001cab2600000000000fce2600000000000fce260000000000bdcc2600000000008fcc260000000000b45f3d000000000085ce26000000000056c326000000000053ce260000000000aec526000000000021bc260000000000acc82600000000009bd02600000000005ad026000000000038c426000000000019c3260000000000e1cd260000000000b0ce26000000000034c526000000000020be2600000000000b7d320000000000aecd26000000000048c6260000000000c1cf26000000000063d026000000000003cd260000000000ddc62600000000000d2b280000000000b3aa2400000000001ac82600000000001c522600000000008ac726000000000042ce2600000000004fce260000000000aabf26000000000017cc2600000000009e753300000000009cce2600000000008ecc26000000000009ca26000000000044cd26000000000024d02600000000009fbb260000000000a7c72600000000009cc6260000000000a6d026000000000061d0260000000000eac326000000000084b526000000000086cd2600000000000cc2260000000000d9c62600000000003ec32600000000002ec8260000000000c3cb26000000000085cf260000000000d7ce2600000000009dc226000000000033cc26000000000037ca26000000000055ce26000000000085ec44000000000095d0260000000000c9c6260000000000b7ca260000000000fcbd26000000000024d026000000000075bb260000000000e4b7260000000000087d32000000000020cf26000000000019ce26000000000054e644000000000022c62600000000009cc72600000000009dd0260000000000c8af4e000000000062ce260000000000019e26000000000049cc260000000000abcb260000000000c05026000000000066cb260000000000adcf260000000000aa9626000000000072cd2600000000003dc226000000000040573b00000000000dca260000000000adcc2600000000006bd0260000000000accc260000000000ccc9260000000000638f250000000000ea7c2600000000008b4a290000000000adcd26000000000061c126000000000079cf2600000000009dc5260000000000cece2600000000004dcd260000000000b2d026000000000014cc26000000000004ce2600000000003cce26000000000075cf260000000000d2ba2600000000000ecb2600000000009093260000000000a1c526000000000028ce2600000000007bd026000000000088aa2400000000001f85630000000000acc926000000000008ca260000000000cfc926000000000069cc260000000000c4c42600000000001bd02600000000005ed0260000000000a4cc2600000000008ace26000000000005bc260000000000d5c7260000000000f5c02600000000001dd0260000000000cccb2600000000006bcc260000000000cfce26000000000043ca260000000000b9ca26000000000054c226000000000015cf26000000000005f6250000000000c8cb4000000000009f93260000000000bacd260000000000ecb1260000000000c6c6260000000000f1cd2600000000000ec026000000000052cd2600000000000ed02600000000009ccd260000000000dac52600000000002ec226000000000088d0260000000000eccd26000000000008cf260000000000a6ce26000000000006c5260000000000e6c12600000000002fc7260000000000a9d026000000000036d02600000000009ac826000000000061cf260000000000aac826000000000028c3260000000000029f2600000000000cd02600000000009733260000000000692b3400000000007dc326000000000064cf2600000000001ac5260000000000a86d260000000000f9c926000000000019d02600000000009ec7260000000000a9f52400000000000dc6260000000000e6cf260000000000edce26000000000016c42600000000009bf52400000000009888260000000000acaa240000000000b2cd26000000000011cd260000000000ffba260000000000f2c9260000000000a6073c0000000000bf3d26000000000077aa240000000000dc94260000000000cbf5240000000000a6d02600000000005fc5260000000000b273260000000000b7b62600000000003cc6260000000000b3c72600000000001ecc260000000000669e260000000000cacf26000000000039ca2600000000006ecd260000000000f9a7260000000000eb3326000000000020c4260000000000a9cb26000000000076cf26000000000067cc26000000000023f02900000000008bd0260000000000bfc9260000000000c4c72600000000001fd0260000000000a21026000000000097c72600000000006e9a2600000000007e932600000000009acf26000000000076ce260000000000819226000000000014ca2600000000008ecb260000000000becb2600000000000acc2600000000003b453a000000000039cf260000000000e5772600000000009fcb260000000000bf344e00000000005ace26000000000077d0260000000000f4bf260000000000cbcf260000000000e0cf260000000000e8ea2b000000000084ce26000000000012c9260000000000f2c7260000000000a5d0260000000000b9c926000000000018c826000000000093592600000000009f8a260000000000afd0260000000000a9c726000000000091ce26000000000000cd26000000000045aa2400000000006acc260000000000da9f6100000000001acf260000000000a1ac25000000000059cf260000000000ceca260000000000bc2726000000000028aa26000000000072c4260000000000ac7626000000000084c726000000000057c426000000000073c2260000000000389e260000000000ff8b26000000000051d02600000000000ec5260000000000428f25000000000029c42600000000003d8f25000000000048ca26000000000098c8260000000000f896260000000000ffb7260000000000c1cc26000000000018ca260000000000f0c42600000000006993260000000000b0cc260000000000a5c726000000000031cf26000000000081cf2600000000003c73270000000000edc02600000000001ac426000000000000cc26000000000022ce26000000000014cd260000000000e45226000000000010cf26000000000002cf260000000000d9cb26000000000075cb2600000000005dd02600000000003193260000000000a1ca26000000000056cd260000000000cccb2600000000000cc826000000000096d02600000000009fd02600000000004ec526000000000026d026000000000081d026000000000078cf260000000000becf2600000000009ace26000000000042d026000000000060c326000000000097cf26000000000088cd2600000000004b3d260000000000c8cf2600000000000abd2600000000001dcc2600000000007bd02600000000008bb726000000000011c526000000000059d02600000000009078260000000000fbcb26000000000055c3260000000000e6c62600000000009bd0260000000000f8cb2600000000000a7926000000000055cd260000000000d8cd260000000000a4cd260000000000afcc260000000000eac826000000000036cf26000000000053ce2600000000009cca260000000000f0d92a000000000054ce26000000000021c426000000000030cd26000000000020cc26000000000041c226000000000052cc260000000000f2ce260000000000f87626000000000094b92600000000004ec8260000000000e5ca260000000000e5bb260000000000bdce2600000000000dcd26000000000058d026000000000018c726000000000040cf260000000000228f2500000000007eca2600000000007bcd26000000000078b926000000000088d026000000000016ca260000000000fcb326000000000082cb260000000000d5cc2600000000004dc1260000000000bbc9260000000000c9cf2600000000005dd026000000000053cd2600000000000ace260000000000b7ae3100000000005acf260000000000dfca260000000000e5cf2600000000002dc72600000000008fc626000000000024f6250000000000f4c92600000000002b856300000000001fc3260000000000cfbe260000000000decf2600000000006ece26000000000022a02600000000003cc3260000000000b4cd26000000000078512600000000004fcd26000000000097d02600000000004dcc26000000000051cf260000000000438f2600000000004bc626000000000049ca2600000000005f856300000000007f3b61000000000063b2560000000000b6c92600000000008ebb2600000000004bce260000000000f7cd2600000000002ccd260000000000f0cf260000000000c7cd26000000000004c526000000000098cc2600000000004dd02600000000003dbd2600000000006ecd26000000000029cf260000000000b9c326000000000081be260000000000f6ce26000000000056c826000000000096cc2600000000001b3d30000000000061d026000000000002b8260000000000ff90260000000000c1c42600000000002ccc260000000000d0c926000000000035c6260000000000eccb26000000000061cc26000000000072cc260000000000eccd2600000000005fcc2600000000004dd026000000000091cc2600000000009ec0260000000000049e26000000000060cd26000000000094d02600000000006dce260000000000b8cf370000000000bbca26000000000051c326000000000068ca260000000000f6852600000000002f61490000000000cccc26000000000065b926000000000061cc260000000000b4aa2400000000002fcd260000000000b23c30000000000002c7260000000000c78926000000000004be260000000000ffcc2600000000004bb83400000000008cc72600000000003ed0260000000000b5cb2600000000005a474000000000007dc32600000000001ec92600000000002ad0260000000000d8cd260000000000e4cb260000000000ac95260000000000cbcf26000000000002c82600000000009dd0260000000000a683260000000000bdc8260000000000bf092600000000009f7b2600000000000bce260000000000241526000000000097ce260000000000accc260000000000d3ee3900000000006bcd2600000000002b4f26000000000091c62600000000003f8f25000000000044c82600000000001ecb260000000000a9d026000000000050c826000000000051ce260000000000bbdd4200000000006b8226000000000089cb6100000000008bd0260000000000b2cd26000000000076cb260000000000f9cc26000000000029d02600000000007bc7260000000000fbcd2600000000007fca26000000000020b72400000000005bc526000000000016cf26000000000086be26000000000045d0260000000000c3cb26000000000092c4260000000000f8cf26000000000066cd260000000000d9cf260000000000c1873300000000002dc92600000000005fca26000000000082c72600000000003cc72600000000002dd02600000000002a85630000000000aff5240000000000c58226000000000097ca26000000000038cf260000000000937426000000000002ca26000000000022c6260000000000d0cf26000000000080cb26000000000029cd260000000000afcf26000000000034ca260000000000e0c72600000000002cce260000000000bacd26000000000065c82600000000000bcf2600000000009bcc260000000000454e260000000000f0cd2600000000003fcc26000000000004cc26000000000051d026000000000008c126000000000031ce26000000000022be260000000000cacf260000000000cb772600000000009c3e2b000000000076aa240000000000facb2600000000009bc326000000000059b7260000000000b1ca26000000000039cd260000000000aeb42600000000007ed02600000000002bd026000000000018cb260000000000010c590000000000decd260000000000c7c726000000000046d0260000000000b5c8260000000000facc26000000000058c826000000000012b626000000000094cd260000000000d5b92600000000003ed026000000000087d026000000000086d02600000000000fc0260000000000a1c726000000000063ce2600000000001cc02600000000007fc5260000000000e9cd2600000000004ed0260000000000a0b2260000000000aaca260000000000357a260000000000658563000000000048cd260000000000f5f52400000000004dc72600000000006ac426000000000098c226000000000043cc2600000000006293260000000000a1c2260000000000cfc426000000000068af260000000000f2b9260000000000a1d0260000000000ccc9260000000000f0cd26000000000072cd2600000000005fbf2600000000005ebf2600000000005ecf2600000000006e4d2600000000006e0b31000000000011bb26000000000002be26000000000041ca260000000000b6cd260000000000c0c42600000000007ece26000000000081cc260000000000deb12600000000008ccf26000000000063cc260000000000cfad2600000000009cd02600000000003dd026000000000045c9260000000000e4cb2600000000008d8b26000000000040d026000000000069d0260000000000d047260000000000fbcb26000000000021c7260000000000c9ce26000000000012b9260000000000aec7260000000000d2cc2600000000008bc4260000000000deee330000000000962726000000000056c226000000000099cf2600000000008e8f250000000000cbcb26000000000090c2260000000000adcd26000000000094a1260000000000d3b42600000000009cca260000000000ddf524000000000023182f0000000000b04026000000000064d0260000000000a5d026000000000069ca26000000000008ce2600000000000dce26000000000054cc2600000000009dcf26000000000043c5260000000000b9cd2600000000007dd02600000000005ad026000000000086d02600000000003fd0260000000000fd63260000000000228f2500000000004dd0260000000000bdcf260000000000a2cb260000000000c0c92600000000002ccf260000000000d19244000000000015d0260000000000becf26000000000008c72600000000000cd0260000000000abc3260000000000cdbc260000000000a7c82600000000007ac826000000000004792600000000000e9e490000000000e5be2600000000001f83280000000000bbbc2600000000007cd02600000000007dd0260000000000bccd26000000000006c8260000000000fac7260000000000f1c2260000000000f3ce26000000000067c726000000000068445d0000000000ecce260000000000d3c9260000000000e0c226000000000029cf2600000000000ccd260000000000becf26000000000048cb2600000000006186280000000000a7d02600000000007bc9260000000000dadf530000000000b3d026000000000083cf260000000000b1cf26000000000060424b0000000000eacb260000000000fbc826000000000045c3260000000000cdcf260000000000e1ce2600000000002fcb2600000000004dc426000000000095cd26000000000087362700000000004bcb260000000000afc4260000000000f5c626000000000038cd260000000000f9ce260000000000f6733a0000000000cbc9260000000000b4cd260000000000b4cb26000000000014cc26000000000000cf260000000000aac4260000000000ddc72600000000002efc340000000000b7b12600000000008479260000000000f3cf260000000000b5bd2600000000005ace260000000000d6c7260000000000e0c226000000000050ca260000000000f3c3260000000000f18e2600000000000bcc260000000000232e2600000000004b8f2500000000008fc726000000000096cc26000000000004cf2600000000006fc926000000000094ca26000000000024ac26000000000008cb260000000000d2c7260000000000c1cf26000000000079cc260000000000313d30000000000029ce2600000000006cc9260000000000c8cc260000000000e1c626000000000049cb260000000000b1ce260000000000afc5260000000000e1c6260000000000b3c8260000000000fbce2600000000009e733600000000000dcf26000000000079c826000000000030c5260000000000a7aa2400000000006cd026000000000098c6260000000000a4c4260000000000e9ce260000000000d3ce26000000000069cd260000000000f5c526000000000088cd260000000000d8cd260000000000c2cd260000000000df7b260000000000afc8260000000000943f2600000000000253280000000000dbcd2600000000006d7b260000000000dec7260000000000858126000000000073b526000000000025c4260000000000f0bc2600000000000dc126000000000087b726000000000002bd260000000000c7ce26000000000044c4260000000000d5cf260000000000aacd260000000000c5c826000000000028c126000000000078c52600000000004eef5400000000003ccf260000000000ef32300000000000c25145000000000067b52600000000009dc3260000000000def5240000000000e2ce260000000000108126000000000073c5260000000000ebcd26000000000034c8260000000000d2c12600000000006bcc260000000000f69c26000000000026c9260000000000909426000000000021cc260000000000ffc2260000000000fec72600000000007ecc260000000000adc7260000000000773e4000000000009ac226000000000063c5260000000000f7c3260000000000d0cf260000000000c4d9390000000000ea492900000000007acb26000000000017cb2600000000006abd260000000000eec4260000000000a2c726000000000008d026000000000099c826000000000022c72600000000009fca2600000000004ecc2600000000004cd026000000000007d026000000000000ca2600000000008dd026000000000055c226000000000091d02600000000004184260000000000e2cb26000000000006be2600000000002079260000000000cdc72600000000004ac42600000000003fc426000000000040a73e000000000070aa240000000000d3bd26000000000045ce260000000000bbf5240000000000328563000000000002ce260000000000bdcb2600000000007eaa24000000000059c226000000000061bc260000000000f6cd260000000000d6d93400000000005210340000000000f74a31000000000013c8260000000000fd8f260000000000bbc0260000000000a6d02600000000001dcd26000000000019ca260000000000e9cb26000000000068ce26000000000007bc260000000000b6cc260000000000e9ce260000000000cacf26000000000013cc260000000000a319260000000000b174260000000000b9cc260000000000b3cb260000000000d28463000000000048cd26000000000055b826000000000089c726000000000070d02600000000004ccc260000000000bac9260000000000a9d0260000000000c2cf26000000000044cc260000000000b9ee4b000000000098bb260000000000aacc26000000000062ca2600000000009163250000000000a1b42600000000008dcc2600000000008ace260000000000b9ce2600000000008bcd2600000000002bc22600000000005ed0260000000000fdc8260000000000ecc72600000000000dcd26000000000071cb26000000000056cd260000000000a9ca26000000000064c92600000000005a902d00000000002dcf260000000000" + '["0x658faa385070e074c85bf6b568cf0555696e262a16e52255a69d8acd793541460100", "0x2830271e820b419253b79cbafea83f726354bbef26eb318835ffa774288de9ff"]': { + "result": "0x0110a1cf2600000000009bc7260000000000b6fc2d0000000000b43c40000000000036b9260000000000e9445e00000000004ec5330000000000a2d02600000000008dc726000000000057d02600000000002ac826000000000069ca260000000000988a470000000000a8812600000000009cce26000000000080d026000000000057ca26000000000060cb26000000000059ce260000000000a9cc2600000000003ad02600000000007fd0260000000000c5c9260000000000fccf2600000000000efe63000000000011c726000000000015be26000000000039cf260000000000a3d02600000000007bb226000000000057ce2600000000006783260000000000bb093b0000000000b3d026000000000094ce2600000000004a8f2500000000000cc726000000000095c626000000000013b9260000000000fec926000000000070d026000000000078cf26000000000028d026000000000052cb2600000000004aaa240000000000a4c526000000000046ce260000000000c5cd26000000000004ce260000000000f2cc260000000000bcb72b00000000006acc260000000000c7cc260000000000d11c2600000000000dcf2600000000001fcb26000000000000cf26000000000030c1260000000000f3cd2600000000004dd0260000000000ea134b0000000000323d300000000000afcf26000000000016b426000000000087134b000000000094d026000000000012cc2600000000009dc3260000000000c9c3260000000000ecba260000000000f9c6260000000000e0c8260000000000218f25000000000051c8260000000000d2ce2600000000005dce280000000000a2ca260000000000f0cc26000000000089bf260000000000d8cb260000000000ba2526000000000076ab260000000000f8c9260000000000cdc8260000000000b3b32600000000005ed0260000000000f2b4260000000000a4cc26000000000016c926000000000019c6260000000000f1cc260000000000b3d0260000000000f4cc2600000000008db62600000000004fcf2600000000002bc52600000000009a27260000000000848726000000000020c4260000000000ebcb260000000000ea0d290000000000edc4260000000000a2c026000000000078c6260000000000111b2600000000009fc226000000000091d026000000000036c726000000000014c6290000000000a1cc260000000000dfa5260000000000ebc8260000000000ff782600000000001c8f250000000000fe6d260000000000aec0260000000000f5ca260000000000d7cb260000000000a3bd2600000000005dc82600000000009485260000000000c87826000000000090c72600000000002acf260000000000b2c626000000000030ba26000000000010c926000000000035c2260000000000f1c92600000000003acc26000000000095d02600000000001cab2600000000000fce2600000000000fce260000000000bdcc2600000000008fcc260000000000b45f3d000000000085ce26000000000056c326000000000053ce260000000000aec526000000000021bc260000000000acc82600000000009bd02600000000005ad026000000000038c426000000000019c3260000000000e1cd260000000000b0ce26000000000034c526000000000020be2600000000000b7d320000000000aecd26000000000048c6260000000000c1cf26000000000063d026000000000003cd260000000000ddc62600000000000d2b280000000000b3aa2400000000001ac82600000000001c522600000000008ac726000000000042ce2600000000004fce260000000000aabf26000000000017cc2600000000009e753300000000009cce2600000000008ecc26000000000009ca26000000000044cd26000000000024d02600000000009fbb260000000000a7c72600000000009cc6260000000000a6d026000000000061d0260000000000eac326000000000084b526000000000086cd2600000000000cc2260000000000d9c62600000000003ec32600000000002ec8260000000000c3cb26000000000085cf260000000000d7ce2600000000009dc226000000000033cc26000000000037ca26000000000055ce26000000000085ec44000000000095d0260000000000c9c6260000000000b7ca260000000000fcbd26000000000024d026000000000075bb260000000000e4b7260000000000087d32000000000020cf26000000000019ce26000000000054e644000000000022c62600000000009cc72600000000009dd0260000000000c8af4e000000000062ce260000000000019e26000000000049cc260000000000abcb260000000000c05026000000000066cb260000000000adcf260000000000aa9626000000000072cd2600000000003dc226000000000040573b00000000000dca260000000000adcc2600000000006bd0260000000000accc260000000000ccc9260000000000638f250000000000ea7c2600000000008b4a290000000000adcd26000000000061c126000000000079cf2600000000009dc5260000000000cece2600000000004dcd260000000000b2d026000000000014cc26000000000004ce2600000000003cce26000000000075cf260000000000d2ba2600000000000ecb2600000000009093260000000000a1c526000000000028ce2600000000007bd026000000000088aa2400000000001bfe630000000000acc926000000000008ca260000000000cfc926000000000069cc260000000000c4c42600000000001bd02600000000005ed0260000000000a4cc2600000000008ace26000000000005bc260000000000d5c7260000000000f5c02600000000001dd0260000000000cccb2600000000006bcc260000000000cfce26000000000043ca260000000000b9ca26000000000054c226000000000015cf26000000000005f6250000000000c8cb4000000000009f93260000000000bacd260000000000ecb1260000000000c6c6260000000000f1cd2600000000000ec026000000000052cd2600000000000ed02600000000009ccd260000000000dac52600000000002ec226000000000088d0260000000000eccd26000000000008cf260000000000a6ce26000000000006c5260000000000e6c12600000000002fc7260000000000a9d026000000000036d02600000000009ac826000000000061cf260000000000aac826000000000028c3260000000000029f2600000000000cd02600000000009733260000000000692b3400000000007dc326000000000064cf2600000000001ac5260000000000a86d260000000000f9c926000000000019d02600000000009ec7260000000000a9f52400000000000dc6260000000000e6cf260000000000edce26000000000016c42600000000009bf52400000000009888260000000000acaa240000000000b2cd26000000000011cd260000000000ffba260000000000f2c9260000000000a6073c0000000000bf3d26000000000077aa240000000000dc94260000000000cbf5240000000000a6d02600000000005fc5260000000000b273260000000000b7b62600000000003cc6260000000000b3c72600000000001ecc260000000000669e260000000000cacf26000000000039ca2600000000006ecd260000000000f9a7260000000000eb3326000000000020c4260000000000a9cb26000000000076cf26000000000067cc26000000000023f02900000000008bd0260000000000bfc9260000000000c4c72600000000001fd0260000000000a21026000000000097c72600000000006e9a2600000000007e932600000000009acf26000000000076ce260000000000819226000000000014ca2600000000008ecb260000000000becb2600000000000acc2600000000003b453a000000000039cf260000000000e5772600000000009fcb260000000000bf344e00000000005ace26000000000077d0260000000000f4bf260000000000cbcf260000000000e0cf260000000000e8ea2b000000000084ce26000000000012c9260000000000f2c7260000000000a5d0260000000000b9c926000000000018c826000000000093592600000000009f8a260000000000afd0260000000000a9c726000000000091ce26000000000000cd26000000000045aa2400000000006acc260000000000da9f6100000000001acf260000000000a1ac25000000000059cf260000000000ceca260000000000bc2726000000000028aa26000000000072c4260000000000ac7626000000000084c726000000000057c426000000000073c2260000000000389e260000000000ff8b26000000000051d02600000000000ec5260000000000428f25000000000029c42600000000003d8f25000000000048ca26000000000098c8260000000000f896260000000000ffb7260000000000c1cc26000000000018ca260000000000f0c42600000000006993260000000000b0cc260000000000a5c726000000000031cf26000000000081cf2600000000003c73270000000000edc02600000000001ac426000000000000cc26000000000022ce26000000000014cd260000000000e45226000000000010cf26000000000002cf260000000000d9cb26000000000075cb2600000000005dd02600000000003193260000000000a1ca26000000000056cd260000000000cccb2600000000000cc826000000000096d02600000000009fd02600000000004ec526000000000026d026000000000081d026000000000078cf260000000000becf2600000000009ace26000000000042d026000000000060c326000000000097cf26000000000088cd2600000000004b3d260000000000c8cf2600000000000abd2600000000001dcc2600000000007bd02600000000008bb726000000000011c526000000000059d0260000000000907826000000000017fe63000000000055c3260000000000e6c62600000000009bd0260000000000f8cb2600000000000a7926000000000055cd260000000000d8cd260000000000a4cd260000000000afcc260000000000eac826000000000036cf26000000000053ce2600000000009cca260000000000f0d92a000000000054ce26000000000021c426000000000030cd26000000000020cc26000000000041c226000000000052cc260000000000f2ce260000000000f87626000000000094b92600000000004ec8260000000000e5ca260000000000e5bb260000000000bdce2600000000000dcd26000000000058d026000000000018c726000000000040cf260000000000228f2500000000007eca2600000000007bcd26000000000078b926000000000088d026000000000016ca260000000000fcb326000000000082cb260000000000d5cc2600000000004dc1260000000000bbc9260000000000c9cf2600000000005dd026000000000053cd2600000000000ace260000000000b7ae3100000000005acf260000000000dfca260000000000e5cf2600000000002dc72600000000008fc626000000000024f6250000000000f4c926000000000026fe6300000000001fc3260000000000cfbe260000000000decf2600000000006ece26000000000022a02600000000003cc3260000000000b4cd26000000000078512600000000004fcd26000000000097d02600000000004dcc26000000000051cf260000000000438f2600000000004bc626000000000049ca26000000000037fe6300000000007f3b61000000000063b2560000000000b6c92600000000008ebb2600000000004bce260000000000f7cd2600000000002ccd260000000000f0cf260000000000c7cd26000000000004c526000000000098cc2600000000004dd02600000000003dbd2600000000006ecd26000000000029cf260000000000b9c326000000000081be260000000000f6ce26000000000056c826000000000096cc2600000000001b3d30000000000061d026000000000002b8260000000000ff90260000000000c1c42600000000002ccc260000000000d0c926000000000035c6260000000000eccb26000000000061cc26000000000072cc260000000000eccd2600000000005fcc2600000000004dd026000000000091cc2600000000009ec0260000000000049e26000000000060cd26000000000094d02600000000006dce260000000000b8cf370000000000bbca26000000000051c326000000000068ca260000000000f6852600000000002f61490000000000cccc26000000000065b926000000000061cc260000000000b4aa2400000000002fcd260000000000b23c30000000000002c7260000000000c78926000000000004be260000000000ffcc2600000000004bb83400000000008cc72600000000003ed0260000000000b5cb2600000000005a474000000000007dc32600000000001ec92600000000002ad0260000000000d8cd260000000000e4cb260000000000ac95260000000000cbcf26000000000002c82600000000009dd0260000000000a683260000000000bdc8260000000000bf092600000000009f7b2600000000000bce260000000000241526000000000097ce260000000000accc260000000000d3ee3900000000006bcd2600000000002b4f26000000000091c62600000000003f8f25000000000044c82600000000001ecb260000000000a9d026000000000050c826000000000051ce260000000000bbdd4200000000006b8226000000000089cb6100000000008bd0260000000000b2cd26000000000076cb260000000000f9cc26000000000029d02600000000007bc7260000000000fbcd2600000000007fca26000000000020b72400000000005bc526000000000016cf26000000000086be26000000000045d0260000000000c3cb26000000000092c4260000000000f8cf26000000000066cd260000000000d9cf260000000000c1873300000000002dc92600000000005fca26000000000082c72600000000003cc72600000000002dd02600000000009d85630000000000aff5240000000000c58226000000000097ca26000000000038cf260000000000937426000000000002ca26000000000022c6260000000000d0cf26000000000080cb26000000000029cd260000000000afcf26000000000034ca260000000000e0c72600000000002cce260000000000bacd26000000000065c82600000000000bcf2600000000009bcc260000000000454e260000000000f0cd2600000000003fcc26000000000004cc26000000000051d026000000000008c126000000000031ce26000000000022be260000000000cacf260000000000cb772600000000009c3e2b000000000076aa240000000000facb2600000000009bc326000000000059b7260000000000b1ca26000000000039cd260000000000aeb42600000000007ed02600000000002bd026000000000018cb260000000000010c590000000000decd260000000000c7c726000000000046d0260000000000b5c8260000000000facc26000000000058c826000000000012b626000000000094cd260000000000d5b92600000000003ed026000000000087d026000000000086d02600000000000fc0260000000000a1c726000000000063ce2600000000001cc02600000000007fc5260000000000e9cd2600000000004ed0260000000000a0b2260000000000aaca260000000000357a26000000000019fe63000000000048cd260000000000f5f52400000000004dc72600000000006ac426000000000098c226000000000043cc2600000000006293260000000000a1c2260000000000cfc426000000000068af260000000000f2b9260000000000a1d0260000000000ccc9260000000000f0cd26000000000072cd2600000000005fbf2600000000005ebf2600000000005ecf2600000000006e4d2600000000006e0b31000000000011bb26000000000002be26000000000041ca260000000000b6cd260000000000c0c42600000000007ece26000000000081cc260000000000deb12600000000008ccf26000000000063cc260000000000cfad2600000000009cd02600000000003dd026000000000045c9260000000000e4cb2600000000008d8b26000000000040d026000000000069d0260000000000d047260000000000fbcb26000000000021c7260000000000c9ce26000000000012b9260000000000aec7260000000000d2cc2600000000008bc4260000000000deee330000000000962726000000000056c226000000000099cf2600000000008e8f250000000000cbcb26000000000090c2260000000000adcd26000000000094a1260000000000d3b42600000000009cca260000000000ddf524000000000023182f0000000000b04026000000000064d0260000000000a5d026000000000069ca26000000000008ce2600000000000dce26000000000054cc2600000000009dcf26000000000043c5260000000000b9cd2600000000007dd02600000000005ad026000000000086d02600000000003fd0260000000000fd63260000000000228f2500000000004dd0260000000000bdcf260000000000a2cb260000000000c0c92600000000002ccf260000000000d19244000000000015d0260000000000becf26000000000008c72600000000000cd0260000000000abc3260000000000cdbc260000000000a7c82600000000007ac826000000000004792600000000000e9e490000000000e5be2600000000001f83280000000000bbbc2600000000007cd02600000000007dd0260000000000bccd26000000000006c8260000000000fac7260000000000f1c2260000000000f3ce26000000000067c726000000000068445d0000000000ecce260000000000d3c9260000000000e0c226000000000029cf2600000000000ccd260000000000becf26000000000048cb2600000000006186280000000000a7d02600000000007bc9260000000000dadf530000000000b3d026000000000083cf260000000000b1cf26000000000060424b0000000000eacb260000000000fbc826000000000045c3260000000000cdcf260000000000e1ce2600000000002fcb2600000000004dc426000000000095cd26000000000087362700000000004bcb260000000000afc4260000000000f5c626000000000038cd260000000000f9ce260000000000f6733a0000000000cbc9260000000000b4cd260000000000b4cb26000000000014cc26000000000000cf260000000000aac4260000000000ddc72600000000002efc340000000000b7b12600000000008479260000000000f3cf260000000000b5bd2600000000005ace260000000000d6c7260000000000e0c226000000000050ca260000000000f3c3260000000000f18e2600000000000bcc260000000000232e2600000000004b8f2500000000008fc726000000000096cc26000000000004cf2600000000006fc926000000000094ca26000000000024ac26000000000008cb260000000000d2c7260000000000c1cf26000000000079cc260000000000313d30000000000029ce2600000000006cc9260000000000c8cc260000000000e1c626000000000049cb260000000000b1ce260000000000afc5260000000000e1c6260000000000b3c8260000000000fbce2600000000009e733600000000000dcf26000000000079c826000000000030c5260000000000a7aa2400000000006cd026000000000098c6260000000000a4c4260000000000e9ce260000000000d3ce26000000000069cd260000000000f5c526000000000088cd260000000000d8cd260000000000c2cd260000000000df7b260000000000afc8260000000000943f2600000000000253280000000000dbcd2600000000006d7b260000000000dec7260000000000858126000000000073b526000000000025c4260000000000f0bc2600000000000dc126000000000087b726000000000002bd260000000000c7ce26000000000044c4260000000000d5cf260000000000aacd260000000000c5c826000000000028c126000000000078c52600000000004eef5400000000003ccf260000000000ef32300000000000c25145000000000067b52600000000009dc3260000000000def5240000000000e2ce260000000000108126000000000073c5260000000000ebcd26000000000034c8260000000000d2c12600000000006bcc260000000000f69c26000000000026c9260000000000909426000000000021cc260000000000ffc2260000000000fec72600000000007ecc260000000000adc7260000000000773e4000000000009ac226000000000063c5260000000000f7c3260000000000d0cf260000000000c4d9390000000000ea492900000000007acb26000000000017cb2600000000006abd260000000000eec4260000000000a2c726000000000008d026000000000099c826000000000022c72600000000009fca2600000000004ecc2600000000004cd026000000000007d026000000000000ca2600000000008dd026000000000055c226000000000091d02600000000004184260000000000e2cb26000000000006be2600000000002079260000000000cdc72600000000004ac42600000000003fc426000000000040a73e000000000070aa240000000000d3bd26000000000045ce260000000000bbf524000000000059fe63000000000002ce260000000000bdcb2600000000007eaa24000000000059c226000000000061bc260000000000f6cd260000000000d6d93400000000005210340000000000f74a31000000000013c8260000000000fd8f260000000000bbc0260000000000a6d02600000000001dcd26000000000019ca260000000000e9cb26000000000068ce26000000000007bc260000000000b6cc260000000000e9ce260000000000cacf26000000000013cc260000000000a319260000000000b174260000000000b9cc260000000000b3cb2600000000004efe63000000000048cd26000000000055b826000000000089c726000000000070d02600000000004ccc260000000000bac9260000000000a9d0260000000000c2cf26000000000044cc260000000000b9ee4b000000000098bb260000000000aacc26000000000062ca2600000000009163250000000000a1b42600000000008dcc2600000000008ace260000000000b9ce2600000000008bcd2600000000002bc22600000000005ed0260000000000fdc8260000000000ecc72600000000000dcd26000000000071cb26000000000056cd260000000000a9ca26000000000064c92600000000005a902d00000000002dcf260000000000" }, }, }, @@ -5303,7 +5308,7 @@ }, "system_chain": {"[]": {"jsonrpc": "2.0", "result": "Bittensor"}}, }, - "get_subnets": { + "get_all_subnets_netuid": { "chain_getHead": { "[]": { "jsonrpc": "2.0", diff --git a/tests/integration_tests/test_subtensor_integration.py b/tests/integration_tests/test_subtensor_integration.py index d907890389..c95c15a1af 100644 --- a/tests/integration_tests/test_subtensor_integration.py +++ b/tests/integration_tests/test_subtensor_integration.py @@ -25,7 +25,7 @@ async def prepare_test(mocker, seed, **subtensor_args): "async_substrate_interface.sync_substrate.connect", mocker.Mock(return_value=FakeWebsocket(seed=seed)), ) - subtensor = Subtensor("unknown", _mock=True, **subtensor_args) + subtensor = Subtensor("unknown", mock=True, **subtensor_args) return subtensor @@ -96,7 +96,7 @@ async def test_is_hotkey_registered(mocker): async def test_blocks_since_last_update(mocker): subtensor = await prepare_test(mocker, "blocks_since_last_update") result = subtensor.blocks_since_last_update(1, 0) - assert result == 3978699 + assert result == 4009702 @pytest.mark.asyncio diff --git a/tests/integration_tests/test_timelock.py b/tests/integration_tests/test_timelock.py index 33e31db782..a1faf44cf6 100644 --- a/tests/integration_tests/test_timelock.py +++ b/tests/integration_tests/test_timelock.py @@ -3,7 +3,7 @@ import pytest -from bittensor.core import timelock +from bittensor.extras import timelock def test_encrypt_returns_valid_tuple(): diff --git a/tests/unit_tests/conftest.py b/tests/unit_tests/conftest.py index bed6f28bb3..7b13c7893e 100644 --- a/tests/unit_tests/conftest.py +++ b/tests/unit_tests/conftest.py @@ -28,7 +28,7 @@ def mock_substrate(mocker): @pytest.fixture def subtensor(mock_substrate): - return bittensor.core.subtensor.Subtensor(_mock=True) + return bittensor.core.subtensor.Subtensor(mock=True) @pytest.fixture diff --git a/tests/unit_tests/extrinsics/asyncex/test_unstaking.py b/tests/unit_tests/extrinsics/asyncex/test_unstaking.py index 8b0032a79e..0721adfca2 100644 --- a/tests/unit_tests/extrinsics/asyncex/test_unstaking.py +++ b/tests/unit_tests/extrinsics/asyncex/test_unstaking.py @@ -7,23 +7,23 @@ @pytest.mark.asyncio async def test_unstake_extrinsic(fake_wallet, mocker): + # Preps fake_substrate = mocker.AsyncMock( **{"get_payment_info.return_value": {"partial_fee": 10}} ) - # Preps + fake_netuid = 14 fake_subtensor = mocker.AsyncMock( **{ "get_hotkey_owner.return_value": "hotkey_owner", - "get_stake_for_coldkey_and_hotkey.return_value": Balance(10.0), + "get_stake_for_coldkey_and_hotkey.return_value": Balance.from_tao(10.0, fake_netuid), "sign_and_send_extrinsic.return_value": ExtrinsicResponse(True, ""), - "get_stake.return_value": Balance(10.0), + "get_stake.return_value": Balance.from_tao(10.0, fake_netuid), "substrate": fake_substrate, } ) fake_wallet.coldkeypub.ss58_address = "hotkey_owner" hotkey_ss58 = "hotkey" - fake_netuid = 1 amount = Balance.from_tao(1.1) wait_for_inclusion = True wait_for_finalization = True @@ -48,7 +48,7 @@ async def test_unstake_extrinsic(fake_wallet, mocker): call_params={ "hotkey": "hotkey", "amount_unstaked": 1100000000, - "netuid": 1, + "netuid": fake_netuid, }, ) fake_subtensor.sign_and_send_extrinsic.assert_awaited_once_with( @@ -113,6 +113,9 @@ async def test_unstake_all_extrinsic(fake_wallet, mocker): async def test_unstake_multiple_extrinsic_some_unstake_is_happy(fake_wallet, mocker): """Verify that sync `unstake_multiple_extrinsic` method calls proper async method.""" # Preps + sn_5 = 5 + sn_14 = 14 + fake_netuids = [sn_5, sn_14] fake_substrate = mocker.AsyncMock( **{"get_payment_info.return_value": {"partial_fee": 10}} ) @@ -125,12 +128,11 @@ async def test_unstake_multiple_extrinsic_some_unstake_is_happy(fake_wallet, moc unstaking, "unstake_extrinsic", return_value=ExtrinsicResponse(True, "") ) mocker.patch.object( - unstaking, "get_old_stakes", return_value=[Balance(1.1), Balance(0.3)] + unstaking, "get_old_stakes", return_value=[Balance.from_tao(1.1, sn_5), Balance.from_tao(0.3, sn_14)] ) fake_wallet.coldkeypub.ss58_address = "hotkey_owner" hotkey_ss58s = ["hotkey1", "hotkey2"] - fake_netuids = [1, 2] - amounts = [Balance.from_tao(1.1), Balance.from_tao(1.2)] + amounts = [Balance.from_tao(1.1, sn_5), Balance.from_tao(1.2, sn_14)] wait_for_inclusion = True wait_for_finalization = True @@ -146,15 +148,13 @@ async def test_unstake_multiple_extrinsic_some_unstake_is_happy(fake_wallet, moc ) # Asserts - print(">>> result", response) - print(">>> result.success", response.success) assert response.success is False assert response.message == "Some unstake were successful." assert len(response.data) == 2 mocked_unstake_extrinsic.assert_awaited_once_with( subtensor=fake_subtensor, wallet=fake_wallet, - amount=Balance.from_tao(1.1), + amount=Balance.from_tao(1.1, sn_5), hotkey_ss58=hotkey_ss58s[0], netuid=fake_netuids[0], period=None, diff --git a/tests/unit_tests/extrinsics/test_staking.py b/tests/unit_tests/extrinsics/test_staking.py index 0240fdf560..9fb40bf26d 100644 --- a/tests/unit_tests/extrinsics/test_staking.py +++ b/tests/unit_tests/extrinsics/test_staking.py @@ -60,7 +60,7 @@ def test_add_stake_multiple_extrinsic(subtensor, mocker, fake_wallet): """Verify that sync `add_stake_multiple_extrinsic` method calls proper async method.""" # Preps mocked_get_stake_for_coldkey = mocker.patch.object( - subtensor, "get_stake_for_coldkey", return_value=[Balance(1.1), Balance(0.3)] + subtensor, "get_stake_info_for_coldkey", return_value=[Balance(1.1), Balance(0.3)] ) mocked_get_balance = mocker.patch.object( subtensor, "get_balance", return_value=Balance.from_tao(10) diff --git a/tests/unit_tests/extrinsics/test_unstaking.py b/tests/unit_tests/extrinsics/test_unstaking.py index 6c8320ff8d..4a88a5c8ba 100644 --- a/tests/unit_tests/extrinsics/test_unstaking.py +++ b/tests/unit_tests/extrinsics/test_unstaking.py @@ -4,22 +4,22 @@ def test_unstake_extrinsic(fake_wallet, mocker): + # Preps fake_substrate = mocker.Mock( **{"get_payment_info.return_value": {"partial_fee": 10}} ) - # Preps + fake_netuid = 14 fake_subtensor = mocker.Mock( **{ "get_hotkey_owner.return_value": "hotkey_owner", - "get_stake_for_coldkey_and_hotkey.return_value": Balance(10.0), + "get_stake_for_coldkey_and_hotkey.return_value": Balance.from_tao(10.0, fake_netuid), "sign_and_send_extrinsic.return_value": ExtrinsicResponse(True, ""), - "get_stake.return_value": Balance(10.0), + "get_stake.return_value": Balance.from_tao(10.0, fake_netuid), "substrate": fake_substrate, } ) fake_wallet.coldkeypub.ss58_address = "hotkey_owner" hotkey_ss58 = "hotkey" - fake_netuid = 1 amount = Balance.from_tao(1.1) wait_for_inclusion = True wait_for_finalization = True @@ -44,7 +44,7 @@ def test_unstake_extrinsic(fake_wallet, mocker): call_params={ "hotkey": "hotkey", "amount_unstaked": 1100000000, - "netuid": 1, + "netuid": fake_netuid, }, ) fake_subtensor.sign_and_send_extrinsic.assert_called_once_with( @@ -107,6 +107,9 @@ def test_unstake_all_extrinsic(fake_wallet, mocker): def test_unstake_multiple_extrinsic(subtensor, fake_wallet, mocker): """Tests when out of 2 unstakes 1 is completed and 1 is not.""" # Preps + sn_5 = 5 + sn_14 = 14 + fake_netuids = [sn_5, sn_14] mocked_balance = mocker.patch.object( subtensor, "get_balance", return_value=Balance.from_tao(1.0) ) @@ -119,12 +122,11 @@ def test_unstake_multiple_extrinsic(subtensor, fake_wallet, mocker): mocker.patch.object( unstaking, "get_old_stakes", - return_value=[Balance.from_tao(10), Balance.from_tao(0.3)], + return_value=[Balance.from_tao(10, sn_5), Balance.from_tao(0.3, sn_14)], ) fake_wallet.coldkeypub.ss58_address = "hotkey_owner" hotkey_ss58s = ["hotkey1", "hotkey2"] - fake_netuids = [1, 2] - amounts = [Balance.from_tao(1.1), Balance.from_tao(1.2)] + amounts = [Balance.from_tao(1.1, sn_5), Balance.from_tao(1.2, sn_14)] wait_for_inclusion = True wait_for_finalization = True @@ -151,9 +153,9 @@ def test_unstake_multiple_extrinsic(subtensor, fake_wallet, mocker): mocked_unstake_extrinsic.assert_called_once_with( subtensor=subtensor, wallet=fake_wallet, - netuid=1, + netuid=sn_5, hotkey_ss58="hotkey1", - amount=Balance.from_tao(1.1), + amount=Balance.from_tao(1.1, sn_5), period=None, raise_error=False, wait_for_inclusion=wait_for_inclusion, diff --git a/tests/unit_tests/test_async_subtensor.py b/tests/unit_tests/test_async_subtensor.py index fab019fc1c..50348838eb 100644 --- a/tests/unit_tests/test_async_subtensor.py +++ b/tests/unit_tests/test_async_subtensor.py @@ -1,6 +1,6 @@ import datetime import unittest.mock as mock - +from bittensor.core.errors import BalanceTypeError import pytest from async_substrate_interface.types import ScaleObj from bittensor_wallet import Wallet @@ -390,7 +390,7 @@ async def test_get_total_subnets(subtensor, mocker): ) @pytest.mark.asyncio async def test_get_subnets(subtensor, mocker, records, response): - """Tests get_subnets method with any return.""" + """Tests get_all_subnets_netuid method with any return.""" # Preps fake_result = mocker.AsyncMock(autospec=list) fake_result.records = records @@ -405,7 +405,7 @@ async def test_get_subnets(subtensor, mocker, records, response): fake_block_hash = None # Call - result = await subtensor.get_subnets(block_hash=fake_block_hash) + result = await subtensor.get_all_subnets_netuid(block_hash=fake_block_hash) # Asserts mocked_substrate_query_map.assert_called_once_with( @@ -559,7 +559,7 @@ async def test_get_stake_for_coldkey_and_hotkey(subtensor, mocker): subtensor.substrate, "get_chain_head", return_value=block_hash ) mocked_get_subnets = mocker.patch.object( - subtensor, "get_subnets", return_value=netuids + subtensor, "get_all_subnets_netuid", return_value=netuids ) result = await subtensor.get_stake_for_coldkey_and_hotkey( @@ -662,14 +662,14 @@ async def test_get_balance(subtensor, mocker): assert result == mocked_balance.return_value -@pytest.mark.parametrize("balance", [100, 100.1]) +@pytest.mark.parametrize("balance", [Balance.from_tao(100), Balance.from_tao(100.1)]) @pytest.mark.asyncio async def test_get_transfer_fee(subtensor, fake_wallet, mocker, balance): """Tests get_transfer_fee method.""" # Preps fake_wallet.coldkeypub = "coldkeypub" fake_dest = "fake_dest" - fake_value = Balance(balance) + fake_value = balance mocked_compose_call = mocker.AsyncMock() subtensor.substrate.compose_call = mocked_compose_call @@ -679,7 +679,7 @@ async def test_get_transfer_fee(subtensor, fake_wallet, mocker, balance): # Call result = await subtensor.get_transfer_fee( - wallet=fake_wallet, dest=fake_dest, value=fake_value + wallet=fake_wallet, dest=fake_dest, amount=fake_value ) # Assertions @@ -710,13 +710,11 @@ async def test_get_transfer_with_exception(subtensor, mocker): subtensor.substrate.compose_call = mocked_compose_call subtensor.substrate.get_payment_info.side_effect = Exception - # Call - result = await subtensor.get_transfer_fee( - wallet=mocker.Mock(), dest=mocker.Mock(), value=fake_value - ) - - # Assertions - assert result == async_subtensor.Balance.from_rao(int(2e7)) + # Call + Assertions + with pytest.raises(BalanceTypeError): + await subtensor.get_transfer_fee( + wallet=mocker.Mock(), dest=mocker.Mock(), amount=fake_value + ) @pytest.mark.asyncio @@ -2508,23 +2506,26 @@ async def test_blocks_since_last_update_success(subtensor, mocker): current_block = 100 fake_blocks_since_update = current_block - last_update_block + mocker.patch.object( + subtensor.substrate, "get_block_number", return_value=current_block, + ) mocked_get_hyperparameter = mocker.patch.object( subtensor, "get_hyperparameter", return_value={fake_uid: last_update_block}, ) - mocked_get_current_block = mocker.AsyncMock(return_value=current_block) - subtensor.get_current_block = mocked_get_current_block - # Call result = await subtensor.blocks_since_last_update(netuid=fake_netuid, uid=fake_uid) # Asserts mocked_get_hyperparameter.assert_called_once_with( - param_name="LastUpdate", netuid=fake_netuid + param_name="LastUpdate", + netuid=fake_netuid, + block=subtensor.substrate.get_block_number.return_value, + block_hash=None, + reuse_block=False, ) - mocked_get_current_block.assert_called_once() assert result == fake_blocks_since_update @@ -2543,11 +2544,18 @@ async def test_blocks_since_last_update_no_last_update(subtensor, mocker): ) # Call - result = await subtensor.blocks_since_last_update(netuid=fake_netuid, uid=fake_uid) + result = await subtensor.blocks_since_last_update( + netuid=fake_netuid, + uid=fake_uid, + ) # Asserts mocked_get_hyperparameter.assert_called_once_with( - param_name="LastUpdate", netuid=fake_netuid + param_name="LastUpdate", + netuid=fake_netuid, + block=subtensor.substrate.get_block_number.return_value, + block_hash=None, + reuse_block=False, ) assert result is None @@ -3103,6 +3111,8 @@ async def test_get_subnet_owner_hotkey_has_return(subtensor, mocker): name="SubnetOwnerHotkey", block=block, params=[netuid], + block_hash=None, + reuse_block=False, ) assert result == expected_owner_hotkey @@ -3125,6 +3135,8 @@ async def test_get_subnet_owner_hotkey_is_none(subtensor, mocker): name="SubnetOwnerHotkey", block=block, params=[netuid], + block_hash=None, + reuse_block=False, ) assert result is None @@ -3148,6 +3160,8 @@ async def test_get_subnet_validator_permits_has_values(subtensor, mocker): name="ValidatorPermit", block=block, params=[netuid], + block_hash=None, + reuse_block=False, ) assert result == expected_validator_permits @@ -3171,6 +3185,8 @@ async def test_get_subnet_validator_permits_is_none(subtensor, mocker): name="ValidatorPermit", block=block, params=[netuid], + block_hash=None, + reuse_block=False, ) assert result is None @@ -3499,8 +3515,8 @@ async def test_add_liquidity(subtensor, fake_wallet, mocker): wallet=fake_wallet, netuid=netuid, liquidity=Balance.from_tao(150), - price_low=Balance.from_tao(180).rao, - price_high=Balance.from_tao(130).rao, + price_low=Balance.from_tao(180), + price_high=Balance.from_tao(130), ) # Asserts @@ -3511,7 +3527,7 @@ async def test_add_liquidity(subtensor, fake_wallet, mocker): liquidity=Balance.from_tao(150), price_low=Balance.from_tao(180).rao, price_high=Balance.from_tao(130).rao, - hotkey=None, + hotkey_ss58=None, wait_for_inclusion=True, wait_for_finalization=True, period=None, @@ -3545,7 +3561,7 @@ async def test_modify_liquidity(subtensor, fake_wallet, mocker): netuid=netuid, position_id=position_id, liquidity_delta=Balance.from_tao(150), - hotkey=None, + hotkey_ss58=None, wait_for_inclusion=True, wait_for_finalization=True, period=None, @@ -3577,7 +3593,7 @@ async def test_remove_liquidity(subtensor, fake_wallet, mocker): wallet=fake_wallet, netuid=netuid, position_id=position_id, - hotkey=None, + hotkey_ss58=None, wait_for_inclusion=True, wait_for_finalization=True, period=None, @@ -3783,7 +3799,7 @@ async def test_get_stake_operations_fee(subtensor, mocker): params=[netuid], block_hash=mocked_determine_block_hash.return_value, ) - assert result == Balance.from_rao(299076829).set_unit(netuid) + assert result == Balance.from_rao(299076829) @pytest.mark.asyncio @@ -3791,7 +3807,7 @@ async def test_get_stake_add_fee(subtensor, mocker): """Verify that `get_stake_add_fee` calls proper methods and returns the correct value.""" # Preps netuid = mocker.Mock() - amount = mocker.Mock() + amount = mocker.Mock(spec=Balance) mocked_get_stake_operations_fee = mocker.patch.object( subtensor, "get_stake_operations_fee" ) @@ -3814,7 +3830,7 @@ async def test_get_unstake_fee(subtensor, mocker): """Verify that `get_unstake_fee` calls proper methods and returns the correct value.""" # Preps netuid = mocker.Mock() - amount = mocker.Mock() + amount = mocker.Mock(spec=Balance) mocked_get_stake_operations_fee = mocker.patch.object( subtensor, "get_stake_operations_fee" ) @@ -3837,7 +3853,7 @@ async def test_get_stake_movement_fee(subtensor, mocker): """Verify that `get_stake_movement_fee` calls proper methods and returns the correct value.""" # Preps netuid = mocker.Mock() - amount = mocker.Mock() + amount = mocker.Mock(spec=Balance) mocked_get_stake_operations_fee = mocker.patch.object( subtensor, "get_stake_operations_fee" ) diff --git a/tests/unit_tests/test_config.py b/tests/unit_tests/test_config.py index 5c1c2a0edf..18b8ee36d5 100644 --- a/tests/unit_tests/test_config.py +++ b/tests/unit_tests/test_config.py @@ -6,12 +6,12 @@ def test_py_config_parsed_successfully_rust_wallet(): """Verify that python based config object is successfully parsed with rust-based wallet object.""" parser = argparse.ArgumentParser() - bittensor.wallet.add_args(parser) - bittensor.subtensor.add_args(parser) - bittensor.axon.add_args(parser) + bittensor.Wallet.add_args(parser) + bittensor.Subtensor.add_args(parser) + bittensor.Axon.add_args(parser) bittensor.logging.add_args(parser) - config = bittensor.config(parser) + config = bittensor.Config(parser) # override config manually since we can't apply mocking to rust objects easily config.wallet.name = "new_wallet_name" @@ -19,13 +19,13 @@ def test_py_config_parsed_successfully_rust_wallet(): config.wallet.path = "/some/not_default/path" # Pass in the whole bittensor config - wallet = bittensor.wallet(config=config) + wallet = bittensor.Wallet(config=config) assert wallet.name == config.wallet.name assert wallet.hotkey_str == config.wallet.hotkey assert wallet.path == config.wallet.path # Pass in only the btwallet's config - wallet_two = bittensor.wallet(config=config.wallet) + wallet_two = bittensor.Wallet(config=config.wallet) assert wallet_two.name == config.wallet.name assert wallet_two.hotkey_str == config.wallet.hotkey assert wallet_two.path == config.wallet.path diff --git a/tests/unit_tests/test_deprecated.py b/tests/unit_tests/test_deprecated.py deleted file mode 100644 index f47337e019..0000000000 --- a/tests/unit_tests/test_deprecated.py +++ /dev/null @@ -1,34 +0,0 @@ -import sys - - -def test_mock_import(): - """ - Tests that `bittensor.mock` can be imported and is the same as `bittensor.utils.mock`. - """ - import bittensor.mock as redirected_mock - import bittensor.utils.mock as real_mock - - assert "bittensor.mock" in sys.modules - assert redirected_mock is real_mock - - -def test_extrinsics_import(): - """Tests that `bittensor.extrinsics` can be imported and is the same as `bittensor.utils.deprecated.extrinsics`.""" - import bittensor.extrinsics as redirected_extrinsics - import bittensor.core.extrinsics as real_extrinsics - - assert "bittensor.extrinsics" in sys.modules - assert redirected_extrinsics is real_extrinsics - - -def test_object_aliases_are_correctly_mapped(): - """Ensures all object aliases correctly map to their respective classes in Bittensor package.""" - import bittensor - - assert issubclass(bittensor.axon, bittensor.Axon) - assert issubclass(bittensor.config, bittensor.Config) - assert issubclass(bittensor.dendrite, bittensor.Dendrite) - assert issubclass(bittensor.keyfile, bittensor.Keyfile) - assert issubclass(bittensor.metagraph, bittensor.Metagraph) - assert issubclass(bittensor.wallet, bittensor.Wallet) - assert issubclass(bittensor.synapse, bittensor.Synapse) diff --git a/tests/unit_tests/test_metagraph.py b/tests/unit_tests/test_metagraph.py index cdb735f627..acf62e22d0 100644 --- a/tests/unit_tests/test_metagraph.py +++ b/tests/unit_tests/test_metagraph.py @@ -1,5 +1,6 @@ import asyncio import copy +from bittensor.utils.btlogging import logging from bittensor.utils.balance import Balance from unittest.mock import Mock @@ -159,10 +160,11 @@ def __contains__(self, item): ], ) def test_sync_warning_cases(block, test_id, metagraph_instance, mock_subtensor, caplog): + """Makes sure that the warning message is logged when the block is greater than 300 with debug level.""" + logging.set_debug() mock_subtensor.get_current_block.return_value = 601 mock_subtensor.get_metagraph_info.return_value = [] metagraph_instance.sync(block=block, lite=True, subtensor=mock_subtensor) - expected_message = "Attempting to sync longer than 300 blocks ago on a non-archive node. Please use the 'archive' network for subtensor and retry." assert expected_message in caplog.text, ( f"Test ID: {test_id} - Expected warning message not found in Loguru sink." diff --git a/tests/unit_tests/test_subtensor.py b/tests/unit_tests/test_subtensor.py index 07d8796987..3f31bcf0a7 100644 --- a/tests/unit_tests/test_subtensor.py +++ b/tests/unit_tests/test_subtensor.py @@ -61,8 +61,8 @@ def call_params_with_certificate(): def test_methods_comparable(mock_substrate): """Verifies that methods in sync and async Subtensors are comparable.""" # Preps - subtensor = Subtensor(_mock=True) - async_subtensor = AsyncSubtensor(_mock=True) + subtensor = Subtensor(mock=True) + async_subtensor = AsyncSubtensor(mock=True) # methods which lives in async subtensor only excluded_async_subtensor_methods = ["initialize"] @@ -368,7 +368,7 @@ def test_blocks_since_last_update_success_calls(subtensor, mocker): # Assertions mocked_get_current_block.assert_called_once() - mocked_get_hyperparameter.assert_called_once_with(param_name="LastUpdate", netuid=7) + mocked_get_hyperparameter.assert_called_once_with(param_name="LastUpdate", netuid=7, block=mocked_current_block) assert result == 1 # if we change the methods logic in the future we have to be make sure the returned type is correct assert isinstance(result, int) @@ -759,9 +759,9 @@ def test_get_total_subnets_no_block(mocker, subtensor): subtensor.substrate.get_block_hash.assert_not_called() -# `get_subnets` tests +# `get_all_subnets_netuid` tests def test_get_subnets_success(mocker, subtensor): - """Test get_subnets returns correct list when subnet information is found.""" + """Test get_all_subnets_netuid returns correct list when subnet information is found.""" # Prep block = 123 mock_result = mocker.MagicMock() @@ -770,7 +770,7 @@ def test_get_subnets_success(mocker, subtensor): mocker.patch.object(subtensor.substrate, "query_map", return_value=mock_result) # Call - result = subtensor.get_subnets(block) + result = subtensor.get_all_subnets_netuid(block) # Asserts assert result == [1, 2] @@ -783,7 +783,7 @@ def test_get_subnets_success(mocker, subtensor): def test_get_subnets_no_data(mocker, subtensor): - """Test get_subnets returns empty list when no subnet information is found.""" + """Test get_all_subnets_netuid returns empty list when no subnet information is found.""" # Prep block = 123 mock_result = mocker.MagicMock() @@ -791,7 +791,7 @@ def test_get_subnets_no_data(mocker, subtensor): mocker.patch.object(subtensor.substrate, "query_map", return_value=mock_result) # Call - result = subtensor.get_subnets(block) + result = subtensor.get_all_subnets_netuid(block) # Asserts assert result == [] @@ -804,7 +804,7 @@ def test_get_subnets_no_data(mocker, subtensor): def test_get_subnets_no_block_specified(mocker, subtensor): - """Test get_subnets with no block specified.""" + """Test get_all_subnets_netuid with no block specified.""" # Prep mock_result = mocker.MagicMock() mock_result.records = [(1, True), (2, True)] @@ -812,7 +812,7 @@ def test_get_subnets_no_block_specified(mocker, subtensor): mocker.patch.object(subtensor.substrate, "query_map", return_value=mock_result) # Call - result = subtensor.get_subnets() + result = subtensor.get_all_subnets_netuid() # Asserts assert result == [1, 2] @@ -1252,7 +1252,7 @@ def test_transfer(subtensor, fake_wallet, mocker): """Tests successful transfer call.""" # Prep fake_dest = "SS58PUBLICKEY" - fake_amount = 1.1 + fake_amount = Balance.from_tao(1.1) fake_wait_for_inclusion = True fake_wait_for_finalization = True mocked_transfer_extrinsic = mocker.patch.object( @@ -1273,7 +1273,7 @@ def test_transfer(subtensor, fake_wallet, mocker): subtensor=subtensor, wallet=fake_wallet, destination=fake_dest, - amount=Balance(fake_amount), + amount=fake_amount, transfer_all=False, wait_for_inclusion=fake_wait_for_inclusion, wait_for_finalization=fake_wait_for_finalization, @@ -1729,7 +1729,7 @@ def test_get_transfer_fee(subtensor, fake_wallet, mocker): subtensor.substrate.get_payment_info.return_value = fake_payment_info # Call - result = subtensor.get_transfer_fee(wallet=fake_wallet, dest=fake_dest, value=value) + result = subtensor.get_transfer_fee(wallet=fake_wallet, dest=fake_dest, amount=value) # Asserts subtensor.substrate.compose_call.assert_called_once_with( @@ -2087,7 +2087,7 @@ def test_get_stake_for_coldkey_and_hotkey(subtensor, mocker): subtensor, "query_runtime_api", side_effect=query_fetcher ) mocked_get_subnets = mocker.patch.object( - subtensor, "get_subnets", return_value=netuids + subtensor, "get_all_subnets_netuid", return_value=netuids ) result = subtensor.get_stake_for_coldkey_and_hotkey( @@ -2727,7 +2727,7 @@ def test_unstake_success(mocker, subtensor, fake_wallet): # Preps fake_hotkey_ss58 = "hotkey_1" fake_netuid = 1 - fake_amount = 10.0 + fake_amount = Balance.from_tao(10.0) mock_unstake_extrinsic = mocker.patch.object(subtensor_module, "unstake_extrinsic") @@ -2750,7 +2750,7 @@ def test_unstake_success(mocker, subtensor, fake_wallet): wallet=fake_wallet, netuid=fake_netuid, hotkey_ss58=fake_hotkey_ss58, - amount=Balance.from_rao(fake_amount), + amount=fake_amount, safe_unstaking=False, allow_partial_stake=False, rate_tolerance=0.005, @@ -2765,7 +2765,7 @@ def test_unstake_success(mocker, subtensor, fake_wallet): 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_amount = Balance.from_tao(10.0) fake_netuid = 14 fake_rate_tolerance = 0.01 # 1% threshold @@ -2790,7 +2790,7 @@ def test_unstake_with_safe_unstaking(mocker, subtensor, fake_wallet): wallet=fake_wallet, netuid=fake_netuid, hotkey_ss58=fake_hotkey_ss58, - amount=Balance.from_rao(fake_amount), + amount=fake_amount, safe_unstaking=True, allow_partial_stake=True, rate_tolerance=fake_rate_tolerance, @@ -2808,7 +2808,7 @@ def test_swap_stake_success(mocker, subtensor, fake_wallet): fake_hotkey_ss58 = "hotkey_1" fake_origin_netuid = 1 fake_destination_netuid = 2 - fake_amount = 10.0 + fake_amount = Balance.from_tao(10.0) mock_swap_stake_extrinsic = mocker.patch.object( subtensor_module, "swap_stake_extrinsic" @@ -2835,7 +2835,7 @@ def test_swap_stake_success(mocker, subtensor, fake_wallet): hotkey_ss58=fake_hotkey_ss58, origin_netuid=fake_origin_netuid, destination_netuid=fake_destination_netuid, - amount=Balance.from_rao(fake_amount), + amount=fake_amount, wait_for_inclusion=True, wait_for_finalization=False, safe_swapping=False, @@ -2853,7 +2853,7 @@ def test_swap_stake_with_safe_staking(mocker, subtensor, fake_wallet): fake_hotkey_ss58 = "hotkey_1" fake_origin_netuid = 1 fake_destination_netuid = 2 - fake_amount = 10.0 + fake_amount = Balance.from_tao(10.0) fake_rate_tolerance = 0.01 # 1% threshold mock_swap_stake_extrinsic = mocker.patch.object( @@ -2881,7 +2881,7 @@ def test_swap_stake_with_safe_staking(mocker, subtensor, fake_wallet): hotkey_ss58=fake_hotkey_ss58, origin_netuid=fake_origin_netuid, destination_netuid=fake_destination_netuid, - amount=Balance.from_rao(fake_amount), + amount=fake_amount, wait_for_inclusion=True, wait_for_finalization=False, safe_swapping=True, @@ -3094,7 +3094,6 @@ def test_get_owned_hotkeys_happy_path(subtensor, mocker): storage_function="OwnedHotkeys", params=[fake_coldkey], block_hash=None, - reuse_block_hash=False, ) assert result == [mocked_decode_account_id.return_value] mocked_decode_account_id.assert_called_once_with(fake_hotkey) @@ -3116,7 +3115,6 @@ def test_get_owned_hotkeys_return_empty(subtensor, mocker): storage_function="OwnedHotkeys", params=[fake_coldkey], block_hash=None, - reuse_block_hash=False, ) assert result == [] @@ -3738,7 +3736,7 @@ def test_add_liquidity(subtensor, fake_wallet, mocker): liquidity=Balance.from_tao(150), price_low=Balance.from_tao(180).rao, price_high=Balance.from_tao(130).rao, - hotkey=None, + hotkey_ss58=None, wait_for_inclusion=True, wait_for_finalization=True, period=None, @@ -3771,7 +3769,7 @@ def test_modify_liquidity(subtensor, fake_wallet, mocker): netuid=netuid, position_id=position_id, liquidity_delta=Balance.from_tao(150), - hotkey=None, + hotkey_ss58=None, wait_for_inclusion=True, wait_for_finalization=True, period=None, @@ -3802,7 +3800,7 @@ def test_remove_liquidity(subtensor, fake_wallet, mocker): wallet=fake_wallet, netuid=netuid, position_id=position_id, - hotkey=None, + hotkey_ss58=None, wait_for_inclusion=True, wait_for_finalization=True, period=None, @@ -3988,14 +3986,14 @@ def test_get_stake_operations_fee(subtensor, mocker): params=[netuid], block_hash=mocked_determine_block_hash.return_value, ) - assert result == Balance.from_rao(299076829).set_unit(netuid) + assert result == Balance.from_rao(299076829) def test_get_stake_add_fee(subtensor, mocker): """Verify that `get_stake_add_fee` calls proper methods and returns the correct value.""" # Preps netuid = mocker.Mock() - amount = mocker.Mock() + amount = mocker.Mock(spec=Balance) mocked_get_stake_operations_fee = mocker.patch.object( subtensor, "get_stake_operations_fee" ) @@ -4017,7 +4015,7 @@ def test_get_unstake_fee(subtensor, mocker): """Verify that `get_unstake_fee` calls proper methods and returns the correct value.""" # Preps netuid = mocker.Mock() - amount = mocker.Mock() + amount = mocker.Mock(spec=Balance) mocked_get_stake_operations_fee = mocker.patch.object( subtensor, "get_stake_operations_fee" ) @@ -4039,7 +4037,7 @@ def test_get_stake_movement_fee(subtensor, mocker): """Verify that `get_stake_movement_fee` calls proper methods and returns the correct value.""" # Preps netuid = mocker.Mock() - amount = mocker.Mock() + amount = mocker.Mock(spec=Balance) mocked_get_stake_operations_fee = mocker.patch.object( subtensor, "get_stake_operations_fee" ) diff --git a/tests/unit_tests/test_subtensor_api.py b/tests/unit_tests/test_subtensor_api.py index 5007370d96..7eaac5fc3a 100644 --- a/tests/unit_tests/test_subtensor_api.py +++ b/tests/unit_tests/test_subtensor_api.py @@ -1,15 +1,16 @@ -from bittensor.core.subtensor import Subtensor -from bittensor.core.subtensor_api import SubtensorApi import pytest +from bittensor.extras import SubtensorApi +from bittensor.core.subtensor import Subtensor + def test_properties_methods_comparable(other_class: "Subtensor" = None): """Verifies that methods in SubtensorApi and its properties contains all Subtensors methods.""" # Preps subtensor = ( - other_class(network="latent-lite", _mock=True) + other_class(network="latent-lite", mock=True) if other_class - else Subtensor(network="latent-lite", _mock=True) + else Subtensor(network="latent-lite", mock=True) ) subtensor_api = SubtensorApi(network="latent-lite", mock=True) @@ -69,7 +70,7 @@ def test__methods_comparable_with_passed_legacy_methods( subtensor = ( other_class(network="latent-lite", mock=True) if other_class - else Subtensor(network="latent-lite", _mock=True) + else Subtensor(network="latent-lite", mock=True) ) subtensor_api = SubtensorApi(network="latent-lite", mock=True, legacy_methods=True) diff --git a/tests/unit_tests/utils/test_balance.py b/tests/unit_tests/utils/test_balance.py index 4ff97bdb81..fab62002c3 100644 --- a/tests/unit_tests/utils/test_balance.py +++ b/tests/unit_tests/utils/test_balance.py @@ -5,8 +5,8 @@ import pytest from hypothesis import given from hypothesis import strategies as st - -from bittensor.utils.balance import Balance +from bittensor.core.errors import BalanceTypeError, BalanceUnitMismatchError +from bittensor.utils.balance import Balance, check_balance_amount from tests.helpers import CloseInValue @@ -518,3 +518,31 @@ def test_from_float(): def test_from_rao(): """Tests from_rao method call.""" assert Balance.from_tao(1) == Balance(1000000000) + + +@pytest.mark.parametrize( + "first, second", + [ + (Balance.from_tao(1), Balance.from_tao(1).set_unit(2)), + (Balance.from_tao(1).set_unit(2), Balance.from_tao(1)), + ], +) +def test_balance_raise_errors(first, second): + """Tests any cases with balance raise errors.""" + with pytest.raises(BalanceUnitMismatchError): + _ = first + second + + +@pytest.mark.parametrize( + "amount", + [ + 100, + 100.1, + "100", + "10.2" + ], +) +def test_check_balance_amount_raise_error(amount): + """Tests Balance.check_rao_value method.""" + with pytest.raises(BalanceTypeError): + check_balance_amount(amount) diff --git a/tests/unit_tests/utils/test_version.py b/tests/unit_tests/utils/test_version.py index 6d1785b0bd..6d8d535d18 100644 --- a/tests/unit_tests/utils/test_version.py +++ b/tests/unit_tests/utils/test_version.py @@ -133,20 +133,3 @@ def test_check_version_up_to_date( assert captured.out == "" - -def test_version_checking(mocker: MockerFixture): - mock = mocker.patch("bittensor.utils.version.check_version") - - version.version_checking() - - mock.assert_called_once() - - -def test_version_checking_exception(mocker: MockerFixture): - mock = mocker.patch( - "bittensor.utils.version.check_version", side_effect=version.VersionCheckError - ) - - version.version_checking() - - mock.assert_called_once()