diff --git a/CHANGELOG.md b/CHANGELOG.md index 4992a86911..0f3fa2f34c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,23 @@ # Changelog +## 6.4.2 / 2023-12-07 + +## What's Changed +* Fix broken explorer links https://github.com/opentensor/bittensor/pull/1607 +* Fix spamming bittensor subtensor logging https://github.com/opentensor/bittensor/pull/1608 +* Fix hanging subtensor websocket https://github.com/opentensor/bittensor/pull/1609 +* Hparam update to palette: https://github.com/opentensor/bittensor/pull/1612 + +**Full Changelog**: https://github.com/opentensor/bittensor/compare/v6.4.1...v6.4.2 + + ## 6.4.1 / 2023-12-01 ## What's Changed * add helpful messages to signal coming changes in https://github.com/opentensor/bittensor/pull/1600/commits/86c0c3ccfcd91d0e3ff87f53bdc3e9c5e68661da * revert default subtensor network to finney in https://github.com/opentensor/bittensor/pull/1600/commits/8c69a3c15cd556384d0309e951f0a9b164dd36cb -**Full Changelog**: https://github.com/opentensor/bittensor/compare/v6.0.1...v6.4.1 +**Full Changelog**: https://github.com/opentensor/bittensor/compare/v6.4.0...v6.4.1 ## 6.4.0 / 2023-11-29 diff --git a/README.md b/README.md index 38ac11ab7c..fd631c35ee 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ positional arguments: lock_cost Return the lock cost to register a subnet. create Create a new bittensor subnetwork on this chain. register Register a wallet to a network. - register Register a wallet to a network using PoW. + pow_register Register a wallet to a network using PoW. hyperparameters View subnet hyperparameters. options: @@ -282,28 +282,28 @@ Axon: Serves Synapse protocols with custom blacklist, priority and verify functi ```python import bittensor -class MySyanpse( bittensor.Synapse ): +class MySynapse( bittensor.Synapse ): input: int = 1 output: int = None # Define a custom request forwarding function -def forward( synapse: MySyanpse ) -> MySyanpse: +def forward( synapse: MySynapse ) -> MySynapse: # Apply custom logic to synapse and return it synapse.output = 2 return synapse # Define a custom request verification function -def verify_my_synapse( synapse: MySyanpse ): +def verify_my_synapse( synapse: MySynapse ): # Apply custom verification logic to synapse # Optionally raise Exception # Define a custom request blacklist function -def blacklist_my_synapse( synapse: MySyanpse ) -> bool: +def blacklist_my_synapse( synapse: MySynapse ) -> bool: # Apply custom blacklist # return False ( if non blacklisted ) or True ( if blacklisted ) # Define a custom request priority function -def prioritize_my_synape( synapse: MySyanpse ) -> float: +def prioritize_my_synape( synapse: MySynapse ) -> float: # Apply custom priority return 1.0 @@ -321,6 +321,7 @@ my_axon.attach( Dendrite: Inheriting from PyTorch's Module class, represents the abstracted implementation of a network client module designed to send requests to those endpoints to receive inputs. + Example: ```python dendrite_obj = dendrite( wallet = bittensor.wallet() ) @@ -340,7 +341,7 @@ Use the `root` subcommand to access setting weights on the network across subnet ```bash btcli root weights --wallet.name --wallet.hotkey Enter netuids (e.g. 0, 1, 2 ...): -# Here enter your selected netuids to wet weights on +# Here enter your selected netuids to set weights on 1, 2 >Enter weights (e.g. 0.09, 0.09, 0.09 ...): @@ -377,4 +378,4 @@ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR I ## Acknowledgments -**learning-at-home/hivemind** +**learning-at-home/hivemind** \ No newline at end of file diff --git a/VERSION b/VERSION index 306894a15e..04757a5d3c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.4.1 \ No newline at end of file +6.4.2 \ No newline at end of file diff --git a/bittensor/__init__.py b/bittensor/__init__.py index 196f632ce4..3006a8de15 100644 --- a/bittensor/__init__.py +++ b/bittensor/__init__.py @@ -27,7 +27,7 @@ nest_asyncio.apply() # Bittensor code and protocol version. -__version__ = "6.4.1" +__version__ = "6.4.2" version_split = __version__.split(".") __version_as_int__ = ( (100 * int(version_split[0])) @@ -107,9 +107,16 @@ def debug(on: bool = True): # Block Explorers map network to explorer url ## Must all be polkadotjs explorer urls __network_explorer_map__ = { - "local": "https://explorer.finney.opentensor.ai/#/explorer", - "endpoint": "https://explorer.finney.opentensor.ai/#/explorer", - "finney": "https://explorer.finney.opentensor.ai/#/explorer", + "opentensor": { + "local": "https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fentrypoint-finney.opentensor.ai%3A443#/explorer", + "endpoint": "https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fentrypoint-finney.opentensor.ai%3A443#/explorer", + "finney": "https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fentrypoint-finney.opentensor.ai%3A443#/explorer", + }, + "taostats": { + "local": "https://x.taostats.io", + "endpoint": "https://x.taostats.io", + "finney": "https://x.taostats.io", + }, } # --- Type Registry --- diff --git a/bittensor/chain_data.py b/bittensor/chain_data.py index 3f44a66a01..eeb946e20f 100644 --- a/bittensor/chain_data.py +++ b/bittensor/chain_data.py @@ -174,6 +174,8 @@ ["max_burn", "Compact"], ["bonds_moving_avg", "Compact"], ["max_regs_per_block", "Compact"], + ["serving_rate_limit", "Compact"], + ["max_validators", "Compact"], ], }, } @@ -963,6 +965,8 @@ class SubnetHyperparameters: max_burn: int bonds_moving_avg: int max_regs_per_block: int + serving_rate_limit: int + max_validators: int @classmethod def from_vec_u8(cls, vec_u8: List[int]) -> Optional["SubnetHyperparameters"]: @@ -1013,6 +1017,8 @@ def fix_decoded_values(cls, decoded: Dict) -> "SubnetHyperparameters": max_burn=decoded["max_burn"], bonds_moving_avg=decoded["bonds_moving_avg"], max_regs_per_block=decoded["max_regs_per_block"], + max_validators=decoded["max_validators"], + serving_rate_limit=decoded["serving_rate_limit"], ) def to_parameter_dict(self) -> "torch.nn.ParameterDict": diff --git a/bittensor/commands/network.py b/bittensor/commands/network.py index 32ae141cb6..6c0eefff39 100644 --- a/bittensor/commands/network.py +++ b/bittensor/commands/network.py @@ -249,7 +249,6 @@ def add_args(parser: argparse.ArgumentParser): "immunity_period": "sudo_set_immunity_period", "min_allowed_weights": "sudo_set_min_allowed_weights", "activity_cutoff": "sudo_set_activity_cutoff", - "max_validators": "sudo_set_max_allowed_validators", } diff --git a/bittensor/commands/overview.py b/bittensor/commands/overview.py index 39fc465b07..c8317b572f 100644 --- a/bittensor/commands/overview.py +++ b/bittensor/commands/overview.py @@ -558,7 +558,7 @@ def _get_neurons_for_netuid( result: List["bittensor.NeuronInfoLite"] = [] try: - subtensor = bittensor.subtensor(config=subtensor_config) + subtensor = bittensor.subtensor(config=subtensor_config, log_verbose=False) all_neurons: List["bittensor.NeuronInfoLite"] = subtensor.neurons_lite( netuid=netuid @@ -587,7 +587,7 @@ def _get_de_registered_stake_for_coldkey_wallet( result: List[Tuple[str, "bittensor.Balance"]] = [] try: - subtensor = bittensor.subtensor(config=subtensor_config) + subtensor = bittensor.subtensor(config=subtensor_config, log_verbose=False) # Pull all stake for our coldkey all_stake_info_for_coldkey = subtensor.get_stake_info_for_coldkey( diff --git a/bittensor/commands/stake.py b/bittensor/commands/stake.py index 51f54afe97..400d70404c 100644 --- a/bittensor/commands/stake.py +++ b/bittensor/commands/stake.py @@ -375,7 +375,7 @@ def get_stake_accounts(wallet) -> Dict[str, Dict[str, Union[str, Balance]]]: Returns: A dictionary mapping SS58 addresses to their respective stake account details. """ - subtensor = bittensor.subtensor(config=cli.config) + subtensor = bittensor.subtensor(config=cli.config, log_verbose=False) wallet_stake_accounts = {} diff --git a/bittensor/extrinsics/network.py b/bittensor/extrinsics/network.py index 04447e9f14..d148005e31 100644 --- a/bittensor/extrinsics/network.py +++ b/bittensor/extrinsics/network.py @@ -159,7 +159,7 @@ def set_hyperparameter_extrinsic( ): with subtensor.substrate as substrate: extrinsic_params = substrate.get_metadata_call_function( - "SubtensorModule", extrinsic + "AdminUtils", extrinsic ) value_argument = extrinsic_params["fields"][ len(extrinsic_params["fields"]) - 1 @@ -167,7 +167,7 @@ def set_hyperparameter_extrinsic( # create extrinsic call call = substrate.compose_call( - call_module="SubtensorModule", + call_module="AdminUtils", call_function=extrinsic, call_params={"netuid": netuid, str(value_argument["name"]): value}, ) diff --git a/bittensor/extrinsics/transfer.py b/bittensor/extrinsics/transfer.py index 86fcce70a5..915cf8730a 100644 --- a/bittensor/extrinsics/transfer.py +++ b/bittensor/extrinsics/transfer.py @@ -129,12 +129,19 @@ def transfer_extrinsic( "[green]Block Hash: {}[/green]".format(block_hash) ) - explorer_url = bittensor.utils.get_explorer_url_for_network( + explorer_urls = bittensor.utils.get_explorer_url_for_network( subtensor.network, block_hash, bittensor.__network_explorer_map__ ) - if explorer_url is not None: + if explorer_urls != {}: bittensor.__console__.print( - "[green]Explorer Link: {}[/green]".format(explorer_url) + "[green]Opentensor Explorer Link: {}[/green]".format( + explorer_urls.get("opentensor") + ) + ) + bittensor.__console__.print( + "[green]Taostats Explorer Link: {}[/green]".format( + explorer_urls.get("taostats") + ) ) else: bittensor.__console__.print( diff --git a/bittensor/subtensor.py b/bittensor/subtensor.py index 52ae1b482c..dd08c75953 100644 --- a/bittensor/subtensor.py +++ b/bittensor/subtensor.py @@ -298,6 +298,7 @@ def __init__( network: str = None, config: "bittensor.config" = None, _mock: bool = False, + log_verbose: bool = True, ) -> None: """ Initializes a Subtensor interface for interacting with the Bittensor blockchain. @@ -333,7 +334,7 @@ def __init__( if ( self.network == "finney" or self.chain_endpoint == bittensor.__finney_entrypoint__ - ): + ) and log_verbose: bittensor.logging.info( f"You are connecting to {self.network} network with endpoint {self.chain_endpoint}." ) @@ -375,6 +376,11 @@ def __init__( exit(1) # TODO (edu/phil): Advise to run local subtensor and point to dev docs. + try: + self.substrate.websocket.settimeout(600) + except: + bittensor.logging.warning("Could not set websocket timeout.") + bittensor.logging.info( f"Connected to {self.network} network and {self.chain_endpoint}." ) diff --git a/bittensor/utils/__init__.py b/bittensor/utils/__init__.py index aa9b5e854b..2b3aba4c97 100644 --- a/bittensor/utils/__init__.py +++ b/bittensor/utils/__init__.py @@ -123,8 +123,8 @@ def strtobool(val: str) -> Union[bool, Literal["==SUPRESS=="]]: def get_explorer_root_url_by_network_from_map( - network: str, network_map: Dict[str, str] -) -> Optional[str]: + network: str, network_map: Dict[str, Dict[str, str]] +) -> Optional[Dict[str, str]]: r""" Returns the explorer root url for the given network name from the given network map. @@ -136,42 +136,48 @@ def get_explorer_root_url_by_network_from_map( The explorer url for the given network. Or None if the network is not in the network map. """ - explorer_url: Optional[str] = None - if network in network_map: - explorer_url = network_map[network] + explorer_urls: Optional[Dict[str, str]] = {} + for entity_nm, entity_network_map in network_map.items(): + if network in entity_network_map: + explorer_urls[entity_nm] = entity_network_map[network] - return explorer_url + return explorer_urls def get_explorer_url_for_network( network: str, block_hash: str, network_map: Dict[str, str] -) -> Optional[str]: +) -> Optional[List[str]]: r""" Returns the explorer url for the given block hash and network. Args: network(str): The network to get the explorer url for. block_hash(str): The block hash to get the explorer url for. - network_map(Dict[str, str]): The network map to get the explorer url from. + network_map(Dict[str, Dict[str, str]]): The network maps to get the explorer urls from. Returns: The explorer url for the given block hash and network. Or None if the network is not known. """ - explorer_url: Optional[str] = None + explorer_urls: Optional[Dict[str, str]] = {} # Will be None if the network is not known. i.e. not in network_map - explorer_root_url: Optional[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_url is not None: + if explorer_root_urls != {}: # We are on a known network. - explorer_url = "{root_url}/query/{block_hash}".format( - root_url=explorer_root_url, block_hash=block_hash + explorer_opentensor_url = "{root_url}/query/{block_hash}".format( + root_url=explorer_root_urls.get("opentensor"), block_hash=block_hash + ) + explorer_taostats_url = "{root_url}/search?query={block_hash}".format( + root_url=explorer_root_urls.get("taostats"), block_hash=block_hash ) + explorer_urls["opentensor"] = explorer_opentensor_url + explorer_urls["taostats"] = explorer_taostats_url - return explorer_url + return explorer_urls def ss58_address_to_bytes(ss58_address: str) -> bytes: diff --git a/tests/unit_tests/utils/test_utils.py b/tests/unit_tests/utils/test_utils.py index c3d214ff07..3309bc35b0 100644 --- a/tests/unit_tests/utils/test_utils.py +++ b/tests/unit_tests/utils/test_utils.py @@ -700,63 +700,71 @@ class MockException(Exception): @ddt class TestExplorerURL(unittest.TestCase): - network_map: Dict[str, str] = { - "nakamoto": "https://polkadot.js.org/apps/?rpc=wss://archivelb.nakamoto.opentensor.ai:9943#/explorer", - "example": "https://polkadot.js.org/apps/?rpc=wss://example.example.com#/explorer", - "nobunaga": "https://polkadot.js.org/apps/?rpc=wss://nobunaga.bittensor.com:9943#/explorer", - # "bad": None # no explorer for this network - } - @data( ( - "nobunaga", - "https://polkadot.js.org/apps/?rpc=wss://nobunaga.bittensor.com:9943#/explorer", + "local", + { + "opentensor": "https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fentrypoint-finney.opentensor.ai%3A443#/explorer", + "taostats": "https://x.taostats.io", + }, ), ( - "nakamoto", - "https://polkadot.js.org/apps/?rpc=wss://archivelb.nakamoto.opentensor.ai:9943#/explorer", + "endpoint", + { + "opentensor": "https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fentrypoint-finney.opentensor.ai%3A443#/explorer", + "taostats": "https://x.taostats.io", + }, ), ( - "example", - "https://polkadot.js.org/apps/?rpc=wss://example.example.com#/explorer", + "finney", + { + "opentensor": "https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fentrypoint-finney.opentensor.ai%3A443#/explorer", + "taostats": "https://x.taostats.io", + }, ), - ("bad", None), - ("", None), - ("networknamewithoutexplorer", None), + ("bad", {}), + ("", {}), + ("unknown", {}), ) @unpack def test_get_explorer_root_url_by_network_from_map( - self, network: str, expected: str - ) -> str: + self, network: str, expected: dict + ) -> None: self.assertEqual( bittensor.utils.get_explorer_root_url_by_network_from_map( - network, self.network_map + network, bittensor.__network_explorer_map__ ), expected, ) @data( ( - "nobunaga", + "local", "0x123", - "https://polkadot.js.org/apps/?rpc=wss://nobunaga.bittensor.com:9943#/explorer/query/0x123", + { + "opentensor": "https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fentrypoint-finney.opentensor.ai%3A443#/explorer/query/0x123", + "taostats": "https://x.taostats.io/search?query=0x123", + }, ), ( - "example", - "0x123", - "https://polkadot.js.org/apps/?rpc=wss://example.example.com#/explorer/query/0x123", + "endpoint", + "0x456", + { + "opentensor": "https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fentrypoint-finney.opentensor.ai%3A443#/explorer/query/0x456", + "taostats": "https://x.taostats.io/search?query=0x456", + }, ), - ("bad", "0x123", None), - ("", "0x123", None), - ("networknamewithoutexplorer", "0x123", None), + ("bad", "0x789", {}), + ("", "0xabc", {}), + ("unknown", "0xdef", {}), ) @unpack def test_get_explorer_url_for_network_by_network_and_block_hash( - self, network: str, block_hash: str, expected: str - ) -> str: + self, network: str, block_hash: str, expected: dict + ) -> None: self.assertEqual( bittensor.utils.get_explorer_url_for_network( - network, block_hash, self.network_map + network, block_hash, bittensor.__network_explorer_map__ ), expected, )