From 967ffe3da7faa5528aac7b7e6fce8e265a569351 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Wed, 31 Jan 2024 06:11:26 +0000 Subject: [PATCH 1/5] change req, test to ensure all good --- requirements/prod.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/prod.txt b/requirements/prod.txt index 1f05519df6..dec7766b29 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -26,7 +26,7 @@ requests rich scalecodec==1.2.7 shtab==1.6.5 -substrate-interface==1.5.2 +substrate-interface==1.7.5 termcolor torch>=1.13.1 tqdm From c6ffda48c51f4911b0171e56de6eea4be5ac60d4 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Wed, 31 Jan 2024 20:24:14 +0000 Subject: [PATCH 2/5] black format from staging --- bittensor/__init__.py | 4 +- bittensor/axon.py | 9 ++- bittensor/btlogging.py | 7 ++- bittensor/chain_data.py | 18 ++++-- bittensor/commands/delegates.py | 14 ++--- bittensor/commands/inspect.py | 12 ++-- bittensor/commands/metagraph.py | 8 ++- bittensor/commands/overview.py | 12 ++-- bittensor/commands/root.py | 8 ++- bittensor/commands/senate.py | 20 ++++--- bittensor/commands/stake.py | 6 +- bittensor/commands/wallets.py | 6 +- bittensor/config.py | 3 +- bittensor/dendrite.py | 38 ++++++------ bittensor/errors.py | 22 +++++++ bittensor/extrinsics/log_utilities.py | 26 ++++++--- bittensor/keyfile.py | 72 ++++++++++++----------- bittensor/mock/subtensor_mock.py | 20 ++++--- bittensor/subtensor.py | 84 ++++++++++++++------------- bittensor/synapse.py | 44 +++++++------- bittensor/threadpool.py | 4 +- bittensor/utils/__init__.py | 6 +- bittensor/utils/networking.py | 1 + bittensor/utils/stats.py | 1 + bittensor/utils/weight_utils.py | 1 + bittensor/wallet.py | 19 +++--- tests/unit_tests/test_wallet.py | 16 +++-- 27 files changed, 272 insertions(+), 209 deletions(-) diff --git a/bittensor/__init__.py b/bittensor/__init__.py index f27a85ebd4..8a562f5ce9 100644 --- a/bittensor/__init__.py +++ b/bittensor/__init__.py @@ -80,7 +80,9 @@ def debug(on: bool = True): __pipaddress__ = "https://pypi.org/pypi/bittensor/json" # Raw github url for delegates registry file -__delegates_details_url__: str = "https://raw.githubusercontent.com/opentensor/bittensor-delegates/main/public/delegates.json" +__delegates_details_url__: str = ( + "https://raw.githubusercontent.com/opentensor/bittensor-delegates/main/public/delegates.json" +) # Substrate ss58_format __ss58_format__ = 42 diff --git a/bittensor/axon.py b/bittensor/axon.py index 59f45ba4f0..46d331d653 100644 --- a/bittensor/axon.py +++ b/bittensor/axon.py @@ -1,5 +1,6 @@ """ Create and initialize Axon, which services the forward and backward requests from other neurons. """ + # The MIT License (MIT) # Copyright © 2021 Yuma Rao # Copyright © 2022 Opentensor Foundation @@ -1207,9 +1208,11 @@ async def verify(self, synapse: bittensor.Synapse): # We attempt to run the verification function using the synapse instance # created from the request. If this function runs without throwing an exception, # it means that the verification was successful. - await verify_fn(synapse) if inspect.iscoroutinefunction( - verify_fn - ) else verify_fn(synapse) + ( + await verify_fn(synapse) + if inspect.iscoroutinefunction(verify_fn) + else verify_fn(synapse) + ) except Exception as e: # If there was an exception during the verification process, we log that # there was a verification exception. diff --git a/bittensor/btlogging.py b/bittensor/btlogging.py index d17a0dd00a..25ead64d76 100644 --- a/bittensor/btlogging.py +++ b/bittensor/btlogging.py @@ -1,5 +1,6 @@ """ Standardized logging for Bittensor. """ + # The MIT License (MIT) # Copyright © 2021 Yuma Rao @@ -59,7 +60,7 @@ def __new__( logging_dir: str = None, ): r"""Instantiate Bittensor logging system backend. - + Args: config (bittensor.config, optional): bittensor.logging.config() @@ -131,8 +132,8 @@ def __new__( @classmethod def config(cls): """Get config from the argument parser. - - Return: + + Return: bittensor.config object """ parser = argparse.ArgumentParser() diff --git a/bittensor/chain_data.py b/bittensor/chain_data.py index be2486c8b7..f48971fcbb 100644 --- a/bittensor/chain_data.py +++ b/bittensor/chain_data.py @@ -341,6 +341,7 @@ class NeuronInfo: r""" Dataclass for neuron metadata. """ + hotkey: str coldkey: str uid: int @@ -516,6 +517,7 @@ class NeuronInfoLite: r""" Dataclass for neuron metadata, but without the weights and bonds. """ + hotkey: str coldkey: str uid: int @@ -673,6 +675,7 @@ class PrometheusInfo: r""" Dataclass for prometheus info. """ + block: int version: int ip: str @@ -694,6 +697,7 @@ class DelegateInfo: r""" Dataclass for delegate info. """ + hotkey_ss58: str # Hotkey of delegate total_stake: Balance # Total stake of the delegate nominators: List[ @@ -766,7 +770,7 @@ def delegated_list_from_vec_u8( cls, vec_u8: List[int] ) -> List[Tuple["DelegateInfo", Balance]]: r"""Returns a list of Tuples of DelegateInfo objects, and Balance, from a ``vec_u8``. - + This is the list of delegates that the user has delegated to, and the amount of stake delegated. """ decoded = from_scale_encoding(vec_u8, ChainDataType.DelegatedInfo, is_vec=True) @@ -787,6 +791,7 @@ class StakeInfo: r""" Dataclass for stake info. """ + hotkey_ss58: str # Hotkey address coldkey_ss58: str # Coldkey address stake: Balance # Stake for the hotkey-coldkey pair @@ -821,10 +826,10 @@ def list_of_tuple_from_vec_u8( cls, vec_u8: List[int] ) -> Dict[str, List["StakeInfo"]]: r"""Returns a list of StakeInfo objects from a ``vec_u8``.""" - decoded: Optional[ - List[Tuple(str, List[object])] - ] = from_scale_encoding_using_type_string( - input=vec_u8, type_string="Vec<(AccountId, Vec)>" + decoded: Optional[List[Tuple(str, List[object])]] = ( + from_scale_encoding_using_type_string( + input=vec_u8, type_string="Vec<(AccountId, Vec)>" + ) ) if decoded is None: @@ -857,6 +862,7 @@ class SubnetInfo: r""" Dataclass for subnet info. """ + netuid: int rho: int kappa: int @@ -948,6 +954,7 @@ class SubnetHyperparameters: r""" Dataclass for subnet hyperparameters. """ + rho: int kappa: int immunity_period: int @@ -1039,6 +1046,7 @@ class IPInfo: r""" Dataclass for associated IP Info. """ + ip: str ip_type: int protocol: int diff --git a/bittensor/commands/delegates.py b/bittensor/commands/delegates.py index e96a43963b..774a26e72a 100644 --- a/bittensor/commands/delegates.py +++ b/bittensor/commands/delegates.py @@ -101,9 +101,9 @@ def show_delegates( for prev_delegate in prev_delegates: prev_delegates_dict[prev_delegate.hotkey_ss58] = prev_delegate - registered_delegate_info: Optional[ - Dict[str, DelegatesDetails] - ] = get_delegates_details(url=bittensor.__delegates_details_url__) + registered_delegate_info: Optional[Dict[str, DelegatesDetails]] = ( + get_delegates_details(url=bittensor.__delegates_details_url__) + ) if registered_delegate_info is None: bittensor.__console__.print( ":warning:[yellow]Could not get delegate info from chain.[/yellow]" @@ -793,9 +793,9 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): delegates.sort(key=lambda delegate: delegate[0].total_stake, reverse=True) total_delegated += sum(my_delegates.values()) - registered_delegate_info: Optional[ - DelegatesDetails - ] = get_delegates_details(url=bittensor.__delegates_details_url__) + registered_delegate_info: Optional[DelegatesDetails] = ( + get_delegates_details(url=bittensor.__delegates_details_url__) + ) if registered_delegate_info is None: bittensor.__console__.print( ":warning:[yellow]Could not get delegate info from chain.[/yellow]" @@ -845,7 +845,7 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): ), # f'{delegate.take * 100:.1f}%',s f"{ delegate[0].total_daily_return.tao * ( 1000 / ( 0.001 + delegate[0].total_stake.tao ) )!s:6.6}", - str(delegate_description) + str(delegate_description), # f'{delegate_profile.description:140.140}', ) diff --git a/bittensor/commands/inspect.py b/bittensor/commands/inspect.py index bdf2a00e26..f2b3caeaad 100644 --- a/bittensor/commands/inspect.py +++ b/bittensor/commands/inspect.py @@ -141,9 +141,9 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): ) bittensor.logging.debug(f"Netuids to check: {netuids}") - registered_delegate_info: Optional[ - Dict[str, DelegatesDetails] - ] = get_delegates_details(url=bittensor.__delegates_details_url__) + registered_delegate_info: Optional[Dict[str, DelegatesDetails]] = ( + get_delegates_details(url=bittensor.__delegates_details_url__) + ) if registered_delegate_info is None: bittensor.__console__.print( ":warning:[yellow]Could not get delegate info from chain.[/yellow]" @@ -184,9 +184,9 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): "[overline white]Emission", footer_style="overline white", style="green" ) for wallet in tqdm(wallets): - delegates: List[ - Tuple(bittensor.DelegateInfo, bittensor.Balance) - ] = subtensor.get_delegated(coldkey_ss58=wallet.coldkeypub.ss58_address) + delegates: List[Tuple(bittensor.DelegateInfo, bittensor.Balance)] = ( + subtensor.get_delegated(coldkey_ss58=wallet.coldkeypub.ss58_address) + ) if not wallet.coldkeypub_file.exists_on_device(): continue cold_balance = subtensor.get_balance(wallet.coldkeypub.ss58_address) diff --git a/bittensor/commands/metagraph.py b/bittensor/commands/metagraph.py index d837e19028..73383e5ba1 100644 --- a/bittensor/commands/metagraph.py +++ b/bittensor/commands/metagraph.py @@ -124,9 +124,11 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): "*" if metagraph.validator_permit[uid] else "", str((metagraph.block.item() - metagraph.last_update[uid].item())), str(metagraph.active[uid].item()), - ep.ip + ":" + str(ep.port) - if ep.is_serving - else "[yellow]none[/yellow]", + ( + ep.ip + ":" + str(ep.port) + if ep.is_serving + else "[yellow]none[/yellow]" + ), ep.hotkey[:10], ep.coldkey[:10], ] diff --git a/bittensor/commands/overview.py b/bittensor/commands/overview.py index 068c11f004..8e94b1f2e1 100644 --- a/bittensor/commands/overview.py +++ b/bittensor/commands/overview.py @@ -372,11 +372,13 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): "{:.5f}".format(validator_trust), "*" if validator_permit else "", str(last_update), - bittensor.utils.networking.int_to_ip(nn.axon_info.ip) - + ":" - + str(nn.axon_info.port) - if nn.axon_info.port != 0 - else "[yellow]none[/yellow]", + ( + bittensor.utils.networking.int_to_ip(nn.axon_info.ip) + + ":" + + str(nn.axon_info.port) + if nn.axon_info.port != 0 + else "[yellow]none[/yellow]" + ), nn.hotkey, ] diff --git a/bittensor/commands/root.py b/bittensor/commands/root.py index 49355d23f2..0ac387bb13 100644 --- a/bittensor/commands/root.py +++ b/bittensor/commands/root.py @@ -192,9 +192,11 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): for neuron_data in root_neurons: table.add_row( str(neuron_data.uid), - delegate_info[neuron_data.hotkey].name - if neuron_data.hotkey in delegate_info - else "", + ( + delegate_info[neuron_data.hotkey].name + if neuron_data.hotkey in delegate_info + else "" + ), neuron_data.hotkey, "{:.5f}".format( float(subtensor.get_total_stake_for_hotkey(neuron_data.hotkey)) diff --git a/bittensor/commands/senate.py b/bittensor/commands/senate.py index adb704a582..20c02f8a98 100644 --- a/bittensor/commands/senate.py +++ b/bittensor/commands/senate.py @@ -93,9 +93,11 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): for ss58_address in senate_members: table.add_row( - delegate_info[ss58_address].name - if ss58_address in delegate_info - else "", + ( + delegate_info[ss58_address].name + if ss58_address in delegate_info + else "" + ), ss58_address, ) @@ -210,9 +212,9 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): senate_members = subtensor.get_senate_members() proposals = subtensor.get_proposals() - registered_delegate_info: Optional[ - Dict[str, DelegatesDetails] - ] = get_delegates_details(url=bittensor.__delegates_details_url__) + registered_delegate_info: Optional[Dict[str, DelegatesDetails]] = ( + get_delegates_details(url=bittensor.__delegates_details_url__) + ) table = Table(show_footer=False) table.title = ( @@ -341,9 +343,9 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): console.print(":cross_mark: [red]Failed[/red]: Proposal not found.") return - registered_delegate_info: Optional[ - Dict[str, DelegatesDetails] - ] = get_delegates_details(url=bittensor.__delegates_details_url__) + registered_delegate_info: Optional[Dict[str, DelegatesDetails]] = ( + get_delegates_details(url=bittensor.__delegates_details_url__) + ) table = Table(show_footer=False) table.title = "[white]Votes for Proposal {}".format(proposal_hash) diff --git a/bittensor/commands/stake.py b/bittensor/commands/stake.py index cbb210f34b..f93d4e24ab 100644 --- a/bittensor/commands/stake.py +++ b/bittensor/commands/stake.py @@ -392,9 +392,9 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): wallets = _get_coldkey_wallets_for_path(cli.config.wallet.path) else: wallets = [bittensor.wallet(config=cli.config)] - registered_delegate_info: Optional[ - Dict[str, DelegatesDetails] - ] = get_delegates_details(url=bittensor.__delegates_details_url__) + registered_delegate_info: Optional[Dict[str, DelegatesDetails]] = ( + get_delegates_details(url=bittensor.__delegates_details_url__) + ) def get_stake_accounts( wallet, subtensor diff --git a/bittensor/commands/wallets.py b/bittensor/commands/wallets.py index ea19155b6e..0c05cf75c4 100644 --- a/bittensor/commands/wallets.py +++ b/bittensor/commands/wallets.py @@ -199,9 +199,9 @@ def check_config(config: "bittensor.config"): else: config.ss58_address = prompt_answer if not bittensor.utils.is_valid_bittensor_address_or_public_key( - address=config.ss58_address - if config.ss58_address - else config.public_key_hex + address=( + config.ss58_address if config.ss58_address else config.public_key_hex + ) ): sys.exit(1) diff --git a/bittensor/config.py b/bittensor/config.py index 3962615c25..52ea745e91 100644 --- a/bittensor/config.py +++ b/bittensor/config.py @@ -1,6 +1,7 @@ """ Implementation of the config class, which manages the configuration of different Bittensor modules. """ + # The MIT License (MIT) # Copyright © 2021 Yuma Rao # Copyright © 2022 Opentensor Foundation @@ -247,7 +248,7 @@ def __parse_args__( args: List[str], parser: argparse.ArgumentParser = None, strict: bool = False ) -> argparse.Namespace: """Parses the passed args use the passed parser. - + Args: args (List[str]): List of arguments to parse. diff --git a/bittensor/dendrite.py b/bittensor/dendrite.py index bb41b81929..160d281c71 100644 --- a/bittensor/dendrite.py +++ b/bittensor/dendrite.py @@ -31,8 +31,8 @@ class dendrite(torch.nn.Module): """ - The Dendrite class, inheriting from PyTorch's Module class, represents the abstracted implementation of a network client module. - + The Dendrite class, inheriting from PyTorch's Module class, represents the abstracted implementation of a network client module. + In the brain analogy, dendrites receive signals from other neurons (in this case, network servers or axons), and the Dendrite class here is designed to send requests to those endpoint to recieve inputs. @@ -73,11 +73,11 @@ class dendrite(torch.nn.Module): aclose_session(self): Asynchronously closes the internal aiohttp client session. - NOTE: + NOTE: When working with async `aiohttp `_ client sessions, it is recommended to use a context manager. Example with a context manager:: - + >>> aysnc with dendrite(wallet = bittensor.wallet()) as d: >>> print(d) >>> d( ) # ping axon @@ -87,7 +87,7 @@ class dendrite(torch.nn.Module): However, you are able to safely call :func:`dendrite.query()` without a context manager in a synchronous setting. Example without a context manager:: - + >>> d = dendrite(wallet = bittensor.wallet() ) >>> print(d) >>> d( ) # ping axon @@ -141,7 +141,7 @@ async def session(self) -> aiohttp.ClientSession: the dendrite, adhering to the async nature of the network interactions in the Bittensor framework. Example usage:: - + import bittensor as bt # Import bittensor wallet = bt.wallet( ... ) # Initialize a wallet dendrite = bt.dendrite( wallet ) # Initialize a dendrite instance with the wallet @@ -167,7 +167,7 @@ def close_session(self): resources like open connections and internal buffers. It is crucial for preventing resource leakage and should be called when the dendrite instance is no longer in use, especially in synchronous contexts. - Note: + Note: This method utilizes asyncio's event loop to close the session asynchronously from a synchronous context. It is advisable to use this method only when asynchronous context management is not feasible. Usage: @@ -193,7 +193,7 @@ async def aclose_session(self): await :func:`dendrite_instance.aclose_session()`. Example:: - + async with dendrite_instance: # Operations using dendrite pass @@ -237,7 +237,7 @@ def _handle_request_errors(self, synapse, request_name, exception): request_name: The name of the request during which the exception occurred. exception: The exception object caught during the request. - Note: + Note: This method updates the synapse object in-place. """ if isinstance(exception, aiohttp.ClientConnectorError): @@ -263,7 +263,7 @@ def _log_outgoing_request(self, synapse): is crucial for monitoring and debugging network activity within the Bittensor network. To turn on debug messages, set the environment variable BITTENSOR_DEBUG to ``1``, or call the bittensor debug method like so:: - + import bittensor bittensor.debug() @@ -289,9 +289,7 @@ def _log_incoming_response(self, synapse): f"dendrite | <-- | {synapse.get_total_size()} B | {synapse.name} | {synapse.axon.hotkey} | {synapse.axon.ip}:{str(synapse.axon.port)} | {synapse.dendrite.status_code} | {synapse.dendrite.status_message}" ) - def query( - self, *args, **kwargs - ) -> Union[ + def query(self, *args, **kwargs) -> Union[ bittensor.Synapse, List[bittensor.Synapse], bittensor.StreamingSynapse, @@ -349,7 +347,7 @@ async def forward( returned, each containing the response from the corresponding Axon. For example:: - + >>> ... >>> wallet = bittensor.wallet() # Initialize a wallet >>> synapse = bittensor.Synapse(...) # Create a synapse object that contains query data @@ -362,7 +360,7 @@ async def forward( iterated over to process each chunk individually. For example:: - + >>> ... >>> dendrte = bittensor.dendrite(wallet = wallet) >>> async for chunk in dendrite.forward(axons, synapse, timeout, deserialize, run_async, streaming): @@ -768,7 +766,7 @@ async def __aenter__(self): Dendrite: The current instance of the Dendrite class. Usage:: - + async with Dendrite() as dendrite: await dendrite.some_async_method() """ @@ -787,11 +785,11 @@ async def __aexit__(self, exc_type, exc_value, traceback): traceback (TracebackType, optional): A traceback object encapsulating the call stack at the point where the exception was raised. Usage:: - + async with bt.dendrite( wallet ) as dendrite: await dendrite.some_async_method() - Note: + Note: This automatically closes the session by calling :func:`__aexit__` after the context closes. """ await self.aclose_session() @@ -803,11 +801,11 @@ def __del__(self): This method is invoked when the Dendrite instance is about to be destroyed. The destructor ensures that the aiohttp client session is closed before the instance is fully destroyed, releasing any remaining resources. - Note: + Note: Relying on the destructor for cleanup can be unpredictable. It is recommended to explicitly close sessions using the provided methods or the ``async with`` context manager. Usage:: - + dendrite = Dendrite() # ... some operations ... del dendrite # This will implicitly invoke the __del__ method and close the session. diff --git a/bittensor/errors.py b/bittensor/errors.py index 8b8440bb8d..5cd56cb31e 100644 --- a/bittensor/errors.py +++ b/bittensor/errors.py @@ -18,61 +18,73 @@ class ChainError(BaseException): r"""Base error for any chain related errors.""" + pass class ChainConnectionError(ChainError): r"""Error for any chain connection related errors.""" + pass class ChainTransactionError(ChainError): r"""Error for any chain transaction related errors.""" + pass class ChainQueryError(ChainError): r"""Error for any chain query related errors.""" + pass class StakeError(ChainTransactionError): r"""Error raised when a stake transaction fails.""" + pass class UnstakeError(ChainTransactionError): r"""Error raised when an unstake transaction fails.""" + pass class IdentityError(ChainTransactionError): r"""Error raised when an identity transaction fails.""" + pass class NominationError(ChainTransactionError): r"""Error raised when a nomination transaction fails.""" + pass class TransferError(ChainTransactionError): r"""Error raised when a transfer transaction fails.""" + pass class RegistrationError(ChainTransactionError): r"""Error raised when a neuron registration transaction fails.""" + pass class NotRegisteredError(ChainTransactionError): r"""Error raised when a neuron is not registered, and the transaction requires it to be.""" + pass class NotDelegateError(StakeError): r"""Error raised when a hotkey you are trying to stake to is not a delegate.""" + pass @@ -84,49 +96,59 @@ class KeyFileError(Exception): class MetadataError(ChainTransactionError): r"""Error raised when metadata commitment transaction fails.""" + pass class InvalidRequestNameError(Exception): r"""This exception is raised when the request name is invalid. Ususally indicates a broken URL.""" + pass class UnknownSynapseError(Exception): r"""This exception is raised when the request name is not found in the Axon's forward_fns dictionary.""" + pass class SynapseParsingError(Exception): r"""This exception is raised when the request headers are unable to be parsed into the synapse type.""" + pass class NotVerifiedException(Exception): r"""This exception is raised when the request is not verified.""" + pass class BlacklistedException(Exception): r"""This exception is raised when the request is blacklisted.""" + pass class PriorityException(Exception): r"""This exception is raised when the request priority is not met.""" + pass class PostProcessException(Exception): r"""This exception is raised when the response headers cannot be updated.""" + pass class RunException(Exception): r"""This exception is raised when the requested function cannot be executed. Indicates a server error.""" + pass class InternalServerError(Exception): r"""This exception is raised when the requested function fails on the server. Indicates a server error.""" + pass diff --git a/bittensor/extrinsics/log_utilities.py b/bittensor/extrinsics/log_utilities.py index bcd6f09890..448dfa69a9 100644 --- a/bittensor/extrinsics/log_utilities.py +++ b/bittensor/extrinsics/log_utilities.py @@ -347,9 +347,11 @@ def print_synergy_table(self, stats: Dict, syn_loss_diff: Dict, sort_col: str): ( "[bright_cyan]{:.2f}[/bright_cyan]" if t == s - else "[magenta]{:.3f}[/magenta]" - if syn_loss_diff[s[0]][t[0]] > 0 - else "[dim]{:.0f}[/dim]" + else ( + "[magenta]{:.3f}[/magenta]" + if syn_loss_diff[s[0]][t[0]] > 0 + else "[dim]{:.0f}[/dim]" + ) ) .format(syn_loss_diff[s[0]][t[0]]) .replace("0.", ".") @@ -409,12 +411,18 @@ def print_stats_table( ] # available columns intersecting with stats_keys rows = [ [ - ("", 0) - if key not in stat - else ( - ("* " if key == "uid" and mark_uids and uid in mark_uids else "") - + txt.format(stat[key]), - stat[key], + ( + ("", 0) + if key not in stat + else ( + ( + "* " + if key == "uid" and mark_uids and uid in mark_uids + else "" + ) + + txt.format(stat[key]), + stat[key], + ) ) for _, key, txt, _ in columns ] diff --git a/bittensor/keyfile.py b/bittensor/keyfile.py index 0bcadaa86b..722687bfe1 100644 --- a/bittensor/keyfile.py +++ b/bittensor/keyfile.py @@ -44,7 +44,7 @@ def serialized_keypair_to_keyfile_data(keypair: "bittensor.Keypair") -> bytes: """Serializes keypair object into keyfile data. - + Args: keypair (bittensor.Keypair): The keypair object to be serialized. Returns: @@ -54,14 +54,16 @@ def serialized_keypair_to_keyfile_data(keypair: "bittensor.Keypair") -> bytes: "accountId": "0x" + keypair.public_key.hex() if keypair.public_key else None, "publicKey": "0x" + keypair.public_key.hex() if keypair.public_key else None, "secretPhrase": keypair.mnemonic if keypair.mnemonic else None, - "secretSeed": "0x" - + ( - keypair.seed_hex - if isinstance(keypair.seed_hex, str) - else keypair.seed_hex.hex() - ) - if keypair.seed_hex - else None, + "secretSeed": ( + "0x" + + ( + keypair.seed_hex + if isinstance(keypair.seed_hex, str) + else keypair.seed_hex.hex() + ) + if keypair.seed_hex + else None + ), "ss58Address": keypair.ss58_address if keypair.ss58_address else None, } data = json.dumps(json_data).encode() @@ -70,7 +72,7 @@ def serialized_keypair_to_keyfile_data(keypair: "bittensor.Keypair") -> bytes: def deserialize_keypair_from_keyfile_data(keyfile_data: bytes) -> "bittensor.Keypair": """Deserializes Keypair object from passed keyfile data. - + Args: keyfile_data (bytes): The keyfile data as bytes to be loaded. Returns: @@ -118,7 +120,7 @@ def deserialize_keypair_from_keyfile_data(keyfile_data: bytes) -> "bittensor.Key def validate_password(password: str) -> bool: """Validates the password against a password policy. - + Args: password (str): The password to verify. Returns: @@ -145,7 +147,7 @@ def validate_password(password: str) -> bool: def ask_password_to_encrypt() -> str: """Prompts the user to enter a password for key encryption. - + Returns: password (str): The valid password entered by the user. """ @@ -158,7 +160,7 @@ def ask_password_to_encrypt() -> str: def keyfile_data_is_encrypted_nacl(keyfile_data: bytes) -> bool: """Returns true if the keyfile data is NaCl encrypted. - + Args: keyfile_data ( bytes, required ): Bytes to validate. @@ -171,7 +173,7 @@ def keyfile_data_is_encrypted_nacl(keyfile_data: bytes) -> bool: def keyfile_data_is_encrypted_ansible(keyfile_data: bytes) -> bool: """Returns true if the keyfile data is ansible encrypted. - + Args: keyfile_data (bytes): The bytes to validate. Returns: @@ -192,7 +194,7 @@ def keyfile_data_is_encrypted_legacy(keyfile_data: bytes) -> bool: def keyfile_data_is_encrypted(keyfile_data: bytes) -> bool: """Returns ``true`` if the keyfile data is encrypted. - + Args: keyfile_data (bytes): The bytes to validate. Returns: @@ -207,7 +209,7 @@ def keyfile_data_is_encrypted(keyfile_data: bytes) -> bool: def keyfile_data_encryption_method(keyfile_data: bytes) -> bool: """Returns ``true`` if the keyfile data is encrypted. - + Args: keyfile_data ( bytes, required ): Bytes to validate @@ -236,7 +238,7 @@ def legacy_encrypt_keyfile_data(keyfile_data: bytes, password: str = None) -> by def encrypt_keyfile_data(keyfile_data: bytes, password: str = None) -> bytes: """Encrypts the passed keyfile data using ansible vault. - + Args: keyfile_data (bytes): The bytes to encrypt. password (str, optional): The password used to encrypt the data. If ``None``, asks for user input. @@ -260,7 +262,7 @@ def encrypt_keyfile_data(keyfile_data: bytes, password: str = None) -> bytes: def get_coldkey_password_from_environment(coldkey_name: str) -> Optional[str]: """Retrieves the cold key password from the environment variables. - + Args: coldkey_name (str): The name of the cold key. Returns: @@ -279,7 +281,7 @@ def decrypt_keyfile_data( keyfile_data: bytes, password: str = None, coldkey_name: Optional[str] = None ) -> bytes: """Decrypts the passed keyfile data using ansible vault. - + Args: keyfile_data (bytes): The bytes to decrypt. password (str, optional): The password used to decrypt the data. If ``None``, asks for user input. @@ -373,7 +375,7 @@ def __repr__(self): @property def keypair(self) -> "bittensor.Keypair": """Returns the keypair from path, decrypts data if the file is encrypted. - + Returns: keypair (bittensor.Keypair): The keypair stored under the path. Raises: @@ -384,7 +386,7 @@ def keypair(self) -> "bittensor.Keypair": @property def data(self) -> bytes: """Returns the keyfile data under path. - + Returns: keyfile_data (bytes): The keyfile data stored under the path. Raises: @@ -395,7 +397,7 @@ def data(self) -> bytes: @property def keyfile_data(self) -> bytes: """Returns the keyfile data under path. - + Returns: keyfile_data (bytes): The keyfile data stored under the path. Raises: @@ -411,7 +413,7 @@ def set_keypair( password: str = None, ): """Writes the keypair to the file and optionally encrypts data. - + Args: keypair (bittensor.Keypair): The keypair to store under the path. encrypt (bool, optional): If ``True``, encrypts the file under the path. Default is ``True``. @@ -428,7 +430,7 @@ def set_keypair( def get_keypair(self, password: str = None) -> "bittensor.Keypair": """Returns the keypair from the path, decrypts data if the file is encrypted. - + Args: password (str, optional): The password used to decrypt the file. If ``None``, asks for user input. Returns: @@ -453,7 +455,7 @@ def make_dirs(self): def exists_on_device(self) -> bool: """Returns ``True`` if the file exists on the device. - + Returns: on_device (bool): ``True`` if the file is on the device. """ @@ -463,7 +465,7 @@ def exists_on_device(self) -> bool: def is_readable(self) -> bool: """Returns ``True`` if the file under path is readable. - + Returns: readable (bool): ``True`` if the file is readable. """ @@ -475,7 +477,7 @@ def is_readable(self) -> bool: def is_writable(self) -> bool: """Returns ``True`` if the file under path is writable. - + Returns: writable (bool): ``True`` if the file is writable. """ @@ -485,7 +487,7 @@ def is_writable(self) -> bool: def is_encrypted(self) -> bool: """Returns ``True`` if the file under path is encrypted. - + Returns: encrypted (bool): ``True`` if the file is encrypted. """ @@ -497,7 +499,7 @@ def is_encrypted(self) -> bool: def _may_overwrite(self) -> bool: """Asks the user if it is okay to overwrite the file. - + Returns: may_overwrite (bool): ``True`` if the user allows overwriting the file. """ @@ -508,7 +510,7 @@ def check_and_update_encryption( self, print_result: bool = True, no_prompt: bool = False ): """Check the version of keyfile and update if needed. - + Args: print_result (bool): Print the checking result or not. @@ -609,7 +611,7 @@ def check_and_update_encryption( def encrypt(self, password: str = None): """Encrypts the file under the path. - + Args: password (str, optional): The password for encryption. If ``None``, asks for user input. Raises: @@ -636,7 +638,7 @@ def encrypt(self, password: str = None): def decrypt(self, password: str = None): """Decrypts the file under the path. - + Args: password (str, optional): The password for decryption. If ``None``, asks for user input. Raises: @@ -665,7 +667,7 @@ def decrypt(self, password: str = None): def _read_keyfile_data_from_file(self) -> bytes: """Reads the keyfile data from the file. - + Returns: keyfile_data (bytes): The keyfile data stored under the path. Raises: @@ -685,7 +687,7 @@ def _read_keyfile_data_from_file(self) -> bytes: def _write_keyfile_data_to_file(self, keyfile_data: bytes, overwrite: bool = False): """Writes the keyfile data to the file. - + Args: keyfile_data (bytes): The byte data to store under the path. overwrite (bool, optional): If ``True``, overwrites the data without asking for permission from the user. Default is ``False``. @@ -707,7 +709,7 @@ def _write_keyfile_data_to_file(self, keyfile_data: bytes, overwrite: bool = Fal class Mockkeyfile: """ The Mockkeyfile is a mock object representing a keyfile that does not exist on the device. - + It is designed for use in testing scenarios and simulations where actual filesystem operations are not required. The keypair stored in the Mockkeyfile is treated as non-encrypted and the data is stored as a serialized string. """ diff --git a/bittensor/mock/subtensor_mock.py b/bittensor/mock/subtensor_mock.py index 57b4e5011b..a3775226bc 100644 --- a/bittensor/mock/subtensor_mock.py +++ b/bittensor/mock/subtensor_mock.py @@ -145,15 +145,21 @@ def __init__( ] = None, ): _records = [ - (MockSubtensorValue(value=record[0]), MockSubtensorValue(value=record[1])) - # Make sure record is a tuple of MockSubtensorValue (dict with value attr) - if not ( - isinstance(record, tuple) - and all( - isinstance(item, dict) and hasattr(item, "value") for item in record + ( + ( + MockSubtensorValue(value=record[0]), + MockSubtensorValue(value=record[1]), ) + # Make sure record is a tuple of MockSubtensorValue (dict with value attr) + if not ( + isinstance(record, tuple) + and all( + isinstance(item, dict) and hasattr(item, "value") + for item in record + ) + ) + else record ) - else record for record in records ] diff --git a/bittensor/subtensor.py b/bittensor/subtensor.py index 137d416ce9..1bd766c387 100644 --- a/bittensor/subtensor.py +++ b/bittensor/subtensor.py @@ -93,8 +93,8 @@ class ParamWithTypes(TypedDict): class subtensor: """ - The Subtensor class in Bittensor serves as a crucial interface for interacting with the Bittensor blockchain, facilitating a range of operations essential for the decentralized machine learning network. - + The Subtensor class in Bittensor serves as a crucial interface for interacting with the Bittensor blockchain, facilitating a range of operations essential for the decentralized machine learning network. + This class enables neurons (network participants) to engage in activities such as registering on the network, managing staked weights, setting inter-neuronal weights, and participating in consensus mechanisms. @@ -118,7 +118,7 @@ class subtensor: chain_endpoint (str): The blockchain node endpoint URL, enabling direct communication with the Bittensor blockchain for transaction processing and data retrieval. Example Usage:: - + # Connect to the main Bittensor network (Finney). finney_subtensor = subtensor(network='finney') @@ -204,12 +204,12 @@ def add_args(cls, parser: argparse.ArgumentParser, prefix: str = None): @staticmethod def determine_chain_endpoint_and_network(network: str): """Determines the chain endpoint and network from the passed network or chain_endpoint. - + Args: network (str): The network flag. The choices are: ``-- finney`` (main network), ``-- archive`` (archive network +300 blocks), ``-- local`` (local running network), ``-- test`` (test network). chain_endpoint (str): The chain endpoint flag. If set, overrides the network argument. Returns: - network (str): The network flag. + network (str): The network flag. chain_endpoint (str): The chain endpoint flag. If set, overrides the ``network`` argument. """ if network == None: @@ -310,7 +310,7 @@ def __init__( """ Initializes a Subtensor interface for interacting with the Bittensor blockchain. - NOTE: + NOTE: Currently subtensor defaults to the ``finney`` network. This will change in a future release. We strongly encourage users to run their own local subtensor node whenever possible. This increases @@ -748,7 +748,7 @@ def run_faucet( This function is part of Bittensor's onboarding process, ensuring that new neurons have the necessary resources to begin their journey in the decentralized AI network. - Note: + Note: This is for testnet ONLY and is disabled currently. You must build your own staging subtensor chain with the ``--features pow-faucet`` argument to enable this. """ return run_faucet_extrinsic( @@ -810,7 +810,7 @@ def _do_pow_register( wait_for_finalization: bool = True, ) -> Tuple[bool, Optional[str]]: """Sends a (POW) register extrinsic to the chain. - + Args: netuid (int): The subnet to register on. wallet (bittensor.wallet): The wallet to register. @@ -1042,7 +1042,7 @@ def _do_transfer( wait_for_finalization: bool = False, ) -> Tuple[bool, Optional[str], Optional[str]]: """Sends a transfer extrinsic to the chain. - + Args: wallet (:func:`bittensor.wallet`): Wallet object. dest (str): Destination public key address. @@ -1520,7 +1520,7 @@ def _do_stake( wait_for_finalization: bool = False, ) -> bool: """Sends a stake extrinsic to the chain. - + Args: wallet (:func:`bittensor.wallet`): Wallet object that can sign the extrinsic. hotkey_ss58 (str): Hotkey ``ss58`` address to stake to. @@ -1647,7 +1647,7 @@ def _do_unstake( wait_for_finalization: bool = False, ) -> bool: """Sends an unstake extrinsic to the chain. - + Args: wallet (:func:`bittensor.wallet`): Wallet object that can sign the extrinsic. hotkey_ss58 (str): Hotkey ``ss58`` address to unstake from. @@ -2055,7 +2055,7 @@ def query_identity( detailed identity information about a specific neuron, which is a crucial aspect of the network's decentralized identity and governance system. - NOTE: + NOTE: See the `Bittensor CLI documentation `_ for supported identity parameters. Args: @@ -2076,9 +2076,9 @@ def make_substrate_call_with_retry(): module="Registry", storage_function="IdentityOf", params=[key], - block_hash=None - if block == None - else substrate.get_block_hash(block), + block_hash=( + None if block == None else substrate.get_block_hash(block) + ), ) identity_info = make_substrate_call_with_retry() @@ -2098,7 +2098,7 @@ def update_identity( Updates the identity of a neuron on the Bittensor blockchain. This function allows neurons to modify their identity attributes, reflecting changes in their roles, stakes, or other network-specific parameters. - NOTE: + NOTE: See the `Bittensor CLI documentation `_ for supported identity parameters. Args: @@ -2197,9 +2197,9 @@ def make_substrate_call_with_retry(): module="SubtensorModule", storage_function=name, params=params, - block_hash=None - if block == None - else substrate.get_block_hash(block), + block_hash=( + None if block == None else substrate.get_block_hash(block) + ), ) return make_substrate_call_with_retry() @@ -2235,9 +2235,9 @@ def make_substrate_call_with_retry(): module="SubtensorModule", storage_function=name, params=params, - block_hash=None - if block == None - else substrate.get_block_hash(block), + block_hash=( + None if block == None else substrate.get_block_hash(block) + ), ) return make_substrate_call_with_retry() @@ -2269,9 +2269,9 @@ def make_substrate_call_with_retry(): return substrate.get_constant( module_name=module_name, constant_name=constant_name, - block_hash=None - if block == None - else substrate.get_block_hash(block), + block_hash=( + None if block == None else substrate.get_block_hash(block) + ), ) return make_substrate_call_with_retry() @@ -2310,9 +2310,9 @@ def make_substrate_call_with_retry(): module=module, storage_function=name, params=params, - block_hash=None - if block == None - else substrate.get_block_hash(block), + block_hash=( + None if block == None else substrate.get_block_hash(block) + ), ) return make_substrate_call_with_retry() @@ -2350,9 +2350,9 @@ def make_substrate_call_with_retry(): module=module, storage_function=name, params=params, - block_hash=None - if block == None - else substrate.get_block_hash(block), + block_hash=( + None if block == None else substrate.get_block_hash(block) + ), ) return make_substrate_call_with_retry() @@ -2420,9 +2420,11 @@ def query_runtime_api( json_result = self.state_call( method=f"{runtime_api}_{method}", - data="0x" - if params is None - else self._encode_params(call_definition=call_definition, params=params), + data=( + "0x" + if params is None + else self._encode_params(call_definition=call_definition, params=params) + ), block=block, ) @@ -2474,7 +2476,7 @@ def rho(self, netuid: int, block: Optional[int] = None) -> Optional[int]: Retrieves the 'Rho' hyperparameter for a specified subnet within the Bittensor network. 'Rho' represents the global inflation rate, which directly influences the network's token emission rate and economic model. - Note: + Note: This is currently fixed such that the Bittensor blockchain emmits 7200 Tao per day. Args: @@ -4090,9 +4092,9 @@ def make_substrate_call_with_retry(): module="System", storage_function="Account", params=[address], - block_hash=None - if block == None - else substrate.get_block_hash(block), + block_hash=( + None if block == None else substrate.get_block_hash(block) + ), ) result = make_substrate_call_with_retry() @@ -4143,9 +4145,9 @@ def make_substrate_call_with_retry(): return substrate.query_map( module="System", storage_function="Account", - block_hash=None - if block == None - else substrate.get_block_hash(block), + block_hash=( + None if block == None else substrate.get_block_hash(block) + ), ) result = make_substrate_call_with_retry() diff --git a/bittensor/synapse.py b/bittensor/synapse.py index d6d9551ca0..338e661744 100644 --- a/bittensor/synapse.py +++ b/bittensor/synapse.py @@ -96,8 +96,8 @@ def cast_float(raw: str) -> float: class TerminalInfo(pydantic.BaseModel): """ - TerminalInfo encapsulates detailed information about a network synapse (node) involved in a communication process. - + TerminalInfo encapsulates detailed information about a network synapse (node) involved in a communication process. + This class serves as a metadata carrier, providing essential details about the state and configuration of a terminal during network interactions. This is a crucial class in the Bittensor framework. @@ -122,7 +122,7 @@ class TerminalInfo(pydantic.BaseModel): signature (str): Digital signature verifying the tuple of nonce, axon_hotkey, dendrite_hotkey, and uuid, critical for ensuring data authenticity and security. Usage:: - + # Creating a TerminalInfo instance terminal_info = TerminalInfo( status_code=200, @@ -254,7 +254,7 @@ class Config: class Synapse(pydantic.BaseModel): """ Represents a Synapse in the Bittensor network, serving as a communication schema between neurons (nodes). - + Synapses ensure the format and correctness of transmission tensors according to the Bittensor protocol. Each Synapse type is tailored for a specific machine learning (ML) task, following unique compression and communication processes. This helps maintain sanitized, correct, and useful information flow across the network. @@ -306,7 +306,7 @@ class Synapse(pydantic.BaseModel): the robustness of their applications. Example usage:: - + # Creating a Synapse instance with default values synapse = Synapse() @@ -377,7 +377,7 @@ def deserialize(self) -> "Synapse": In its default form, this method simply returns the instance of the Synapse itself without any modifications. Subclasses of Synapse can override this method to add specific deserialization behaviors, such as converting serialized data back into complex object types or performing additional data integrity checks. Example:: - + class CustomSynapse(Synapse): additional_data: str @@ -584,21 +584,21 @@ def failed_verification(self) -> bool: def to_headers(self) -> dict: """ - Converts the state of a Synapse instance into a dictionary of HTTP headers. - + Converts the state of a Synapse instance into a dictionary of HTTP headers. + This method is essential for packaging Synapse data for network transmission in the Bittensor framework, ensuring that each key aspect of the Synapse is represented in a format suitable for HTTP communication. Process: - + 1. Basic Information: It starts by including the ``name`` and ``timeout`` of the Synapse, which are fundamental for identifying the query and managing its lifespan on the network. 2. Complex Objects: The method serializes the ``axon`` and ``dendrite`` objects, if present, into strings. This serialization is crucial for preserving the state and structure of these objects over the network. 3. Encoding: Non-optional complex objects are serialized and encoded in base64, making them safe for HTTP transport. 4. Size Metrics: The method calculates and adds the size of headers and the total object size, providing valuable information for network bandwidth management. Example Usage:: - + synapse = Synapse(name="ExampleSynapse", timeout=30) headers = synapse.to_headers() # headers now contains a dictionary representing the Synapse instance @@ -665,20 +665,20 @@ def to_headers(self) -> dict: @property def body_hash(self) -> str: """ - Computes a SHA3-256 hash of the serialized body of the Synapse instance. - + Computes a SHA3-256 hash of the serialized body of the Synapse instance. + This hash is used to ensure the data integrity and security of the Synapse instance when it's transmitted across the network. It is a crucial feature for verifying that the data received is the same as the data sent. Process: - + 1. Iterates over each required field as specified in ``required_fields_hash``. 2. Concatenates the string representation of these fields. 3. Applies SHA3-256 hashing to the concatenated string to produce a unique fingerprint of the data. Example:: - + synapse = Synapse(name="ExampleRoute", timeout=10) hash_value = synapse.body_hash # hash_value is the SHA3-256 hash of the serialized body of the Synapse instance @@ -703,19 +703,19 @@ def body_hash(self) -> str: @classmethod def parse_headers_to_inputs(cls, headers: dict) -> dict: """ - Interprets and transforms a given dictionary of headers into a structured dictionary, facilitating the reconstruction of Synapse objects. - + Interprets and transforms a given dictionary of headers into a structured dictionary, facilitating the reconstruction of Synapse objects. + This method is essential for parsing network-transmitted data back into a Synapse instance, ensuring data consistency and integrity. Process: - + 1. Separates headers into categories based on prefixes (``axon``, ``dendrite``, etc.). 2. Decodes and deserializes ``input_obj`` headers into their original objects. 3. Assigns simple fields directly from the headers to the input dictionary. Example:: - + received_headers = { 'bt_header_axon_address': '127.0.0.1', 'bt_header_dendrite_port': '8080', @@ -724,7 +724,7 @@ def parse_headers_to_inputs(cls, headers: dict) -> dict: inputs = Synapse.parse_headers_to_inputs(received_headers) # inputs now contains a structured representation of Synapse properties based on the headers - Note: + Note: This is handled automatically when calling :func:`Synapse.from_headers(headers)` and does not need to be called directly. Args: @@ -795,14 +795,14 @@ def parse_headers_to_inputs(cls, headers: dict) -> dict: @classmethod def from_headers(cls, headers: dict) -> "Synapse": """ - Constructs a new Synapse instance from a given headers dictionary, enabling the re-creation of the Synapse's state as it was prior to network transmission. - + Constructs a new Synapse instance from a given headers dictionary, enabling the re-creation of the Synapse's state as it was prior to network transmission. + This method is a key part of the deserialization process in the Bittensor network, allowing nodes to accurately reconstruct Synapse objects from received data. Example:: - + received_headers = { 'bt_header_axon_address': '127.0.0.1', 'bt_header_dendrite_port': '8080', diff --git a/bittensor/threadpool.py b/bittensor/threadpool.py index d4de054bde..2211331453 100644 --- a/bittensor/threadpool.py +++ b/bittensor/threadpool.py @@ -130,7 +130,7 @@ def __init__( initargs=(), ): """Initializes a new `ThreadPoolExecutor `_ instance. - + Args: max_workers: The maximum number of threads that can be used to execute the given calls. @@ -195,7 +195,7 @@ def add_args(cls, parser: argparse.ArgumentParser, prefix: str = None): @classmethod def config(cls) -> "bittensor.config": """Get config from the argument parser. - + Return: :func:`bittensor.config` object. """ parser = argparse.ArgumentParser() diff --git a/bittensor/utils/__init__.py b/bittensor/utils/__init__.py index 74485fc630..a79ed2cf38 100644 --- a/bittensor/utils/__init__.py +++ b/bittensor/utils/__init__.py @@ -162,9 +162,9 @@ def get_explorer_url_for_network( explorer_urls: Optional[Dict[str, str]] = {} # Will be None if the network is not known. i.e. not in network_map - explorer_root_urls: Optional[ - Dict[str, str] - ] = get_explorer_root_url_by_network_from_map(network, network_map) + explorer_root_urls: Optional[Dict[str, str]] = ( + get_explorer_root_url_by_network_from_map(network, network_map) + ) if explorer_root_urls != {}: # We are on a known network. diff --git a/bittensor/utils/networking.py b/bittensor/utils/networking.py index d8e1b79e9f..f8bc105ba4 100644 --- a/bittensor/utils/networking.py +++ b/bittensor/utils/networking.py @@ -1,5 +1,6 @@ """ Utils for handling local network with ip and ports. """ + # The MIT License (MIT) # Copyright © 2021-2022 Yuma Rao # Copyright © 2022-2023 Opentensor Foundation diff --git a/bittensor/utils/stats.py b/bittensor/utils/stats.py index 117eb43e4b..fd52dade20 100644 --- a/bittensor/utils/stats.py +++ b/bittensor/utils/stats.py @@ -1,5 +1,6 @@ """ A exponential moving average that updates values based on time since last update. """ + # The MIT License (MIT) # Copyright © 2021 Yuma Rao diff --git a/bittensor/utils/weight_utils.py b/bittensor/utils/weight_utils.py index 102f145606..0c5c944a0e 100644 --- a/bittensor/utils/weight_utils.py +++ b/bittensor/utils/weight_utils.py @@ -1,5 +1,6 @@ """ Conversion for weight between chain representation and torch tensor """ + # The MIT License (MIT) # Copyright © 2021 Yuma Rao diff --git a/bittensor/wallet.py b/bittensor/wallet.py index 29a6129ca2..40b36aa21b 100644 --- a/bittensor/wallet.py +++ b/bittensor/wallet.py @@ -1,5 +1,6 @@ """ Implementation of the wallet class, which manages balances with staking and transfer. Also manages hotkey and coldkey. """ + # The MIT License (MIT) # Copyright © 2021 Yuma Rao @@ -668,8 +669,7 @@ def regenerate_coldkey( use_password: bool = True, overwrite: bool = False, suppress: bool = False, - ) -> "wallet": - ... + ) -> "wallet": ... @overload def regenerate_coldkey( @@ -678,8 +678,7 @@ def regenerate_coldkey( use_password: bool = True, overwrite: bool = False, suppress: bool = False, - ) -> "wallet": - ... + ) -> "wallet": ... @overload def regenerate_coldkey( @@ -688,8 +687,7 @@ def regenerate_coldkey( use_password: bool = True, overwrite: bool = False, suppress: bool = False, - ) -> "wallet": - ... + ) -> "wallet": ... def regenerate_coldkey( self, @@ -776,8 +774,7 @@ def regenerate_hotkey( use_password: bool = True, overwrite: bool = False, suppress: bool = False, - ) -> "wallet": - ... + ) -> "wallet": ... @overload def regenerate_hotkey( @@ -786,8 +783,7 @@ def regenerate_hotkey( use_password: bool = True, overwrite: bool = False, suppress: bool = False, - ) -> "wallet": - ... + ) -> "wallet": ... @overload def regenerate_hotkey( @@ -796,8 +792,7 @@ def regenerate_hotkey( use_password: bool = True, overwrite: bool = False, suppress: bool = False, - ) -> "wallet": - ... + ) -> "wallet": ... def regenerate_hotkey( self, diff --git a/tests/unit_tests/test_wallet.py b/tests/unit_tests/test_wallet.py index 1c27d427bf..119e3a3115 100644 --- a/tests/unit_tests/test_wallet.py +++ b/tests/unit_tests/test_wallet.py @@ -338,9 +338,11 @@ def test_regen_coldkey_from_hex_seed_str(self): mock_set_coldkey.assert_called_once() keypair: bittensor.Keypair = mock_set_coldkey.call_args_list[0][0][0] self.assertRegex( - keypair.seed_hex - if isinstance(keypair.seed_hex, str) - else keypair.seed_hex.hex(), + ( + keypair.seed_hex + if isinstance(keypair.seed_hex, str) + else keypair.seed_hex.hex() + ), rf"(0x|){seed_str[2:]}", ) self.assertEqual( @@ -368,9 +370,11 @@ def test_regen_hotkey_from_hex_seed_str(self): mock_set_hotkey.assert_called_once() keypair: bittensor.Keypair = mock_set_hotkey.call_args_list[0][0][0] self.assertRegex( - keypair.seed_hex - if isinstance(keypair.seed_hex, str) - else keypair.seed_hex.hex(), + ( + keypair.seed_hex + if isinstance(keypair.seed_hex, str) + else keypair.seed_hex.hex() + ), rf"(0x|){seed_str[2:]}", ) self.assertEqual( From 2d6766bbdcd1f17f7d66f152a6524eee78cb2382 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Wed, 31 Jan 2024 22:02:36 +0000 Subject: [PATCH 3/5] black format with correct version --- bittensor/__init__.py | 4 +--- bittensor/chain_data.py | 8 ++++---- bittensor/commands/delegates.py | 12 ++++++------ bittensor/commands/inspect.py | 12 ++++++------ bittensor/commands/senate.py | 12 ++++++------ bittensor/commands/stake.py | 6 +++--- bittensor/dendrite.py | 4 +++- bittensor/utils/__init__.py | 6 +++--- bittensor/wallet.py | 18 ++++++++++++------ 9 files changed, 44 insertions(+), 38 deletions(-) diff --git a/bittensor/__init__.py b/bittensor/__init__.py index 8a562f5ce9..f27a85ebd4 100644 --- a/bittensor/__init__.py +++ b/bittensor/__init__.py @@ -80,9 +80,7 @@ def debug(on: bool = True): __pipaddress__ = "https://pypi.org/pypi/bittensor/json" # Raw github url for delegates registry file -__delegates_details_url__: str = ( - "https://raw.githubusercontent.com/opentensor/bittensor-delegates/main/public/delegates.json" -) +__delegates_details_url__: str = "https://raw.githubusercontent.com/opentensor/bittensor-delegates/main/public/delegates.json" # Substrate ss58_format __ss58_format__ = 42 diff --git a/bittensor/chain_data.py b/bittensor/chain_data.py index f48971fcbb..e06a33d727 100644 --- a/bittensor/chain_data.py +++ b/bittensor/chain_data.py @@ -826,10 +826,10 @@ def list_of_tuple_from_vec_u8( cls, vec_u8: List[int] ) -> Dict[str, List["StakeInfo"]]: r"""Returns a list of StakeInfo objects from a ``vec_u8``.""" - decoded: Optional[List[Tuple(str, List[object])]] = ( - from_scale_encoding_using_type_string( - input=vec_u8, type_string="Vec<(AccountId, Vec)>" - ) + decoded: Optional[ + List[Tuple(str, List[object])] + ] = from_scale_encoding_using_type_string( + input=vec_u8, type_string="Vec<(AccountId, Vec)>" ) if decoded is None: diff --git a/bittensor/commands/delegates.py b/bittensor/commands/delegates.py index 774a26e72a..9c3bb5ed97 100644 --- a/bittensor/commands/delegates.py +++ b/bittensor/commands/delegates.py @@ -101,9 +101,9 @@ def show_delegates( for prev_delegate in prev_delegates: prev_delegates_dict[prev_delegate.hotkey_ss58] = prev_delegate - registered_delegate_info: Optional[Dict[str, DelegatesDetails]] = ( - get_delegates_details(url=bittensor.__delegates_details_url__) - ) + registered_delegate_info: Optional[ + Dict[str, DelegatesDetails] + ] = get_delegates_details(url=bittensor.__delegates_details_url__) if registered_delegate_info is None: bittensor.__console__.print( ":warning:[yellow]Could not get delegate info from chain.[/yellow]" @@ -793,9 +793,9 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): delegates.sort(key=lambda delegate: delegate[0].total_stake, reverse=True) total_delegated += sum(my_delegates.values()) - registered_delegate_info: Optional[DelegatesDetails] = ( - get_delegates_details(url=bittensor.__delegates_details_url__) - ) + registered_delegate_info: Optional[ + DelegatesDetails + ] = get_delegates_details(url=bittensor.__delegates_details_url__) if registered_delegate_info is None: bittensor.__console__.print( ":warning:[yellow]Could not get delegate info from chain.[/yellow]" diff --git a/bittensor/commands/inspect.py b/bittensor/commands/inspect.py index f2b3caeaad..bdf2a00e26 100644 --- a/bittensor/commands/inspect.py +++ b/bittensor/commands/inspect.py @@ -141,9 +141,9 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): ) bittensor.logging.debug(f"Netuids to check: {netuids}") - registered_delegate_info: Optional[Dict[str, DelegatesDetails]] = ( - get_delegates_details(url=bittensor.__delegates_details_url__) - ) + registered_delegate_info: Optional[ + Dict[str, DelegatesDetails] + ] = get_delegates_details(url=bittensor.__delegates_details_url__) if registered_delegate_info is None: bittensor.__console__.print( ":warning:[yellow]Could not get delegate info from chain.[/yellow]" @@ -184,9 +184,9 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): "[overline white]Emission", footer_style="overline white", style="green" ) for wallet in tqdm(wallets): - delegates: List[Tuple(bittensor.DelegateInfo, bittensor.Balance)] = ( - subtensor.get_delegated(coldkey_ss58=wallet.coldkeypub.ss58_address) - ) + delegates: List[ + Tuple(bittensor.DelegateInfo, bittensor.Balance) + ] = subtensor.get_delegated(coldkey_ss58=wallet.coldkeypub.ss58_address) if not wallet.coldkeypub_file.exists_on_device(): continue cold_balance = subtensor.get_balance(wallet.coldkeypub.ss58_address) diff --git a/bittensor/commands/senate.py b/bittensor/commands/senate.py index 20c02f8a98..931da96d42 100644 --- a/bittensor/commands/senate.py +++ b/bittensor/commands/senate.py @@ -212,9 +212,9 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): senate_members = subtensor.get_senate_members() proposals = subtensor.get_proposals() - registered_delegate_info: Optional[Dict[str, DelegatesDetails]] = ( - get_delegates_details(url=bittensor.__delegates_details_url__) - ) + registered_delegate_info: Optional[ + Dict[str, DelegatesDetails] + ] = get_delegates_details(url=bittensor.__delegates_details_url__) table = Table(show_footer=False) table.title = ( @@ -343,9 +343,9 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): console.print(":cross_mark: [red]Failed[/red]: Proposal not found.") return - registered_delegate_info: Optional[Dict[str, DelegatesDetails]] = ( - get_delegates_details(url=bittensor.__delegates_details_url__) - ) + registered_delegate_info: Optional[ + Dict[str, DelegatesDetails] + ] = get_delegates_details(url=bittensor.__delegates_details_url__) table = Table(show_footer=False) table.title = "[white]Votes for Proposal {}".format(proposal_hash) diff --git a/bittensor/commands/stake.py b/bittensor/commands/stake.py index f93d4e24ab..cbb210f34b 100644 --- a/bittensor/commands/stake.py +++ b/bittensor/commands/stake.py @@ -392,9 +392,9 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): wallets = _get_coldkey_wallets_for_path(cli.config.wallet.path) else: wallets = [bittensor.wallet(config=cli.config)] - registered_delegate_info: Optional[Dict[str, DelegatesDetails]] = ( - get_delegates_details(url=bittensor.__delegates_details_url__) - ) + registered_delegate_info: Optional[ + Dict[str, DelegatesDetails] + ] = get_delegates_details(url=bittensor.__delegates_details_url__) def get_stake_accounts( wallet, subtensor diff --git a/bittensor/dendrite.py b/bittensor/dendrite.py index 160d281c71..b96e819ce9 100644 --- a/bittensor/dendrite.py +++ b/bittensor/dendrite.py @@ -289,7 +289,9 @@ def _log_incoming_response(self, synapse): f"dendrite | <-- | {synapse.get_total_size()} B | {synapse.name} | {synapse.axon.hotkey} | {synapse.axon.ip}:{str(synapse.axon.port)} | {synapse.dendrite.status_code} | {synapse.dendrite.status_message}" ) - def query(self, *args, **kwargs) -> Union[ + def query( + self, *args, **kwargs + ) -> Union[ bittensor.Synapse, List[bittensor.Synapse], bittensor.StreamingSynapse, diff --git a/bittensor/utils/__init__.py b/bittensor/utils/__init__.py index a79ed2cf38..74485fc630 100644 --- a/bittensor/utils/__init__.py +++ b/bittensor/utils/__init__.py @@ -162,9 +162,9 @@ def get_explorer_url_for_network( explorer_urls: Optional[Dict[str, str]] = {} # Will be None if the network is not known. i.e. not in network_map - explorer_root_urls: Optional[Dict[str, str]] = ( - get_explorer_root_url_by_network_from_map(network, network_map) - ) + explorer_root_urls: Optional[ + Dict[str, str] + ] = get_explorer_root_url_by_network_from_map(network, network_map) if explorer_root_urls != {}: # We are on a known network. diff --git a/bittensor/wallet.py b/bittensor/wallet.py index 40b36aa21b..54837182aa 100644 --- a/bittensor/wallet.py +++ b/bittensor/wallet.py @@ -669,7 +669,8 @@ def regenerate_coldkey( use_password: bool = True, overwrite: bool = False, suppress: bool = False, - ) -> "wallet": ... + ) -> "wallet": + ... @overload def regenerate_coldkey( @@ -678,7 +679,8 @@ def regenerate_coldkey( use_password: bool = True, overwrite: bool = False, suppress: bool = False, - ) -> "wallet": ... + ) -> "wallet": + ... @overload def regenerate_coldkey( @@ -687,7 +689,8 @@ def regenerate_coldkey( use_password: bool = True, overwrite: bool = False, suppress: bool = False, - ) -> "wallet": ... + ) -> "wallet": + ... def regenerate_coldkey( self, @@ -774,7 +777,8 @@ def regenerate_hotkey( use_password: bool = True, overwrite: bool = False, suppress: bool = False, - ) -> "wallet": ... + ) -> "wallet": + ... @overload def regenerate_hotkey( @@ -783,7 +787,8 @@ def regenerate_hotkey( use_password: bool = True, overwrite: bool = False, suppress: bool = False, - ) -> "wallet": ... + ) -> "wallet": + ... @overload def regenerate_hotkey( @@ -792,7 +797,8 @@ def regenerate_hotkey( use_password: bool = True, overwrite: bool = False, suppress: bool = False, - ) -> "wallet": ... + ) -> "wallet": + ... def regenerate_hotkey( self, From d3da946ea7a49b5d2688ac5bce3c5627168be1e1 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Wed, 31 Jan 2024 22:46:15 +0000 Subject: [PATCH 4/5] update cache keys for black error --- .circleci/config.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 34f1050f6d..959e6993b5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -20,7 +20,7 @@ jobs: - restore_cache: name: Restore cached black venv keys: - - v1-pypi-py-black-<< parameters.python-version >> + - v2-pypi-py-black-<< parameters.python-version >> - run: name: Update & Activate black venv @@ -34,7 +34,7 @@ jobs: name: Save cached black venv paths: - "env/" - key: v1-pypi-py-black-<< parameters.python-version >> + key: v2-pypi-py-black-<< parameters.python-version >> - run: name: Black format check @@ -79,8 +79,8 @@ jobs: - restore_cache: name: Restore cached venv keys: - - v1-pypi-py<< parameters.python-version >>-{{ checksum "requirements/prod.txt" }}+{{ checksum "requirements/dev.txt" }} - - v1-pypi-py<< parameters.python-version >> + - v2-pypi-py<< parameters.python-version >>-{{ checksum "requirements/prod.txt" }}+{{ checksum "requirements/dev.txt" }} + - v2-pypi-py<< parameters.python-version >> - run: name: Update & Activate venv @@ -94,7 +94,7 @@ jobs: name: Save cached venv paths: - "env/" - key: v1-pypi-py<< parameters.python-version >>-{{ checksum "requirements/prod.txt" }}+{{ checksum "requirements/dev.txt" }} + key: v2-pypi-py<< parameters.python-version >>-{{ checksum "requirements/prod.txt" }}+{{ checksum "requirements/dev.txt" }} - run: name: Install Bittensor From c6d70a4b97fff14cde97b73bb318e27f3eab9a74 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Wed, 31 Jan 2024 22:50:40 +0000 Subject: [PATCH 5/5] specific black version for ci --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 959e6993b5..6664443a73 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -28,7 +28,7 @@ jobs: python -m venv env/ . env/bin/activate python -m pip install --upgrade pip - pip install black + pip install black==23.7.0 - save_cache: name: Save cached black venv