Skip to content

Commit 963386e

Browse files
committed
generate the right id
1 parent 6be8718 commit 963386e

1 file changed

Lines changed: 60 additions & 28 deletions

File tree

subvortex/validator/neuron/src/challenge.py

Lines changed: 60 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@
1818
import time
1919
import random
2020
import asyncio
21+
import string
2122
import traceback
2223
import websockets
2324
import bittensor.core.subtensor as btcs
2425
import bittensor.utils.btlogging as btul
26+
from itertools import cycle
27+
from websockets.sync.client import connect, ClientConnection
2528
from typing import Dict
2629
from collections import Counter
2730
from websockets.exceptions import (
@@ -76,6 +79,19 @@
7679
"last_update",
7780
]
7881

82+
id_cycle = cycle(range(1, 999))
83+
84+
rng = random.Random()
85+
86+
87+
def get_next_id() -> str:
88+
"""
89+
Generates a pseudo-random ID by returning the next int of a range from 1-998 prepended with
90+
two random ascii characters.
91+
"""
92+
random_letters = "".join(rng.choices(string.ascii_letters, k=2))
93+
return f"{random_letters}{next(id_cycle)}"
94+
7995

8096
def get_runtime_call_definition(
8197
substrate: btcs.SubstrateInterface, api: str, method: str
@@ -219,7 +235,7 @@ async def challenge_miner(self, miner: Miner):
219235
return (verified, reason, details)
220236

221237

222-
async def challenge_subtensor(miner: Miner, challenge, max_retries=3):
238+
def challenge_subtensor(miner: Miner, challenge, max_retries=3):
223239
"""
224240
Challenge the subtensor by requesting the value of a property of a specific neuron in a specific subnet at a certain block
225241
"""
@@ -229,48 +245,52 @@ async def challenge_subtensor(miner: Miner, challenge, max_retries=3):
229245
process_time = None
230246

231247
# Retry logic for geographic connectivity issues
248+
ws: ClientConnection = None
232249
for attempt in range(max_retries):
233250
try:
234251
# Get the details of the challenge
235252
block_hash, params, value = challenge
236-
253+
237254
# Add small delay between retries
238255
if attempt > 0:
239-
await asyncio.sleep(attempt * 1.0) # 1s, 2s, 3s delays
240-
btul.logging.debug(f"[{CHALLENGE_NAME}][{miner.uid}] Retry attempt {attempt + 1}/{max_retries}")
256+
btul.logging.trace(
257+
f"[{CHALLENGE_NAME}][{miner.uid}] Retry attempt {attempt + 1}/{max_retries}"
258+
)
241259

242-
ws = None
243260
try:
244261
# Increase connection timeout for international connections
245-
ws = await websockets.connect(
246-
f"ws://{miner.ip}:9944",
247-
ping_timeout=None, # Disable ping timeout
248-
ping_interval=None, # Disable ping
249-
close_timeout=10, # 10s close timeout
250-
open_timeout=15, # 15s connection timeout
251-
additional_headers={
252-
"Connection": "keep-alive",
253-
},
254-
)
262+
ws = (
263+
connect(
264+
f"ws://{miner.ip}:9944",
265+
max_size=2**32,
266+
)
267+
if not ws or ws.close_code
268+
else ws
269+
)
255270

256271
except InvalidURI as ex:
257272
# Invalid URI - don't retry, fail immediately
258273
reason = f"Invalid WebSocket URI ws://{miner.ip}:9944"
259274
details = str(ex)
260275
break
261-
262-
except (asyncio.TimeoutError, OSError, InvalidHandshake, WebSocketException) as ex:
276+
277+
except (
278+
asyncio.TimeoutError,
279+
OSError,
280+
InvalidHandshake,
281+
WebSocketException,
282+
) as ex:
263283
# These are connection errors - let retry logic handle them
264284
raise ex
265285

266-
267286
# Set start time
268287
start_time = time.time()
269288

270289
# Prepare data payload
290+
item_id = get_next_id()
271291
data = json.dumps(
272292
{
273-
"id": "state_call0",
293+
"id": item_id,
274294
"jsonrpc": "2.0",
275295
"method": "state_call",
276296
"params": [
@@ -283,18 +303,30 @@ async def challenge_subtensor(miner: Miner, challenge, max_retries=3):
283303

284304
try:
285305
# Send request
286-
await ws.send(data)
306+
ws.send(data)
287307

288308
except ConnectionClosed as ex:
289309
# Connection error - let retry logic handle
310+
btul.logging.trace(
311+
f"[{CHALLENGE_NAME}][{miner.uid}] WebSocket closed during send: {ex}"
312+
)
290313
raise ex
291314

292315
try:
293316
# Receive response with timeout for international connections
294-
response = await asyncio.wait_for(ws.recv(), timeout=20.0)
317+
response = ws.recv(decode=False, timeout=60.0)
318+
319+
except asyncio.TimeoutError as ex:
320+
btul.logging.trace(
321+
f"[{CHALLENGE_NAME}][{miner.uid}] WebSocket receive timeout: {ex}"
322+
)
323+
raise ex
295324

296-
except (asyncio.TimeoutError, ConnectionClosed) as ex:
325+
except ConnectionClosed as ex:
297326
# Connection error - let retry logic handle
327+
btul.logging.trace(
328+
f"[{CHALLENGE_NAME}][{miner.uid}] WebSocket closed during receive: {ex}"
329+
)
298330
raise ex
299331

300332
# Calculate process time
@@ -327,18 +359,18 @@ async def challenge_subtensor(miner: Miner, challenge, max_retries=3):
327359
btul.logging.trace(
328360
f"[{CHALLENGE_NAME}][{miner.uid}] Total challenge time: {total_time:.2f}s"
329361
)
330-
362+
331363
# Success - break retry loop
332364
break
333365

334366
except (ConnectionClosed, WebSocketException, asyncio.TimeoutError) as ex:
335367
# These are retryable errors - continue to next attempt
336368
reason = f"Connection error on attempt {attempt + 1}/{max_retries}"
337369
details = str(ex)
338-
btul.logging.debug(f"[{CHALLENGE_NAME}][{miner.uid}] {reason}: {details}")
339-
370+
btul.logging.trace(f"[{CHALLENGE_NAME}][{miner.uid}] {reason}: {details}")
371+
340372
if attempt == max_retries - 1: # Last attempt
341-
reason = "WebSocket connection failed after retries"
373+
reason = f"WebSocket connection failed after {max_retries} retries: {str(ex)}"
342374
break
343375

344376
except Exception as ex:
@@ -349,7 +381,7 @@ async def challenge_subtensor(miner: Miner, challenge, max_retries=3):
349381

350382
finally:
351383
if ws:
352-
await ws.close()
384+
ws.close()
353385
ws = None
354386

355387
return (verified, reason, details, process_time)
@@ -383,7 +415,7 @@ async def handle_challenge(self, uid: int, challenge):
383415
# Challenge Subtensor - Process time + check the challenge
384416
btul.logging.debug(f"[{CHALLENGE_NAME}][{miner.uid}] Challenging subtensor")
385417
subtensor_verified, subtensor_reason, subtensor_details, subtensor_time = (
386-
await challenge_subtensor(miner, challenge)
418+
challenge_subtensor(miner, challenge)
387419
)
388420
if subtensor_verified:
389421
btul.logging.success(f"[{CHALLENGE_NAME}][{miner.uid}] Subtensor verified")

0 commit comments

Comments
 (0)