Skip to content

Commit 81bbe5c

Browse files
Merge branch 'staging' into feat/zyzniewski/set_children_and_pending_children
2 parents 3bc829f + ce83530 commit 81bbe5c

17 files changed

+1042
-117
lines changed

.github/workflows/e2e-subtensor-tests.yaml

Lines changed: 34 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ env:
2525

2626
# job to run tests in parallel
2727
jobs:
28-
# Job to find all test files
28+
2929
find-tests:
3030
runs-on: ubuntu-latest
3131
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
@@ -42,68 +42,55 @@ jobs:
4242
echo "::set-output name=test-files::$test_files"
4343
shell: bash
4444

45+
pull-docker-image:
46+
runs-on: ubuntu-latest
47+
steps:
48+
- name: Log in to GitHub Container Registry
49+
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin
50+
51+
- name: Pull Docker Image
52+
run: docker pull ghcr.io/opentensor/subtensor-localnet:latest
53+
54+
- name: Save Docker Image to Cache
55+
run: docker save -o subtensor-localnet.tar ghcr.io/opentensor/subtensor-localnet:latest
56+
57+
- name: Upload Docker Image as Artifact
58+
uses: actions/upload-artifact@v4
59+
with:
60+
name: subtensor-localnet
61+
path: subtensor-localnet.tar
62+
4563
# Job to run tests in parallel
4664
run:
47-
needs: find-tests
48-
runs-on: SubtensorCI
65+
needs:
66+
- find-tests
67+
- pull-docker-image
68+
runs-on: ubuntu-latest
4969
timeout-minutes: 45
5070
strategy:
5171
fail-fast: false # Allow other matrix jobs to run even if this job fails
52-
max-parallel: 8 # Set the maximum number of parallel jobs
72+
max-parallel: 32 # Set the maximum number of parallel jobs (same as we have cores in SubtensorCI runner)
5373
matrix:
54-
rust-branch:
55-
- stable
56-
rust-target:
57-
- x86_64-unknown-linux-gnu
5874
os:
5975
- ubuntu-latest
6076
test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }}
61-
env:
62-
RELEASE_NAME: development
63-
RUSTV: ${{ matrix.rust-branch }}
64-
RUST_BACKTRACE: full
65-
RUST_BIN_DIR: target/${{ matrix.rust-target }}
66-
TARGET: ${{ matrix.rust-target }}
6777
steps:
68-
- name: Check-out repository under $GITHUB_WORKSPACE
78+
- name: Check-out repository
6979
uses: actions/checkout@v4
7080

71-
- name: Install dependencies
72-
run: |
73-
sudo apt-get update &&
74-
sudo apt-get install -y clang curl libssl-dev llvm libudev-dev protobuf-compiler
75-
76-
- name: Install Rust ${{ matrix.rust-branch }}
77-
uses: actions-rs/[email protected]
78-
with:
79-
toolchain: ${{ matrix.rust-branch }}
80-
components: rustfmt
81-
profile: minimal
82-
83-
- name: Add wasm32-unknown-unknown target
84-
run: |
85-
rustup target add wasm32-unknown-unknown --toolchain stable-x86_64-unknown-linux-gnu
86-
rustup component add rust-src --toolchain stable-x86_64-unknown-linux-gnu
87-
88-
- name: Clone subtensor repo
89-
run: git clone https://github.com/opentensor/subtensor.git
90-
91-
- name: Setup subtensor repo
92-
working-directory: ${{ github.workspace }}/subtensor
93-
run: git checkout devnet-ready
94-
9581
- name: Install uv
9682
uses: astral-sh/setup-uv@v4
9783

9884
- name: install dependencies
9985
run: uv sync --all-extras --dev
10086

101-
- name: Run tests
102-
run: |
103-
LOCALNET_SH_PATH="${{ github.workspace }}/subtensor/scripts/localnet.sh" uv run pytest ${{ matrix.test-file }} -s
87+
- name: Download Cached Docker Image
88+
uses: actions/download-artifact@v4
89+
with:
90+
name: subtensor-localnet
10491

105-
- name: Retry failed tests
106-
if: failure()
107-
run: |
108-
sleep 10
109-
LOCALNET_SH_PATH="${{ github.workspace }}/subtensor/scripts/localnet.sh" uv run pytest ${{ matrix.test-file }} -s
92+
- name: Load Docker Image
93+
run: docker load -i subtensor-localnet.tar
94+
95+
- name: Run tests
96+
run: uv run pytest ${{ matrix.test-file }} -s

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## 9.2.0 /2025-03-18
4+
5+
## What's Changed
6+
* Fix E2E test_incentive by waiting till start of the very next epoch by @zyzniewski-reef in https://github.com/opentensor/bittensor/pull/2746
7+
* New era of e2e Tests Bittensor by @roman-opentensor in https://github.com/opentensor/bittensor/pull/2743
8+
* Allow installation on Py 3.13 by @thewhaleking in https://github.com/opentensor/bittensor/pull/2756
9+
* Feat/dynamic stake prices by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2755
10+
11+
**Full Changelog**: https://github.com/opentensor/bittensor/compare/v9.1.0...v9.2.0
12+
313
## 9.1.0 /2025-03-12
414

515
## What's Changed

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,49 @@ The Python interpreter output will look like below.
221221
>>>
222222
```
223223

224+
### Testing
225+
You can run integration and unit tests in interactive mode of IDE or in terminal mode using the command:
226+
```bash
227+
pytest tests/integration_tests
228+
pytest tests/unit_tests
229+
```
230+
231+
#### E2E tests have 2 options for launching (legacy runner):
232+
- using a compiler based on the substrait code
233+
- using an already built docker image (docker runner)
234+
235+
#### Using `docker runner` (default for now):
236+
- E2E tests with docker image do not require preliminary compilation
237+
- are executed very quickly
238+
- require docker installed in OS
239+
240+
Ho to use:
241+
```bash
242+
pytest tests/e2e_tests
243+
```
244+
245+
#### TUsing `legacy runner`:
246+
- Will start compilation of the collected code in your subtensor repository
247+
- you must provide the `LOCALNET_SH_PATH` variable in the local environment with the path to the file `/scripts/localnet.sh` in the cloned repository within your OS
248+
- you can use the `BUILD_BINARY=0` variable, this will skip the copy step for each test.
249+
- you can use the `USE_DOCKER=0` variable, this will run tests using the "legacy runner", even if docker is installed in your OS
250+
251+
#### Ho to use:
252+
Regular e2e tests run
253+
```bash
254+
LOCALNET_SH_PATH=/path/to/your/localnet.sh pytest tests/e2e_tests
255+
```
256+
257+
If you want to skip re-build process for each e2e test
258+
```bash
259+
BUILD_BINARY=0 LOCALNET_SH_PATH=/path/to/your/localnet.sh pytest tests/e2e_tests
260+
```
261+
262+
If you want to use legacy runner even with installed Docker in your OS
263+
```bash
264+
USE_DOCKER=0 BUILD_BINARY=0 LOCALNET_SH_PATH=/path/to/your/localnet.sh pytest tests/e2e_tests
265+
```
266+
224267
---
225268

226269
## Release Guidelines

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
9.1.0
1+
9.2.0

bittensor/core/async_subtensor.py

Lines changed: 114 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,6 +1628,117 @@ async def get_stake(
16281628

16291629
return Balance.from_rao(int(stake)).set_unit(netuid=netuid)
16301630

1631+
async def get_stake_add_fee(
1632+
self,
1633+
amount: Balance,
1634+
netuid: int,
1635+
coldkey_ss58: str,
1636+
hotkey_ss58: str,
1637+
block: Optional[int] = None,
1638+
) -> Balance:
1639+
"""
1640+
Calculates the fee for adding new stake to a hotkey.
1641+
1642+
Args:
1643+
amount: Amount of stake to add in TAO
1644+
netuid: Netuid of subnet
1645+
coldkey_ss58: SS58 address of source coldkey
1646+
hotkey_ss58: SS58 address of destination hotkey
1647+
block: Block number at which to perform the calculation
1648+
1649+
Returns:
1650+
The calculated stake fee as a Balance object
1651+
"""
1652+
result = await self.query_runtime_api(
1653+
runtime_api="StakeInfoRuntimeApi",
1654+
method="get_stake_fee",
1655+
params=[
1656+
None,
1657+
coldkey_ss58,
1658+
(hotkey_ss58, netuid),
1659+
coldkey_ss58,
1660+
amount.rao,
1661+
],
1662+
block=block,
1663+
)
1664+
return Balance.from_rao(result)
1665+
1666+
async def get_unstake_fee(
1667+
self,
1668+
amount: Balance,
1669+
netuid: int,
1670+
coldkey_ss58: str,
1671+
hotkey_ss58: str,
1672+
block: Optional[int] = None,
1673+
) -> Balance:
1674+
"""
1675+
Calculates the fee for unstaking from a hotkey.
1676+
1677+
Args:
1678+
amount: Amount of stake to unstake in TAO
1679+
netuid: Netuid of subnet
1680+
coldkey_ss58: SS58 address of source coldkey
1681+
hotkey_ss58: SS58 address of destination hotkey
1682+
block: Block number at which to perform the calculation
1683+
1684+
Returns:
1685+
The calculated stake fee as a Balance object
1686+
"""
1687+
result = await self.query_runtime_api(
1688+
runtime_api="StakeInfoRuntimeApi",
1689+
method="get_stake_fee",
1690+
params=[
1691+
None,
1692+
coldkey_ss58,
1693+
(hotkey_ss58, netuid),
1694+
coldkey_ss58,
1695+
amount.rao,
1696+
],
1697+
block=block,
1698+
)
1699+
return Balance.from_rao(result)
1700+
1701+
async def get_stake_movement_fee(
1702+
self,
1703+
amount: Balance,
1704+
origin_netuid: int,
1705+
origin_hotkey_ss58: str,
1706+
origin_coldkey_ss58: str,
1707+
destination_netuid: int,
1708+
destination_hotkey_ss58: str,
1709+
destination_coldkey_ss58: str,
1710+
block: Optional[int] = None,
1711+
) -> Balance:
1712+
"""
1713+
Calculates the fee for moving stake between hotkeys/subnets/coldkeys.
1714+
1715+
Args:
1716+
amount: Amount of stake to move in TAO
1717+
origin_netuid: Netuid of source subnet
1718+
origin_hotkey_ss58: SS58 address of source hotkey
1719+
origin_coldkey_ss58: SS58 address of source coldkey
1720+
destination_netuid: Netuid of destination subnet
1721+
destination_hotkey_ss58: SS58 address of destination hotkey
1722+
destination_coldkey_ss58: SS58 address of destination coldkey
1723+
block: Block number at which to perform the calculation
1724+
1725+
Returns:
1726+
The calculated stake fee as a Balance object
1727+
"""
1728+
result = await self.query_runtime_api(
1729+
runtime_api="StakeInfoRuntimeApi",
1730+
method="get_stake_fee",
1731+
params=[
1732+
(origin_hotkey_ss58, origin_netuid),
1733+
origin_coldkey_ss58,
1734+
(destination_hotkey_ss58, destination_netuid),
1735+
destination_coldkey_ss58,
1736+
amount.rao,
1737+
],
1738+
block=block,
1739+
)
1740+
return Balance.from_rao(result)
1741+
16311742
async def get_stake_for_coldkey_and_hotkey(
16321743
self,
16331744
coldkey_ss58: str,
@@ -1962,10 +2073,11 @@ async def get_vote_data(
19622073
block_hash=block_hash,
19632074
reuse_block_hash=reuse_block,
19642075
)
2076+
19652077
if vote_data is None:
19662078
return None
1967-
else:
1968-
return ProposalVoteData(vote_data)
2079+
2080+
return ProposalVoteData.from_dict(vote_data)
19692081

19702082
async def get_uid_for_hotkey_on_subnet(
19712083
self,
Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
1+
from dataclasses import dataclass
2+
3+
from bittensor.core.chain_data.info_base import InfoBase
14
from bittensor.core.chain_data.utils import decode_account_id
25

36

4-
# Senate / Proposal data
5-
class ProposalVoteData:
7+
@dataclass
8+
class ProposalVoteData(InfoBase):
9+
"""
10+
Senate / Proposal data
11+
"""
12+
613
index: int
714
threshold: int
815
ayes: list[str]
916
nays: list[str]
1017
end: int
1118

12-
def __init__(self, proposal_dict: dict) -> None:
13-
self.index = proposal_dict["index"]
14-
self.threshold = proposal_dict["threshold"]
15-
self.ayes = self.decode_ss58_tuples(proposal_dict["ayes"])
16-
self.nays = self.decode_ss58_tuples(proposal_dict["nays"])
17-
self.end = proposal_dict["end"]
18-
19-
@staticmethod
20-
def decode_ss58_tuples(line: tuple):
21-
"""Decodes a tuple of ss58 addresses formatted as bytes tuples."""
22-
return [decode_account_id(line[x][0]) for x in range(len(line))]
19+
@classmethod
20+
def from_dict(cls, proposal_dict: dict) -> "ProposalVoteData":
21+
return cls(
22+
ayes=[decode_account_id(key) for key in proposal_dict["ayes"]],
23+
end=proposal_dict["end"],
24+
index=proposal_dict["index"],
25+
nays=[decode_account_id(key) for key in proposal_dict["nays"]],
26+
threshold=proposal_dict["threshold"],
27+
)

bittensor/core/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "9.1.0"
1+
__version__ = "9.2.0"
22

33
import os
44
import re

0 commit comments

Comments
 (0)