From 0a29230915ce16cb9751c63b96b85ed95374259e Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Tue, 15 Aug 2023 15:20:48 -0400 Subject: [PATCH 01/21] remove miniupnpc --- bittensor/_subtensor/extrinsics/serving.py | 25 +------ bittensor/utils/networking.py | 68 ------------------- requirements/prod.txt | 1 - scripts/environments/apple_m1_environment.yml | 1 - .../utils/test_network_utils.py | 21 +----- 5 files changed, 2 insertions(+), 114 deletions(-) diff --git a/bittensor/_subtensor/extrinsics/serving.py b/bittensor/_subtensor/extrinsics/serving.py index dc5144c5bb..ab9fe73106 100644 --- a/bittensor/_subtensor/extrinsics/serving.py +++ b/bittensor/_subtensor/extrinsics/serving.py @@ -188,30 +188,7 @@ def serve_axon_extrinsic( """ axon.wallet.hotkey axon.wallet.coldkeypub - - # ---- Setup UPNPC ---- - if use_upnpc: - if prompt: - if not Confirm.ask("Attempt port forwarding with upnpc?"): - return False - try: - external_port = net.upnpc_create_port_map(port=axon.port) - bittensor.__console__.print( - ":white_heavy_check_mark: [green]Forwarded port: {}[/green]".format( - axon.port - ) - ) - bittensor.logging.success( - prefix="Forwarded port", sufix="{}".format(axon.port) - ) - except net.UPNPCException as upnpc_exception: - raise RuntimeError( - "Failed to hole-punch with upnpc with exception {}".format( - upnpc_exception - ) - ) from upnpc_exception - else: - external_port = axon.external_port + external_port = axon.external_port # ---- Get external ip ---- if axon.external_ip == None: diff --git a/bittensor/utils/networking.py b/bittensor/utils/networking.py index 0ae28babfa..07cef927e2 100644 --- a/bittensor/utils/networking.py +++ b/bittensor/utils/networking.py @@ -20,7 +20,6 @@ import os import urllib import json -import miniupnpc import netaddr import requests @@ -154,73 +153,6 @@ def get_external_ip() -> str: raise ExternalIPNotFound -class UPNPCException(Exception): - """Raised when trying to perform a port mapping on your router.""" - - -def upnpc_create_port_map(port: int): - r"""Creates a upnpc port map on your router from passed external_port to local port. - - Args: - port (int, `required`): - The local machine port to map from your external port. - - Return: - external_port (int, `required`): - The external port mapped to the local port on your machine. - - Raises: - UPNPCException (Exception): - Raised if UPNPC port mapping fails, for instance, if upnpc is not enabled on your router. - """ - try: - upnp = miniupnpc.UPnP() - upnp.discoverdelay = 200 - logger.debug("UPNPC: Using UPnP to open a port on your router ...") - logger.debug("UPNPC: Discovering... delay={}ms", upnp.discoverdelay) - ndevices = upnp.discover() - upnp.selectigd() - logger.debug("UPNPC: " + str(ndevices) + " device(s) detected") - - ip = upnp.lanaddr - external_ip = upnp.externalipaddress() - - logger.debug("UPNPC: your local ip address: " + str(ip)) - logger.debug("UPNPC: your external ip address: " + str(external_ip)) - logger.debug( - "UPNPC: status = " - + str(upnp.statusinfo()) - + " connection type = " - + str(upnp.connectiontype()) - ) - - # find a free port for the redirection - external_port = port - rc = upnp.getspecificportmapping(external_port, "TCP") - while rc != None and external_port < 65536: - external_port += 1 - rc = upnp.getspecificportmapping(external_port, "TCP") - if rc != None: - raise UPNPCException("UPNPC: No available external ports for port mapping.") - - logger.info( - "UPNPC: trying to redirect remote: {}:{} => local: {}:{} over TCP", - external_ip, - external_port, - ip, - port, - ) - upnp.addportmapping( - external_port, "TCP", ip, port, "Bittensor: %u" % external_port, "" - ) - logger.info("UPNPC: Create Success") - - return external_port - - except Exception as e: - raise UPNPCException(e) from e - - def get_formatted_ws_endpoint_url(endpoint_url: str) -> str: """ Returns a formatted websocket endpoint url. diff --git a/requirements/prod.txt b/requirements/prod.txt index 9927192e9e..661ed87d85 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -15,7 +15,6 @@ langchain>=0.0.132,<=0.0.188 loguru==0.6.0 msgpack==1.0.4 msgpack-numpy==0.4.7.1 -miniupnpc==2.0.2 munch==2.5.0 nest_asyncio==1.5.6 netaddr==0.8.0 diff --git a/scripts/environments/apple_m1_environment.yml b/scripts/environments/apple_m1_environment.yml index f153bca074..8830f3e339 100644 --- a/scripts/environments/apple_m1_environment.yml +++ b/scripts/environments/apple_m1_environment.yml @@ -184,7 +184,6 @@ dependencies: - markupsafe==2.0.1 - marshmallow==3.19.0 - marshmallow-enum==1.5.1 - - miniupnpc==2.0.2 - more-itertools==9.1.0 - msgpack==1.0.4 - msgpack-numpy==0.4.7.1 diff --git a/tests/unit_tests/bittensor_tests/utils/test_network_utils.py b/tests/unit_tests/bittensor_tests/utils/test_network_utils.py index 623d34cbe8..dddb4d4a14 100644 --- a/tests/unit_tests/bittensor_tests/utils/test_network_utils.py +++ b/tests/unit_tests/bittensor_tests/utils/test_network_utils.py @@ -5,9 +5,6 @@ import requests import urllib import pytest -import miniupnpc - -from bittensor.utils.networking import UPNPCException, upnpc_create_port_map def test_int_to_ip_zero(): @@ -127,21 +124,6 @@ def returnNoPortMapping(): return None -@mock.patch("miniupnpc.UPnP") -def test_upnpc_create_port_map(mocked_upnp): - port = 65535 - mocked_upnp.discover = MagicMock(return_value=1) - mocked_upnp.selectgid = MagicMock(return_value=1) - mocked_upnp.lanaddr = MagicMock(return_value="127.0.0.1") - mocked_upnp.selectigd = MagicMock(return_value="127.0.0.1") - mocked_upnp.statusinfo = MagicMock(return_value="200") - mocked_upnp.connectiontype = MagicMock(return_value="some_type") - mocked_upnp.getspecificportmapping = returnNoPortMapping - - with pytest.raises(UPNPCException): - upnpc_create_port_map(port=port) - - @pytest.mark.parametrize( "url, expected", [ @@ -178,5 +160,4 @@ def test_format(url: str, expected: str): if __name__ == "__main__": - test_get_external_ip() - test_upnpc_create_port_map() + test_get_external_ip() \ No newline at end of file From c64505f6987ee28562a035b1e91adac79bedd790 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Tue, 15 Aug 2023 20:20:42 +0000 Subject: [PATCH 02/21] remove arg for upnpc --- bittensor/_subtensor/extrinsics/serving.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bittensor/_subtensor/extrinsics/serving.py b/bittensor/_subtensor/extrinsics/serving.py index ab9fe73106..24997e1311 100644 --- a/bittensor/_subtensor/extrinsics/serving.py +++ b/bittensor/_subtensor/extrinsics/serving.py @@ -159,7 +159,6 @@ def serve_axon_extrinsic( subtensor: "bittensor.Subtensor", netuid: int, axon: "bittensor.Axon", - use_upnpc: bool = False, wait_for_inclusion: bool = False, wait_for_finalization: bool = True, prompt: bool = False, @@ -170,9 +169,6 @@ def serve_axon_extrinsic( The netuid being served on. axon (bittensor.Axon): Axon to serve. - use_upnpc (:type:bool, `optional`): - If true, the axon attempts port forward through your router before - subscribing. wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning true, or returns false if the extrinsic fails to enter the block within the timeout. From dc76522a025c64babad7403169330be95fc03027 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Tue, 15 Aug 2023 21:09:42 +0000 Subject: [PATCH 03/21] rerun black --- tests/unit_tests/bittensor_tests/utils/test_network_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit_tests/bittensor_tests/utils/test_network_utils.py b/tests/unit_tests/bittensor_tests/utils/test_network_utils.py index dddb4d4a14..753bcd0a9c 100644 --- a/tests/unit_tests/bittensor_tests/utils/test_network_utils.py +++ b/tests/unit_tests/bittensor_tests/utils/test_network_utils.py @@ -160,4 +160,4 @@ def test_format(url: str, expected: str): if __name__ == "__main__": - test_get_external_ip() \ No newline at end of file + test_get_external_ip() From 3fefdbb9136158cb585999e6c2e916e262108969 Mon Sep 17 00:00:00 2001 From: gitphantomman <140101294+gitphantomman@users.noreply.github.com> Date: Mon, 7 Aug 2023 08:11:09 -0700 Subject: [PATCH 04/21] update CONTRIBUTING.md and DEVELOPMENT_WORKFLOW.md (#1475) * update CONTRIBUTING.md and DEVELOPMENT_WORKFLOW.md * Update contrib/DEVELOPMENT_WORKFLOW.md Co-authored-by: philanthrope * move styles to style guide * update workflow doc based on comment * update contributing.md delete Architecture section * fix CODE_REVIEW_DOC dev_note link * Update contrib/CONTRIBUTING.md Great Co-authored-by: philanthrope * Update contrib/CONTRIBUTING.md Ditto: Co-authored-by: philanthrope --------- Co-authored-by: gitphantomman Co-authored-by: philanthrope --- contrib/CODE_REVIEW_DOCS.md | 71 +++++++++++++++++++++++++++++++++++++ contrib/CONTRIBUTING.md | 48 ++++++++++++++++++++++++- contrib/STYLE.md | 57 ++++++++++++++++++++++++++--- 3 files changed, 171 insertions(+), 5 deletions(-) create mode 100644 contrib/CODE_REVIEW_DOCS.md diff --git a/contrib/CODE_REVIEW_DOCS.md b/contrib/CODE_REVIEW_DOCS.md new file mode 100644 index 0000000000..d1f41c5fcd --- /dev/null +++ b/contrib/CODE_REVIEW_DOCS.md @@ -0,0 +1,71 @@ +# Code Review +### Conceptual Review + +A review can be a conceptual review, where the reviewer leaves a comment + * `Concept (N)ACK`, meaning "I do (not) agree with the general goal of this pull + request", + * `Approach (N)ACK`, meaning `Concept ACK`, but "I do (not) agree with the + approach of this change". + +A `NACK` needs to include a rationale why the change is not worthwhile. +NACKs without accompanying reasoning may be disregarded. +After conceptual agreement on the change, code review can be provided. A review +begins with `ACK BRANCH_COMMIT`, where `BRANCH_COMMIT` is the top of the PR +branch, followed by a description of how the reviewer did the review. The +following language is used within pull request comments: + + - "I have tested the code", involving change-specific manual testing in + addition to running the unit, functional, or fuzz tests, and in case it is + not obvious how the manual testing was done, it should be described; + - "I have not tested the code, but I have reviewed it and it looks + OK, I agree it can be merged"; + - A "nit" refers to a trivial, often non-blocking issue. +### Code Review +Project maintainers reserve the right to weigh the opinions of peer reviewers +using common sense judgement and may also weigh based on merit. Reviewers that +have demonstrated a deeper commitment and understanding of the project over time +or who have clear domain expertise may naturally have more weight, as one would +expect in all walks of life. + +Where a patch set affects consensus-critical code, the bar will be much +higher in terms of discussion and peer review requirements, keeping in mind that +mistakes could be very costly to the wider community. This includes refactoring +of consensus-critical code. + +Where a patch set proposes to change the Bittensor consensus, it must have been +discussed extensively on the mailing list and IRC, be accompanied by a widely +discussed BIP and have a generally widely perceived technical consensus of being +a worthwhile change based on the judgement of the maintainers. + +### Finding Reviewers + +As most reviewers are themselves developers with their own projects, the review +process can be quite lengthy, and some amount of patience is required. If you find +that you've been waiting for a pull request to be given attention for several +months, there may be a number of reasons for this, some of which you can do something +about: + + - It may be because of a feature freeze due to an upcoming release. During this time, + only bug fixes are taken into consideration. If your pull request is a new feature, + it will not be prioritized until after the release. Wait for the release. + - It may be because the changes you are suggesting do not appeal to people. Rather than + nits and critique, which require effort and means they care enough to spend time on your + contribution, thundering silence is a good sign of widespread (mild) dislike of a given change + (because people don't assume *others* won't actually like the proposal). Don't take + that personally, though! Instead, take another critical look at what you are suggesting + and see if it: changes too much, is too broad, doesn't adhere to the + [developer notes](DEVELOPMENT_WORKFLOW.md), is dangerous or insecure, is messily written, etc. + Identify and address any of the issues you find. Then ask e.g. on IRC if someone could give + their opinion on the concept itself. + - It may be because your code is too complex for all but a few people, and those people + may not have realized your pull request even exists. A great way to find people who + are qualified and care about the code you are touching is the + [Git Blame feature](https://docs.github.com/en/github/managing-files-in-a-repository/managing-files-on-github/tracking-changes-in-a-file). Simply + look up who last modified the code you are changing and see if you can find + them and give them a nudge. Don't be incessant about the nudging, though. + - Finally, if all else fails, ask on IRC or elsewhere for someone to give your pull request + a look. If you think you've been waiting for an unreasonably long time (say, + more than a month) for no particular reason (a few lines changed, etc.), + this is totally fine. Try to return the favor when someone else is asking + for feedback on their code, and the universe balances out. + - Remember that the best thing you can do while waiting is give review to others! \ No newline at end of file diff --git a/contrib/CONTRIBUTING.md b/contrib/CONTRIBUTING.md index cb04527a52..0a47469250 100644 --- a/contrib/CONTRIBUTING.md +++ b/contrib/CONTRIBUTING.md @@ -3,9 +3,11 @@ The following is a set of guidelines for contributing to Bittensor, which are hosted in the [Opentensor Organization](https://github.com/opentensor) on GitHub. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. ## Table Of Contents - 1. [I don't want to read this whole thing, I just have a question!!!](#i-dont-want-to-read-this-whole-thing-i-just-have-a-question) 1. [What should I know before I get started?](#what-should-i-know-before-i-get-started) +1. [Getting Started](#getting-started) + 1. [Good First Issue Label](#good-first-issue-label) + 1. [Beginner and Help-wanted Issues Label](#beginner-and-help-wanted-issues-label) 1. [How Can I Contribute?](#how-can-i-contribute) 1. [Code Contribution General Guideline](#code-contribution-general-guidelines) 1. [Pull Request Philosophy](#pull-request-philosophy) @@ -14,6 +16,7 @@ The following is a set of guidelines for contributing to Bittensor, which are ho 1. [Addressing Feedback](#addressing-feedback) 1. [Squashing Commits](#squashing-commits) 1. [Refactoring](#refactoring) + 1. [Peer Review](#peer-review) 1. [Reporting Bugs](#reporting-bugs) 1. [Suggesting Features](#suggesting-enhancements) @@ -34,6 +37,34 @@ Additionally, note that the core implementation of Bittensor consists of two sep Supplemental, yet necessary repositories are [openvalidators](https://github.com/opentensor/validators) and [openminers](https://github.com/opentensor/miners) which contain Bittensor Validators and Miners (respectively) designed by the OpenTensor Foundation team and open-sourced for the community to use. +## Getting Started +New contributors are very welcome and needed. +Reviewing and testing is highly valued and the most effective way you can contribute as a new contributor. It also will teach you much more about the code and process than opening pull requests. + +Before you start contributing, familiarize yourself with the Bittensor Core build system and tests. Refer to the documentation in the repository on how to build Bittensor core and how to run the unit tests, functional tests. + +There are many open issues of varying difficulty waiting to be fixed. If you're looking for somewhere to start contributing, check out the [good first issue](https://github.com/opentensor/bittensor/labels/good%20first%20issue) list or changes that are up for grabs. Some of them might no longer be applicable. So if you are interested, but unsure, you might want to leave a comment on the issue first. +### Good First Issue Label +The purpose of the good first issue label is to highlight which issues are suitable for a new contributor without a deep understanding of the codebase. + +However, good first issues can be solved by anyone. If they remain unsolved for a longer time, a frequent contributor might address them. + +You do not need to request permission to start working on an issue. However, you are encouraged to leave a comment if you are planning to work on it. This will help other contributors monitor which issues are actively being addressed and is also an effective way to request assistance if and when you need it. +### Beginner and Help-wanted Issues Label +You can start by looking through these `beginner` and `help-wanted` issues: + +* [Beginner issues](https://github.com/opentensor/bittensor/labels/beginner) - issues which should only require a few lines of code, and a test or two. +* [Help wanted issues](https://github.com/opentensor/bittensor/labels/help%20wanted) - issues which should be a bit more involved than `beginner` issues. + + +## Communication Channels +Most communication about Bittensor development happens on Discord channel. +Here's the link of Discord community. +[Bittensor Discord](https://discord.com/channels/799672011265015819/799672011814862902) + +And also here. +[Bittensor Community Discord](https://discord.com/channels/1120750674595024897/1120799375703162950) + ## How Can I Contribute? @@ -183,6 +214,21 @@ Project maintainers aim for a quick turnaround on refactoring pull requests, so Pull requests that refactor the code should not be made by new contributors. It requires a certain level of experience to know where the code belongs to and to understand the full ramification (including rebase effort of open pull requests). Trivial pull requests or pull requests that refactor the code with no clear benefits may be immediately closed by the maintainers to reduce unnecessary workload on reviewing. +#### Peer Review + +Anyone may participate in peer review which is expressed by comments in the pull request. Typically reviewers will review the code for obvious errors, as well as test out the patch set and opine on the technical merits of the patch. Project maintainers take into account the peer review when determining if there is consensus to merge a pull request (remember that discussions may have taken place elsewhere, not just on GitHub). The following language is used within pull-request comments: + +- ACK means "I have tested the code and I agree it should be merged"; +- NACK means "I disagree this should be merged", and must be accompanied by sound technical justification. NACKs without accompanying reasoning may be disregarded; +- utACK means "I have not tested the code, but I have reviewed it and it looks OK, I agree it can be merged"; +- Concept ACK means "I agree in the general principle of this pull request"; +- Nit refers to trivial, often non-blocking issues. + +Reviewers should include the commit(s) they have reviewed in their comments. This can be done by copying the commit SHA1 hash. + +A pull request that changes consensus-critical code is considerably more involved than a pull request that adds a feature to the wallet, for example. Such patches must be reviewed and thoroughly tested by several reviewers who are knowledgeable about the changed subsystems. Where new features are proposed, it is helpful for reviewers to try out the patch set on a test network and indicate that they have done so in their review. Project maintainers will take this into consideration when merging changes. + +For a more detailed description of the review process, see the [Code Review Guidelines](CODE_REVIEW_DOCS.md). ### Reporting Bugs diff --git a/contrib/STYLE.md b/contrib/STYLE.md index daf2a68d32..b7ac755fc0 100644 --- a/contrib/STYLE.md +++ b/contrib/STYLE.md @@ -6,21 +6,58 @@ Most programming languages have well-established conventions as to what constitu # Table of Contents 1. [Code Style](#code-style) -2. [Git Commit Style](#git-commit-style) -3. [The Six Rules of a Great Commit](#the-six-rules-of-a-great-commit) +2. [Naming Conventions](#naming-conventions) +3. [Git Commit Style](#git-commit-style) +4. [The Six Rules of a Great Commit](#the-six-rules-of-a-great-commit) - [1. Atomic Commits](#1-atomic-commits) - [2. Separate Subject from Body with a Blank Line](#2-separate-subject-from-body-with-a-blank-line) - [3. Limit the Subject Line to 50 Characters](#3-limit-the-subject-line-to-50-characters) - [4. Use the Imperative Mood in the Subject Line](#4-use-the-imperative-mood-in-the-subject-line) - [5. Wrap the Body at 72 Characters](#5-wrap-the-body-at-72-characters) - [6. Use the Body to Explain What and Why vs. How](#6-use-the-body-to-explain-what-and-why-vs-how) -4. [Tools Worth Mentioning](#tools-worth-mentioning) +5. [Tools Worth Mentioning](#tools-worth-mentioning) - [Using `--fixup`](#using---fixup) - [Interactive Rebase](#interactive-rebase) -5. [Pull Request and Squashing Commits Caveats](#pull-request-and-squashing-commits-caveats) +6. [Pull Request and Squashing Commits Caveats](#pull-request-and-squashing-commits-caveats) ### Code style + +#### General Style +Python's official style guide is PEP 8, which provides conventions for writing code for the main Python distribution. Here are some key points: + +- `Indentation:` Use 4 spaces per indentation level. + +- `Line Length:` Limit all lines to a maximum of 79 characters. + +- `Blank Lines:` Surround top-level function and class definitions with two blank lines. Method definitions inside a class are surrounded by a single blank line. + +- `Imports:` Imports should usually be on separate lines and should be grouped in the following order: + + - Standard library imports. + - Related third party imports. + - Local application/library specific imports. +- `Whitespace:` Avoid extraneous whitespace in the following situations: + + - Immediately inside parentheses, brackets or braces. + - Immediately before a comma, semicolon, or colon. + - Immediately before the open parenthesis that starts the argument list of a function call. +- `Comments:` Comments should be complete sentences and should be used to clarify code and are not a substitute for poorly written code. + +#### For Python + +- `List Comprehensions:` Use list comprehensions for concise and readable creation of lists. + +- `Generators:` Use generators when dealing with large amounts of data to save memory. + +- `Context Managers:` Use context managers (with statement) for resource management. + +- `String Formatting:` Use f-strings for formatting strings in Python 3.6 and above. + +- `Error Handling:` Use exceptions for error handling whenever possible. + +#### More details + Use `black` to format your python code before commiting for consistency across such a large pool of contributors. Black's code [style](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#code-style) ensures consistent and opinionated code formatting. It automatically formats your Python code according to the Black style guide, enhancing code readability and maintainability. Key Features of Black: @@ -31,6 +68,18 @@ Key Features of Black: Automation: Black automates the code formatting process, saving time and effort. It eliminates the need for manual formatting and reduces the likelihood of inconsistencies. +### Naming Conventions + +- `Classes:` Class names should normally use the CapWords Convention. +- `Functions and Variables:` Function names should be lowercase, with words separated by underscores as necessary to improve readability. Variable names follow the same convention as function names. + +- `Constants:` Constants are usually defined on a module level and written in all capital letters with underscores separating words. + +- `Non-public Methods and Instance Variables:` Use a single leading underscore (_). This is a weak "internal use" indicator. + +- `Strongly "private" methods and variables:` Use a double leading underscore (__). This triggers name mangling in Python. + + ### Git commit style Here’s a model Git commit message when contributing: From a6a89fdd7cf0ad83d73eff3b26d7dd830215cb10 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Wed, 26 Jul 2023 17:19:58 +0000 Subject: [PATCH 05/21] add try/except and timeout to version checking with exception handles --- bittensor/utils/__init__.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/bittensor/utils/__init__.py b/bittensor/utils/__init__.py index 1618c7ad1b..bf1da4abf8 100644 --- a/bittensor/utils/__init__.py +++ b/bittensor/utils/__init__.py @@ -68,22 +68,20 @@ def unbiased_topk(values, k, dim=0, sorted=True, largest=True): return topk, permutation[indices] -def version_checking(): - response = requests.get(bittensor.__pipaddress__) - latest_version = response.json()["info"]["version"] - version_split = latest_version.split(".") - latest_version_as_int = ( - (100 * int(version_split[0])) - + (10 * int(version_split[1])) - + (1 * int(version_split[2])) - ) - - if latest_version_as_int > bittensor.__version_as_int__: - print( - "\u001b[33mBittensor Version: Current {}/Latest {}\nPlease update to the latest version at your earliest convenience\u001b[0m".format( - bittensor.__version__, latest_version - ) - ) +def version_checking( timeout : int = 15 ): + try: + response = requests.get(bittensor.__pipaddress__, timeout=timeout) + latest_version = response.json()['info']['version'] + version_split = latest_version.split(".") + latest_version_as_int = (100 * int(version_split[0])) + (10 * int(version_split[1])) + (1 * int(version_split[2])) + + if latest_version_as_int > bittensor.__version_as_int__: + print('\u001b[33mBittensor Version: Current {}/Latest {}\nPlease update to the latest version at your earliest convenience\u001b[0m'.format(bittensor.__version__,latest_version)) + + except requests.exceptions.Timeout: + bittensor.logging.error('Version check failed due to timeout') + except requests.exceptions.RequestException as e: + bittensor.logging.error(f'Version check failed due to request failure: {e}') def strtobool_with_default( From e80d3d5e27ad53f094b71b6f3e2f160943cdd713 Mon Sep 17 00:00:00 2001 From: Inquinim <114695354+Inquinim@users.noreply.github.com> Date: Wed, 26 Jul 2023 11:01:58 +1000 Subject: [PATCH 06/21] Fix blacklist vpermit_required (#1452) * - Adjusted blacklist argument default to False - Tweaked description * - Fix blacklist vpermit rejecting validators instead of non-validators * - Blacklist vpermit return true without permit, return false with permit * - Added text response to the return value for vpermit --- bittensor/_blacklist/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bittensor/_blacklist/__init__.py b/bittensor/_blacklist/__init__.py index a1f02bf2d2..7b0f0481df 100644 --- a/bittensor/_blacklist/__init__.py +++ b/bittensor/_blacklist/__init__.py @@ -113,7 +113,10 @@ def blacklist( and is_registered ): uid = metagraph.hotkeys.index(src_hotkey) - return metagraph.neurons[uid].validator_permit + # Return False (pass) if there is a permit, and True (fail) if there isn't. + if metagraph.neurons[uid].validator_permit: + return False, "has vpermit" + return True, "no vpermit" # All checks passed. return False, "passed blacklist" From 57d7d1c45898857be9b66afa08f5c869f203744a Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Wed, 16 Aug 2023 19:19:14 +0000 Subject: [PATCH 07/21] run black --- bittensor/utils/__init__.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/bittensor/utils/__init__.py b/bittensor/utils/__init__.py index bf1da4abf8..6d9ba16d25 100644 --- a/bittensor/utils/__init__.py +++ b/bittensor/utils/__init__.py @@ -68,20 +68,28 @@ def unbiased_topk(values, k, dim=0, sorted=True, largest=True): return topk, permutation[indices] -def version_checking( timeout : int = 15 ): +def version_checking(timeout: int = 15): try: response = requests.get(bittensor.__pipaddress__, timeout=timeout) - latest_version = response.json()['info']['version'] + latest_version = response.json()["info"]["version"] version_split = latest_version.split(".") - latest_version_as_int = (100 * int(version_split[0])) + (10 * int(version_split[1])) + (1 * int(version_split[2])) + latest_version_as_int = ( + (100 * int(version_split[0])) + + (10 * int(version_split[1])) + + (1 * int(version_split[2])) + ) if latest_version_as_int > bittensor.__version_as_int__: - print('\u001b[33mBittensor Version: Current {}/Latest {}\nPlease update to the latest version at your earliest convenience\u001b[0m'.format(bittensor.__version__,latest_version)) - + print( + "\u001b[33mBittensor Version: Current {}/Latest {}\nPlease update to the latest version at your earliest convenience\u001b[0m".format( + bittensor.__version__, latest_version + ) + ) + except requests.exceptions.Timeout: - bittensor.logging.error('Version check failed due to timeout') + bittensor.logging.error("Version check failed due to timeout") except requests.exceptions.RequestException as e: - bittensor.logging.error(f'Version check failed due to request failure: {e}') + bittensor.logging.error(f"Version check failed due to request failure: {e}") def strtobool_with_default( From 56466090be4a4a6114cdaeae3e5e50cb8b84cbb6 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Wed, 16 Aug 2023 19:29:15 +0000 Subject: [PATCH 08/21] add changelog and version --- CHANGELOG.md | 12 ++++++++++++ VERSION | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f50be696ef..b7c41d5066 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 5.3.4 / 2023-08-16 + +# What's Changed +* Removes miniupnpc by @ifrit98 (completely unused and requires a sudo install) +* Fixes blacklist vpermit_required by @inquinim e80d3d5 +* Add try/except and timeout to version checking with exception handles by @ifrit98 a6a89fd +* Further updates CONTRIBUTING.md and DEVELOPMENT_WORKFLOW.md by @gitphantomman 3fefdbb + + +**Full Changelog**: https://github.com/opentensor/bittensor/compare/v5.3.3...v5.3.4 + + ## 5.3.3 / 2023-07-26 ## What's Changed diff --git a/VERSION b/VERSION index 3884b9bcd9..86f2a61e3d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.3.3 \ No newline at end of file +5.3.4 \ No newline at end of file From e46df5c8287b260fd3454cedb3670337e62025a9 Mon Sep 17 00:00:00 2001 From: philanthrope Date: Wed, 16 Aug 2023 16:19:21 -0400 Subject: [PATCH 09/21] add checks (#1484) * add checks * fix docker img * fix docker img2 --- .circleci/config.yml | 32 +++++++++++++++ scripts/check_compatibility.sh | 71 ++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100755 scripts/check_compatibility.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 2b6f3aac69..e17aed8351 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,6 +42,23 @@ jobs: . env/bin/activate python -m black --exclude '(env|venv|.eggs)' --check . + check_compatibility: + parameters: + python_version: + type: string + docker: + - image: cimg/python:3.10 + steps: + - checkout + - run: + name: Install dependencies + command: | + sudo apt-get update + sudo apt-get install -y jq curl + - run: + name: Check compatibility + command: ./scripts/check_compatibility.sh << parameters.python_version >> + build-and-test: resource_class: medium parallelism: 2 @@ -203,6 +220,21 @@ jobs: workflows: + compatibility_checks: + jobs: + - check_compatibility: + python_version: "3.8" + name: check-compatibility-3.8 + - check_compatibility: + python_version: "3.9" + name: check-compatibility-3.9 + - check_compatibility: + python_version: "3.10" + name: check-compatibility-3.10 + - check_compatibility: + python_version: "3.11" + name: check-compatibility-3.11 + pr-requirements: jobs: - black: diff --git a/scripts/check_compatibility.sh b/scripts/check_compatibility.sh new file mode 100755 index 0000000000..3a6cf47e4c --- /dev/null +++ b/scripts/check_compatibility.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo "Please provide a Python version as an argument." + exit 1 +fi + +python_version="$1" +all_passed=true + +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +check_compatibility() { + all_supported=0 + + while read -r requirement; do + package_name=$(echo "$requirement" | awk -F'[!=<>]' '{print $1}' | awk -F'[' '{print $1}') # Strip off brackets + echo -n "Checking $package_name... " + + url="https://pypi.org/pypi/$package_name/json" + response=$(curl -s $url) + status_code=$(curl -s -o /dev/null -w "%{http_code}" $url) + + if [ "$status_code" != "200" ]; then + echo -e "${RED}Information not available for $package_name. Failure.${NC}" + all_supported=1 + continue + fi + + classifiers=$(echo "$response" | jq -r '.info.classifiers[]') + requires_python=$(echo "$response" | jq -r '.info.requires_python') + + base_version="Programming Language :: Python :: ${python_version%%.*}" + specific_version="Programming Language :: Python :: $python_version" + + if echo "$classifiers" | grep -q "$specific_version" || echo "$classifiers" | grep -q "$base_version"; then + echo -e "${GREEN}Supported${NC}" + elif [ "$requires_python" != "null" ]; then + if echo "$requires_python" | grep -Eq "==$python_version|>=$python_version|<=$python_version"; then + echo -e "${GREEN}Supported${NC}" + else + echo -e "${RED}Not compatible with Python $python_version due to constraint $requires_python.${NC}" + all_supported=1 + fi + else + echo -e "${YELLOW}Warning: Specific version not listed, assuming compatibility${NC}" + fi + done < requirements/prod.txt + + return $all_supported +} + +echo "Checking compatibility for Python $python_version..." +check_compatibility +if [ $? -eq 0 ]; then + echo -e "${GREEN}All requirements are compatible with Python $python_version.${NC}" +else + echo -e "${RED}All requirements are NOT compatible with Python $python_version.${NC}" + all_passed=false +fi + +echo "" +if $all_passed; then + echo -e "${GREEN}All tests passed.${NC}" +else + echo -e "${RED}All tests did not pass.${NC}" + exit 1 +fi From 5816187296b760e9ad701ac310b337ca5b2e3075 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Wed, 16 Aug 2023 20:24:13 +0000 Subject: [PATCH 10/21] update version --- bittensor/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittensor/__init__.py b/bittensor/__init__.py index e3205c712f..9a7d8fb27f 100644 --- a/bittensor/__init__.py +++ b/bittensor/__init__.py @@ -28,7 +28,7 @@ nest_asyncio.apply() # Bittensor code and protocol version. -__version__ = "5.3.3" +__version__ = "5.3.4" version_split = __version__.split(".") __version_as_int__ = ( (100 * int(version_split[0])) From 744ab62205180920498f573feb737c1be9d423df Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Fri, 18 Aug 2023 13:44:50 +0000 Subject: [PATCH 11/21] remove unused multiforward in example --- examples/text_prompting.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/examples/text_prompting.py b/examples/text_prompting.py index 3b8cd27a83..4ef16ae085 100644 --- a/examples/text_prompting.py +++ b/examples/text_prompting.py @@ -39,9 +39,6 @@ def backward( def forward(self, messages: List[Dict[str, str]]) -> str: return "hello im a chat bot." - def multi_forward(self, messages: List[Dict[str, str]]) -> List[str]: - return ["hello im a chat bot.", "my name is bob"] - # Create a mock wallet. wallet = bittensor.wallet().create_if_non_existent() @@ -67,20 +64,3 @@ def multi_forward(self, messages: List[Dict[str, str]]) -> List[str]: forward_call.did_timeout, ) print("completion", forward_call.completion) - - -multi_forward_call = dendrite.multi_forward( - roles=["system", "assistant"], - messages=["you are chat bot", "what is the whether"], - timeout=1e6, -) -print(multi_forward_call) -print( - "success", - multi_forward_call.is_success, - "failed", - multi_forward_call.did_fail, - "timedout", - multi_forward_call.did_timeout, -) -print("completions", multi_forward_call.multi_completions) From 8114e1018d4364180ab8514da61f53d6a2ec8f17 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Fri, 18 Aug 2023 13:53:22 +0000 Subject: [PATCH 12/21] only run check_requirements job when an actual requirement changes --- .circleci/config.yml | 3 +++ scripts/check_requirements_changes.sh | 10 ++++++++++ 2 files changed, 13 insertions(+) create mode 100644 scripts/check_requirements_changes.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index e17aed8351..fa3d2b5df5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -50,6 +50,9 @@ jobs: - image: cimg/python:3.10 steps: - checkout + - run: + name: Check if requirements files have changed + command: ./scripts/check_requirements_changes.sh - run: name: Install dependencies command: | diff --git a/scripts/check_requirements_changes.sh b/scripts/check_requirements_changes.sh new file mode 100644 index 0000000000..11ec1359ae --- /dev/null +++ b/scripts/check_requirements_changes.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Check if requirements files have changed in the last commit +if git diff --name-only HEAD~1 | grep -E 'requirements/prod.txt|requirements/dev.txt'; then + echo "Requirements files have changed. Running compatibility checks..." + exit 0 +else + echo "Requirements files have not changed. Skipping compatibility checks..." + exit 1 +fi From 1cee00fa1724fd00463d48ba84eb367e0e8c57ac Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Fri, 18 Aug 2023 14:25:44 +0000 Subject: [PATCH 13/21] log bittensor pipaddress for version_checking --- bittensor/utils/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bittensor/utils/__init__.py b/bittensor/utils/__init__.py index 6d9ba16d25..d5eb4f3034 100644 --- a/bittensor/utils/__init__.py +++ b/bittensor/utils/__init__.py @@ -70,6 +70,7 @@ def unbiased_topk(values, k, dim=0, sorted=True, largest=True): def version_checking(timeout: int = 15): try: + bittensor.logging.info(f"Checking latest Bittensor version at: {bittensor.__pipaddress__}") response = requests.get(bittensor.__pipaddress__, timeout=timeout) latest_version = response.json()["info"]["version"] version_split = latest_version.split(".") From 1f83a920a77f2e855943efa45163084c69d1065e Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Fri, 18 Aug 2023 14:31:03 +0000 Subject: [PATCH 14/21] add newline --- contrib/CODE_REVIEW_DOCS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/CODE_REVIEW_DOCS.md b/contrib/CODE_REVIEW_DOCS.md index d1f41c5fcd..275319f160 100644 --- a/contrib/CODE_REVIEW_DOCS.md +++ b/contrib/CODE_REVIEW_DOCS.md @@ -20,6 +20,7 @@ following language is used within pull request comments: - "I have not tested the code, but I have reviewed it and it looks OK, I agree it can be merged"; - A "nit" refers to a trivial, often non-blocking issue. + ### Code Review Project maintainers reserve the right to weigh the opinions of peer reviewers using common sense judgement and may also weigh based on merit. Reviewers that From ed7d10f4a0d4fc2ad4b5ad41c10335c59918e1ee Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Fri, 18 Aug 2023 14:31:46 +0000 Subject: [PATCH 15/21] add newline to contrib --- contrib/CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/CONTRIBUTING.md b/contrib/CONTRIBUTING.md index 0a47469250..5ebbb7df22 100644 --- a/contrib/CONTRIBUTING.md +++ b/contrib/CONTRIBUTING.md @@ -50,6 +50,7 @@ The purpose of the good first issue label is to highlight which issues are suita However, good first issues can be solved by anyone. If they remain unsolved for a longer time, a frequent contributor might address them. You do not need to request permission to start working on an issue. However, you are encouraged to leave a comment if you are planning to work on it. This will help other contributors monitor which issues are actively being addressed and is also an effective way to request assistance if and when you need it. + ### Beginner and Help-wanted Issues Label You can start by looking through these `beginner` and `help-wanted` issues: From d4e716cc4d0f8ca6196bd75d07752596093c270f Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Fri, 18 Aug 2023 14:33:45 +0000 Subject: [PATCH 16/21] fix formatting to 1 newline --- contrib/CONTRIBUTING.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/contrib/CONTRIBUTING.md b/contrib/CONTRIBUTING.md index 5ebbb7df22..628c52614a 100644 --- a/contrib/CONTRIBUTING.md +++ b/contrib/CONTRIBUTING.md @@ -57,7 +57,6 @@ You can start by looking through these `beginner` and `help-wanted` issues: * [Beginner issues](https://github.com/opentensor/bittensor/labels/beginner) - issues which should only require a few lines of code, and a test or two. * [Help wanted issues](https://github.com/opentensor/bittensor/labels/help%20wanted) - issues which should be a bit more involved than `beginner` issues. - ## Communication Channels Most communication about Bittensor development happens on Discord channel. Here's the link of Discord community. @@ -66,7 +65,6 @@ Here's the link of Discord community. And also here. [Bittensor Community Discord](https://discord.com/channels/1120750674595024897/1120799375703162950) - ## How Can I Contribute? You can contribute to Bittensor in one of three main ways (as well as many others): @@ -97,7 +95,6 @@ Here is a high-level summary: If you're looking to contribute to Bittensor but unsure where to start, please join our community [discord](https://discord.gg/bittensor), a developer-friendly Bittensor town square. Start with [#development](https://discord.com/channels/799672011265015819/799678806159392768) and [#bounties](https://discord.com/channels/799672011265015819/1095684873810890883) to see what issues are currently posted. For a greater understanding of Bittensor's usage and development, check the [Bittensor Documentation](https://bittensor.com/docs). - #### Pull Request Philosophy Patchsets and enhancements should always be focused. A pull request could add a feature, fix a bug, or refactor code, but it should not contain a mixture of these. Please also avoid 'super' pull requests which attempt to do too much, are overly large, or overly complex as this makes review difficult. @@ -112,7 +109,6 @@ Specifically, pull requests must adhere to the following criteria: - If your changes are extensive, consider breaking your PR into smaller, related PRs. This makes your contributions easier to understand and review. - Be active in the discussion about your PR. Respond promptly to comments and questions to help reviewers understand your changes and speed up the acceptance process. - Generally, all pull requests must: - Have a clear use case, fix a demonstrable bug or serve the greater good of the project (e.g. refactoring for modularisation). @@ -126,7 +122,6 @@ Generally, all pull requests must: Please follow these steps to have your contribution considered by the maintainers: - *Before* creating the PR: 1. Read the [development workflow](./DEVELOPMENT_WORKFLOW.md) defined for this repository to understand our workflow. 2. Ensure your PR meets the criteria stated in the 'Pull Request Philosophy' section. @@ -178,7 +173,6 @@ Here is a quick summary: Remember, testing is crucial for maintaining code health, catching issues early, and facilitating the addition of new features or refactoring of existing code. - #### Addressing Feedback After submitting your pull request, expect comments and reviews from other contributors. You can add more commits to your pull request by committing them locally and pushing to your fork. From 84e1ff7bc3cac0b38dc8df9154c163b4e0263c65 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Fri, 18 Aug 2023 14:44:15 +0000 Subject: [PATCH 17/21] run black --- bittensor/utils/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bittensor/utils/__init__.py b/bittensor/utils/__init__.py index d5eb4f3034..e52b06b07a 100644 --- a/bittensor/utils/__init__.py +++ b/bittensor/utils/__init__.py @@ -70,7 +70,9 @@ def unbiased_topk(values, k, dim=0, sorted=True, largest=True): def version_checking(timeout: int = 15): try: - bittensor.logging.info(f"Checking latest Bittensor version at: {bittensor.__pipaddress__}") + bittensor.logging.info( + f"Checking latest Bittensor version at: {bittensor.__pipaddress__}" + ) response = requests.get(bittensor.__pipaddress__, timeout=timeout) latest_version = response.json()["info"]["version"] version_split = latest_version.split(".") From 6300480b51b3e51b0d7c27eb26e40829ebf1b101 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Fri, 18 Aug 2023 14:45:03 +0000 Subject: [PATCH 18/21] add perms to checK-compat script --- scripts/check_requirements_changes.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/check_requirements_changes.sh diff --git a/scripts/check_requirements_changes.sh b/scripts/check_requirements_changes.sh old mode 100644 new mode 100755 From b064e8bb5fc248d852171dc42e989e94d7b166fa Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Fri, 18 Aug 2023 15:09:16 +0000 Subject: [PATCH 19/21] fix check_reqs ci --- .circleci/config.yml | 14 ++++++++------ scripts/check_requirements_changes.sh | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fa3d2b5df5..63644ec467 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -54,13 +54,15 @@ jobs: name: Check if requirements files have changed command: ./scripts/check_requirements_changes.sh - run: - name: Install dependencies + name: Install dependencies and Check compatibility command: | - sudo apt-get update - sudo apt-get install -y jq curl - - run: - name: Check compatibility - command: ./scripts/check_compatibility.sh << parameters.python_version >> + if [ "$REQUIREMENTS_CHANGED" == "true" ]; then + sudo apt-get update + sudo apt-get install -y jq curl + ./scripts/check_compatibility.sh << parameters.python_version >> + else + echo "Skipping compatibility checks..." + fi build-and-test: resource_class: medium diff --git a/scripts/check_requirements_changes.sh b/scripts/check_requirements_changes.sh index 11ec1359ae..5fcd27ea3f 100755 --- a/scripts/check_requirements_changes.sh +++ b/scripts/check_requirements_changes.sh @@ -3,8 +3,8 @@ # Check if requirements files have changed in the last commit if git diff --name-only HEAD~1 | grep -E 'requirements/prod.txt|requirements/dev.txt'; then echo "Requirements files have changed. Running compatibility checks..." - exit 0 + echo 'export REQUIREMENTS_CHANGED="true"' >> $BASH_ENV else echo "Requirements files have not changed. Skipping compatibility checks..." - exit 1 + echo 'export REQUIREMENTS_CHANGED="false"' >> $BASH_ENV fi From 8bf5eb3867d627e7a7e50a97e231a2ecece453a8 Mon Sep 17 00:00:00 2001 From: ifrit98 Date: Fri, 18 Aug 2023 15:19:20 +0000 Subject: [PATCH 20/21] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7c41d5066..2e58a027ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ * Fixes blacklist vpermit_required by @inquinim e80d3d5 * Add try/except and timeout to version checking with exception handles by @ifrit98 a6a89fd * Further updates CONTRIBUTING.md and DEVELOPMENT_WORKFLOW.md by @gitphantomman 3fefdbb - +* Adds automatic compatibility checks to circleci for all major python3 supported versions. add checks by @ifrit98 #1484 **Full Changelog**: https://github.com/opentensor/bittensor/compare/v5.3.3...v5.3.4 From c3a9eb651900fad138b73b50ee606ec4933964d3 Mon Sep 17 00:00:00 2001 From: philanthrope Date: Fri, 18 Aug 2023 17:34:51 -0400 Subject: [PATCH 21/21] Update contrib/CODE_REVIEW_DOCS.md Co-authored-by: Cameron Fairchild --- contrib/CODE_REVIEW_DOCS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/CODE_REVIEW_DOCS.md b/contrib/CODE_REVIEW_DOCS.md index 275319f160..9909606a89 100644 --- a/contrib/CODE_REVIEW_DOCS.md +++ b/contrib/CODE_REVIEW_DOCS.md @@ -34,7 +34,7 @@ mistakes could be very costly to the wider community. This includes refactoring of consensus-critical code. Where a patch set proposes to change the Bittensor consensus, it must have been -discussed extensively on the mailing list and IRC, be accompanied by a widely +discussed extensively on the discord server and other channels, be accompanied by a widely discussed BIP and have a generally widely perceived technical consensus of being a worthwhile change based on the judgement of the maintainers.