def test_that_calculate_subtask_verification_time_will_not_call_subtask_verification_time_when_custom_protocol_times_is_on( self): with mock.patch('core.utils.subtask_verification_time', return_value=datetime.timedelta() ) as mock_subtask_verification_time: calculate_subtask_verification_time(self.report_computed_task) mock_subtask_verification_time.assert_not_called()
def test_that_subtask_verification_time_query_gives_correct_value_without_custom_protocol_times( self): with override_settings( CUSTOM_PROTOCOL_TIMES=False, CONCENT_MESSAGING_TIME=int(constants.CMT.total_seconds()), MINIMUM_UPLOAD_RATE=constants.DEFAULT_UPLOAD_RATE, DOWNLOAD_LEADIN_TIME=constants.DOWNLOAD_LEADIN_TIME. total_seconds(), ): subtask_verification_time = calculate_subtask_verification_time( self.report_computed_task) assert_that( Subtask.objects_with_timing_columns.get( subtask_id=self.report_computed_task.task_to_compute. subtask_id).subtask_verification_time).is_equal_to( subtask_verification_time)
def test_that_subtask_verification_time_query_gives_correct_value( self, minimum_upload_rate, download_leadin_time, concent_messaging_time, custom_protocol_times): with override_settings( MINIMUM_UPLOAD_RATE=minimum_upload_rate, DOWNLOAD_LEADIN_TIME=download_leadin_time, CONCENT_MESSAGING_TIME=concent_messaging_time, CUSTOM_PROTOCOL_TIMES=custom_protocol_times, ): subtask_verification_time = calculate_subtask_verification_time( self.report_computed_task) assert_that( Subtask.objects_with_timing_columns.get( subtask_id=self.report_computed_task.task_to_compute. subtask_id).subtask_verification_time).is_equal_to( subtask_verification_time)
def calculate_token_expiration_deadline( operation: FileTransferToken.Operation, report_computed_task: message.tasks.ReportComputedTask, ) -> int: if operation == FileTransferToken.Operation.upload: token_expiration_deadline = ( int(report_computed_task.task_to_compute.compute_task_def['deadline']) + 3 * settings.CONCENT_MESSAGING_TIME + 2 * calculate_maximum_download_time(report_computed_task.size, settings.MINIMUM_UPLOAD_RATE) ) elif operation == FileTransferToken.Operation.download: token_expiration_deadline = ( int(report_computed_task.task_to_compute.compute_task_def['deadline']) + calculate_subtask_verification_time(report_computed_task) ) return token_expiration_deadline
def test_that_both_subtask_verification_time_implementation_should_return_same_result_when_golem_messages_constants_match_concent_settings(self): current_time = get_current_utc_timestamp() for size, timestamp, deadline in [ (7, current_time + 7, current_time + 7), (10, current_time, current_time + 10), (19, current_time + 19, current_time + 19), (100, current_time + 100, current_time + 100), (331, current_time + 331, current_time + 331), (999, current_time + 999, current_time + 999), ]: report_computed_task = self._get_deserialized_report_computed_task( size=size, task_to_compute=self._get_deserialized_task_to_compute( timestamp=parse_timestamp_to_utc_datetime(timestamp), deadline=deadline, ) ) self.assertEqual( calculate_subtask_verification_time(report_computed_task), int(helpers.subtask_verification_time(report_computed_task).total_seconds()) )
def upload_finished(subtask_id: str): try: subtask = Subtask.objects.get(subtask_id=subtask_id) except Subtask.DoesNotExist: logging.error( f'Task `upload_finished` tried to get Subtask object with ID {subtask_id} but it does not exist.' ) return report_computed_task = deserialize_message( subtask.report_computed_task.data.tobytes()) # Check subtask state, if it's VERIFICATION FILE TRANSFER, proceed with the task. if subtask.state_enum == Subtask.SubtaskState.VERIFICATION_FILE_TRANSFER: # If subtask is past the deadline, processes the timeout. if subtask.next_deadline.timestamp() < get_current_utc_timestamp(): # Worker makes a payment from requestor's deposit just like in the forced acceptance use case. payments_service.make_force_payment_to_provider( # pylint: disable=no-value-for-parameter requestor_eth_address=report_computed_task.task_to_compute. requestor_ethereum_address, provider_eth_address=report_computed_task.task_to_compute. provider_ethereum_address, value=report_computed_task.task_to_compute.price, payment_ts=get_current_utc_timestamp(), ) update_subtask_state( subtask=subtask, state=Subtask.SubtaskState.FAILED.name, # pylint: disable=no-member ) # Worker adds SubtaskResultsSettled to provider's and requestor's receive queues (both out-of-band) for public_key in [ subtask.provider.public_key_bytes, subtask.requestor.public_key_bytes ]: store_pending_message( response_type=PendingResponse.ResponseType. SubtaskResultsSettled, client_public_key=public_key, queue=PendingResponse.Queue.ReceiveOutOfBand, subtask=subtask, ) return # Change subtask state to ADDITIONAL VERIFICATION. update_subtask_state( subtask=subtask, state=Subtask.SubtaskState.ADDITIONAL_VERIFICATION.name, # pylint: disable=no-member next_deadline=int(subtask.next_deadline.timestamp()) + calculate_subtask_verification_time(report_computed_task)) # Add upload_acknowledged task to the work queue. tasks.upload_acknowledged.delay( subtask_id=subtask_id, source_file_size=report_computed_task.task_to_compute.size, source_package_hash=report_computed_task.task_to_compute. package_hash, result_file_size=report_computed_task.size, result_package_hash=report_computed_task.package_hash, ) # If it's ADDITIONAL VERIFICATION, ACCEPTED or FAILED, log a warning and ignore the notification. # Processing ends here. This means that it's a duplicate notification. elif subtask.state_enum in [ Subtask.SubtaskState.ADDITIONAL_VERIFICATION, Subtask.SubtaskState.ACCEPTED, Subtask.SubtaskState.FAILED ]: logging.warning( f'Subtask with ID {subtask_id} is expected to be in `VERIFICATION_FILE_TRANSFER` state, but was in {subtask.state}.' ) # If it's one of the states that can precede verification, report an error. Processing ends here. else: logging.error( f'Subtask with ID {subtask_id} is expected to be in `VERIFICATION_FILE_TRANSFER` state, but was in {subtask.state}.' )