diff --git a/.gitignore b/.gitignore index a798d092..fd03cb6d 100644 --- a/.gitignore +++ b/.gitignore @@ -200,6 +200,7 @@ bt_venv/ ENV/ env.bak/ venv.bak/ +bt_venv # Spyder project settings .spyderproject diff --git a/simulation/validator/forward.py b/simulation/validator/forward.py index c177305b..1e842001 100644 --- a/simulation/validator/forward.py +++ b/simulation/validator/forward.py @@ -31,6 +31,7 @@ from simulation.validator.miner_data_handler import MinerDataHandler from simulation.validator.moving_average import compute_weighted_averages from simulation.validator.price_data_provider import PriceDataProvider +from simulation.validator.response_validation import validate_responses from simulation.validator.reward import get_rewards @@ -249,7 +250,7 @@ async def _query_available_miners_and_save_responses( miner_predictions = {} for i, response in enumerate(responses): - if response is None or len(response) == 0: + if validate_responses(response, simulation_input) is False: continue miner_id = miner_uids[i] miner_predictions[miner_id] = response diff --git a/simulation/validator/response_validation.py b/simulation/validator/response_validation.py new file mode 100644 index 00000000..98dedd8a --- /dev/null +++ b/simulation/validator/response_validation.py @@ -0,0 +1,48 @@ +import json +from datetime import datetime, timedelta + + +from simulation.simulation_input import SimulationInput + + +def validate_responses(response, simulation_input: SimulationInput) -> bool: + """ + Validate responses from miners. + + Return False if response is incorrect. + """ + if response is None or len(response) == 0: + return False + + # check the number of paths + if len(response) != simulation_input.num_simulations: + return False + + for path in response: + # check the number of time points + if ( + len(path) + != ( + simulation_input.time_length // simulation_input.time_increment + ) + + 1 + ): + return False + + # check the start time + if path[0]["time"] != simulation_input.start_time: + return False + + for i in range(1, len(path)): + # check the time increment + i_minus_one_time = datetime.fromisoformat(path[i - 1]["time"]) + i_time = datetime.fromisoformat(path[i]["time"]) + expected_delta = timedelta(seconds=simulation_input.time_increment) + if i_time - i_minus_one_time != expected_delta: + return False + + # check the price format + if not isinstance(path[i]["price"], (int, float)): + return False + + return True