From dc441afed2ca957d3ce2227cf12f0f34f5730648 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 11 Jul 2025 14:25:30 -0700 Subject: [PATCH 01/41] improve make file --- Makefile | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 154d6a1f2f..d68152d42d 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ -SHELL:=/bin/bash +SHELL := /bin/bash +.PHONY: init-venv clean-venv clean install install-dev reinstall reinstall-dev init-venv: python3 -m venv venv && source ./venv/bin/activate @@ -6,18 +7,20 @@ init-venv: clean-venv: source ./venv/bin/activate && \ pip freeze > make_venv_to_uninstall.txt && \ - pip uninstall -r make_venv_to_uninstall.txt && \ + pip uninstall -r make_venv_to_uninstall.txt -y && \ rm make_venv_to_uninstall.txt clean: - rm -rf dist/ && \ - rm -rf build/ && \ - rm -rf bittensor.egg-info/ && \ - rm -rf .pytest_cache/ && \ - rm -rf lib/ + rm -rf dist/ build/ bittensor.egg-info/ .pytest_cache/ lib/ -install: +install: init-venv + source ./venv/bin/activate && \ python3 -m pip install . -install-dev: - python3 -m pip install '.[dev]' +install-dev: init-venv + source ./venv/bin/activate && \ + python3 -m pip install -e '.[dev]' + +reinstall: clean clean-venv install + +reinstall-dev: clean clean-venv install-dev From 436b3bf45fedf5b8fa95e96b2ec255702b2969ac Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 15 Jul 2025 14:22:22 -0700 Subject: [PATCH 02/41] add ruff checker --- .github/workflows/ruff.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/ruff.yml diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml new file mode 100644 index 0000000000..7dfaf2eda5 --- /dev/null +++ b/.github/workflows/ruff.yml @@ -0,0 +1,33 @@ +name: Ruff - formatter check +permissions: + contents: read + +on: + pull_request: + types: [opened, synchronize, reopened, edited] + +jobs: + ruff: + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install Ruff in virtual environment + run: | + python -m venv venv + source venv/bin/activate + python -m pip install --upgrade pip + python -m pip install ruff==0.11.5 + + - name: Ruff format check + run: | + source venv/bin/activate + python -m ruff format --diff bittensor From 76da2ef27ec502c1d18fbdb4cd163cb8bd3fa006 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 15 Jul 2025 14:25:41 -0700 Subject: [PATCH 03/41] add flake8 and mypy checkers --- .github/workflows/flake8-and-mypy.yml | 56 +++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .github/workflows/flake8-and-mypy.yml diff --git a/.github/workflows/flake8-and-mypy.yml b/.github/workflows/flake8-and-mypy.yml new file mode 100644 index 0000000000..1fbe094728 --- /dev/null +++ b/.github/workflows/flake8-and-mypy.yml @@ -0,0 +1,56 @@ +name: Flake8 and Mypy - linters check +permissions: + contents: read + +on: + pull_request: + types: [opened, synchronize, reopened, edited] + +jobs: + linters: + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + + strategy: + fail-fast: false + max-parallel: 5 + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Cache venv + id: cache + uses: actions/cache@v4 + with: + path: venv + key: | + v3-${{ runner.os }}-${{ runner.arch }}-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }} + restore-keys: | + v3-${{ runner.os }}-${{ runner.arch }}-${{ matrix.python-version }}- + + - name: Install deps (flake8 + mypy + project.dev) + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + run: | + python -m venv venv + source venv/bin/activate + python -m pip install --upgrade pip + python -m pip install uv + python -m uv sync --extra dev --active + + - name: Flake8 + run: | + source venv/bin/activate + python -m flake8 bittensor/ --count + + - name: mypy + run: | + source venv/bin/activate + python -m mypy --ignore-missing-imports bittensor/ From 1b1301b70129fd4f523e5daaec7a216578bd9d1b Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 15 Jul 2025 14:25:52 -0700 Subject: [PATCH 04/41] add tests checkers --- .../workflows/unit-and-integration-tests.yml | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 .github/workflows/unit-and-integration-tests.yml diff --git a/.github/workflows/unit-and-integration-tests.yml b/.github/workflows/unit-and-integration-tests.yml new file mode 100644 index 0000000000..64f9404167 --- /dev/null +++ b/.github/workflows/unit-and-integration-tests.yml @@ -0,0 +1,53 @@ +name: Unit tests checker +permissions: + contents: read + +on: + pull_request: + types: [opened, synchronize, reopened, edited] + +jobs: + unit-tests: + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Cache venv + id: cache + uses: actions/cache@v4 + with: + path: venv + key: v2-${{ runner.os }}-${{ hashFiles('pyproject.toml') }} + + - name: Install deps + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + run: | + python -m venv venv + source venv/bin/activate + python -m pip install --upgrade pip + python -m pip install uv + python -m uv sync --extra dev --active + + - name: Unit tests + timeout-minutes: 20 + env: + PYTHONUNBUFFERED: "1" + run: | + source venv/bin/activate + python -m uv run pytest -n 2 tests/unit_tests/ --reruns 3 + + - name: Integration tests + timeout-minutes: 20 + env: + PYTHONUNBUFFERED: "1" + run: | + source venv/bin/activate + python -m uv run pytest -n 2 tests/integration_tests/ --reruns 3 From bf7caad66fa56fc4e151a8c9e86f870bc6dd11ca Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 15 Jul 2025 14:26:00 -0700 Subject: [PATCH 05/41] add compatibility checkers --- .github/workflows/compatibility.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/compatibility.yml diff --git a/.github/workflows/compatibility.yml b/.github/workflows/compatibility.yml new file mode 100644 index 0000000000..2ef9a1b95f --- /dev/null +++ b/.github/workflows/compatibility.yml @@ -0,0 +1,27 @@ +name: Requirements compatibility for supported Python versions +permissions: + contents: read + +on: + pull_request: + paths: + - "pyproject.toml" + +jobs: + compatibility: + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - run: | + python -m pip install --upgrade pip + python -m pip install ".[dev,cli]" --dry-run --no-deps From 3078d1970d6b95721a21ef9b42aa9c7b71688500 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 15 Jul 2025 14:26:17 -0700 Subject: [PATCH 06/41] add changelog checker --- .github/workflows/changelog-checker.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/changelog-checker.yml diff --git a/.github/workflows/changelog-checker.yml b/.github/workflows/changelog-checker.yml new file mode 100644 index 0000000000..9342a34344 --- /dev/null +++ b/.github/workflows/changelog-checker.yml @@ -0,0 +1,21 @@ +name: Changelog guard (for release of hotfix) +on: + pull_request: + branches: + - 'release/**' + - 'Release/**' + - 'hotfix/**' + - 'Hotfix/**' + +jobs: + changelog: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: tj-actions/changed-files@v42 + id: changed + - name: Ensure CHANGELOG.md updated + if: contains(steps.changed.outputs.all_changed_files, 'CHANGELOG.md') == false + uses: actions/github-script@v7 + with: + script: core.setFailed('CHANGELOG.md must be updated.') From 0688326b6c4a069940690419f6754e28c14a45e9 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 15 Jul 2025 14:27:42 -0700 Subject: [PATCH 07/41] temporarily comment on the ci workflow --- .circleci/config.yml | 607 ++++++++++++++++++++++--------------------- 1 file changed, 307 insertions(+), 300 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1c14c8730a..509936a34c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,300 +1,307 @@ -version: 2.1 - -orbs: - python: circleci/python@2.1.1 - python-lib: dialogue/python-lib@0.1.55 - -jobs: - check-if-pr-is-draft: - docker: - - image: cimg/python:3.10 - steps: - - checkout - - run: - name: Install jq - command: sudo apt-get update && sudo apt-get install -y jq - - run: - name: Check if PR is a draft - command: .circleci/check_pr_status.sh - - ruff: - resource_class: small - parameters: - python-version: - type: string - docker: - - image: cimg/python:<< parameters.python-version >> - - steps: - - checkout - - - restore_cache: - name: Restore cached ruff venv - keys: - - v2-pypi-py-ruff-<< parameters.python-version >> - - - run: - name: Update & Activate ruff venv - command: | - python -m venv .venv - . .venv/bin/activate - python -m pip install --upgrade uv - uv pip install ruff==0.11.5 - - - save_cache: - name: Save cached ruff venv - paths: - - ".venv/" - key: v2-pypi-py-ruff-<< parameters.python-version >> - - - run: - name: Ruff format check - command: | - . .venv/bin/activate - ruff format --diff . - - check_compatibility: - parameters: - python_version: - type: string - docker: - - 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 and Check compatibility - command: | - if [ "$REQUIREMENTS_CHANGED" == "true" ]; then - python -m pip install ".[dev,cli]" --dry-run --python-version << parameters.python_version >> --no-deps - else - echo "Skipping compatibility checks..." - fi - - build-and-test: - resource_class: medium - parallelism: 2 - parameters: - python-version: - type: string - docker: - - image: cimg/python:<< parameters.python-version >> - - steps: - - checkout - - - run: - name: Update & Activate venv - command: | - python -m venv .venv - . .venv/bin/activate - python -m pip install --upgrade uv - uv sync --extra dev --dev - - - run: - name: Install Bittensor - command: | - . .venv/bin/activate - uv sync --extra dev --dev - - - run: - name: Instantiate Mock Wallet - command: | - . .venv/bin/activate - ./scripts/create_wallet.sh - - - run: - name: Unit Tests - no_output_timeout: 20m - command: | - . .venv/bin/activate - export PYTHONUNBUFFERED=1 - pytest -n2 --reruns 3 --durations=0 --verbose --junitxml=test-results/unit_tests.xml \ - --cov=. --cov-append --cov-config .coveragerc \ - --splits $CIRCLE_NODE_TOTAL --group $((CIRCLE_NODE_INDEX + 1)) \ - --splitting-algorithm duration_based_chunks --store-durations --durations-path .test_durations \ - tests/unit_tests/ - - - run: - name: Integration Tests - no_output_timeout: 30m - command: | - . .venv/bin/activate - export PYTHONUNBUFFERED=1 - pytest -n2 --reruns 3 --reruns-delay 15 --durations=0 --verbose --junitxml=test-results/integration_tests.xml \ - --cov=. --cov-append --cov-config .coveragerc \ - --splits $CIRCLE_NODE_TOTAL --group $((CIRCLE_NODE_INDEX + 1)) \ - --splitting-algorithm duration_based_chunks --store-durations --durations-path .test_durations \ - tests/integration_tests/ - - - store_test_results: - path: test-results - - store_artifacts: - path: test-results - - - #- when: - #condition: - #equal: ["3.10.5", << parameters.python-version >> ] - #steps: - #- run: - #name: Upload Coverage - #command: | - #. .venv/bin/activate && coveralls - #env: - #CI_NAME: circleci - #CI_BUILD_NUMBER: $CIRCLE_BUILD_NUM - #CI_BUILD_URL: $CIRCLE_BUILD_URL - #CI_BRANCH: $CIRCLE_BRANCH - #CI_JOB_ID: $CIRCLE_NODE_INDEX - #COVERALLS_PARALLEL: true - - - lint-and-type-check: - resource_class: medium - parallelism: 2 - parameters: - python-version: - type: string - docker: - - image: cimg/python:<< parameters.python-version >> - - steps: - - checkout - - - run: - name: Update & Activate venv - command: | - python -m venv .venv - . .venv/bin/activate - python -m pip install --upgrade uv - uv sync --extra dev --dev - uv pip install flake8 - - - run: - name: Install Bittensor - command: | - . .venv/bin/activate - uv sync --extra dev --dev - - - run: - name: Lint with flake8 - command: | - . .venv/bin/activate - python -m flake8 bittensor/ --count - - - run: - name: Type check with mypy - command: | - . .venv/bin/activate - python -m mypy --ignore-missing-imports bittensor/ - - unit-tests-all-python-versions: - docker: - - image: cimg/python:3.10 - steps: - - run: - name: Placeholder command - command: echo "Success, only runs if all python versions ran" - - coveralls: - docker: - - image: cimg/python:3.10 - steps: - - run: - name: Combine Coverage - command: | - uv pip install --upgrade coveralls - coveralls --finish --rcfile .coveragerc || echo "Failed to upload coverage" - - check-changelog-updated: - docker: - - image: cimg/python:3.10 - steps: - - checkout - - run: - name: File CHANGELOG.md is updated - command: | - [[ $(git diff-tree --no-commit-id --name-only -r HEAD..master | grep CHANGELOG.md | wc -l) == 1 ]] && echo "CHANGELOG.md has changed" - - check-version-not-released: - docker: - - image: cimg/python:3.10 - steps: - - checkout - - run: - name: Git tag does not exist for the current version - command: | - [[ $(git tag | grep `cat VERSION` | wc -l) == 0 ]] && echo "VERSION is not a tag" - - run: - name: Pypi package 'bittensor' does not exist for the current version - command: | - [[ $(pip index versions bittensor | grep `cat VERSION` | wc -l) == 0 ]] && echo "Pypi package 'bittensor' does not exist" - - run: - name: Docker image 'opentensorfdn/bittensor' does not exist for the current version - command: | - [[ $(docker manifest inspect opentensorfdn/bittensor:`cat VERSION` > /dev/null 2> /dev/null ; echo $?) == 1 ]] && echo "Docker image 'opentensorfdn/bittensor:`cat VERSION`' does not exist in dockerhub" - -workflows: - compatibility_checks: - jobs: - - 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 - - check_compatibility: - python_version: "3.12" - name: check-compatibility-3.12 - - check_compatibility: - python_version: "3.13" - name: check-compatibility-3.13 - - - pr-requirements: - jobs: - - check-if-pr-is-draft - - ruff: - python-version: "3.9.13" - requires: - - check-if-pr-is-draft - - build-and-test: - matrix: - parameters: - python-version: [ "3.9.13", "3.10.6", "3.11.4", "3.12.7", "3.13.1" ] - requires: - - check-if-pr-is-draft - - unit-tests-all-python-versions: - requires: - - build-and-test - - lint-and-type-check: - matrix: - parameters: - python-version: [ "3.9.13", "3.10.6", "3.11.4", "3.12.7", "3.13.1" ] - requires: - - check-if-pr-is-draft - #- coveralls: - #requires: - #- build-and-test - - release-branches-requirements: - jobs: - - check-changelog-updated: - filters: - branches: - only: - - /^(release|hotfix)/.*/ - - release-requirements: - jobs: - - check-version-not-released: - filters: - branches: - only: - - master +#version: 2.1 +# +#orbs: +# python: circleci/python@2.1.1 +# python-lib: dialogue/python-lib@0.1.55 +# +#jobs: +# check-if-pr-is-draft: +# docker: +# - image: cimg/python:3.10 +# steps: +# - checkout +# - run: +# name: Install jq +# command: sudo apt-get update && sudo apt-get install -y jq +# - run: +# name: Check if PR is a draft +# command: .circleci/check_pr_status.sh +# +# ruff: +# resource_class: small +# parameters: +# python-version: +# type: string +# docker: +# - image: cimg/python:<< parameters.python-version >> +# +# steps: +# - checkout +# +# - restore_cache: +# name: Restore cached ruff venv +# keys: +# - v2-pypi-py-ruff-<< parameters.python-version >> +# +# - run: +# name: Update & Activate ruff venv +# command: | +# python -m venv .venv +# . .venv/bin/activate +# python -m pip install --upgrade uv +# uv pip install ruff==0.11.5 +# +# - save_cache: +# name: Save cached ruff venv +# paths: +# - ".venv/" +# key: v2-pypi-py-ruff-<< parameters.python-version >> +# +# - run: +# name: Ruff format check +# command: | +# . .venv/bin/activate +# ruff format --diff . +# +# +# check_compatibility: +# parameters: +# python_version: +# type: string +# docker: +# - 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 and Check compatibility +# command: | +# if [ "$REQUIREMENTS_CHANGED" == "true" ]; then +# python -m pip install ".[dev,cli]" --dry-run --python-version << parameters.python_version >> --no-deps +# else +# echo "Skipping compatibility checks..." +# fi +# +# +# build-and-test: +# resource_class: medium +# parallelism: 2 +# parameters: +# python-version: +# type: string +# docker: +# - image: cimg/python:<< parameters.python-version >> +# +# steps: +# - checkout +# +# - run: +# name: Update & Activate venv +# command: | +# python -m venv .venv +# . .venv/bin/activate +# python -m pip install --upgrade uv +# uv sync --extra dev --dev +# +# - run: +# name: Install Bittensor +# command: | +# . .venv/bin/activate +# uv sync --extra dev --dev +# +# - run: +# name: Instantiate Mock Wallet +# command: | +# . .venv/bin/activate +# ./scripts/create_wallet.sh +# +# - run: +# name: Unit Tests +# no_output_timeout: 20m +# command: | +# . .venv/bin/activate +# export PYTHONUNBUFFERED=1 +# pytest -n2 --reruns 3 --durations=0 --verbose --junitxml=test-results/unit_tests.xml \ +# --cov=. --cov-append --cov-config .coveragerc \ +# --splits $CIRCLE_NODE_TOTAL --group $((CIRCLE_NODE_INDEX + 1)) \ +# --splitting-algorithm duration_based_chunks --store-durations --durations-path .test_durations \ +# tests/unit_tests/ +# +# - run: +# name: Integration Tests +# no_output_timeout: 30m +# command: | +# . .venv/bin/activate +# export PYTHONUNBUFFERED=1 +# pytest -n2 --reruns 3 --reruns-delay 15 --durations=0 --verbose --junitxml=test-results/integration_tests.xml \ +# --cov=. --cov-append --cov-config .coveragerc \ +# --splits $CIRCLE_NODE_TOTAL --group $((CIRCLE_NODE_INDEX + 1)) \ +# --splitting-algorithm duration_based_chunks --store-durations --durations-path .test_durations \ +# tests/integration_tests/ +# +# - store_test_results: +# path: test-results +# - store_artifacts: +# path: test-results +# +# +# #- when: +# #condition: +# #equal: ["3.10.5", << parameters.python-version >> ] +# #steps: +# #- run: +# #name: Upload Coverage +# #command: | +# #. .venv/bin/activate && coveralls +# #env: +# #CI_NAME: circleci +# #CI_BUILD_NUMBER: $CIRCLE_BUILD_NUM +# #CI_BUILD_URL: $CIRCLE_BUILD_URL +# #CI_BRANCH: $CIRCLE_BRANCH +# #CI_JOB_ID: $CIRCLE_NODE_INDEX +# #COVERALLS_PARALLEL: true +# +# lint-and-type-check: +# resource_class: medium +# parallelism: 2 +# parameters: +# python-version: +# type: string +# docker: +# - image: cimg/python:<< parameters.python-version >> +# +# steps: +# - checkout +# +# - run: +# name: Update & Activate venv +# command: | +# python -m venv .venv +# . .venv/bin/activate +# python -m pip install --upgrade uv +# uv sync --extra dev --dev +# uv pip install flake8 +# +# - run: +# name: Install Bittensor +# command: | +# . .venv/bin/activate +# uv sync --extra dev --dev +# +# - run: +# name: Lint with flake8 +# command: | +# . .venv/bin/activate +# python -m flake8 bittensor/ --count +# +# - run: +# name: Type check with mypy +# command: | +# . .venv/bin/activate +# python -m mypy --ignore-missing-imports bittensor/ +# +# +# unit-tests-all-python-versions: +# docker: +# - image: cimg/python:3.10 +# steps: +# - run: +# name: Placeholder command +# command: echo "Success, only runs if all python versions ran" +# +# coveralls: +# docker: +# - image: cimg/python:3.10 +# steps: +# - run: +# name: Combine Coverage +# command: | +# uv pip install --upgrade coveralls +# coveralls --finish --rcfile .coveragerc || echo "Failed to upload coverage" +# +# +# +# check-changelog-updated: +# docker: +# - image: cimg/python:3.10 +# steps: +# - checkout +# - run: +# name: File CHANGELOG.md is updated +# command: | +# [[ $(git diff-tree --no-commit-id --name-only -r HEAD..master | grep CHANGELOG.md | wc -l) == 1 ]] && echo "CHANGELOG.md has changed" +# +# +# +# check-version-not-released: +# docker: +# - image: cimg/python:3.10 +# steps: +# - checkout +# - run: +# name: Git tag does not exist for the current version +# command: | +# [[ $(git tag | grep `cat VERSION` | wc -l) == 0 ]] && echo "VERSION is not a tag" +# - run: +# name: Pypi package 'bittensor' does not exist for the current version +# command: | +# [[ $(pip index versions bittensor | grep `cat VERSION` | wc -l) == 0 ]] && echo "Pypi package 'bittensor' does not exist" +# - run: +# name: Docker image 'opentensorfdn/bittensor' does not exist for the current version +# command: | +# [[ $(docker manifest inspect opentensorfdn/bittensor:`cat VERSION` > /dev/null 2> /dev/null ; echo $?) == 1 ]] && echo "Docker image 'opentensorfdn/bittensor:`cat VERSION`' does not exist in dockerhub" +# +# +#workflows: +# compatibility_checks: +# jobs: +# - 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 +# - check_compatibility: +# python_version: "3.12" +# name: check-compatibility-3.12 +# - check_compatibility: +# python_version: "3.13" +# name: check-compatibility-3.13 +# +# +# pr-requirements: +# jobs: +# - check-if-pr-is-draft +# - ruff: +# python-version: "3.9.13" +# requires: +# - check-if-pr-is-draft +# - build-and-test: +# matrix: +# parameters: +# python-version: [ "3.9.13", "3.10.6", "3.11.4", "3.12.7", "3.13.1" ] +# requires: +# - check-if-pr-is-draft +# - unit-tests-all-python-versions: +# requires: +# - build-and-test +# - lint-and-type-check: +# matrix: +# parameters: +# python-version: [ "3.9.13", "3.10.6", "3.11.4", "3.12.7", "3.13.1" ] +# requires: +# - check-if-pr-is-draft +# #- coveralls: +# #requires: +# #- build-and-test +# +# release-branches-requirements: +# jobs: +# - check-changelog-updated: +# filters: +# branches: +# only: +# - /^(release|hotfix)/.*/ +# +# release-requirements: +# jobs: +# - check-version-not-released: +# filters: +# branches: +# only: +# - master From 4a8a9472c8125b8a4cb405f3547a48bff210a371 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 15 Jul 2025 14:30:29 -0700 Subject: [PATCH 08/41] add permissions and delete CI workflow --- .circleci/check_pr_status.sh | 26 -- .circleci/config.yml | 307 ------------------------ .github/workflows/changelog-checker.yml | 4 + 3 files changed, 4 insertions(+), 333 deletions(-) delete mode 100755 .circleci/check_pr_status.sh delete mode 100644 .circleci/config.yml diff --git a/.circleci/check_pr_status.sh b/.circleci/check_pr_status.sh deleted file mode 100755 index 4b31a29698..0000000000 --- a/.circleci/check_pr_status.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -# Extract the repository owner -REPO_OWNER=$(echo $CIRCLE_PULL_REQUEST | awk -F'/' '{print $(NF-3)}') - -# Extract the repository name -REPO_NAME=$(echo $CIRCLE_PULL_REQUEST | awk -F'/' '{print $(NF-2)}') - -# Extract the pull request number -PR_NUMBER=$(echo $CIRCLE_PULL_REQUEST | awk -F'/' '{print $NF}') - - -PR_DETAILS=$(curl -s \ - "https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/pulls/$PR_NUMBER") - - -IS_DRAFT=$(echo "$PR_DETAILS" | jq -r .draft) -echo $IS_DRAFT - -if [ "$IS_DRAFT" == "true" ]; then - echo "This PR is a draft. Skipping the workflow." - exit 1 -else - echo "This PR is not a draft. Proceeding with the workflow." - exit 0 -fi diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 509936a34c..0000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,307 +0,0 @@ -#version: 2.1 -# -#orbs: -# python: circleci/python@2.1.1 -# python-lib: dialogue/python-lib@0.1.55 -# -#jobs: -# check-if-pr-is-draft: -# docker: -# - image: cimg/python:3.10 -# steps: -# - checkout -# - run: -# name: Install jq -# command: sudo apt-get update && sudo apt-get install -y jq -# - run: -# name: Check if PR is a draft -# command: .circleci/check_pr_status.sh -# -# ruff: -# resource_class: small -# parameters: -# python-version: -# type: string -# docker: -# - image: cimg/python:<< parameters.python-version >> -# -# steps: -# - checkout -# -# - restore_cache: -# name: Restore cached ruff venv -# keys: -# - v2-pypi-py-ruff-<< parameters.python-version >> -# -# - run: -# name: Update & Activate ruff venv -# command: | -# python -m venv .venv -# . .venv/bin/activate -# python -m pip install --upgrade uv -# uv pip install ruff==0.11.5 -# -# - save_cache: -# name: Save cached ruff venv -# paths: -# - ".venv/" -# key: v2-pypi-py-ruff-<< parameters.python-version >> -# -# - run: -# name: Ruff format check -# command: | -# . .venv/bin/activate -# ruff format --diff . -# -# -# check_compatibility: -# parameters: -# python_version: -# type: string -# docker: -# - 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 and Check compatibility -# command: | -# if [ "$REQUIREMENTS_CHANGED" == "true" ]; then -# python -m pip install ".[dev,cli]" --dry-run --python-version << parameters.python_version >> --no-deps -# else -# echo "Skipping compatibility checks..." -# fi -# -# -# build-and-test: -# resource_class: medium -# parallelism: 2 -# parameters: -# python-version: -# type: string -# docker: -# - image: cimg/python:<< parameters.python-version >> -# -# steps: -# - checkout -# -# - run: -# name: Update & Activate venv -# command: | -# python -m venv .venv -# . .venv/bin/activate -# python -m pip install --upgrade uv -# uv sync --extra dev --dev -# -# - run: -# name: Install Bittensor -# command: | -# . .venv/bin/activate -# uv sync --extra dev --dev -# -# - run: -# name: Instantiate Mock Wallet -# command: | -# . .venv/bin/activate -# ./scripts/create_wallet.sh -# -# - run: -# name: Unit Tests -# no_output_timeout: 20m -# command: | -# . .venv/bin/activate -# export PYTHONUNBUFFERED=1 -# pytest -n2 --reruns 3 --durations=0 --verbose --junitxml=test-results/unit_tests.xml \ -# --cov=. --cov-append --cov-config .coveragerc \ -# --splits $CIRCLE_NODE_TOTAL --group $((CIRCLE_NODE_INDEX + 1)) \ -# --splitting-algorithm duration_based_chunks --store-durations --durations-path .test_durations \ -# tests/unit_tests/ -# -# - run: -# name: Integration Tests -# no_output_timeout: 30m -# command: | -# . .venv/bin/activate -# export PYTHONUNBUFFERED=1 -# pytest -n2 --reruns 3 --reruns-delay 15 --durations=0 --verbose --junitxml=test-results/integration_tests.xml \ -# --cov=. --cov-append --cov-config .coveragerc \ -# --splits $CIRCLE_NODE_TOTAL --group $((CIRCLE_NODE_INDEX + 1)) \ -# --splitting-algorithm duration_based_chunks --store-durations --durations-path .test_durations \ -# tests/integration_tests/ -# -# - store_test_results: -# path: test-results -# - store_artifacts: -# path: test-results -# -# -# #- when: -# #condition: -# #equal: ["3.10.5", << parameters.python-version >> ] -# #steps: -# #- run: -# #name: Upload Coverage -# #command: | -# #. .venv/bin/activate && coveralls -# #env: -# #CI_NAME: circleci -# #CI_BUILD_NUMBER: $CIRCLE_BUILD_NUM -# #CI_BUILD_URL: $CIRCLE_BUILD_URL -# #CI_BRANCH: $CIRCLE_BRANCH -# #CI_JOB_ID: $CIRCLE_NODE_INDEX -# #COVERALLS_PARALLEL: true -# -# lint-and-type-check: -# resource_class: medium -# parallelism: 2 -# parameters: -# python-version: -# type: string -# docker: -# - image: cimg/python:<< parameters.python-version >> -# -# steps: -# - checkout -# -# - run: -# name: Update & Activate venv -# command: | -# python -m venv .venv -# . .venv/bin/activate -# python -m pip install --upgrade uv -# uv sync --extra dev --dev -# uv pip install flake8 -# -# - run: -# name: Install Bittensor -# command: | -# . .venv/bin/activate -# uv sync --extra dev --dev -# -# - run: -# name: Lint with flake8 -# command: | -# . .venv/bin/activate -# python -m flake8 bittensor/ --count -# -# - run: -# name: Type check with mypy -# command: | -# . .venv/bin/activate -# python -m mypy --ignore-missing-imports bittensor/ -# -# -# unit-tests-all-python-versions: -# docker: -# - image: cimg/python:3.10 -# steps: -# - run: -# name: Placeholder command -# command: echo "Success, only runs if all python versions ran" -# -# coveralls: -# docker: -# - image: cimg/python:3.10 -# steps: -# - run: -# name: Combine Coverage -# command: | -# uv pip install --upgrade coveralls -# coveralls --finish --rcfile .coveragerc || echo "Failed to upload coverage" -# -# -# -# check-changelog-updated: -# docker: -# - image: cimg/python:3.10 -# steps: -# - checkout -# - run: -# name: File CHANGELOG.md is updated -# command: | -# [[ $(git diff-tree --no-commit-id --name-only -r HEAD..master | grep CHANGELOG.md | wc -l) == 1 ]] && echo "CHANGELOG.md has changed" -# -# -# -# check-version-not-released: -# docker: -# - image: cimg/python:3.10 -# steps: -# - checkout -# - run: -# name: Git tag does not exist for the current version -# command: | -# [[ $(git tag | grep `cat VERSION` | wc -l) == 0 ]] && echo "VERSION is not a tag" -# - run: -# name: Pypi package 'bittensor' does not exist for the current version -# command: | -# [[ $(pip index versions bittensor | grep `cat VERSION` | wc -l) == 0 ]] && echo "Pypi package 'bittensor' does not exist" -# - run: -# name: Docker image 'opentensorfdn/bittensor' does not exist for the current version -# command: | -# [[ $(docker manifest inspect opentensorfdn/bittensor:`cat VERSION` > /dev/null 2> /dev/null ; echo $?) == 1 ]] && echo "Docker image 'opentensorfdn/bittensor:`cat VERSION`' does not exist in dockerhub" -# -# -#workflows: -# compatibility_checks: -# jobs: -# - 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 -# - check_compatibility: -# python_version: "3.12" -# name: check-compatibility-3.12 -# - check_compatibility: -# python_version: "3.13" -# name: check-compatibility-3.13 -# -# -# pr-requirements: -# jobs: -# - check-if-pr-is-draft -# - ruff: -# python-version: "3.9.13" -# requires: -# - check-if-pr-is-draft -# - build-and-test: -# matrix: -# parameters: -# python-version: [ "3.9.13", "3.10.6", "3.11.4", "3.12.7", "3.13.1" ] -# requires: -# - check-if-pr-is-draft -# - unit-tests-all-python-versions: -# requires: -# - build-and-test -# - lint-and-type-check: -# matrix: -# parameters: -# python-version: [ "3.9.13", "3.10.6", "3.11.4", "3.12.7", "3.13.1" ] -# requires: -# - check-if-pr-is-draft -# #- coveralls: -# #requires: -# #- build-and-test -# -# release-branches-requirements: -# jobs: -# - check-changelog-updated: -# filters: -# branches: -# only: -# - /^(release|hotfix)/.*/ -# -# release-requirements: -# jobs: -# - check-version-not-released: -# filters: -# branches: -# only: -# - master diff --git a/.github/workflows/changelog-checker.yml b/.github/workflows/changelog-checker.yml index 9342a34344..7407e21607 100644 --- a/.github/workflows/changelog-checker.yml +++ b/.github/workflows/changelog-checker.yml @@ -1,4 +1,8 @@ name: Changelog guard (for release of hotfix) + +permissions: + contents: read + on: pull_request: branches: From 47ea90e0fa48e97724b7aef38a24657bc6e14810 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 15 Jul 2025 14:34:56 -0700 Subject: [PATCH 09/41] remove deprecated workflow --- .github/workflows/auto-assign.yml | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 .github/workflows/auto-assign.yml diff --git a/.github/workflows/auto-assign.yml b/.github/workflows/auto-assign.yml deleted file mode 100644 index 3a952f91b8..0000000000 --- a/.github/workflows/auto-assign.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: Auto Assign Cortex to Pull Requests - -on: - pull_request: - types: [opened, reopened] - -jobs: - auto-assign: - runs-on: ubuntu-latest - steps: - - name: Auto-assign Cortex Team - uses: kentaro-m/auto-assign-action@v1.2.4 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" - configuration-path: .github/auto_assign.yml \ No newline at end of file From 0ea23382405699fe5588cad0735408f0cb1478ef Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 15 Jul 2025 14:41:09 -0700 Subject: [PATCH 10/41] rename job --- .github/workflows/unit-and-integration-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-and-integration-tests.yml b/.github/workflows/unit-and-integration-tests.yml index 64f9404167..b74e9bd36e 100644 --- a/.github/workflows/unit-and-integration-tests.yml +++ b/.github/workflows/unit-and-integration-tests.yml @@ -7,7 +7,7 @@ on: types: [opened, synchronize, reopened, edited] jobs: - unit-tests: + tests: if: github.event.pull_request.draft == false runs-on: ubuntu-latest From c5c3cad6054c578ba7535575e64e937cb51c0651 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 15 Jul 2025 14:44:01 -0700 Subject: [PATCH 11/41] rename and add matrix --- .github/workflows/unit-and-integration-tests.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/unit-and-integration-tests.yml b/.github/workflows/unit-and-integration-tests.yml index b74e9bd36e..206aaa6842 100644 --- a/.github/workflows/unit-and-integration-tests.yml +++ b/.github/workflows/unit-and-integration-tests.yml @@ -7,10 +7,16 @@ on: types: [opened, synchronize, reopened, edited] jobs: - tests: + unit-and-integration-tests: if: github.event.pull_request.draft == false runs-on: ubuntu-latest + strategy: + fail-fast: false + max-parallel: 5 + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + steps: - name: Checkout repository uses: actions/checkout@v4 From ad517e739e1c5585ee1188dd9a13ee7e2abe72cb Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 15 Jul 2025 14:59:02 -0700 Subject: [PATCH 12/41] update workflow name --- .github/workflows/unit-and-integration-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-and-integration-tests.yml b/.github/workflows/unit-and-integration-tests.yml index 206aaa6842..7bc70ae030 100644 --- a/.github/workflows/unit-and-integration-tests.yml +++ b/.github/workflows/unit-and-integration-tests.yml @@ -1,4 +1,4 @@ -name: Unit tests checker +name: Unit and integration tests checker permissions: contents: read From 619110112757c5d4f2d337c0012f7d15e4e97afc Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 15 Jul 2025 17:02:18 -0700 Subject: [PATCH 13/41] improve changelog workflow --- .github/workflows/changelog-checker.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/changelog-checker.yml b/.github/workflows/changelog-checker.yml index 7407e21607..8c8de24a0d 100644 --- a/.github/workflows/changelog-checker.yml +++ b/.github/workflows/changelog-checker.yml @@ -6,13 +6,12 @@ permissions: on: pull_request: branches: - - 'release/**' - - 'Release/**' - - 'hotfix/**' - - 'Hotfix/**' + - staging + - master jobs: changelog: + if: startsWith(github.head_ref, 'release/') || startsWith(github.head_ref, 'hotfix/') runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From 6784b85f46eb6b20a50ba3cd1d0e67026ffa6c7c Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 16 Jul 2025 12:37:58 -0700 Subject: [PATCH 14/41] add `LOCALNET_IMAGE_NAME` local env variable --- tests/e2e_tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/conftest.py b/tests/e2e_tests/conftest.py index 863e9c3210..c79446be26 100644 --- a/tests/e2e_tests/conftest.py +++ b/tests/e2e_tests/conftest.py @@ -18,7 +18,7 @@ setup_wallet, ) -LOCALNET_IMAGE_NAME = "ghcr.io/opentensor/subtensor-localnet:devnet-ready" +LOCALNET_IMAGE_NAME = os.getenv("LOCALNET_IMAGE_NAME") or "ghcr.io/opentensor/subtensor-localnet:devnet-ready" CONTAINER_NAME_PREFIX = "test_local_chain_" From dc489207d13d7797d6aa896d53f0ee070f74ccb1 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 16 Jul 2025 12:38:15 -0700 Subject: [PATCH 15/41] add nightly tests --- .../nightly-e2e-tests-subtensor-main.yml | 358 ++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 .github/workflows/nightly-e2e-tests-subtensor-main.yml diff --git a/.github/workflows/nightly-e2e-tests-subtensor-main.yml b/.github/workflows/nightly-e2e-tests-subtensor-main.yml new file mode 100644 index 0000000000..bf5cfba0eb --- /dev/null +++ b/.github/workflows/nightly-e2e-tests-subtensor-main.yml @@ -0,0 +1,358 @@ +name: Nightly E2E Subtensor tests (main) + +concurrency: + group: e2e-subtensor-${{ github.ref }} + cancel-in-progress: true + +on: + schedule: + - cron: '0 9 * * *' # Run every night at 2:00 PST + + workflow_dispatch: + inputs: + verbose: + description: "Output more information when triggered manually" + required: false + default: "" + +env: + CARGO_TERM_COLOR: always + VERBOSE: ${{ github.event.inputs.verbose }} + +# job to run tests in parallel +jobs: + # Looking for e2e tests + find-tests: + runs-on: ubuntu-latest + if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} + outputs: + test-files: ${{ steps.get-tests.outputs.test-files }} + steps: + - name: Check-out repository under $GITHUB_WORKSPACE + uses: actions/checkout@v4 + + - name: Find test files + id: get-tests + run: | + test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') + # keep it here for future debug + # test_files=$(find tests/e2e_tests -type f -name "test*.py" | grep -E 'test_(hotkeys|staking)\.py$' | jq -R -s -c 'split("\n") | map(select(. != ""))') + echo "test-files=$test_files" >> "$GITHUB_OUTPUT" + shell: bash + # Pull docker images (devnet-ready and main) + pull-docker-images: + runs-on: ubuntu-latest + steps: + - name: Log in to GitHub Container Registry + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin + + - name: Pull Docker Image + run: | + docker pull ghcr.io/opentensor/subtensor-localnet:main + docker pull ghcr.io/opentensor/subtensor-localnet:devnet-ready + + - name: List pulled images + run: docker images + + - name: Save Docker Images to Cache + run: | + docker save -o subtensor-localnet-main.tar ghcr.io/opentensor/subtensor-localnet:main + docker save -o subtensor-localnet-devnet-ready.tar ghcr.io/opentensor/subtensor-localnet:devnet-ready + + - name: Upload main Docker Image as Artifact + uses: actions/upload-artifact@v4 + with: + name: subtensor-localnet-main + path: subtensor-localnet-main.tar + + - name: Upload devnet-ready Docker Image as Artifact + uses: actions/upload-artifact@v4 + with: + name: subtensor-localnet-devnet-ready + path: subtensor-localnet-devnet-ready.tar + # Determine the day for non-fast-blocks run + check-if-saturday: + runs-on: ubuntu-latest + outputs: + is-saturday: ${{ steps.check.outputs.is-saturday }} + steps: + - id: check + run: | + day=$(date -u +%u) + echo "Today is weekday $day" + if [ "$day" -ne 6 ]; then + echo "โญ๏ธ Skipping: not Saturday" + echo "is-saturday=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + echo "is-saturday=true" + echo "is-saturday=true" >> "$GITHUB_OUTPUT" + + # Daily run of fast-blocks tests from `bittensor:master` based on `subtensor:main docker` image + run-fast-blocks-e2e-test-master: + name: "FB master: ${{ matrix.test-file }} / Python ${{ matrix.python-version }}" + needs: + - find-tests + - pull-docker-images + runs-on: ubuntu-latest + timeout-minutes: 25 + strategy: + fail-fast: false # Allow other matrix jobs to run even if this job fails + max-parallel: 32 # Set the maximum number of parallel jobs (same as we have cores in ubuntu-latest runner) + matrix: + os: + - ubuntu-latest + test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + steps: + - name: Check-out repository + uses: actions/checkout@v4 + with: + ref: master + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install uv + uses: astral-sh/setup-uv@v4 + + - name: install dependencies + run: uv sync --extra dev --dev + + - name: Download Cached Docker Image + uses: actions/download-artifact@v4 + with: + name: subtensor-localnet-main + + - name: Load Docker Image + run: docker load -i subtensor-localnet-main.tar + + - name: Run tests with retry + env: + FAST_BLOCKS: "1" + LOCALNET_IMAGE_NAME: "ghcr.io/opentensor/subtensor-localnet:main" + run: | + set +e + for i in 1 2 3; do + echo "๐Ÿ” Attempt $i: Running tests" + uv run pytest ${{ matrix.test-file }} -s + status=$? + if [ $status -eq 0 ]; then + echo "โœ… Tests passed on attempt $i" + break + else + echo "โŒ Tests failed on attempt $i" + if [ $i -eq 3 ]; then + echo "Tests failed after 3 attempts" + exit 1 + fi + echo "Retrying..." + sleep 5 + fi + done + + # Daily run of fast-blocks tests from `bittensor:staging` based on `subtensor:devnet-ready` docker image + run-fast-blocks-e2e-test-staging: + name: "FB staging: ${{ matrix.test-file }} / Python ${{ matrix.python-version }}" + needs: + - find-tests + - pull-docker-images + runs-on: ubuntu-latest + timeout-minutes: 25 + strategy: + fail-fast: false # Allow other matrix jobs to run even if this job fails + max-parallel: 32 # Set the maximum number of parallel jobs (same as we have cores in ubuntu-latest runner) + matrix: + os: + - ubuntu-latest + test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + steps: + - name: Check-out repository + uses: actions/checkout@v4 + with: + ref: staging + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install uv + uses: astral-sh/setup-uv@v4 + + - name: install dependencies + run: uv sync --extra dev --dev + + - name: Download Cached Docker Image + uses: actions/download-artifact@v4 + with: + name: subtensor-localnet-devnet-ready + + - name: Load Docker Image + run: docker load -i subtensor-localnet-devnet-ready.tar + + - name: Run tests with retry + env: + FAST_BLOCKS: "1" + LOCALNET_IMAGE_NAME: "ghcr.io/opentensor/subtensor-localnet:devnet-ready" + run: | + set +e + for i in 1 2 3; do + echo "๐Ÿ” Attempt $i: Running tests" + uv run pytest ${{ matrix.test-file }} -s + status=$? + if [ $status -eq 0 ]; then + echo "โœ… Tests passed on attempt $i" + break + else + echo "โŒ Tests failed on attempt $i" + if [ $i -eq 3 ]; then + echo "Tests failed after 3 attempts" + exit 1 + fi + echo "Retrying..." + sleep 5 + fi + done + + # Saturday run of non-fast-blocks tests from `bittensor:master` based on `subtensor:main` docker image + run-non-fast-blocks-e2e-test-master: + if: needs.check-if-saturday.outputs.is-saturday == 'true' + name: "NFB master: ${{ matrix.test-file }} / Python ${{ matrix.python-version }}" + needs: + - check-if-saturday + - find-tests + - pull-docker-images + runs-on: ubuntu-latest + timeout-minutes: 1440 + + strategy: + fail-fast: false # Allow other matrix jobs to run even if this job fails + max-parallel: 32 # Set the maximum number of parallel jobs (same as we have cores in ubuntu-latest runner) + matrix: + os: + - ubuntu-latest + test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + + steps: + - name: Check-out repository + uses: actions/checkout@v4 + with: + ref: master + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install uv + uses: astral-sh/setup-uv@v4 + + - name: install dependencies + run: uv sync --extra dev --dev + + - name: Download Cached Docker Image + uses: actions/download-artifact@v4 + with: + name: subtensor-localnet-main + + - name: Load Docker Image + run: docker load -i subtensor-localnet-main.tar + + - name: Run patched E2E tests + env: + FAST_BLOCKS: "0" + LOCALNET_IMAGE_NAME: "ghcr.io/opentensor/subtensor-localnet:main" + run: | + set +e + for i in 1 2 3; do + echo "๐Ÿ” Attempt $i: Running tests" + uv run pytest ${{ matrix.test-file }} -s + status=$? + if [ $status -eq 0 ]; then + echo "โœ… Tests passed on attempt $i" + break + else + echo "โŒ Tests failed on attempt $i" + if [ $i -eq 3 ]; then + echo "Tests failed after 3 attempts" + exit 1 + fi + echo "Retrying..." + sleep 5 + fi + done + + # Saturday run of non-fast-blocks tests from `bittensor:staging` based on `subtensor:devnet-ready` docker image + run-non-fast-blocks-e2e-test-staging: + if: needs.check-if-saturday.outputs.is-saturday == 'true' + name: "NFB staging: ${{ matrix.test-file }} / Python ${{ matrix.python-version }}" + needs: + - check-if-saturday + - find-tests + - pull-docker-images + runs-on: ubuntu-latest + timeout-minutes: 1440 + + strategy: + fail-fast: false # Allow other matrix jobs to run even if this job fails + max-parallel: 32 # Set the maximum number of parallel jobs (same as we have cores in ubuntu-latest runner) + matrix: + os: + - ubuntu-latest + test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + + steps: + - name: Check-out repository + uses: actions/checkout@v4 + with: + ref: staging + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install uv + uses: astral-sh/setup-uv@v4 + + - name: install dependencies + run: uv sync --extra dev --dev + + - name: Download Cached Docker Image + uses: actions/download-artifact@v4 + with: + name: subtensor-localnet-devnet-ready + + - name: Load Docker Image + run: docker load -i subtensor-localnet-devnet-ready.tar + + - name: Run patched E2E tests + env: + FAST_BLOCKS: "0" + LOCALNET_IMAGE_NAME: "ghcr.io/opentensor/subtensor-localnet:devnet-ready" + run: | + set +e + for i in 1 2 3; do + echo "๐Ÿ” Attempt $i: Running tests" + uv run pytest ${{ matrix.test-file }} -s + status=$? + if [ $status -eq 0 ]; then + echo "โœ… Tests passed on attempt $i" + break + else + echo "โŒ Tests failed on attempt $i" + if [ $i -eq 3 ]; then + echo "Tests failed after 3 attempts" + exit 1 + fi + echo "Retrying..." + sleep 5 + fi + done + From 07952fcf4512d07e3f82d64df49646f446a2edbc Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 16 Jul 2025 12:38:36 -0700 Subject: [PATCH 16/41] cleanup and improve regular e2e tests workflow --- .github/workflows/e2e-subtensor-tests.yaml | 118 ++++----------------- 1 file changed, 23 insertions(+), 95 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 364b96698b..7c8fcc017b 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -6,15 +6,12 @@ concurrency: on: push: - branches: [master, development, staging] + branches: * pull_request: - branches: [master, development, staging] + branches: * types: [ opened, synchronize, reopened, ready_for_review ] - schedule: - - cron: '0 9 * * *' # Run every night at 2:00 PST - workflow_dispatch: inputs: verbose: @@ -28,7 +25,7 @@ env: # job to run tests in parallel jobs: - + # Looking for e2e tests find-tests: runs-on: ubuntu-latest if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} @@ -44,20 +41,36 @@ jobs: test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') # keep it here for future debug # test_files=$(find tests/e2e_tests -type f -name "test*.py" | grep -E 'test_(hotkeys|staking)\.py$' | jq -R -s -c 'split("\n") | map(select(. != ""))') + echo "Found test files: $test_files" echo "test-files=$test_files" >> "$GITHUB_OUTPUT" shell: bash + # Pull docker image pull-docker-image: runs-on: ubuntu-latest + outputs: + image-name: ${{ steps.set-output.outputs.image-name }} steps: + - name: Set Docker image tag based on branch + id: set-output + run: | + ref="${{ github.ref_name }}" + if [[ "$ref" == "master" ]]; then + image="ghcr.io/opentensor/subtensor-localnet:main" + else + image="ghcr.io/opentensor/subtensor-localnet:devnet-ready" + fi + echo "Using image: $image" + echo "image-name=$image" >> "$GITHUB_OUTPUT" + - name: Log in to GitHub Container Registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin - name: Pull Docker Image - run: docker pull ghcr.io/opentensor/subtensor-localnet:devnet-ready + run: docker pull ${{ steps.set-output.outputs.image-name }} - name: Save Docker Image to Cache - run: docker save -o subtensor-localnet.tar ghcr.io/opentensor/subtensor-localnet:devnet-ready + run: docker save -o subtensor-localnet.tar ${{ steps.set-output.outputs.image-name }} - name: Upload Docker Image as Artifact uses: actions/upload-artifact@v4 @@ -104,95 +117,9 @@ jobs: - name: Load Docker Image run: docker load -i subtensor-localnet.tar -# - name: Run tests -# run: uv run pytest ${{ matrix.test-file }} -s - - name: Run tests with retry - run: | - set +e - for i in 1 2 3; do - echo "๐Ÿ” Attempt $i: Running tests" - uv run pytest ${{ matrix.test-file }} -s - status=$? - if [ $status -eq 0 ]; then - echo "โœ… Tests passed on attempt $i" - break - else - echo "โŒ Tests failed on attempt $i" - if [ $i -eq 3 ]; then - echo "Tests failed after 3 attempts" - exit 1 - fi - echo "Retrying..." - sleep 5 - fi - done - - # run non-fast-blocks only on Saturday and by cron schedule - check-if-saturday: - if: github.event_name == 'schedule' - runs-on: ubuntu-latest - outputs: - is-saturday: ${{ steps.check.outputs.is-saturday }} - steps: - - id: check - run: | - day=$(date -u +%u) - echo "Today is weekday $day" - if [ "$day" -ne 6 ]; then - echo "โญ๏ธ Skipping: not Saturday" - echo "is-saturday=false" >> "$GITHUB_OUTPUT" - exit 0 - fi - echo "is-saturday=true" - echo "is-saturday=true" >> "$GITHUB_OUTPUT" - - - cron-run-non-fast-blocks-e2e-test: - if: github.event_name == 'schedule' && needs.check-if-saturday.outputs.is-saturday == 'true' - name: "NFB: ${{ matrix.test-file }} / Python ${{ matrix.python-version }}" - needs: - - check-if-saturday - - find-tests - - pull-docker-image - runs-on: ubuntu-latest - timeout-minutes: 1440 - - strategy: - fail-fast: false # Allow other matrix jobs to run even if this job fails - max-parallel: 32 # Set the maximum number of parallel jobs (same as we have cores in ubuntu-latest runner) - matrix: - os: - - ubuntu-latest - test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] - - steps: - - name: Check-out repository - uses: actions/checkout@v4 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Install uv - uses: astral-sh/setup-uv@v4 - - - name: install dependencies - run: uv sync --extra dev --dev - - - name: Download Cached Docker Image - uses: actions/download-artifact@v4 - with: - name: subtensor-localnet - - - name: Load Docker Image - run: docker load -i subtensor-localnet.tar - - - name: Run patched E2E tests env: - FAST_BLOCKS: "0" + LOCALNET_IMAGE_NAME: ${{ needs.pull-docker-image.outputs.image-name }} run: | set +e for i in 1 2 3; do @@ -212,3 +139,4 @@ jobs: sleep 5 fi done + From 320afde386c2f11b2e50f549bf15e6d0e4363449 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 16 Jul 2025 12:56:53 -0700 Subject: [PATCH 17/41] improve --- .github/workflows/e2e-subtensor-tests.yaml | 3 ++- .../workflows/nightly-e2e-tests-subtensor-main.yml | 14 ++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 7c8fcc017b..72ad5fa799 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -22,6 +22,7 @@ on: env: CARGO_TERM_COLOR: always VERBOSE: ${{ github.event.inputs.verbose }} + PYTHON_VERSIONS: '["3.9", "3.10", "3.11", "3.12", "3.13"]' # job to run tests in parallel jobs: @@ -93,7 +94,7 @@ jobs: os: - ubuntu-latest test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ${{ fromJson(env.PYTHON_VERSIONS) }} steps: - name: Check-out repository uses: actions/checkout@v4 diff --git a/.github/workflows/nightly-e2e-tests-subtensor-main.yml b/.github/workflows/nightly-e2e-tests-subtensor-main.yml index bf5cfba0eb..b2b2acd0cc 100644 --- a/.github/workflows/nightly-e2e-tests-subtensor-main.yml +++ b/.github/workflows/nightly-e2e-tests-subtensor-main.yml @@ -1,4 +1,4 @@ -name: Nightly E2E Subtensor tests (main) +name: Nightly E2E Subtensor tests concurrency: group: e2e-subtensor-${{ github.ref }} @@ -18,6 +18,7 @@ on: env: CARGO_TERM_COLOR: always VERBOSE: ${{ github.event.inputs.verbose }} + PYTHON_VERSIONS: '["3.9", "3.10", "3.11", "3.12", "3.13"]' # job to run tests in parallel jobs: @@ -37,8 +38,10 @@ jobs: test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') # keep it here for future debug # test_files=$(find tests/e2e_tests -type f -name "test*.py" | grep -E 'test_(hotkeys|staking)\.py$' | jq -R -s -c 'split("\n") | map(select(. != ""))') + echo "Found test files: $test_files" echo "test-files=$test_files" >> "$GITHUB_OUTPUT" shell: bash + # Pull docker images (devnet-ready and main) pull-docker-images: runs-on: ubuntu-latest @@ -103,7 +106,7 @@ jobs: os: - ubuntu-latest test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ${{ fromJson(env.PYTHON_VERSIONS) }} steps: - name: Check-out repository uses: actions/checkout@v4 @@ -168,7 +171,7 @@ jobs: os: - ubuntu-latest test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ${{ fromJson(env.PYTHON_VERSIONS) }} steps: - name: Check-out repository uses: actions/checkout@v4 @@ -236,7 +239,7 @@ jobs: os: - ubuntu-latest test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ${{ fromJson(env.PYTHON_VERSIONS) }} steps: - name: Check-out repository @@ -305,7 +308,7 @@ jobs: os: - ubuntu-latest test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ${{ fromJson(env.PYTHON_VERSIONS) }} steps: - name: Check-out repository @@ -355,4 +358,3 @@ jobs: sleep 5 fi done - From fcc6a359f8c16d24a23ce71d1e70c1b37467f1d0 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 16 Jul 2025 12:59:41 -0700 Subject: [PATCH 18/41] fix `- '**'` --- .github/workflows/e2e-subtensor-tests.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 72ad5fa799..d0b74eb4e3 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -6,10 +6,11 @@ concurrency: on: push: - branches: * - + branches: + - '**' pull_request: - branches: * + branches: + - '**' types: [ opened, synchronize, reopened, ready_for_review ] workflow_dispatch: From 183d65c85764dd416cd486d28757147be1904445 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 16 Jul 2025 13:02:14 -0700 Subject: [PATCH 19/41] fix python version --- .github/workflows/e2e-subtensor-tests.yaml | 3 +-- .github/workflows/nightly-e2e-tests-subtensor-main.yml | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index d0b74eb4e3..b8e672ef8e 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -23,7 +23,6 @@ on: env: CARGO_TERM_COLOR: always VERBOSE: ${{ github.event.inputs.verbose }} - PYTHON_VERSIONS: '["3.9", "3.10", "3.11", "3.12", "3.13"]' # job to run tests in parallel jobs: @@ -95,7 +94,7 @@ jobs: os: - ubuntu-latest test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ${{ fromJson(env.PYTHON_VERSIONS) }} + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - name: Check-out repository uses: actions/checkout@v4 diff --git a/.github/workflows/nightly-e2e-tests-subtensor-main.yml b/.github/workflows/nightly-e2e-tests-subtensor-main.yml index b2b2acd0cc..3ef9434382 100644 --- a/.github/workflows/nightly-e2e-tests-subtensor-main.yml +++ b/.github/workflows/nightly-e2e-tests-subtensor-main.yml @@ -18,7 +18,6 @@ on: env: CARGO_TERM_COLOR: always VERBOSE: ${{ github.event.inputs.verbose }} - PYTHON_VERSIONS: '["3.9", "3.10", "3.11", "3.12", "3.13"]' # job to run tests in parallel jobs: @@ -106,7 +105,7 @@ jobs: os: - ubuntu-latest test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ${{ fromJson(env.PYTHON_VERSIONS) }} + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - name: Check-out repository uses: actions/checkout@v4 @@ -171,7 +170,7 @@ jobs: os: - ubuntu-latest test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ${{ fromJson(env.PYTHON_VERSIONS) }} + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - name: Check-out repository uses: actions/checkout@v4 @@ -239,7 +238,7 @@ jobs: os: - ubuntu-latest test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ${{ fromJson(env.PYTHON_VERSIONS) }} + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - name: Check-out repository @@ -308,7 +307,7 @@ jobs: os: - ubuntu-latest test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ${{ fromJson(env.PYTHON_VERSIONS) }} + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - name: Check-out repository From 21821b8468dd57631fbcc3544970dcd7a5d4de06 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 16 Jul 2025 13:03:59 -0700 Subject: [PATCH 20/41] add permissions --- .github/workflows/nightly-e2e-tests-subtensor-main.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/nightly-e2e-tests-subtensor-main.yml b/.github/workflows/nightly-e2e-tests-subtensor-main.yml index 3ef9434382..589141ec1b 100644 --- a/.github/workflows/nightly-e2e-tests-subtensor-main.yml +++ b/.github/workflows/nightly-e2e-tests-subtensor-main.yml @@ -1,5 +1,9 @@ name: Nightly E2E Subtensor tests +permissions: + contents: read + packages: write + concurrency: group: e2e-subtensor-${{ github.ref }} cancel-in-progress: true From ad986d5704ca31d8b804724da7a8600588d9e320 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 16 Jul 2025 13:17:07 -0700 Subject: [PATCH 21/41] fix test --- tests/e2e_tests/test_stake_fee.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/e2e_tests/test_stake_fee.py b/tests/e2e_tests/test_stake_fee.py index b20440c651..049ee3cbe7 100644 --- a/tests/e2e_tests/test_stake_fee.py +++ b/tests/e2e_tests/test_stake_fee.py @@ -19,7 +19,7 @@ async def test_stake_fee_api(local_chain, subtensor, alice_wallet, bob_wallet): netuid = 2 root_netuid = 0 stake_amount = Balance.from_tao(100) # 100 TAO - min_stake_fee = Balance.from_tao(0.299076829) + min_stake_fee = Balance.from_tao(0.050354772) # Register subnet as Alice assert subtensor.register_subnet(alice_wallet), "Unable to register the subnet" @@ -32,9 +32,9 @@ async def test_stake_fee_api(local_chain, subtensor, alice_wallet, bob_wallet): coldkey_ss58=alice_wallet.coldkeypub.ss58_address, hotkey_ss58=alice_wallet.hotkey.ss58_address, ) - assert isinstance(stake_fee_0, Balance), "Stake fee should be a Balance object" + assert isinstance(stake_fee_0, Balance), "Stake fee should be a Balance object." assert stake_fee_0 == min_stake_fee, ( - "Stake fee should be equal the minimum stake fee" + "Stake fee should be equal the minimum stake fee." ) # Test unstake fee @@ -44,9 +44,11 @@ async def test_stake_fee_api(local_chain, subtensor, alice_wallet, bob_wallet): coldkey_ss58=alice_wallet.coldkeypub.ss58_address, hotkey_ss58=bob_wallet.hotkey.ss58_address, ) - assert isinstance(unstake_fee_root, Balance), "Stake fee should be a Balance object" - assert unstake_fee_root == Balance.from_rao(299076829), ( - "Root unstake fee should be 0." + assert isinstance(unstake_fee_root, Balance), ( + "Stake fee should be a Balance object." + ) + assert unstake_fee_root == min_stake_fee, ( + "Root unstake fee should be equal the minimum stake fee." ) # Test various stake movement scenarios From aefa1d584a9a36c7f1cb8bbc0943630b590b56da Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 16 Jul 2025 13:55:31 -0700 Subject: [PATCH 22/41] fix test --- tests/e2e_tests/test_delegate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_delegate.py b/tests/e2e_tests/test_delegate.py index 4bd181ae2e..9fb4b9dd1a 100644 --- a/tests/e2e_tests/test_delegate.py +++ b/tests/e2e_tests/test_delegate.py @@ -342,7 +342,7 @@ def test_nominator_min_required_stake( wallet=dave_wallet, hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, - amount=Balance.from_tao(10_000), + amount=Balance.from_tao(1000), wait_for_inclusion=True, wait_for_finalization=True, ) From 6b85ab2ed363f5fa866a89d77c8f0a6d6fa6d624 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 16 Jul 2025 18:07:13 -0700 Subject: [PATCH 23/41] Add SECURITY.md --- SECURITY.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..ef06884bb2 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,42 @@ +# Security Policy + +## Reporting a Vulnerability + +If you discover a security vulnerability in the Bittensor protocol, SDK, or any of its components, we strongly encourage you to report it responsibly. + +Please **do not publicly disclose** the vulnerability until we have had a reasonable chance to address it. + +### ๐Ÿ” Confidential Reporting + +To report a vulnerability, you can use any of the following methods: + +- Create a [GitHub Issue](https://github.com/opentensor/bittensor/issues) using the `Security` label or title. + +- Contact us via our official Discord support thread: [#btcli-btsdk](https://discord.com/channels/1120750674595024897/1242999357436071956) + +### ๐Ÿงพ What to Include + +When reporting a vulnerability, please provide as much detail as possible: + +- Affected component (e.g., `bittensor`, `bittensor-cli`, `bittensor-wallet`, etc.) +- Version or commit hash +- Description of the vulnerability +- Steps to reproduce (if possible) +- Impact assessment +- Any potential mitigations or recommendations + +--- + +## Response Process + +1. We will acknowledge your report within **48 hours**. +2. We will investigate and confirm the issue. +3. If confirmed, we will coordinate on a fix and set an embargo period if needed. +4. A fix will be developed, tested, and released as soon as possible. +5. You will be credited (if you wish) in the security section of our release notes. + +--- + +## Thank You + +We appreciate your efforts in keeping the Bittensor ecosystem secure and responsible. From 9e2eeddc1e321d8ef9c402e96b7c65eb91b24142 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 17 Jul 2025 17:50:41 -0700 Subject: [PATCH 24/41] add labels checker --- .github/workflows/e2e-subtensor-tests.yaml | 42 ++++++++++++++++++---- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index b8e672ef8e..45aab13e6b 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -52,16 +52,46 @@ jobs: outputs: image-name: ${{ steps.set-output.outputs.image-name }} steps: - - name: Set Docker image tag based on branch + - name: Set Docker image tag based on label or branch id: set-output run: | - ref="${{ github.ref_name }}" - if [[ "$ref" == "master" ]]; then - image="ghcr.io/opentensor/subtensor-localnet:main" + echo "Event: $GITHUB_EVENT_NAME" + echo "Branch: $GITHUB_REF_NAME" + + echo "Reading labels ..." + if [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then + labels=$(jq -r '.pull_request.labels[].name' "$GITHUB_EVENT_PATH") else - image="ghcr.io/opentensor/subtensor-localnet:devnet-ready" + labels="" fi - echo "Using image: $image" + + image="" + + for label in $labels; do + echo "Found label: $label" + case "$label" in + "subtensor-localnet:main") + image="ghcr.io/opentensor/subtensor-localnet:main" + ;; + "subtensor-localnet:testnet") + image="ghcr.io/opentensor/subtensor-localnet:testnet" + ;; + "subtensor-localnet:devnet") + image="ghcr.io/opentensor/subtensor-localnet:devnet" + ;; + esac + done + + if [[ -z "$image" ]]; then + # fallback to default based on branch + if [[ "${GITHUB_REF_NAME}" == "master" ]]; then + image="ghcr.io/opentensor/subtensor-localnet:main" + else + image="ghcr.io/opentensor/subtensor-localnet:devnet-ready" + fi + fi + + echo "โœ… Final selected image: $image" echo "image-name=$image" >> "$GITHUB_OUTPUT" - name: Log in to GitHub Container Registry From c688e475f576cf2add1a498f03217a2fa0b043d3 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 17 Jul 2025 17:53:29 -0700 Subject: [PATCH 25/41] add trigger --- .github/workflows/e2e-subtensor-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 45aab13e6b..75911e73f9 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -11,7 +11,7 @@ on: pull_request: branches: - '**' - types: [ opened, synchronize, reopened, ready_for_review ] + types: [ opened, synchronize, reopened, ready_for_review, labeled, unlabeled ] workflow_dispatch: inputs: From fdf04de3b6a5e01fabd36ed3816f53f73d4e2d91 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 17 Jul 2025 18:04:52 -0700 Subject: [PATCH 26/41] unique group name --- .github/workflows/e2e-subtensor-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 75911e73f9..3a96b161ce 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -1,7 +1,7 @@ name: E2E Subtensor Tests concurrency: - group: e2e-subtensor-${{ github.ref }} + : e2e-subtensor-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true on: From b6f06d8b0657e625ef6c6e0b375d2706702811e3 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 17 Jul 2025 18:09:41 -0700 Subject: [PATCH 27/41] improvements --- .github/workflows/e2e-subtensor-tests.yaml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 3a96b161ce..2fb48256fd 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -1,7 +1,7 @@ name: E2E Subtensor Tests concurrency: - : e2e-subtensor-${{ github.event.pull_request.number || github.ref }} + group: e2e-subtensor-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true on: @@ -50,10 +50,10 @@ jobs: pull-docker-image: runs-on: ubuntu-latest outputs: - image-name: ${{ steps.set-output.outputs.image-name }} + image-name: ${{ steps.set-image.outputs.image }} steps: - name: Set Docker image tag based on label or branch - id: set-output + id: set-image run: | echo "Event: $GITHUB_EVENT_NAME" echo "Branch: $GITHUB_REF_NAME" @@ -72,12 +72,15 @@ jobs: case "$label" in "subtensor-localnet:main") image="ghcr.io/opentensor/subtensor-localnet:main" + break ;; "subtensor-localnet:testnet") image="ghcr.io/opentensor/subtensor-localnet:testnet" + break ;; "subtensor-localnet:devnet") image="ghcr.io/opentensor/subtensor-localnet:devnet" + break ;; esac done @@ -98,10 +101,10 @@ jobs: run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin - name: Pull Docker Image - run: docker pull ${{ steps.set-output.outputs.image-name }} + run: docker pull ${{ steps.set-image.outputs.image }} - name: Save Docker Image to Cache - run: docker save -o subtensor-localnet.tar ${{ steps.set-output.outputs.image-name }} + run: docker save -o subtensor-localnet.tar ${{ steps.set-image.outputs.image }} - name: Upload Docker Image as Artifact uses: actions/upload-artifact@v4 @@ -154,8 +157,9 @@ jobs: run: | set +e for i in 1 2 3; do - echo "๐Ÿ” Attempt $i: Running tests" + echo "::group::๐Ÿ” Test attempt $i" uv run pytest ${{ matrix.test-file }} -s + echo "::endgroup::" status=$? if [ $status -eq 0 ]; then echo "โœ… Tests passed on attempt $i" From 2de2a6c04134cc855a43ec4567490bc58ed94db7 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 17 Jul 2025 18:11:09 -0700 Subject: [PATCH 28/41] oops --- .github/workflows/e2e-subtensor-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 2fb48256fd..853e5c21b1 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -95,7 +95,7 @@ jobs: fi echo "โœ… Final selected image: $image" - echo "image-name=$image" >> "$GITHUB_OUTPUT" + echo "image=$image" >> "$GITHUB_OUTPUT" - name: Log in to GitHub Container Registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin From d746cf291e20fc3882c0bf3007cab0cde86da1cc Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 17 Jul 2025 18:20:15 -0700 Subject: [PATCH 29/41] trigger CI From 98ab70b68930b1ed37214c9e87be41407424a302 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 17 Jul 2025 18:23:36 -0700 Subject: [PATCH 30/41] if --- .github/workflows/e2e-subtensor-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 853e5c21b1..67029e41c9 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -29,7 +29,7 @@ jobs: # Looking for e2e tests find-tests: runs-on: ubuntu-latest - if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} + if: ${{ github.event.pull_request.draft == false }} outputs: test-files: ${{ steps.get-tests.outputs.test-files }} steps: From fb7e07834113bc508e528100c4042c254a322a84 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 17 Jul 2025 19:17:09 -0700 Subject: [PATCH 31/41] fix double run --- .github/workflows/e2e-subtensor-tests.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 67029e41c9..4cd20ac6e4 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -5,9 +5,6 @@ concurrency: cancel-in-progress: true on: - push: - branches: - - '**' pull_request: branches: - '**' From f09d69060386dcafec7e59006389e18c03963b46 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 17 Jul 2025 19:47:11 -0700 Subject: [PATCH 32/41] kill forever happy test --- .github/workflows/e2e-subtensor-tests.yaml | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 4cd20ac6e4..265b358a84 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -152,23 +152,21 @@ jobs: env: LOCALNET_IMAGE_NAME: ${{ needs.pull-docker-image.outputs.image-name }} run: | - set +e for i in 1 2 3; do echo "::group::๐Ÿ” Test attempt $i" - uv run pytest ${{ matrix.test-file }} -s - echo "::endgroup::" - status=$? - if [ $status -eq 0 ]; then + if uv run pytest ${{ matrix.test-file }} -s; then echo "โœ… Tests passed on attempt $i" - break + echo "::endgroup::" + exit 0 else echo "โŒ Tests failed on attempt $i" - if [ $i -eq 3 ]; then - echo "Tests failed after 3 attempts" - exit 1 + echo "::endgroup::" + if [ "$i" -lt 3 ]; then + echo "Retrying..." + sleep 5 fi - echo "Retrying..." - sleep 5 fi done + echo "Tests failed after 3 attempts" + exit 1 From 5b6c6c8bb005817e78f8e0d3c77e15347664e961 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 18 Jul 2025 14:29:03 +0200 Subject: [PATCH 33/41] `AsyncSubtensor.get_metagraph_info` was only using the block/hash specified when columns were specified. --- bittensor/core/async_subtensor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bittensor/core/async_subtensor.py b/bittensor/core/async_subtensor.py index 058bc10314..de18bd1413 100644 --- a/bittensor/core/async_subtensor.py +++ b/bittensor/core/async_subtensor.py @@ -2035,6 +2035,7 @@ async def get_metagraph_info( "SubnetInfoRuntimeApi", "get_metagraph", params=[netuid], + block_hash=block_hash, ) if query.value is None: From 41426a6ecd98aa415cbc6d4512447284c3d84814 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 18 Jul 2025 15:44:39 +0200 Subject: [PATCH 34/41] Also wrong on subnet_prices --- bittensor/core/subtensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index b64809ee15..76839bdff2 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -455,7 +455,7 @@ def all_subnets(self, block: Optional[int] = None) -> Optional[list["DynamicInfo method="get_all_dynamic_info", block_hash=block_hash, ) - subnet_prices = self.get_subnet_prices() + subnet_prices = self.get_subnet_prices(block=block) decoded = query.decode() for sn in decoded: sn.update({"price": subnet_prices.get(sn["netuid"], Balance.from_tao(0))}) From a5ddfd4d6c5c56d2f098936e494d640c2a56cf37 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 18 Jul 2025 15:45:15 +0200 Subject: [PATCH 35/41] Also wrong on async subnet prices --- bittensor/core/async_subtensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittensor/core/async_subtensor.py b/bittensor/core/async_subtensor.py index de18bd1413..c04ea615f3 100644 --- a/bittensor/core/async_subtensor.py +++ b/bittensor/core/async_subtensor.py @@ -814,7 +814,7 @@ async def all_subnets( method="get_all_dynamic_info", block_hash=block_hash, ), - self.get_subnet_prices(), + self.get_subnet_prices(block_hash=block_hash), ) decoded = query.decode() From 51ad4f4239e943a605f910f254861a0403a0e6e9 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 18 Jul 2025 16:03:23 +0200 Subject: [PATCH 36/41] More missed --- bittensor/core/async_subtensor.py | 43 +++++++++++++++++++++---------- bittensor/core/subtensor.py | 22 +++++++++++----- 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/bittensor/core/async_subtensor.py b/bittensor/core/async_subtensor.py index c04ea615f3..aa6d8f93f9 100644 --- a/bittensor/core/async_subtensor.py +++ b/bittensor/core/async_subtensor.py @@ -815,12 +815,20 @@ async def all_subnets( block_hash=block_hash, ), self.get_subnet_prices(block_hash=block_hash), + return_exceptions=True, ) decoded = query.decode() - for sn in decoded: - sn.update({"price": subnet_prices.get(sn["netuid"], Balance.from_tao(0))}) + if not isinstance(subnet_prices, SubstrateRequestException): + for sn in decoded: + sn.update( + {"price": subnet_prices.get(sn["netuid"], Balance.from_tao(0))} + ) + else: + logging.warning( + f"Unable to fetch subnet prices for block {block_number}, block hash {block_hash}" + ) return DynamicInfo.list_from_dicts(decoded) async def blocks_since_last_step( @@ -1129,21 +1137,30 @@ async def get_all_subnets_info( Notes: See also: """ - result = await self.query_runtime_api( - runtime_api="SubnetInfoRuntimeApi", - method="get_subnets_info_v2", - params=[], - block=block, - block_hash=block_hash, - reuse_block=reuse_block, + result, prices = await asyncio.gather( + self.query_runtime_api( + runtime_api="SubnetInfoRuntimeApi", + method="get_subnets_info_v2", + params=[], + block=block, + block_hash=block_hash, + reuse_block=reuse_block, + ), + self.get_subnet_prices( + block=block, block_hash=block_hash, reuse_block=reuse_block + ), + return_exceptions=True, ) if not result: return [] - subnets_prices = await self.get_subnet_prices() - - for subnet in result: - subnet.update({"price": subnets_prices.get(subnet["netuid"], 0)}) + if not isinstance(prices, SubstrateRequestException): + for subnet in result: + subnet.update({"price": prices.get(subnet["netuid"], 0)}) + else: + logging.warning( + f"Unable to fetch subnet prices for block {block}, block hash {block_hash}" + ) return SubnetInfo.list_from_dicts(result) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 76839bdff2..728d9880c4 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -455,10 +455,16 @@ def all_subnets(self, block: Optional[int] = None) -> Optional[list["DynamicInfo method="get_all_dynamic_info", block_hash=block_hash, ) - subnet_prices = self.get_subnet_prices(block=block) decoded = query.decode() - for sn in decoded: - sn.update({"price": subnet_prices.get(sn["netuid"], Balance.from_tao(0))}) + try: + subnet_prices = self.get_subnet_prices(block=block) + for sn in decoded: + sn.update( + {"price": subnet_prices.get(sn["netuid"], Balance.from_tao(0))} + ) + except SubstrateRequestException: + logging.warning(f"Unable to fetch subnet prices for block {block}") + return DynamicInfo.list_from_dicts(decoded) def blocks_since_last_step( @@ -644,11 +650,13 @@ def get_all_subnets_info(self, block: Optional[int] = None) -> list["SubnetInfo" ) if not result: return [] + try: + subnets_prices = self.get_subnet_prices(block=block) - subnets_prices = self.get_subnet_prices() - - for subnet in result: - subnet.update({"price": subnets_prices.get(subnet["netuid"], 0)}) + for subnet in result: + subnet.update({"price": subnets_prices.get(subnet["netuid"], 0)}) + except SubstrateRequestException: + logging.warning(f"Unable to fetch subnet prices for block {block}") return SubnetInfo.list_from_dicts(result) From 9f47cf6ce805d078fde6e6c03eda4cf6e4aad8d6 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 18 Jul 2025 16:32:03 +0200 Subject: [PATCH 37/41] PR Suggestions --- bittensor/core/async_subtensor.py | 4 ++-- bittensor/core/subtensor.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bittensor/core/async_subtensor.py b/bittensor/core/async_subtensor.py index aa6d8f93f9..bb46e4ddc9 100644 --- a/bittensor/core/async_subtensor.py +++ b/bittensor/core/async_subtensor.py @@ -827,7 +827,7 @@ async def all_subnets( ) else: logging.warning( - f"Unable to fetch subnet prices for block {block_number}, block hash {block_hash}" + f"Unable to fetch subnet prices for block {block_number}, block hash {block_hash}: {subnet_prices}" ) return DynamicInfo.list_from_dicts(decoded) @@ -1159,7 +1159,7 @@ async def get_all_subnets_info( subnet.update({"price": prices.get(subnet["netuid"], 0)}) else: logging.warning( - f"Unable to fetch subnet prices for block {block}, block hash {block_hash}" + f"Unable to fetch subnet prices for block {block}, block hash {block_hash}: {prices}" ) return SubnetInfo.list_from_dicts(result) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 728d9880c4..94e9b7dd91 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -462,8 +462,8 @@ def all_subnets(self, block: Optional[int] = None) -> Optional[list["DynamicInfo sn.update( {"price": subnet_prices.get(sn["netuid"], Balance.from_tao(0))} ) - except SubstrateRequestException: - logging.warning(f"Unable to fetch subnet prices for block {block}") + except SubstrateRequestException as e: + logging.warning(f"Unable to fetch subnet prices for block {block}: {e}") return DynamicInfo.list_from_dicts(decoded) @@ -656,7 +656,7 @@ def get_all_subnets_info(self, block: Optional[int] = None) -> list["SubnetInfo" for subnet in result: subnet.update({"price": subnets_prices.get(subnet["netuid"], 0)}) except SubstrateRequestException: - logging.warning(f"Unable to fetch subnet prices for block {block}") + logging.warning(f"Unable to fetch subnet prices for block {block}: {e}") return SubnetInfo.list_from_dicts(result) From 56ad8b45d0de5c6dc730df9fc941e6b58998a74b Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 18 Jul 2025 16:39:03 +0200 Subject: [PATCH 38/41] Flake --- bittensor/core/subtensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 94e9b7dd91..b4b35d334a 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -655,7 +655,7 @@ def get_all_subnets_info(self, block: Optional[int] = None) -> list["SubnetInfo" for subnet in result: subnet.update({"price": subnets_prices.get(subnet["netuid"], 0)}) - except SubstrateRequestException: + except SubstrateRequestException as e: logging.warning(f"Unable to fetch subnet prices for block {block}: {e}") return SubnetInfo.list_from_dicts(result) From cc611e97f98a0d709268667d470eeefb66b3c940 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 18 Jul 2025 19:11:39 +0200 Subject: [PATCH 39/41] Updates version+changelog --- CHANGELOG.md | 12 ++++++++++++ pyproject.toml | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be626ec86c..9541899a60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 9.8.3 /2025-07-18 +* improve make file by @basfroman in https://github.com/opentensor/bittensor/pull/2965 +* Move all workflows from `app.circleci.com` to `GH actions` by @basfroman in https://github.com/opentensor/bittensor/pull/2970 +* Improve `changelog` workflow by @basfroman in https://github.com/opentensor/bittensor/pull/2973 +* fix e2e test after devnet-ready get new fee by @basfroman in https://github.com/opentensor/bittensor/pull/2975 +* Add SECURITY.md by @basfroman in https://github.com/opentensor/bittensor/pull/2976 +* Improve test infrastructure by @basfroman in https://github.com/opentensor/bittensor/pull/2974 +* Add labels checker by @basfroman in https://github.com/opentensor/bittensor/pull/2977 +* Use specified block/hash in metagraph, get_subnet, get_all_subnets by @thewhaleking in https://github.com/opentensor/bittensor/pull/2979 + +**Full Changelog**: https://github.com/opentensor/bittensor/compare/v9.8.2...v9.8.3 + ## 9.8.2 /2025-07-10 ## What's Changed diff --git a/pyproject.toml b/pyproject.toml index 9c32e6ee7a..de109b014b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "bittensor" -version = "9.8.2" +version = "9.8.3" description = "Bittensor" readme = "README.md" authors = [ From 70225c05bdfcc2800a091ba5d395599c96e403e2 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 18 Jul 2025 19:35:17 +0200 Subject: [PATCH 40/41] Removes 2975 from changelog for 9.8.3 --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9541899a60..acc5c17f16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,6 @@ * improve make file by @basfroman in https://github.com/opentensor/bittensor/pull/2965 * Move all workflows from `app.circleci.com` to `GH actions` by @basfroman in https://github.com/opentensor/bittensor/pull/2970 * Improve `changelog` workflow by @basfroman in https://github.com/opentensor/bittensor/pull/2973 -* fix e2e test after devnet-ready get new fee by @basfroman in https://github.com/opentensor/bittensor/pull/2975 * Add SECURITY.md by @basfroman in https://github.com/opentensor/bittensor/pull/2976 * Improve test infrastructure by @basfroman in https://github.com/opentensor/bittensor/pull/2974 * Add labels checker by @basfroman in https://github.com/opentensor/bittensor/pull/2977 From 5322803ad0133223f7f5ebdc2a5954bcf95d92b5 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 18 Jul 2025 19:45:48 +0200 Subject: [PATCH 41/41] Revert "Merge pull request #2975 from opentensor/fix/roman/fix-after-devnet-ready-update-fee" This reverts commit 9665972a3ee80d511a516b37a50356d9ade95faf, reversing changes made to 81e0a44ac54334c6788df156458155c9861bc60a. --- tests/e2e_tests/test_delegate.py | 2 +- tests/e2e_tests/test_stake_fee.py | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/tests/e2e_tests/test_delegate.py b/tests/e2e_tests/test_delegate.py index 9fb4b9dd1a..4bd181ae2e 100644 --- a/tests/e2e_tests/test_delegate.py +++ b/tests/e2e_tests/test_delegate.py @@ -342,7 +342,7 @@ def test_nominator_min_required_stake( wallet=dave_wallet, hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, - amount=Balance.from_tao(1000), + amount=Balance.from_tao(10_000), wait_for_inclusion=True, wait_for_finalization=True, ) diff --git a/tests/e2e_tests/test_stake_fee.py b/tests/e2e_tests/test_stake_fee.py index 049ee3cbe7..b20440c651 100644 --- a/tests/e2e_tests/test_stake_fee.py +++ b/tests/e2e_tests/test_stake_fee.py @@ -19,7 +19,7 @@ async def test_stake_fee_api(local_chain, subtensor, alice_wallet, bob_wallet): netuid = 2 root_netuid = 0 stake_amount = Balance.from_tao(100) # 100 TAO - min_stake_fee = Balance.from_tao(0.050354772) + min_stake_fee = Balance.from_tao(0.299076829) # Register subnet as Alice assert subtensor.register_subnet(alice_wallet), "Unable to register the subnet" @@ -32,9 +32,9 @@ async def test_stake_fee_api(local_chain, subtensor, alice_wallet, bob_wallet): coldkey_ss58=alice_wallet.coldkeypub.ss58_address, hotkey_ss58=alice_wallet.hotkey.ss58_address, ) - assert isinstance(stake_fee_0, Balance), "Stake fee should be a Balance object." + assert isinstance(stake_fee_0, Balance), "Stake fee should be a Balance object" assert stake_fee_0 == min_stake_fee, ( - "Stake fee should be equal the minimum stake fee." + "Stake fee should be equal the minimum stake fee" ) # Test unstake fee @@ -44,11 +44,9 @@ async def test_stake_fee_api(local_chain, subtensor, alice_wallet, bob_wallet): coldkey_ss58=alice_wallet.coldkeypub.ss58_address, hotkey_ss58=bob_wallet.hotkey.ss58_address, ) - assert isinstance(unstake_fee_root, Balance), ( - "Stake fee should be a Balance object." - ) - assert unstake_fee_root == min_stake_fee, ( - "Root unstake fee should be equal the minimum stake fee." + assert isinstance(unstake_fee_root, Balance), "Stake fee should be a Balance object" + assert unstake_fee_root == Balance.from_rao(299076829), ( + "Root unstake fee should be 0." ) # Test various stake movement scenarios