def test_provider_send_force_payment_beyond_payment_time_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'), ) 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 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'), ))) ] serialized_force_payment = self._get_serialized_force_payment( timestamp="2018-02-05 12:00:19", subtask_results_accepted_list=subtask_results_accepted_list) with freeze_time("2018-02-05 12:00:09"): response = self.send_request( url='core:send', data=serialized_force_payment, ) self._test_response( response, status=200, key=self.PROVIDER_PRIVATE_KEY, message_type=message.concents.ForcePaymentRejected, fields={ 'reason': message.concents.ForcePaymentRejected.REASON.TimestampError, 'timestamp': parse_iso_date_to_timestamp("2018-02-05 12:00:09"), 'force_payment.timestamp': parse_iso_date_to_timestamp("2018-02-05 12:00:19"), 'force_payment.subtask_results_accepted_list': subtask_results_accepted_list, }) self._assert_stored_message_counter_not_increased()
def test_provider_send_force_payment_with_subtask_results_accepted_where_ethereum_accounts_are_different_concent_should_refuse( self): """ Expected message exchange: Provider -> Concent: ForcePayment Concent -> Provider: ServiceRefused """ subtask_results_accepted_list = [ self._get_deserialized_subtask_results_accepted( timestamp="2018-02-05 10:00:15", payment_ts="2018-02-05 12:00:16", 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 10:00:00", deadline="2018-02-05 10:00:10", subtask_id=self._get_uuid('1'), ))), self._get_deserialized_subtask_results_accepted( timestamp="2018-02-05 9:00:15", payment_ts="2018-02-05 11:00:16", 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", requestor_ethereum_public_key=self. _get_requestor_ethereum_hex_public_key_different(), requestor_ethereum_private_key=self. DIFFERENT_REQUESTOR_PRIV_ETH_KEY, subtask_id=self._get_uuid('2'), ))) ] serialized_force_payment = self._get_serialized_force_payment( timestamp="2018-02-05 10:00:15", subtask_results_accepted_list=subtask_results_accepted_list) with freeze_time("2018-02-05 10:00:25"): response = self.send_request( url='core:send', data=serialized_force_payment, ) self._test_response( response, status=200, key=self.PROVIDER_PRIVATE_KEY, message_type=message.concents.ServiceRefused, fields={ 'reason': message.concents.ServiceRefused.REASON.InvalidRequest, 'timestamp': parse_iso_date_to_timestamp("2018-02-05 10:00:25"), }) self._assert_stored_message_counter_not_increased()
def test_that_messages_are_stored_with_correct_timestamps(self): subtask = store_subtask( task_id=self.task_to_compute.compute_task_def['task_id'], subtask_id=self.task_to_compute.compute_task_def['subtask_id'], provider_public_key=self.provider_public_key, requestor_public_key=self.requestor_public_key, state=Subtask.SubtaskState.FORCING_REPORT, next_deadline=int(self.task_to_compute.compute_task_def['deadline']) + settings.CONCENT_MESSAGING_TIME, task_to_compute=self.task_to_compute, report_computed_task=self.report_computed_task, ) self.assertEqual( parse_iso_date_to_timestamp(subtask.task_to_compute.timestamp.isoformat()), parse_iso_date_to_timestamp(self.task_to_compute_timestamp) ) self.assertEqual( parse_iso_date_to_timestamp(subtask.report_computed_task.timestamp.isoformat()), parse_iso_date_to_timestamp(self.report_computed_task_timestamp) )
def test_provider_send_force_payment_with_same_subtasks_id_concent_should_refuse( self): """ Expected message exchange: Provider -> Concent: ForcePayment Concent -> Provider: ServiceRefused """ 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", task_to_compute=self._get_deserialized_task_to_compute( timestamp="2018-02-05 10:00:00", deadline="2018-02-05 10:00:10", task_id='2', subtask_id='4', price=15000, )), self._get_deserialized_subtask_results_accepted( timestamp="2018-02-05 9:00:15", payment_ts="2018-02-05 11:00:00", task_to_compute=self._get_deserialized_task_to_compute( timestamp="2018-02-05 9:00:00", deadline="2018-02-05 9:00:10", task_id='2', subtask_id='4', price=15000, )) ] 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"): response = self.client.post( reverse('core:send'), data=serialized_force_payment, content_type='application/octet-stream', ) self._test_response( response, status=200, key=self.PROVIDER_PRIVATE_KEY, message_type=message.concents.ServiceRefused, fields={ 'reason': message.concents.ServiceRefused.REASON.DuplicateRequest, 'timestamp': parse_iso_date_to_timestamp("2018-02-05 12:00:20"), }) self._assert_stored_message_counter_not_increased()
def test_that_concent_responds_with_service_refused_when_verification_for_this_subtask_is_duplicated( self): """ Provider -> Concent: SubtaskResultsVerify Concent -> Provider: ServiceRefused (DuplicateRequest) """ # given (serialized_subtask_results_verify, subtask_results_verify_time_str ) = self._create_serialized_subtask_results_verify() store_subtask( task_id=self.task_to_compute.task_id, subtask_id=self.task_to_compute.subtask_id, provider_public_key=self.PROVIDER_PUBLIC_KEY, requestor_public_key=self.REQUESTOR_PUBLIC_KEY, state=Subtask.SubtaskState.ADDITIONAL_VERIFICATION, next_deadline=parse_iso_date_to_timestamp( subtask_results_verify_time_str) + (self.compute_task_def['deadline'] - self.task_to_compute.timestamp), task_to_compute=self.report_computed_task.task_to_compute, report_computed_task=self.report_computed_task, ) self._assert_stored_message_counter_increased(3) # when with mock.patch("core.message_handlers.bankster.claim_deposit", side_effect=self.claim_deposit_true_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(), ) # then self._test_response( response, status=200, key=self.PROVIDER_PRIVATE_KEY, message_type=message.concents.ServiceRefused, fields={ 'reason': message.concents.ServiceRefused.REASON.DuplicateRequest, }) self._assert_stored_message_counter_not_increased()
def test_require_golem_auth_message_should_return_http_200_when_message_included( self): with freeze_time("2017-12-31 00:00:00"): request = self.request_factory.post( "/dummy-url/", content_type='application/octet-stream', data=self._create_provider_auth_message()) with freeze_time("2017-12-31 00:00:10"): response = dummy_view_require_golem_auth_message(request) # pylint: disable=no-value-for-parameter self.assertIsInstance(response, message.concents.ClientAuthorization) self.assertEqual(response.client_public_key, self.PROVIDER_PUBLIC_KEY) self.assertEqual( response.sig, self._add_signature_to_message(response, self.PROVIDER_PRIVATE_KEY)) self.assertEqual(response.timestamp, parse_iso_date_to_timestamp("2017-12-31 00:00:00"))
def test_handle_errors_and_responses_should_return_serialized_message_if_gets_deserialized( self): with freeze_time("2017-12-31 00:00:00"): client_auth = message.concents.ClientAuthorization() client_auth.client_public_key = self.PROVIDER_PUBLIC_KEY request = self.request_factory.post( "/dummy-url/", content_type='application/octet-stream') with freeze_time("2017-12-31 00:00:10"): response = dummy_view_handle_errors_and_responses( request, client_auth, self.PROVIDER_PUBLIC_KEY) loaded_response = load(response.content, self.PROVIDER_PRIVATE_KEY, CONCENT_PUBLIC_KEY) # pylint: disable=no-member self.assertEqual(response.status_code, 200) # pylint: disable=no-member self.assertIsInstance(loaded_response, message.concents.ClientAuthorization) self.assertEqual(loaded_response.timestamp, parse_iso_date_to_timestamp("2017-12-31 00:00:00"))
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_provider_send_force_payment_and_concent_should_return_it_to_requestor_with_correct_keys( self): """ Expected message exchange: Provider -> Concent: ForcePayment Concent -> Provider: ForcePaymentCommitted Concent -> WrongRequestor/Provider: HTTP 204 Concent -> Requestor: ForcePaymentCommitted """ 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", 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='2', price=15000, )), self._get_deserialized_subtask_results_accepted( timestamp="2018-02-05 9:00:15", payment_ts="2018-02-05 11:55:00", 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='3', 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 mock.patch( 'core.message_handlers.payments_service.make_force_payment_to_provider', side_effect=self._make_force_payment_to_provider ) as make_force_payment_to_provider_mock: with freeze_time("2018-02-05 12:00:20"): fake_responses = [ self._get_list_of_batch_transactions(), self._get_list_of_force_transactions(), ] with mock.patch( 'core.message_handlers.payments_service.get_list_of_payments', side_effect=fake_responses ) as get_list_of_payments_mock: response_1 = self.client.post( reverse('core:send'), data=serialized_force_payment, content_type='application/octet-stream', ) make_force_payment_to_provider_mock.assert_called_once() self.assertEqual(get_list_of_payments_mock.call_count, 2) 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"), }) 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, self._get_encoded_requestor_public_key()) with freeze_time("2018-02-05 12:00:21"): response_2 = self.client.post( reverse('core:receive_out_of_band'), data=self._create_provider_auth_message(), content_type='application/octet-stream', ) self._test_204_response(response_2) self._assert_stored_message_counter_not_increased() with freeze_time("2018-02-05 12:00:22"): response_3 = self.client.post( reverse('core:receive_out_of_band'), data=self._create_diff_requestor_auth_message(), content_type='application/octet-stream', ) self._test_204_response(response_3) self._assert_stored_message_counter_not_increased() with freeze_time("2018-02-05 12:00:23"): response_4 = self.client.post( reverse('core:receive_out_of_band'), data=self._create_requestor_auth_message(), content_type='application/octet-stream', ) self._test_response( response_4, 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:23"), }) self._assert_stored_message_counter_not_increased() self._assert_client_count_is_equal(1) last_pending_message = PendingResponse.objects.filter( delivered=False).last() self.assertIsNone(last_pending_message)
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_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)
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_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='2', 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", 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", 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='3', 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.payments_service.get_list_of_payments', side_effect=self._get_empty_list_of_transactions ) as get_list_of_payments_mock_function,\ mock.patch( 'core.message_handlers.payments_service.make_force_payment_to_provider', side_effect=self._make_force_payment_to_provider ) as make_force_payment_to_provider_mock_function: response_1 = self.client.post( reverse('core:send'), data=serialized_force_payment, content_type='application/octet-stream', ) make_force_payment_to_provider_mock_function.assert_called_with( requestor_eth_address=task_to_compute.requestor_ethereum_address, provider_eth_address=task_to_compute.provider_ethereum_address, value=25000, payment_ts=parse_iso_date_to_timestamp("2018-02-05 12:00:20"), ) get_list_of_payments_mock_function.assert_called_with( requestor_eth_address=task_to_compute.requestor_ethereum_address, provider_eth_address=task_to_compute.provider_ethereum_address, payment_ts=parse_iso_date_to_timestamp("2018-02-05 11:00:10"), current_time=parse_iso_date_to_timestamp("2018-02-05 12:00:20"), transaction_type=TransactionType.FORCE, ) 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': 25000, 'amount_paid': 0, }) self._assert_stored_message_counter_not_increased() with freeze_time("2018-02-05 12:00:21"): response_2 = self.client.post( reverse('core:receive_out_of_band'), data=self._create_requestor_auth_message(), content_type='application/octet-stream', ) 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': 25000, 'amount_paid': 0, 'task_owner_key': decode_hex(task_to_compute.requestor_ethereum_public_key), }) 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='2', 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", 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", 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='3', 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"): fake_responses = [ self._get_list_of_batch_transactions(), self._get_list_of_force_transactions() ] with mock.patch( 'core.message_handlers.payments_service.make_force_payment_to_provider', side_effect=self._make_force_payment_to_provider ) as make_force_payment_to_provider_mock_function,\ mock.patch( 'core.message_handlers.payments_service.get_list_of_payments', side_effect=fake_responses ) as get_list_of_payments_mock_function: response_1 = self.client.post( reverse('core:send'), data=serialized_force_payment, content_type='application/octet-stream', ) make_force_payment_to_provider_mock_function.assert_called_with( requestor_eth_address=task_to_compute.requestor_ethereum_address, provider_eth_address=task_to_compute.provider_ethereum_address, value=9000, payment_ts=parse_iso_date_to_timestamp("2018-02-05 12:00:20"), ) get_list_of_payments_mock_function.assert_called_with( requestor_eth_address=task_to_compute.requestor_ethereum_address, provider_eth_address=task_to_compute.provider_ethereum_address, payment_ts=parse_iso_date_to_timestamp("2018-02-05 11:55:10"), current_time=parse_iso_date_to_timestamp("2018-02-05 12:00:20"), transaction_type=TransactionType.FORCE, ) # Sum of prices from force and batch lists of transactions which have been paid amount_paid = 10000 + 3000 # Sum of price in all TaskToCompute messages minus amount_paid amount_pending = 15000 + 7000 - amount_paid 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': amount_pending, 'amount_paid': 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.client.post( reverse('core:receive_out_of_band'), data=self._create_requestor_auth_message(), content_type='application/octet-stream', ) 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': amount_pending, 'amount_paid': 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)
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='2', 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", 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", 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='3', 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"): fake_responses = [ self._get_list_of_batch_transactions(), self._get_list_of_force_transactions() ] with mock.patch( 'core.message_handlers.payments_service.get_list_of_payments', side_effect=fake_responses ) as get_list_of_payments_mock_function: response = self.client.post( reverse('core:send'), data=serialized_force_payment, content_type='application/octet-stream', ) get_list_of_payments_mock_function.assert_called_with( requestor_eth_address=task_to_compute.requestor_ethereum_address, provider_eth_address=task_to_compute.provider_ethereum_address, payment_ts=parse_iso_date_to_timestamp("2018-02-05 11:55:10"), current_time=parse_iso_date_to_timestamp("2018-02-05 12:00:20"), transaction_type=TransactionType.FORCE, ) 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_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.payments_service.is_account_status_positive", return_value=True) as is_account_status_positive_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.client.post( reverse('core:send'), data=serialized_subtask_results_verify, content_type='application/octet-stream', HTTP_CONCENT_CLIENT_PUBLIC_KEY=self. _get_encoded_provider_public_key(), HTTP_CONCENT_OTHER_PARTY_PUBLIC_KEY=self. _get_encoded_requestor_public_key(), ) is_account_status_positive_mock.assert_called_with( client_eth_address=self.report_computed_task.task_to_compute. requestor_ethereum_address, pending_value=0, ) send_verification_request_mock.assert_called_once_with( frames=[1], subtask_id=self.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=self.report_computed_task.task_to_compute. compute_task_def['extra_data']['scene_file'], verification_deadline=self._get_verification_deadline_as_timestamp( parse_iso_date_to_timestamp( self.subtask_result_rejected_time_str), self.task_to_compute, ), blender_crop_script=self.report_computed_task.task_to_compute. compute_task_def['extra_data']['script_src'], ) # then self._test_response( response, status=200, key=self.PROVIDER_PRIVATE_KEY, message_type=message.concents.AckSubtaskResultsVerify, fields={ 'subtask_results_verify': self._prepare_subtask_results_verify( serialized_subtask_results_verify), 'file_transfer_token': self._prepare_file_transfer_token( subtask_results_verify_time_str), 'file_transfer_token.files': [ message.FileTransferToken.FileInfo( path='blender/result/task1/task1.subtask1.zip', checksum= 'sha1:4452d71687b6bc2c9389c3349fdc17fbd73b833b', size=1, category=message.FileTransferToken.FileInfo.Category. results, ), message.FileTransferToken.FileInfo( path='blender/source/task1/task1.subtask1.zip', checksum= 'sha1:230fb0cad8c7ed29810a2183f0ec1d39c9df3f4a', size=1, category=message.FileTransferToken.FileInfo.Category. resources, ) ] }) self._assert_stored_message_counter_increased(increased_by=3)
def test_provider_send_force_payment_and_concent_should_return_it_to_requestor_with_correct_keys( self): """ Expected message exchange: Provider -> Concent: ForcePayment Concent -> Provider: ForcePaymentCommitted Concent -> WrongRequestor/Provider: HTTP 204 Concent -> Requestor: ForcePaymentCommitted """ 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=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, ))), 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=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 mock.patch( 'core.message_handlers.bankster.settle_overdue_acceptances', side_effect=self.settle_overdue_acceptances_mock ) as settle_overdue_acceptances: with freeze_time("2018-02-05 12:00:20"): response_1 = self.send_request( url='core:send', data=serialized_force_payment, ) settle_overdue_acceptances.assert_called_once() 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"), }) 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, self._get_encoded_requestor_public_key()) with freeze_time("2018-02-05 12:00:21"): response_2 = self.send_request( url='core:receive', data=self._create_provider_auth_message(), ) self._test_204_response(response_2) self._assert_stored_message_counter_not_increased() with freeze_time("2018-02-05 12:00:22"): response_3 = self.send_request( url='core:receive', data=self._create_diff_requestor_auth_message(), ) self._test_204_response(response_3) self._assert_stored_message_counter_not_increased() with freeze_time("2018-02-05 12:00:23"): response_4 = self.send_request( url='core:receive', data=self._create_requestor_auth_message(), ) self._test_response( response_4, 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:23"), }) self._assert_stored_message_counter_not_increased() self._assert_client_count_is_equal(1) last_pending_message = PendingResponse.objects.filter( delivered=False).last() self.assertIsNone(last_pending_message)