Skip to content

Commit f531c8e

Browse files
authored
Merge pull request #2255 from opentensor/release/7.4.0
Release 7.4.0
2 parents 71b51b2 + eb10bc8 commit f531c8e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+5557
-523
lines changed

.github/auto_assign.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
addReviewers: true
2+
3+
# A list of team slugs to add as assignees
4+
reviewers:
5+
- opentensor/cortex
6+
7+
numberOfReviewers: 0

.github/workflows/auto-assign.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: Auto Assign Cortex to Pull Requests
2+
3+
on:
4+
pull_request:
5+
types: [opened, reopened]
6+
7+
jobs:
8+
auto-assign:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Auto-assign Cortex Team
12+
uses: kentaro-m/auto-assign-action@v1.2.4
13+
with:
14+
repo-token: "${{ secrets.GITHUB_TOKEN }}"
15+
configuration-path: .github/auto_assign.yml

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ jobs:
4646
run:
4747
needs: find-tests
4848
runs-on: SubtensorCI
49+
timeout-minutes: 45
4950
strategy:
5051
fail-fast: false # Allow other matrix jobs to run even if this job fails
5152
max-parallel: 8 # Set the maximum number of parallel jobs

CHANGELOG.md

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

3+
## 7.4.0 /2024-08-29
4+
5+
## What's Changed
6+
* [Fix] Allow unstake below network min by @camfairchild in https://github.com/opentensor/bittensor/pull/2016
7+
* Tests/e2e tests staging by @open-junius in https://github.com/opentensor/bittensor/pull/1943
8+
* Chore: Backmerge 7.2 by @gus-opentensor in https://github.com/opentensor/bittensor/pull/2020
9+
* Fix broken tests and Enforce BTCLI usage by @opendansor in https://github.com/opentensor/bittensor/pull/2027
10+
* Add time delay to faucet by @opendansor in https://github.com/opentensor/bittensor/pull/2030
11+
* Skip faucet test by @opendansor in https://github.com/opentensor/bittensor/pull/2031
12+
* Adds normalization for alpha hyperparams by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2035
13+
* Revert info logging in processing response by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2043
14+
* Pin numpy version to 1.26.4 in prod.txt by @rajkaramchedu in https://github.com/opentensor/bittensor/pull/2045
15+
* Test hot key Swap by @opendansor in https://github.com/opentensor/bittensor/pull/2044
16+
* Do not run Circle-CI on drafts by @thewhaleking in https://github.com/opentensor/bittensor/pull/1959
17+
* Enhancement: Detailed nonce information in-case of failures by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2050
18+
* fix bittensor not installing under Python 3.13 by @mjurbanski-reef in https://github.com/opentensor/bittensor/pull/2053
19+
* Enable Faucet Test by @opendansor in https://github.com/opentensor/bittensor/pull/2056
20+
* Add back BT_SUBTENSOR_CHAIN_ENDPOINT env variable by @bradleytf in https://github.com/opentensor/bittensor/pull/2034
21+
* Fix: Logging configs not being set by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2065
22+
* Feature/gus/liquid alpha params by @gus-opentensor in https://github.com/opentensor/bittensor/pull/2012
23+
* Test Emissions E2E by @opendansor in https://github.com/opentensor/bittensor/pull/2036
24+
* Prevent e2e draft by @opendansor in https://github.com/opentensor/bittensor/pull/2072
25+
* Fix e2e to only run when PR is ready for review by @opendansor in https://github.com/opentensor/bittensor/pull/2077
26+
* Fix Faucet and fastblocks interaction by @opendansor in https://github.com/opentensor/bittensor/pull/2083
27+
* Float normalization for child hotkeys by @opendansor in https://github.com/opentensor/bittensor/pull/2093
28+
* Fix e2e test hanging by @open-junius in https://github.com/opentensor/bittensor/pull/2118
29+
* Fixes leaked semaphores by @thewhaleking in https://github.com/opentensor/bittensor/pull/2125
30+
* Backmerge master -> staging by @roman-opentensor in https://github.com/opentensor/bittensor/pull/2136
31+
* fix: coldkeypub usage instead of coldkey for arbitration_stats by @Rapiiidooo in https://github.com/opentensor/bittensor/pull/2132
32+
* Removes extra no_prompts in commands by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2140
33+
* Adds timeout for e2e tests by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2141
34+
* fix: updates test_axon verify body async tests by @gus-opentensor in https://github.com/opentensor/bittensor/pull/2142
35+
* test: fix mocksubtensor query previous blocks by @timabilov in https://github.com/opentensor/bittensor/pull/2139
36+
* Adds E2E for Metagraph command by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2143
37+
* feat: Enhance dendrite error messaging by @gus-opentensor in https://github.com/opentensor/bittensor/pull/2117
38+
* Adds E2E Tests for wallet creation commands by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2145
39+
* [Ledger Integration] [Feature] bump pysub to 1.7.9+ by @camfairchild in https://github.com/opentensor/bittensor/pull/2156
40+
* Ruff complains about an extra line by @roman-opentensor in https://github.com/opentensor/bittensor/pull/2158
41+
* support Wallet names with hyphens when passing password through ENV vars by @mjurbanski-reef in https://github.com/opentensor/bittensor/pull/1949
42+
* Fix naming convention of swap hotkey test by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2162
43+
* Adds E2E test for wallet regenerations + fixes input bug for regen hotkey by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2149
44+
* Backmerge Master -> Staging (7.4) by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2170
45+
* ci: auto assigns cortex to opened PRs by @gus-opentensor in https://github.com/opentensor/bittensor/pull/2184
46+
* CI/E2E test improvements by @mvds00 in https://github.com/opentensor/bittensor/pull/2168
47+
* Fix multiprocessing POW errors and No Torch logging errors by @thewhaleking in https://github.com/opentensor/bittensor/pull/2186
48+
* ci: update reviewers by @gus-opentensor in https://github.com/opentensor/bittensor/pull/2189
49+
* Adds updated type in timeouts dendrite by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2196
50+
* Bumps setuptools ~=70.0.0 by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2150
51+
* Bump black from 23.7.0 to 24.3.0 in /requirements by @dependabot in https://github.com/opentensor/bittensor/pull/2197
52+
* btlogging/loggingmachine.py: Fix bw compat API. by @mvds00 in https://github.com/opentensor/bittensor/pull/2155
53+
* Check for participation before nomination call by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2193
54+
* test: subnet list e2e by @gus-opentensor in https://github.com/opentensor/bittensor/pull/2198
55+
* ensure msg is str in _concat_msg by @thewhaleking in https://github.com/opentensor/bittensor/pull/2200
56+
* Fixes tests depending on explicit line numbers by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2211
57+
* Merge streaming fix to staging by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2183
58+
* Multiple bittensor versions e2e workflow by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2212
59+
* Changes name of workflow file by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2213
60+
* Enhances e2e tests to contain assertions & logging by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2192
61+
* Security fix: Bumps ansible and certifi by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2214
62+
* Wallet List Command e2e test by @gus-opentensor in https://github.com/opentensor/bittensor/pull/2207
63+
* fix Synapse base performance (more than 10x speed up) by @mjurbanski-reef in https://github.com/opentensor/bittensor/pull/2161
64+
* Child Hotkeys by @opendansor in https://github.com/opentensor/bittensor/pull/2071
65+
* Improve child hotkeys QOL by @opendansor in https://github.com/opentensor/bittensor/pull/2225
66+
* Child hotkeys handle excess normalization by @opendansor in https://github.com/opentensor/bittensor/pull/2229
67+
* Fixes chain compilation timeouts by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2238
68+
* Update Child Hotkey commands by @opendansor in https://github.com/opentensor/bittensor/pull/2245
69+
* feat: return error message instead of raising exception by @gus-opentensor in https://github.com/opentensor/bittensor/pull/2244
70+
* Backmerge master to staging (7.3.1) by @ibraheem-opentensor in https://github.com/opentensor/bittensor/pull/2254
71+
72+
## New Contributors
73+
* @bradleytf made their first contribution in https://github.com/opentensor/bittensor/pull/2034
74+
* @Rapiiidooo made their first contribution in https://github.com/opentensor/bittensor/pull/2132
75+
* @timabilov made their first contribution in https://github.com/opentensor/bittensor/pull/2139
76+
* @mvds00 made their first contribution in https://github.com/opentensor/bittensor/pull/2168
77+
* @dependabot made their first contribution in https://github.com/opentensor/bittensor/pull/2197
78+
79+
**Full Changelog**: https://github.com/opentensor/bittensor/compare/v7.3.1...v7.4.0
80+
381
## 7.3.1 / 2024-08-19
482

583
## What's Changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7.3.1
1+
7.4.0

bittensor/__init__.py

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040

4141

4242
# Bittensor code and protocol version.
43-
__version__ = "7.3.1"
43+
__version__ = "7.4.0"
4444

4545
_version_split = __version__.split(".")
4646
__version_info__ = tuple(int(part) for part in _version_split)
@@ -125,7 +125,14 @@ def debug(on: bool = True):
125125
# Needs to use wss://
126126
__bellagene_entrypoint__ = "wss://parachain.opentensor.ai:443"
127127

128-
__local_entrypoint__ = "ws://127.0.0.1:9944"
128+
129+
if (
130+
BT_SUBTENSOR_CHAIN_ENDPOINT := os.getenv("BT_SUBTENSOR_CHAIN_ENDPOINT")
131+
) is not None:
132+
__local_entrypoint__ = BT_SUBTENSOR_CHAIN_ENDPOINT
133+
else:
134+
__local_entrypoint__ = "ws://127.0.0.1:9944"
135+
129136

130137
__tao_symbol__: str = chr(0x03C4)
131138

@@ -200,19 +207,6 @@ def debug(on: bool = True):
200207
},
201208
},
202209
},
203-
"ValidatorIPRuntimeApi": {
204-
"methods": {
205-
"get_associated_validator_ip_info_for_subnet": {
206-
"params": [
207-
{
208-
"name": "netuid",
209-
"type": "u16",
210-
},
211-
],
212-
"type": "Vec<u8>",
213-
},
214-
},
215-
},
216210
"SubnetInfoRuntimeApi": {
217211
"methods": {
218212
"get_subnet_hyperparams": {
@@ -318,7 +312,6 @@ def debug(on: bool = True):
318312
strtobool,
319313
strtobool_with_default,
320314
get_explorer_root_url_by_network_from_map,
321-
get_explorer_root_url_by_network_from_map,
322315
get_explorer_url_for_network,
323316
ss58_address_to_bytes,
324317
U16_NORMALIZED_FLOAT,

bittensor/axon.py

Lines changed: 92 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@
3131
import traceback
3232
import typing
3333
import uuid
34+
import warnings
3435
from inspect import signature, Signature, Parameter
3536
from typing import List, Optional, Tuple, Callable, Any, Dict, Awaitable
3637

3738
import uvicorn
38-
from fastapi import FastAPI, APIRouter, Depends
39+
from fastapi import APIRouter, Depends, FastAPI
3940
from fastapi.responses import JSONResponse
4041
from fastapi.routing import serialize_response
4142
from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
@@ -44,18 +45,19 @@
4445
from substrateinterface import Keypair
4546

4647
import bittensor
48+
from bittensor.utils.axon_utils import allowed_nonce_window_ns, calculate_diff_seconds
49+
from bittensor.constants import V_7_2_0
4750
from bittensor.errors import (
51+
BlacklistedException,
4852
InvalidRequestNameError,
49-
SynapseDendriteNoneException,
50-
SynapseParsingError,
51-
UnknownSynapseError,
5253
NotVerifiedException,
53-
BlacklistedException,
54-
PriorityException,
5554
PostProcessException,
55+
PriorityException,
56+
SynapseDendriteNoneException,
5657
SynapseException,
58+
SynapseParsingError,
59+
UnknownSynapseError,
5760
)
58-
from bittensor.constants import ALLOWED_DELTA, V_7_2_0
5961
from bittensor.threadpool import PriorityThreadPoolExecutor
6062
from bittensor.utils import networking
6163

@@ -484,17 +486,50 @@ def verify_custom(synapse: MyCustomSynapse):
484486

485487
async def endpoint(*args, **kwargs):
486488
start_time = time.time()
487-
response_synapse = forward_fn(*args, **kwargs)
488-
if isinstance(response_synapse, Awaitable):
489-
response_synapse = await response_synapse
490-
return await self.middleware_cls.synapse_to_response(
491-
synapse=response_synapse, start_time=start_time
492-
)
489+
response = forward_fn(*args, **kwargs)
490+
if isinstance(response, Awaitable):
491+
response = await response
492+
if isinstance(response, bittensor.Synapse):
493+
return await self.middleware_cls.synapse_to_response(
494+
synapse=response, start_time=start_time
495+
)
496+
else:
497+
response_synapse = getattr(response, "synapse", None)
498+
if response_synapse is None:
499+
warnings.warn(
500+
"The response synapse is None. The input synapse will be used as the response synapse. "
501+
"Reliance on forward_fn modifying input synapse as a side-effects is deprecated. "
502+
"Explicitly set `synapse` on response object instead.",
503+
DeprecationWarning,
504+
)
505+
# Replace with `return response` in next major version
506+
response_synapse = args[0]
507+
508+
return await self.middleware_cls.synapse_to_response(
509+
synapse=response_synapse,
510+
start_time=start_time,
511+
response_override=response,
512+
)
513+
514+
return_annotation = forward_sig.return_annotation
515+
516+
if isinstance(return_annotation, type) and issubclass(
517+
return_annotation, bittensor.Synapse
518+
):
519+
if issubclass(
520+
return_annotation,
521+
bittensor.StreamingSynapse,
522+
):
523+
warnings.warn(
524+
"The forward_fn return annotation is a subclass of bittensor.StreamingSynapse. "
525+
"Most likely the correct return annotation would be BTStreamingResponse."
526+
)
527+
else:
528+
return_annotation = JSONResponse
493529

494-
# replace the endpoint signature, but set return annotation to JSONResponse
495530
endpoint.__signature__ = Signature( # type: ignore
496531
parameters=list(forward_sig.parameters.values()),
497-
return_annotation=JSONResponse,
532+
return_annotation=return_annotation,
498533
)
499534

500535
# Add the endpoint to the router, making it available on both GET and POST methods
@@ -847,6 +882,8 @@ async def default_verify(self, synapse: bittensor.Synapse):
847882
The method checks for increasing nonce values, which is a vital
848883
step in preventing replay attacks. A replay attack involves an adversary reusing or
849884
delaying the transmission of a valid data transmission to deceive the receiver.
885+
The first time a nonce is seen, it is checked for freshness by ensuring it is
886+
within an acceptable delta time range.
850887
851888
Authenticity and Integrity Checks
852889
By verifying that the message's digital signature matches
@@ -893,33 +930,43 @@ async def default_verify(self, synapse: bittensor.Synapse):
893930
if synapse.dendrite.nonce is None:
894931
raise Exception("Missing Nonce")
895932

896-
# If we don't have a nonce stored, ensure that the nonce falls within
897-
# a reasonable delta.
898-
933+
# Newer nonce structure post v7.2
899934
if (
900935
synapse.dendrite.version is not None
901936
and synapse.dendrite.version >= V_7_2_0
902937
):
903938
# If we don't have a nonce stored, ensure that the nonce falls within
904939
# a reasonable delta.
940+
current_time_ns = time.time_ns()
941+
allowed_window_ns = allowed_nonce_window_ns(
942+
current_time_ns, synapse.timeout
943+
)
944+
905945
if (
906946
self.nonces.get(endpoint_key) is None
907-
and synapse.dendrite.nonce
908-
<= time.time_ns() - ALLOWED_DELTA - (synapse.timeout or 0)
947+
and synapse.dendrite.nonce <= allowed_window_ns
909948
):
910-
raise Exception("Nonce is too old")
949+
diff_seconds, allowed_delta_seconds = calculate_diff_seconds(
950+
current_time_ns, synapse.timeout, synapse.dendrite.nonce
951+
)
952+
raise Exception(
953+
f"Nonce is too old: acceptable delta is {allowed_delta_seconds:.2f} seconds but request was {diff_seconds:.2f} seconds old"
954+
)
955+
956+
# If a nonce is stored, ensure the new nonce
957+
# is greater than the previous nonce
911958
if (
912959
self.nonces.get(endpoint_key) is not None
913960
and synapse.dendrite.nonce <= self.nonces[endpoint_key]
914961
):
915-
raise Exception("Nonce is too old")
962+
raise Exception("Nonce is too old, a newer one was last processed")
963+
# Older nonce structure pre v7.2
916964
else:
917965
if (
918-
endpoint_key in self.nonces.keys()
919-
and self.nonces[endpoint_key] is not None
966+
self.nonces.get(endpoint_key) is not None
920967
and synapse.dendrite.nonce <= self.nonces[endpoint_key]
921968
):
922-
raise Exception("Nonce is too small")
969+
raise Exception("Nonce is too old, a newer one was last processed")
923970

924971
if not keypair.verify(message, synapse.dendrite.signature):
925972
raise Exception(
@@ -952,7 +999,7 @@ def log_and_handle_error(
952999
exception: Exception,
9531000
status_code: typing.Optional[int] = None,
9541001
start_time: typing.Optional[float] = None,
955-
):
1002+
) -> bittensor.Synapse:
9561003
if isinstance(exception, SynapseException):
9571004
synapse = exception.synapse or synapse
9581005

@@ -1420,14 +1467,21 @@ async def run(
14201467

14211468
@classmethod
14221469
async def synapse_to_response(
1423-
cls, synapse: bittensor.Synapse, start_time: float
1424-
) -> JSONResponse:
1470+
cls,
1471+
synapse: bittensor.Synapse,
1472+
start_time: float,
1473+
*,
1474+
response_override: Optional[Response] = None,
1475+
) -> Response:
14251476
"""
14261477
Converts the Synapse object into a JSON response with HTTP headers.
14271478
14281479
Args:
1429-
synapse (bittensor.Synapse): The Synapse object representing the request.
1430-
start_time (float): The timestamp when the request processing started.
1480+
synapse: The Synapse object representing the request.
1481+
start_time: The timestamp when the request processing started.
1482+
response_override:
1483+
Instead of serializing the synapse, mutate the provided response object.
1484+
This is only really useful for StreamingSynapse responses.
14311485
14321486
Returns:
14331487
Response: The final HTTP response, with updated headers, ready to be sent back to the client.
@@ -1446,11 +1500,14 @@ async def synapse_to_response(
14461500

14471501
synapse.axon.process_time = time.time() - start_time
14481502

1449-
serialized_synapse = await serialize_response(response_content=synapse)
1450-
response = JSONResponse(
1451-
status_code=synapse.axon.status_code,
1452-
content=serialized_synapse,
1453-
)
1503+
if response_override:
1504+
response = response_override
1505+
else:
1506+
serialized_synapse = await serialize_response(response_content=synapse)
1507+
response = JSONResponse(
1508+
status_code=synapse.axon.status_code,
1509+
content=serialized_synapse,
1510+
)
14541511

14551512
try:
14561513
updated_headers = synapse.to_headers()

0 commit comments

Comments
 (0)