22# -*- coding: utf-8 -*-
33
44import os
5- import json
65import time
76import argparse
87import datetime
98import threading
109import traceback
11- from typing import Annotated
1210
13- import uvicorn
1411import requests
1512import bittensor as bt
16- from fastapi import Body , FastAPI
17- from prometheus_fastapi_instrumentator import Instrumentator
1813
1914from neurons .validator .validator import Validator
2015from redteam_core import constants
3732
3833def get_reward_app_config () -> bt .Config :
3934 parser = argparse .ArgumentParser ()
40- parser .add_argument ("--reward_app.port" , type = int , default = 47920 )
4135 parser .add_argument ("--reward_app.epoch_length" , type = int , default = 60 )
4236 config = get_config (parser )
4337 return config
@@ -50,7 +44,6 @@ class RewardApp(Validator):
5044 1. Does not participate in querying miners or setting weights
5145 2. Maintains state like regular validators
5246 3. Scores miner commits retrieved from storage
53- 4. Provides API endpoints for direct access to scoring results
5447 """
5548
5649 def __init__ (self , config : bt .Config ):
@@ -92,29 +85,6 @@ def __init__(self, config: bt.Config):
9285 challenge_name : False for challenge_name in self .active_challenges .keys ()
9386 }
9487
95- # Initialize FastAPI app (May change this to use bt.axon in the future)
96- self .app = FastAPI ()
97- self .app .add_api_route (
98- "/get_scoring_result" ,
99- self .get_scoring_result ,
100- methods = ["POST" ],
101- )
102- Instrumentator ().instrument (self .app ).expose (self .app )
103- # Run FastAPI server in a separate thread
104- self .server_thread = threading .Thread (
105- target = uvicorn .run ,
106- kwargs = {
107- "app" : self .app ,
108- "host" : "0.0.0.0" ,
109- "port" : self .config .reward_app .port ,
110- "log_level" : "debug" ,
111- },
112- daemon = True , # Ensures the thread stops when the main process exits
113- )
114- self .server_thread .start ()
115- bt .logging .info (
116- f"FastAPI server is running on port { self .config .reward_app .port } !"
117- )
11888 bt .logging .info (
11989 f"Reward app constant values: { constants .model_dump_json (indent = 2 )} "
12090 )
@@ -228,39 +198,9 @@ def forward(self):
228198 validate_scoring_date = today_key not in self .scoring_dates
229199
230200 if validate_scoring_hour and validate_scoring_date :
231- # # At this point, all commits should be scored and compared against previous unique commits already, we now need to compare new commits with each other
232- # for challenge in revealed_commits:
233- # if revealed_commits[challenge]:
234- # self._compare_miner_commits(
235- # challenge=challenge,
236- # revealed_commits_list=revealed_commits[challenge],
237- # compare_with_each_other=True,
238- # )
239-
240- # # Update scores and penalties to challenge manager and mark challenge as done
241201 for challenge in revealed_commits :
242- # self.challenge_managers[challenge].update_miner_scores(
243- # miner_commits=revealed_commits[challenge]
244- # )
245202 self .is_scoring_done [challenge ] = True
246203
247- # # Store commits and scoring cache from this challenge
248- # self._store_miner_commits(
249- # miner_commits={challenge: revealed_commits[challenge]}
250- # )
251- # self._store_centralized_scoring(challenge_name=challenge)
252-
253- # self.scoring_dates.append(today_key)
254-
255- # # Store reward app state, this can be viewed by other validators, so we need to make it public view
256- # self.storage_manager.update_validator_state(
257- # data=self.export_state(public_view=True), async_update=True
258- # )
259- # else:
260- # bt.logging.info(
261- # f"[CENTRALIZED FORWARD] Not time to finalize daily result. Hour: {current_hour}, Date: {today_key}"
262- # )
263-
264204 def _score_and_compare_new_miner_commits (
265205 self , challenge : str , revealed_commits_list : list [MinerChallengeCommit ]
266206 ):
@@ -889,62 +829,6 @@ def _sync_scoring_results_from_storage_to_cache(self):
889829 for hashed_cache_key in cache_keys_to_delete :
890830 diskcache_ .delete (hashed_cache_key )
891831
892- # MARK: Endpoints
893- async def get_scoring_result (
894- self ,
895- challenge_name : Annotated [str , Body (..., embed = True )],
896- encrypted_commits : Annotated [list [str ], Body (..., embed = True )],
897- ):
898- """
899- API endpoint to get scoring logs for specific docker hub IDs.
900- This method check for encrypted_commit in miner_commits and return the cached commit result.
901-
902- Args:
903- docker_hub_ids: List of docker hub IDs to look up
904-
905- Returns:
906- dict: {
907- docker_hub_id: scoring_log or None if not found
908- }
909- """
910- assert (
911- challenge_name in self .active_challenges
912- ), f"Challenge { challenge_name } is not active"
913-
914- results : dict [str , MinerChallengeCommit ] = {}
915-
916- for encrypted_commit in encrypted_commits :
917- # Try in-memory cache first
918- cache_key = f"{ challenge_name } ---{ encrypted_commit } "
919- commit_result = self .miner_commits_cache .get (cache_key , None )
920- if commit_result :
921- results [encrypted_commit ] = commit_result .public_view ()
922- continue
923-
924- # Fallback to disk cache
925- try :
926- hashed_cache_key = self .storage_manager .hash_cache_key (encrypted_commit )
927- challenge_cache = self .storage_manager ._get_cache (challenge_name )
928- cached_data = challenge_cache .get (hashed_cache_key )
929-
930- if cached_data :
931- commit_result = MinerChallengeCommit .model_validate (cached_data )
932- results [encrypted_commit ] = commit_result .public_view ()
933- else :
934- results [encrypted_commit ] = None
935- except Exception as e :
936- bt .logging .error (f"Error retrieving from disk cache: { e } " )
937- results [encrypted_commit ] = None
938-
939- return {
940- "status" : "success" ,
941- "message" : "Scoring results retrieved successfully" ,
942- "data" : {
943- "commits" : results ,
944- "is_done" : self .is_scoring_done .get (challenge_name ),
945- },
946- }
947-
948832
949833if __name__ == "__main__" :
950834 # Initialize and run app
0 commit comments