def setUp(self): super().setUp() self.compute_task_def = self._get_deserialized_compute_task_def( deadline=get_current_utc_timestamp() + 100 ) self.task_to_compute = self._get_deserialized_task_to_compute( timestamp=parse_timestamp_to_utc_datetime(get_current_utc_timestamp()), compute_task_def=self.compute_task_def, ) self.report_computed_task = self._get_deserialized_report_computed_task( task_to_compute=self.task_to_compute, ) self.force_report_computed_task = self._get_deserialized_force_report_computed_task( report_computed_task=self.report_computed_task ) self.reject_report_computed_task = self._get_deserialized_reject_report_computed_task( reason=message.tasks.RejectReportComputedTask.REASON.SubtaskTimeLimitExceeded, task_to_compute=self.task_to_compute, ) self.force_get_task_result = self._get_deserialized_force_subtask_results( timestamp=parse_timestamp_to_utc_datetime(get_current_utc_timestamp()), task_to_compute=self.task_to_compute, ) self.provider_public_key = hex_to_bytes_convert(self.task_to_compute.provider_public_key) self.requestor_public_key = hex_to_bytes_convert(self.task_to_compute.requestor_public_key)
def test_that_claim_deposit_return_deposit_claims_if_both_requestor_and_provider_have_enough_funds(self): with mock.patch('core.payments.service.get_deposit_value', return_value=2) as get_deposit_value: (claim_against_requestor, claim_against_provider) = claim_deposit( subtask_id=self.task_to_compute.subtask_id, concent_use_case=ConcentUseCase.ADDITIONAL_VERIFICATION, requestor_ethereum_address=self.task_to_compute.requestor_ethereum_address, provider_ethereum_address=self.task_to_compute.provider_ethereum_address, subtask_cost=self.subtask_cost, requestor_public_key=hex_to_bytes_convert(self.task_to_compute.requestor_public_key), provider_public_key=hex_to_bytes_convert(self.task_to_compute.provider_public_key), ) self.assertIsInstance(claim_against_requestor, DepositClaim) self.assertEqual(claim_against_requestor.subtask_id, self.task_to_compute.subtask_id) self.assertEqual(claim_against_requestor.payee_ethereum_address, self.task_to_compute.provider_ethereum_address) self.assertEqual(claim_against_requestor.amount, self.subtask_cost) self.assertEqual(claim_against_requestor.concent_use_case, ConcentUseCase.ADDITIONAL_VERIFICATION) self.assertIsInstance(claim_against_provider, DepositClaim) self.assertEqual(claim_against_provider.subtask_id, self.task_to_compute.subtask_id) self.assertEqual( claim_against_provider.payee_ethereum_address, ethereum_public_key_to_address(settings.CONCENT_ETHEREUM_PUBLIC_KEY) ) self.assertEqual(claim_against_provider.amount, settings.ADDITIONAL_VERIFICATION_COST) self.assertEqual(claim_against_provider.concent_use_case, ConcentUseCase.ADDITIONAL_VERIFICATION) self.assertEqual(get_deposit_value.call_count, 2)
def setUp(self): super().setUp() self.compute_task_def = self._get_deserialized_compute_task_def( kwargs={ 'deadline': "2017-12-01 11:00:00", 'task_id': self._get_uuid(), }, ) self.task_to_compute_timestamp = "2017-12-01 10:00:00" self.task_to_compute = self._get_deserialized_task_to_compute( timestamp=self.task_to_compute_timestamp, compute_task_def=self.compute_task_def, ) self.report_computed_task_timestamp = "2017-12-01 11:01:00" self.report_computed_task = self._get_deserialized_report_computed_task( timestamp=self.report_computed_task_timestamp, task_to_compute=self.task_to_compute, ) with freeze_time(self.task_to_compute_timestamp): self.force_get_task_result = message.concents.ForceGetTaskResult( report_computed_task=self.report_computed_task, ) self.provider_public_key = hex_to_bytes_convert( self.task_to_compute.provider_public_key) self.requestor_public_key = hex_to_bytes_convert( self.task_to_compute.requestor_public_key)
def test_that_storing_subtask_with_task_to_compute_nested_in_another_messages_will_not_raise_exception_when_messages_are_equal( self, task_to_compute, report_computed_task, ack_report_computed_task, reject_report_computed_task, force_get_task_result, subtask_results_rejected, ): try: store_subtask( task_id=task_to_compute.task_id, subtask_id=task_to_compute.subtask_id, provider_public_key=hex_to_bytes_convert(task_to_compute.provider_public_key), requestor_public_key=hex_to_bytes_convert(task_to_compute.requestor_public_key), state=Subtask.SubtaskState.ACCEPTED, task_to_compute=task_to_compute, report_computed_task=report_computed_task, next_deadline=None, ack_report_computed_task=ack_report_computed_task, reject_report_computed_task=reject_report_computed_task, force_get_task_result=force_get_task_result, subtask_results_rejected=subtask_results_rejected, ) Subtask.objects.get(subtask_id=task_to_compute.subtask_id).delete() except Exception: # pylint: disable=broad-except pytest.fail()
def test_api_view_should_rollback_changes_on_400_error(self): store_subtask( task_id=self.compute_task_def['task_id'], subtask_id=self.compute_task_def['subtask_id'], provider_public_key=hex_to_bytes_convert( self.report_computed_task.task_to_compute.provider_public_key), requestor_public_key=hex_to_bytes_convert( self.report_computed_task.task_to_compute.requestor_public_key ), state=Subtask.SubtaskState.FORCING_RESULT_TRANSFER, next_deadline=(get_current_utc_timestamp() - 10), task_to_compute=self.task_to_compute, report_computed_task=self.report_computed_task, force_get_task_result=self.force_get_task_result, ) self.assertEqual(Client.objects.count(), 2) with mock.patch('core.subtask_helpers.verify_file_status', side_effect=_create_client_and_raise_http400_error_mock ) as _create_client_and_raise_error_mock_function: self.client.post( reverse('core:send'), data=dump(self.force_report_computed_task, PROVIDER_PRIVATE_KEY, CONCENT_PUBLIC_KEY), content_type='application/octet-stream', HTTP_X_GOLEM_MESSAGES=settings.GOLEM_MESSAGES_VERSION, ) _create_client_and_raise_error_mock_function.assert_called() self.assertEqual(Client.objects.count(), 2)
def test_that_claim_deposit_return_only_requestors_deposit_claim_if_requestor_has_enough_funds_and_it_is_not_additional_verification( self): with mock.patch('core.payments.service.get_deposit_value', return_value=1) as get_deposit_value: (claim_against_requestor, claim_against_provider) = claim_deposit( subtask_id=self.task_to_compute.subtask_id, concent_use_case=ConcentUseCase.FORCED_ACCEPTANCE, requestor_ethereum_address=self.task_to_compute. requestor_ethereum_address, provider_ethereum_address=self.task_to_compute. provider_ethereum_address, subtask_cost=1, requestor_public_key=hex_to_bytes_convert( self.task_to_compute.requestor_public_key), provider_public_key=hex_to_bytes_convert( self.task_to_compute.provider_public_key), ) self.assertIsInstance(claim_against_requestor, DepositClaim) self.assertEqual(claim_against_requestor.subtask_id, self.task_to_compute.subtask_id) self.assertEqual(claim_against_requestor.payee_ethereum_address, self.task_to_compute.provider_ethereum_address) self.assertEqual(claim_against_requestor.amount, self.subtask_cost) self.assertEqual(claim_against_requestor.concent_use_case, ConcentUseCase.FORCED_ACCEPTANCE) self.assertIsNone(claim_against_provider) self.assertEqual(get_deposit_value.call_count, 1)
def store_report_computed_task_as_subtask(report_computed_task): store_subtask( task_id=report_computed_task.task_to_compute.task_id, subtask_id=report_computed_task.task_to_compute.subtask_id, provider_public_key=hex_to_bytes_convert( report_computed_task.task_to_compute.provider_public_key), requestor_public_key=hex_to_bytes_convert( report_computed_task.task_to_compute.requestor_public_key), state=Subtask.SubtaskState.FORCING_REPORT, next_deadline=get_current_utc_timestamp() + settings.CONCENT_MESSAGING_TIME, task_to_compute=report_computed_task.task_to_compute, report_computed_task=report_computed_task, )
def test_that_claim_deposit_return_none_for_provider_if_provider_has_less_funds_than_needed(self): with mock.patch('core.payments.service.get_deposit_value', return_value=1) as get_deposit_value: with self.assertRaises(TooSmallProviderDeposit): claim_deposit( subtask_id=self.task_to_compute.subtask_id, concent_use_case=ConcentUseCase.ADDITIONAL_VERIFICATION, requestor_ethereum_address=self.task_to_compute.requestor_ethereum_address, provider_ethereum_address=self.task_to_compute.provider_ethereum_address, subtask_cost=1, requestor_public_key=hex_to_bytes_convert(self.task_to_compute.requestor_public_key), provider_public_key=hex_to_bytes_convert(self.task_to_compute.provider_public_key), ) self.assertEqual(get_deposit_value.call_count, 2)
def test_that_concent_responds_with_too_small_provider_deposit_when_provider_does_not_have_funds( self): """ Provider -> Concent: SubtaskResultsVerify Concent -> Provider: ServiceRefused (TooSmallProviderDeposit) """ # given (serialized_subtask_results_verify, subtask_results_verify_time_str ) = self._create_serialized_subtask_results_verify() # when with mock.patch( "core.message_handlers.bankster.claim_deposit", side_effect=TooSmallProviderDeposit) as claim_deposit_mock: with freeze_time(subtask_results_verify_time_str): response = self.send_request( url='core:send', data=serialized_subtask_results_verify, HTTP_CONCENT_CLIENT_PUBLIC_KEY=self. _get_encoded_provider_public_key(), HTTP_CONCENT_OTHER_PARTY_PUBLIC_KEY=self. _get_encoded_requestor_public_key(), ) claim_deposit_mock.assert_called_with( subtask_id=self.task_to_compute.subtask_id, concent_use_case=ConcentUseCase.ADDITIONAL_VERIFICATION, requestor_ethereum_address=self.task_to_compute. requestor_ethereum_address, provider_ethereum_address=self.task_to_compute. provider_ethereum_address, subtask_cost=self.task_to_compute.price, requestor_public_key=hex_to_bytes_convert( self.task_to_compute.requestor_public_key), provider_public_key=hex_to_bytes_convert( self.task_to_compute.provider_public_key), ) # then self._test_response( response, status=200, key=self.PROVIDER_PRIVATE_KEY, message_type=message.concents.ServiceRefused, fields={ 'reason': message.concents.ServiceRefused.REASON.TooSmallProviderDeposit, }) self._assert_stored_message_counter_not_increased()
def test_that_claim_deposit_return_nones_if_requestor_has_zero_funds(self): with mock.patch('core.payments.service.get_deposit_value', return_value=0) as get_deposit_value: (claim_against_requestor, claim_against_provider) = claim_deposit( subtask_id=self.task_to_compute.subtask_id, concent_use_case=ConcentUseCase.ADDITIONAL_VERIFICATION, requestor_ethereum_address=self.task_to_compute.requestor_ethereum_address, provider_ethereum_address=self.task_to_compute.provider_ethereum_address, subtask_cost=1, requestor_public_key=hex_to_bytes_convert(self.task_to_compute.requestor_public_key), provider_public_key=hex_to_bytes_convert(self.task_to_compute.provider_public_key), ) self.assertIsNone(claim_against_requestor) self.assertIsNone(claim_against_provider) self.assertEqual(get_deposit_value.call_count, 2)
def test_that_settle_overdue_acceptances_should_return_none_if_requestor_deposit_value_is_zero(self): task_to_compute = self._get_deserialized_task_to_compute( price=10000, ) with freeze_time("2018-02-05 10:00:15"): subtask_results_accepted_list = [ self._get_deserialized_subtask_results_accepted( task_to_compute=task_to_compute ) ] with freeze_time("2018-02-05 10:00:25"): with mock.patch( 'core.payments.bankster.service.get_deposit_value', return_value=0 ) as get_deposit_value_mock: claim_against_requestor = settle_overdue_acceptances( requestor_ethereum_address=task_to_compute.requestor_ethereum_address, provider_ethereum_address=task_to_compute.provider_ethereum_address, acceptances=subtask_results_accepted_list, requestor_public_key=hex_to_bytes_convert(task_to_compute.requestor_public_key), ) get_deposit_value_mock.assert_called() self.assertIsNone(claim_against_requestor)
def validate_reject_report_computed_task( client_message: RejectReportComputedTask) -> None: if (isinstance(client_message.cannot_compute_task, message.CannotComputeTask) and isinstance(client_message.task_failure, message.TaskFailure)): raise GolemMessageValidationError( "RejectReportComputedTask cannot contain CannotComputeTask and TaskFailure at the same time.", error_code=ErrorCode.MESSAGE_INVALID, ) if client_message.reason is None: raise GolemMessageValidationError( f'Error during handling RejectReportComputedTask. REASON is None, it should be message.tasks.RejectReportComputedTask.REASON instance', error_code=ErrorCode.MESSAGE_VALUE_WRONG_TYPE) if not isinstance(client_message.reason, RejectReportComputedTask.REASON): raise GolemMessageValidationError( f'Error during handling RejectReportComputedTask. REASON should be message.tasks.RejectReportComputedTask.REASON instance. ' f'Currently it is {type(client_message.reason)} instance', error_code=ErrorCode.MESSAGE_VALUE_WRONG_TYPE) validate_task_to_compute(client_message.task_to_compute) validate_that_golem_messages_are_signed_with_key( hex_to_bytes_convert( client_message.task_to_compute.requestor_public_key), client_message.task_to_compute, )
def test_that_settle_overdue_acceptances_should_raise_exception_if_subtask_costs_where_already_paid(self): task_to_compute = self._get_deserialized_task_to_compute( price=13000, ) subtask_results_accepted_list = [ self._get_deserialized_subtask_results_accepted( task_to_compute=task_to_compute ) ] with mock.patch( 'core.payments.bankster.service.get_list_of_payments', side_effect=[ self._get_list_of_batch_transactions(), self._get_list_of_force_transactions(), ] ) as get_list_of_payments_mock: with self.assertRaises(BanksterTimestampError): settle_overdue_acceptances( requestor_ethereum_address=task_to_compute.requestor_ethereum_address, provider_ethereum_address=task_to_compute.provider_ethereum_address, acceptances=subtask_results_accepted_list, requestor_public_key=hex_to_bytes_convert(task_to_compute.requestor_public_key), ) get_list_of_payments_mock.assert_called()
def are_subtask_results_accepted_messages_signed_by_the_same_requestor( subtask_results_accepted_list: List[SubtaskResultsAccepted]) -> bool: requestor_public_key = subtask_results_accepted_list[ 0].task_to_compute.requestor_public_key are_all_signed_by_requestor = all( is_golem_message_signed_with_key( hex_to_bytes_convert(requestor_public_key), subtask_results_accepted) for subtask_results_accepted in subtask_results_accepted_list) return are_all_signed_by_requestor
def setUp(self): super().setUp() self.compute_task_def = self._get_deserialized_compute_task_def( task_id='1', deadline="2017-12-01 11:00:00" ) self.task_to_compute_timestamp = "2017-12-01 10:00:00" self.task_to_compute = self._get_deserialized_task_to_compute( timestamp=self.task_to_compute_timestamp, compute_task_def=self.compute_task_def, ) self.report_computed_task_timestamp = "2017-12-01 11:01:00" self.report_computed_task = self._get_deserialized_report_computed_task( timestamp=self.report_computed_task_timestamp, task_to_compute=self.task_to_compute, ) self.provider_public_key = hex_to_bytes_convert(self.task_to_compute.provider_public_key) self.requestor_public_key = hex_to_bytes_convert(self.task_to_compute.requestor_public_key)
def get_validated_client_public_key_from_client_message(golem_message: message.base.Message): if isinstance(golem_message, message.concents.ForcePayment): if ( isinstance(golem_message.subtask_results_accepted_list, list) and len(golem_message.subtask_results_accepted_list) > 0 ): task_to_compute = golem_message.subtask_results_accepted_list[0].task_to_compute else: raise ConcentValidationError( "subtask_results_accepted_list must be a list type and contains at least one message", error_code=ErrorCode.MESSAGE_VALUE_WRONG_LENGTH, ) elif isinstance(golem_message, message.tasks.TaskMessage): if not golem_message.is_valid(): raise GolemMessageValidationError( "Golem message invalid", error_code=ErrorCode.MESSAGE_INVALID ) task_to_compute = golem_message.task_to_compute else: raise ConcentValidationError( "Unknown message type", error_code=ErrorCode.MESSAGE_UNKNOWN, ) if task_to_compute is not None: if isinstance(golem_message, ( message.ForceReportComputedTask, message.concents.ForceSubtaskResults, message.concents.ForcePayment, message.concents.SubtaskResultsVerify, )): client_public_key = task_to_compute.provider_public_key validate_hex_public_key(client_public_key, 'provider_public_key') elif isinstance(golem_message, ( message.AckReportComputedTask, message.RejectReportComputedTask, message.concents.ForceGetTaskResult, message.concents.ForceSubtaskResultsResponse, )): client_public_key = task_to_compute.requestor_public_key validate_hex_public_key(client_public_key, 'requestor_public_key') else: raise ConcentValidationError( "Unknown message type", error_code=ErrorCode.MESSAGE_UNKNOWN, ) return hex_to_bytes_convert(client_public_key) return None
def store_report_computed_task_as_subtask(): task_to_compute = factories.tasks.TaskToComputeFactory() report_computed_task = factories.tasks.ReportComputedTaskFactory(task_to_compute=task_to_compute) ack_report_computed_task = factories.tasks.AckReportComputedTaskFactory(report_computed_task=report_computed_task) force_get_task_result = factories.concents.ForceGetTaskResultFactory(report_computed_task=report_computed_task) subtask_results_rejected = factories.tasks.SubtaskResultsRejectedFactory(report_computed_task=report_computed_task) subtask = store_subtask( task_id=task_to_compute.task_id, subtask_id=task_to_compute.subtask_id, provider_public_key=hex_to_bytes_convert(task_to_compute.provider_public_key), requestor_public_key=hex_to_bytes_convert(task_to_compute.requestor_public_key), state=Subtask.SubtaskState.ACCEPTED, task_to_compute=task_to_compute, report_computed_task=report_computed_task, next_deadline=None, ack_report_computed_task=ack_report_computed_task, reject_report_computed_task=None, force_get_task_result=force_get_task_result, subtask_results_rejected=subtask_results_rejected, ) return subtask
def setUp(self) -> None: super().setUp() self.compute_task_def = self._get_deserialized_compute_task_def() self.task_to_compute = self._get_deserialized_task_to_compute( compute_task_def=self.compute_task_def, ) self.report_computed_task = self._get_deserialized_report_computed_task( task_to_compute=self.task_to_compute, ) self.provider_public_key = hex_to_bytes_convert( self.task_to_compute.provider_public_key) self.requestor_public_key = hex_to_bytes_convert( self.task_to_compute.requestor_public_key) self.provider = Client.objects.get_or_create_full_clean( self.provider_public_key) self.requestor = Client.objects.get_or_create_full_clean( self.requestor_public_key) self.size = self.report_computed_task.size self.task_id = self.task_to_compute.task_id self.subtask_id = self.task_to_compute.subtask_id
def store_report_computed_task_as_subtask(self, current_time, task_id, deadline, next_deadline, subtask_state): # pylint: disable=no-self-use subtask_id = task_id + '1' file_content = '1' file_size = len(file_content) file_check_sum = 'sha1:' + hashlib.sha1( file_content.encode()).hexdigest() task_to_compute = self._get_deserialized_task_to_compute( task_id=task_id, subtask_id=subtask_id, deadline=deadline, price=0, timestamp=parse_timestamp_to_utc_datetime(current_time), signer_private_key=self.REQUESTOR_PRIVATE_KEY) report_computed_task = ReportComputedTaskFactory( task_to_compute=task_to_compute, size=file_size, package_hash=file_check_sum, subtask_id=subtask_id, sign__privkey=self.PROVIDER_PRIVATE_KEY, ) force_get_task_result = ForceGetTaskResult( report_computed_task=report_computed_task, ) store_subtask( task_id=report_computed_task.task_to_compute.task_id, subtask_id=report_computed_task.task_to_compute.subtask_id, provider_public_key=hex_to_bytes_convert( report_computed_task.task_to_compute.provider_public_key), requestor_public_key=hex_to_bytes_convert( report_computed_task.task_to_compute.requestor_public_key), state=subtask_state, next_deadline=next_deadline, task_to_compute=report_computed_task.task_to_compute, report_computed_task=report_computed_task, force_get_task_result=force_get_task_result, )
def test_that_storing_subtask_with_task_to_compute_nested_in_another_messages_will_raise_exception_when_it_is_different_from_original_task_to_compute( self, task_to_compute, report_computed_task, ack_report_computed_task, reject_report_computed_task, force_get_task_result, subtask_results_rejected, ): with pytest.raises(ValidationError): store_subtask( task_id=task_to_compute.task_id, subtask_id=task_to_compute.subtask_id, provider_public_key=hex_to_bytes_convert(task_to_compute.provider_public_key), requestor_public_key=hex_to_bytes_convert(task_to_compute.requestor_public_key), state=Subtask.SubtaskState.ACCEPTED, task_to_compute=task_to_compute, report_computed_task=report_computed_task, next_deadline=None, ack_report_computed_task=ack_report_computed_task, reject_report_computed_task=reject_report_computed_task, force_get_task_result=force_get_task_result, subtask_results_rejected=subtask_results_rejected, )
def test_that_incorrect_version_of_golem_messages_in_stored_message_should_raise_validation_error(self): with override_settings(GOLEM_MESSAGES_VERSION=self.second_communication_protocol_version): task_to_compute = tasks.TaskToComputeFactory() report_computed_task=tasks.ReportComputedTaskFactory(task_to_compute=task_to_compute) with self.assertRaises(ValidationError) as error: with mock.patch('core.message_handlers.store_message', side_effect=self.store_message_with_custom_protocol_version): store_subtask( task_id=task_to_compute.task_id, subtask_id=task_to_compute.subtask_id, task_to_compute=task_to_compute, provider_public_key=hex_to_bytes_convert(task_to_compute.provider_public_key), requestor_public_key=hex_to_bytes_convert(task_to_compute.requestor_public_key), report_computed_task=report_computed_task, state=Subtask.SubtaskState.REPORTED, next_deadline=None, ) self.assertIn( f"Unsupported Golem Message version. Version in: `task_to_compute` is {self.first_communication_protocol_version}, " f"Version in Concent is {self.second_communication_protocol_version}", str(error.exception) )
def test_that_settle_overdue_acceptances_should_return_claim_deposit_with_amount_paid(self): task_to_compute = self._get_deserialized_task_to_compute( price=15000, ) with freeze_time("2018-02-05 10:00:15"): subtask_results_accepted_list = [ self._get_deserialized_subtask_results_accepted( task_to_compute=task_to_compute ) ] with freeze_time("2018-02-05 10:00:25"): with mock.patch('core.payments.bankster.service.get_deposit_value', return_value=1000) as get_deposit_value_mock: with mock.patch( 'core.payments.bankster.service.get_list_of_payments', side_effect=[ self._get_list_of_batch_transactions(), self._get_list_of_force_transactions(), ] ) as get_list_of_payments_mock: claim_against_requestor = settle_overdue_acceptances( requestor_ethereum_address=task_to_compute.requestor_ethereum_address, provider_ethereum_address=task_to_compute.provider_ethereum_address, acceptances=subtask_results_accepted_list, requestor_public_key=hex_to_bytes_convert(task_to_compute.requestor_public_key), ) get_deposit_value_mock.assert_called_once() get_list_of_payments_mock.assert_called() self.assertIsNotNone(claim_against_requestor.tx_hash) # The results of payments are calculated in the following way: # already_paid_value = 15000 - ( # (1000 + 2000 + 3000 + 4000)(batch_transactions) + # (1000 + 2000)(force_transactions) # ) # already_paid_value == 13000, so 2000 left # get_deposit_value returns 1000, so 1000 paid and 1000 left (pending) self.assertEqual(claim_against_requestor.amount, 1000)
def call_settle_overdue_acceptances_with_mocked_sci_functions( self, get_deposit_value_return_value=None, get_list_of_payments_return_value=None, ): with freeze_time("2018-02-05 10:00:25"): with mock.patch( 'core.payments.bankster.validate_list_of_transaction_timestamp' ) as self.validate_list_of_transaction_mock: with mock.patch( 'core.payments.bankster.service.get_deposit_value', return_value=( get_deposit_value_return_value if get_deposit_value_return_value is not None else self.get_deposit_value_return_value_default), ) as self.get_deposit_value_mock: with mock.patch( 'core.payments.bankster.service.get_list_of_payments', side_effect=[ (get_list_of_payments_return_value if get_list_of_payments_return_value is not None else self._get_list_of_settlement_transactions()), self._get_list_of_batch_transactions() ], ) as self.get_list_of_payments_mock: claim_against_requestor = settle_overdue_acceptances( requestor_ethereum_address=self.task_to_compute. requestor_ethereum_address, provider_ethereum_address=self.task_to_compute. provider_ethereum_address, acceptances=self.subtask_results_accepted_list, requestor_public_key=hex_to_bytes_convert( self.task_to_compute.requestor_public_key), ) return claim_against_requestor
def test_that_concent_accepts_valid_request_and_sends_verification_order_to_work_queue( self): """ Provider -> Concent: SubtaskResultsVerify Concent -> Provider: AckSubtaskResultsVerify """ # given (serialized_subtask_results_verify, subtask_results_verify_time_str ) = self._create_serialized_subtask_results_verify() # when with mock.patch("core.message_handlers.bankster.claim_deposit", side_effect=self.claim_deposit_true_mock ) as claim_deposit_mock: with mock.patch( "core.queue_operations.blender_verification_request.delay" ) as send_verification_request_mock: with freeze_time(subtask_results_verify_time_str): response = self.send_request( url='core:send', data=serialized_subtask_results_verify, HTTP_CONCENT_CLIENT_PUBLIC_KEY=self. _get_encoded_provider_public_key(), HTTP_CONCENT_OTHER_PARTY_PUBLIC_KEY=self. _get_encoded_requestor_public_key(), ) claim_deposit_mock.assert_called_with( subtask_id=self.task_to_compute.subtask_id, concent_use_case=ConcentUseCase.ADDITIONAL_VERIFICATION, requestor_ethereum_address=self.task_to_compute. requestor_ethereum_address, provider_ethereum_address=self.task_to_compute. provider_ethereum_address, subtask_cost=self.task_to_compute.price, requestor_public_key=hex_to_bytes_convert( self.task_to_compute.requestor_public_key), provider_public_key=hex_to_bytes_convert( self.task_to_compute.provider_public_key), ) send_verification_request_mock.assert_called_once_with( frames=[1], subtask_id=self.task_to_compute.subtask_id, source_package_path=self.source_package_path, result_package_path=self.result_package_path, output_format=self.report_computed_task.task_to_compute. compute_task_def['extra_data']['output_format'], scene_file=extract_name_from_scene_file_path( self.report_computed_task.task_to_compute. compute_task_def['extra_data']['scene_file']), verification_deadline=self. _get_blender_rendering_deadline_as_timestamp( parse_iso_date_to_timestamp( self.subtask_result_rejected_time_str), self.report_computed_task.size, self.report_computed_task.task_to_compute, ), blender_crop_script=self.report_computed_task.task_to_compute. compute_task_def['extra_data']['script_src'], ) # then subtask_results_verify = self._prepare_subtask_results_verify( serialized_subtask_results_verify) self._test_response( response, status=200, key=self.PROVIDER_PRIVATE_KEY, message_type=message.concents.AckSubtaskResultsVerify, fields={ 'subtask_results_verify': subtask_results_verify, 'file_transfer_token': self._prepare_file_transfer_token(subtask_results_verify), 'file_transfer_token.files': [ message.concents.FileTransferToken.FileInfo( path= f'blender/result/{self.task_to_compute.task_id}/{self.task_to_compute.task_id}.{self.task_to_compute.subtask_id}.zip', checksum= 'sha1:4452d71687b6bc2c9389c3349fdc17fbd73b833b', size=1, category=message.concents.FileTransferToken.FileInfo. Category.results, ), message.concents.FileTransferToken.FileInfo( path= f'blender/source/{self.task_to_compute.task_id}/{self.task_to_compute.task_id}.{self.task_to_compute.subtask_id}.zip', checksum= 'sha1:230fb0cad8c7ed29810a2183f0ec1d39c9df3f4a', size=1, category=message.concents.FileTransferToken.FileInfo. Category.resources, ) ] }) self._assert_stored_message_counter_increased(increased_by=4)
def test_sum_of_payments_when_lists_of_transactions_from_payment_api_are_empty( self): """ Expected message exchange: Provider -> Concent: ForcePayment Concent -> Provider: ForcePaymentCommitted Concent -> Requestor: ForcePaymentCommitted """ task_to_compute = self._get_deserialized_task_to_compute( timestamp="2018-02-05 10:00:00", deadline="2018-02-05 10:00:10", subtask_id=self._get_uuid('1'), price=20000, ) subtask_results_accepted_list = [ self._get_deserialized_subtask_results_accepted( timestamp="2018-02-05 10:00:15", payment_ts="2018-02-05 12:00:00", report_computed_task=self. _get_deserialized_report_computed_task( timestamp="2018-02-05 10:00:05", task_to_compute=task_to_compute)), self._get_deserialized_subtask_results_accepted( timestamp="2018-02-05 9:00:15", payment_ts="2018-02-05 11:00:00", report_computed_task=self. _get_deserialized_report_computed_task( timestamp="2018-02-05 10:00:05", task_to_compute=self._get_deserialized_task_to_compute( timestamp="2018-02-05 9:00:00", deadline="2018-02-05 9:00:10", subtask_id=self._get_uuid('2'), price=5000, ))) ] serialized_force_payment = self._get_serialized_force_payment( timestamp="2018-02-05 12:00:20", subtask_results_accepted_list=subtask_results_accepted_list) with freeze_time("2018-02-05 12:00:20"): with mock.patch( 'core.message_handlers.bankster.settle_overdue_acceptances', side_effect=self.settle_overdue_acceptances_mock ) as settle_overdue_acceptances: response_1 = self.send_request( url='core:send', data=serialized_force_payment, ) settle_overdue_acceptances.assert_called_with( requestor_ethereum_address=task_to_compute. requestor_ethereum_address, provider_ethereum_address=task_to_compute. provider_ethereum_address, acceptances=subtask_results_accepted_list, requestor_public_key=hex_to_bytes_convert( task_to_compute.requestor_public_key), ) self._test_response( response_1, status=200, key=self.PROVIDER_PRIVATE_KEY, message_type=message.concents.ForcePaymentCommitted, fields={ 'recipient_type': message.concents.ForcePaymentCommitted.Actor.Provider, 'timestamp': parse_iso_date_to_timestamp("2018-02-05 12:00:20"), 'amount_pending': self.amount_pending, 'amount_paid': self.amount_paid, }) self._assert_stored_message_counter_not_increased() with freeze_time("2018-02-05 12:00:21"): response_2 = self.send_request( url='core:receive', data=self._create_requestor_auth_message(), ) self._test_response( response_2, status=200, key=self.REQUESTOR_PRIVATE_KEY, message_type=message.concents.ForcePaymentCommitted, fields={ 'recipient_type': message.concents.ForcePaymentCommitted.Actor.Requestor, 'timestamp': parse_iso_date_to_timestamp("2018-02-05 12:00:21"), 'amount_pending': self.amount_pending, 'amount_paid': self.amount_paid, 'task_owner_key': decode_hex(task_to_compute.requestor_ethereum_public_key), }) self._assert_stored_message_counter_not_increased()
def test_provider_send_force_payment_with_no_value_to_be_paid_concent_should_reject( self): """ Expected message exchange: Provider -> Concent: ForcePayment Concent -> Provider: ForcePaymentRejected """ task_to_compute = self._get_deserialized_task_to_compute( timestamp="2018-02-05 10:00:00", deadline="2018-02-05 10:00:10", subtask_id=self._get_uuid('1'), price=10000, ) subtask_results_accepted_list = [ self._get_deserialized_subtask_results_accepted( timestamp="2018-02-05 10:00:15", payment_ts="2018-02-05 11:55:00", report_computed_task=self. _get_deserialized_report_computed_task( timestamp="2018-02-05 10:00:05", task_to_compute=task_to_compute)), self._get_deserialized_subtask_results_accepted( timestamp="2018-02-05 9:00:15", payment_ts="2018-02-05 11:55:00", report_computed_task=self. _get_deserialized_report_computed_task( timestamp="2018-02-05 10:00:05", task_to_compute=self._get_deserialized_task_to_compute( timestamp="2018-02-05 9:00:00", deadline="2018-02-05 9:00:10", subtask_id=self._get_uuid('2'), price=3000, ))) ] serialized_force_payment = self._get_serialized_force_payment( timestamp="2018-02-05 12:00:20", subtask_results_accepted_list=subtask_results_accepted_list) with freeze_time("2018-02-05 12:00:20"): with mock.patch( 'core.message_handlers.bankster.settle_overdue_acceptances', return_value=None) as settle_overdue_acceptances: response = self.send_request( url='core:send', data=serialized_force_payment, ) settle_overdue_acceptances.assert_called_with( requestor_ethereum_address=task_to_compute. requestor_ethereum_address, provider_ethereum_address=task_to_compute. provider_ethereum_address, acceptances=subtask_results_accepted_list, requestor_public_key=hex_to_bytes_convert( task_to_compute.requestor_public_key), ) self._test_response( response, status=200, key=self.PROVIDER_PRIVATE_KEY, message_type=message.concents.ForcePaymentRejected, fields={ 'reason': message.concents.ForcePaymentRejected.REASON. NoUnsettledTasksFound, 'timestamp': parse_iso_date_to_timestamp("2018-02-05 12:00:20"), 'force_payment.timestamp': parse_iso_date_to_timestamp("2018-02-05 12:00:20"), 'force_payment.subtask_results_accepted_list': subtask_results_accepted_list, }) self._assert_stored_message_counter_not_increased()
def test_that_if_requestor_does_not_have_funds_concent_responds_with_service_refused( self): """ Expected message exchange: Provider -> Concent: ForcePayment Concent -> Provider: ServiceRefused (RESASON: TooSmallRequestorDeposit) """ task_to_compute = self._get_deserialized_task_to_compute( timestamp="2018-02-05 10:00:00", deadline="2018-02-05 10:00:10", subtask_id=self._get_uuid('1'), price=10000, ) subtask_results_accepted_list = [ self._get_deserialized_subtask_results_accepted( timestamp="2018-02-05 10:00:15", payment_ts="2018-02-05 9:55:00", report_computed_task=self. _get_deserialized_report_computed_task( timestamp="2018-02-05 10:00:05", task_to_compute=task_to_compute)), self._get_deserialized_subtask_results_accepted( timestamp="2018-02-05 9:00:15", payment_ts="2018-02-05 8:55:00", report_computed_task=self. _get_deserialized_report_computed_task( timestamp="2018-02-05 10:00:05", task_to_compute=self._get_deserialized_task_to_compute( timestamp="2018-02-05 9:00:00", deadline="2018-02-05 9:00:10", subtask_id=self._get_uuid('2'), price=3000, ))) ] serialized_force_payment = self._get_serialized_force_payment( timestamp="2018-02-05 12:00:20", subtask_results_accepted_list=subtask_results_accepted_list) with freeze_time("2018-02-05 12:00:20"): with mock.patch( 'core.message_handlers.bankster.settle_overdue_acceptances', side_effect=BanksterTooSmallRequestorDepositError( )) as settle_overdue_acceptances: response = self.send_request( url='core:send', data=serialized_force_payment, ) settle_overdue_acceptances.assert_called_with( requestor_ethereum_address=task_to_compute. requestor_ethereum_address, provider_ethereum_address=task_to_compute. provider_ethereum_address, acceptances=subtask_results_accepted_list, requestor_public_key=hex_to_bytes_convert( task_to_compute.requestor_public_key), ) self._test_response( response, status=200, key=self.PROVIDER_PRIVATE_KEY, message_type=message.concents.ServiceRefused, fields={ 'reason': message.concents.ServiceRefused.REASON. TooSmallRequestorDeposit, 'timestamp': parse_iso_date_to_timestamp("2018-02-05 12:00:20"), }) self._assert_stored_message_counter_not_increased()
def test_provider_send_correct_force_payment_concent_should_accept(self): """ Expected message exchange: Provider -> Concent: ForcePayment Concent -> Provider: ForcePaymentCommitted Concent -> Requestor: ForcePaymentCommitted """ task_to_compute = self._get_deserialized_task_to_compute( timestamp="2018-02-05 10:00:00", deadline="2018-02-05 10:00:10", subtask_id=self._get_uuid('1'), price=15000, ) subtask_results_accepted_list = [ self._get_deserialized_subtask_results_accepted( timestamp="2018-02-05 10:00:15", payment_ts="2018-02-05 11:55:00", report_computed_task=self. _get_deserialized_report_computed_task( timestamp="2018-02-05 10:00:05", task_to_compute=task_to_compute, )), self._get_deserialized_subtask_results_accepted( timestamp="2018-02-05 9:00:15", payment_ts="2018-02-05 11:55:00", report_computed_task=self. _get_deserialized_report_computed_task( timestamp="2018-02-05 9:00:05", task_to_compute=self._get_deserialized_task_to_compute( timestamp="2018-02-05 9:00:00", deadline="2018-02-05 9:00:10", subtask_id=self._get_uuid('2'), price=7000, ))) ] serialized_force_payment = self._get_serialized_force_payment( timestamp="2018-02-05 12:00:20", subtask_results_accepted_list=subtask_results_accepted_list) with freeze_time("2018-02-05 12:00:20"): with mock.patch( 'core.message_handlers.bankster.settle_overdue_acceptances', side_effect=self.settle_overdue_acceptances_mock ) as settle_overdue_acceptances: response_1 = self.send_request( url='core:send', data=serialized_force_payment, ) settle_overdue_acceptances.assert_called_with( requestor_ethereum_address=task_to_compute. requestor_ethereum_address, provider_ethereum_address=task_to_compute. provider_ethereum_address, acceptances=subtask_results_accepted_list, requestor_public_key=hex_to_bytes_convert( task_to_compute.requestor_public_key), ) self._test_response( response_1, status=200, key=self.PROVIDER_PRIVATE_KEY, message_type=message.concents.ForcePaymentCommitted, fields={ 'recipient_type': message.concents.ForcePaymentCommitted.Actor.Provider, 'timestamp': parse_iso_date_to_timestamp("2018-02-05 12:00:20"), 'amount_pending': self.amount_pending, 'amount_paid': self.amount_paid, }) self._assert_stored_message_counter_not_increased() last_pending_message = PendingResponse.objects.filter( delivered=False).order_by('created_at').last() self.assertEqual( last_pending_message.response_type, PendingResponse.ResponseType.ForcePaymentCommitted.name) # pylint: disable=no-member self.assertEqual(last_pending_message.client.public_key_bytes, self.REQUESTOR_PUBLIC_KEY) with freeze_time("2018-02-05 12:00:21"): response_2 = self.send_request( url='core:receive', data=self._create_requestor_auth_message(), ) self._test_response( response_2, status=200, key=self.REQUESTOR_PRIVATE_KEY, message_type=message.concents.ForcePaymentCommitted, fields={ 'recipient_type': message.concents.ForcePaymentCommitted.Actor.Requestor, 'timestamp': parse_iso_date_to_timestamp("2018-02-05 12:00:21"), 'amount_pending': self.amount_pending, 'amount_paid': self.amount_paid, 'task_owner_key': decode_hex(task_to_compute.requestor_ethereum_public_key), }) self._assert_stored_message_counter_not_increased() last_pending_message = PendingResponse.objects.filter( delivered=False).last() self.assertIsNone(last_pending_message)