示例#1
0
    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)
示例#4
0
 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()
示例#5
0
    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)
示例#6
0
    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)
示例#9
0
    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)
示例#12
0
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()
示例#14
0
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)
示例#16
0
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
示例#17
0
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
示例#18
0
    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,
     )
示例#20
0
 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,
         )
示例#21
0
    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)
示例#23
0
    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
示例#24
0
    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)