示例#1
0
    def create_n_deposits_with_subtasks(self, n=1, amount=2):
        for _ in range(n):
            task_to_compute = self._get_deserialized_task_to_compute(
                provider_public_key=self._get_provider_hex_public_key(),
                requestor_public_key=self._get_requestor_hex_public_key(),
                price=amount,
            )
            store_subtask(
                task_id=task_to_compute.task_id,
                subtask_id=task_to_compute.subtask_id,
                provider_public_key=self.PROVIDER_PUBLIC_KEY,
                requestor_public_key=self.REQUESTOR_PUBLIC_KEY,
                state=Subtask.SubtaskState.ACCEPTED,
                next_deadline=None,
                task_to_compute=task_to_compute,
                report_computed_task=factories.tasks.ReportComputedTaskFactory(
                    task_to_compute=task_to_compute))

            deposit_claim = DepositClaim()
            deposit_claim.subtask_id = task_to_compute.subtask_id
            deposit_claim.payer_deposit_account = self.deposit_account
            deposit_claim.payee_ethereum_address = task_to_compute.provider_ethereum_address
            deposit_claim.concent_use_case = ConcentUseCase.FORCED_ACCEPTANCE
            deposit_claim.amount = amount
            deposit_claim.clean()
            deposit_claim.save()
        return deposit_claim, task_to_compute
示例#2
0
class DiscardClaimBanksterTest(ConcentIntegrationTestCase):
    def setUp(self):
        super().setUp()
        self.task_to_compute = self._get_deserialized_task_to_compute()

        self.client = Client(public_key_bytes=self.PROVIDER_PUBLIC_KEY)
        self.client.clean()
        self.client.save()

        self.deposit_account = DepositAccount()
        self.deposit_account.client = self.client
        self.deposit_account.ethereum_address = self.task_to_compute.requestor_ethereum_address
        self.deposit_account.clean()
        self.deposit_account.save()

        self.deposit_claim = DepositClaim()
        self.deposit_claim.payer_deposit_account = self.deposit_account
        self.deposit_claim.payee_ethereum_address = self.task_to_compute.provider_ethereum_address
        self.deposit_claim.concent_use_case = ConcentUseCase.FORCED_PAYMENT
        self.deposit_claim.amount = 1
        self.deposit_claim.closure_time = parse_timestamp_to_utc_datetime(
            get_current_utc_timestamp())
        self.deposit_claim.full_clean()
        self.deposit_claim.save()

    def test_that_discard_claim_should_return_false_and_not_remove_deposit_claim_if_tx_hash_is_none(
            self):
        claim_removed = discard_claim(self.deposit_claim)

        self.assertFalse(claim_removed)
        self.assertTrue(
            DepositClaim.objects.filter(pk=self.deposit_claim.pk).exists())

    def test_that_discard_claim_should_return_true_and_remove_deposit_claim_if_tx_hash_is_set(
            self):
        self.deposit_claim.tx_hash = 64 * '0'
        self.deposit_claim.clean()
        self.deposit_claim.save()

        claim_removed = discard_claim(self.deposit_claim)

        self.assertTrue(claim_removed)
        self.assertFalse(
            DepositClaim.objects.filter(pk=self.deposit_claim.pk).exists())
示例#3
0
class TestDepositClaimValidation(ConcentIntegrationTestCase):
    def setUp(self):
        super().setUp()
        task_to_compute = self._get_deserialized_task_to_compute()
        self.payer_ethereum_address = task_to_compute.requestor_ethereum_address
        self.payee_ethereum_address = task_to_compute.provider_ethereum_address

        client = Client(public_key_bytes=self.REQUESTOR_PUBLIC_KEY)
        client.clean()
        client.save()

        self.payer_deposit_account = DepositAccount()
        self.payer_deposit_account.client = client
        self.payer_deposit_account.ethereum_address = task_to_compute.requestor_ethereum_address
        self.payer_deposit_account.clean()
        self.payer_deposit_account.save()

        self.deposit_claim = DepositClaim()
        self.deposit_claim.payer_deposit_account = self.payer_deposit_account
        self.deposit_claim.subtask_id = task_to_compute.subtask_id
        self.deposit_claim.payee_ethereum_address = self.payee_ethereum_address
        self.deposit_claim.concent_use_case = ConcentUseCase.FORCED_TASK_RESULT.value
        self.deposit_claim.amount = 1
        self.deposit_claim.tx_hash = encode_hex(MOCK_TRANSACTION.hash)

    def test_that_exception_is_raised_when_subtask_is_null_and_concent_use_case_is_not_forced_payment(self):
        self.deposit_claim.subtask_id = None
        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('subtask_id', exception_info.value.error_dict)

    def test_that_exception_is_not_raised_when_subtask_is_null_and_concent_use_case_is_forced_payment(self):
        self.deposit_claim.subtask = None
        self.deposit_claim.concent_use_case = ConcentUseCase.FORCED_PAYMENT.value
        self.deposit_claim.clean()

    def test_that_exception_is_raised_when_payee_ethereum_address_is_the_same_as_payer_deposit_account_ethereum_address(self):
        self.deposit_claim.payee_ethereum_address = self.deposit_claim.payer_deposit_account.ethereum_address

        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('payer_deposit_account', exception_info.value.error_dict)

    def test_that_exception_is_raised_when_payee_ethereum_address_has_wrong_length(self):
        self.deposit_claim.payee_ethereum_address = self.payee_ethereum_address + '1'
        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('payee_ethereum_address', exception_info.value.error_dict)

    def test_that_exception_is_raised_when_payee_ethereum_address_has_wrong_type(self):
        self.deposit_claim.payee_ethereum_address = b'x' * ETHEREUM_ADDRESS_LENGTH
        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('payee_ethereum_address', exception_info.value.error_dict)

    def test_that_exception_is_raised_when_amount_is_equal_to_zero(self):
        self.deposit_claim.amount = 0
        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('amount', exception_info.value.error_dict)

    def test_that_exception_is_raised_when_amount_is_less_then_zero(self):
        self.deposit_claim.amount = -1
        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('amount', exception_info.value.error_dict)

    def test_that_exception_is_raised_when_amount_is_of_wrong_type(self):
        self.deposit_claim.amount = 5.0
        with pytest.raises(ValidationError):
            self.deposit_claim.clean()

    def test_that_exception_is_raised_when_tx_hash_is_not_none_and_not_string(self):
        self.deposit_claim.tx_hash = b'x' * ETHEREUM_TRANSACTION_HASH_LENGTH
        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('tx_hash', exception_info.value.error_dict)

    def test_that_exception_is_raised_when_tx_hash_has_wrong_length(self):
        self.deposit_claim.tx_hash = encode_hex(MOCK_TRANSACTION.hash) + 'a'
        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('tx_hash', exception_info.value.error_dict)

    def test_that_no_exception_is_raised_when_tx_hash_is_none(self):
        self.deposit_claim.tx_hash = None
        self.deposit_claim.clean()
        self.deposit_claim.save()

    def test_that_deposit_account_is_not_removed_when_deposit_claim_is_deleted(self):
        self.deposit_claim.clean()
        self.deposit_claim.save()

        DepositClaim.objects.filter(pk=self.deposit_claim.pk).delete()

        self.assertTrue(
            DepositAccount.objects.filter(pk=self.payer_deposit_account.pk).exists()  # pylint: disable=no-member
        )

    def test_that_no_exception_is_raised_when_deposit_claim_is_valid(self):
        self.deposit_claim.clean()
        self.deposit_claim.save()
示例#4
0
class FinalizePaymentBanksterTest(ConcentIntegrationTestCase):
    def setUp(self):
        super().setUp()
        self.task_to_compute = self._get_deserialized_task_to_compute()

        self.subtask = 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.ACCEPTED,
            next_deadline=None,
            task_to_compute=self.task_to_compute,
            report_computed_task=factories.tasks.ReportComputedTaskFactory(
                task_to_compute=self.task_to_compute))
        self.subtask.full_clean()
        self.subtask.save()

        self.deposit_account = DepositAccount()
        self.deposit_account.client = self.subtask.requestor
        self.deposit_account.ethereum_address = self.task_to_compute.requestor_ethereum_address
        self.deposit_account.clean()
        self.deposit_account.save()

        self.deposit_claim = DepositClaim()
        self.deposit_claim.subtask_id = self.task_to_compute.subtask_id
        self.deposit_claim.payer_deposit_account = self.deposit_account
        self.deposit_claim.payee_ethereum_address = self.task_to_compute.provider_ethereum_address
        self.deposit_claim.concent_use_case = ConcentUseCase.FORCED_ACCEPTANCE
        self.deposit_claim.amount = 2
        self.deposit_claim.clean()
        self.deposit_claim.save()

    def test_that_when_available_funds_are_zero_finalize_payment_should_delete_deposit_claim_and_return_none(
            self):
        with mock.patch('core.payments.service.get_deposit_value',
                        return_value=0) as get_deposit_value:
            returned_value = finalize_payment(self.deposit_claim)

        self.assertIsNone(returned_value)
        self.assertFalse(
            DepositClaim.objects.filter(pk=self.deposit_claim.pk).exists())

        get_deposit_value.assert_called_with(
            client_eth_address=self.deposit_claim.payer_deposit_account.
            ethereum_address, )

    def test_that_when_deposit_claim_is_for_forced_acceptance_use_case_finalize_payment_should_call_force_subtask_payment(
            self):
        (v, r, s) = self.task_to_compute.promissory_note_sig
        with mock.patch('core.payments.service.get_deposit_value',
                        return_value=2) as get_deposit_value:
            with mock.patch('core.payments.service.force_subtask_payment',
                            return_value=MOCK_TRANSACTION_HASH
                            ) as force_subtask_payment:
                returned_value = finalize_payment(self.deposit_claim)
        self.assertEqual(returned_value, MOCK_TRANSACTION_HASH)

        get_deposit_value.assert_called_with(
            client_eth_address=self.deposit_claim.payer_deposit_account.
            ethereum_address, )
        force_subtask_payment.assert_called_once_with(
            requestor_eth_address=self.deposit_claim.payer_deposit_account.
            ethereum_address,
            provider_eth_address=self.deposit_claim.payee_ethereum_address,
            value=self.task_to_compute.price,
            subtask_id=self.deposit_claim.subtask_id,
            v=v,
            r=r,
            s=s,
            reimburse_amount=self.deposit_claim.amount)

    def test_that_when_deposit_claim_is_for_additional_verification_use_case_finalize_payment_should_call_cover_additional_verification_cost(
            self):
        self.deposit_claim.concent_use_case = ConcentUseCase.ADDITIONAL_VERIFICATION
        self.deposit_claim.clean()
        self.deposit_claim.save()
        (v, r, s) = self.task_to_compute.promissory_note_sig

        with mock.patch('core.payments.service.get_deposit_value',
                        return_value=2) as get_deposit_value:
            with mock.patch('core.payments.service.force_subtask_payment',
                            return_value=MOCK_TRANSACTION_HASH
                            ) as force_subtask_payment:
                returned_value = finalize_payment(self.deposit_claim)

        self.assertEqual(returned_value, MOCK_TRANSACTION_HASH)

        get_deposit_value.assert_called_with(
            client_eth_address=self.deposit_claim.payer_deposit_account.
            ethereum_address, )
        force_subtask_payment.assert_called_once_with(
            requestor_eth_address=self.deposit_claim.payer_deposit_account.
            ethereum_address,
            provider_eth_address=self.deposit_claim.payee_ethereum_address,
            value=self.task_to_compute.price,
            subtask_id=self.deposit_claim.subtask_id,
            v=v,
            r=r,
            s=s,
            reimburse_amount=self.deposit_claim.amount)

    def test_that_when_there_are_other_deposit_claims_finalize_payment_substract_them_from_currently_processed_claim(
            self):
        newest_deposit_claim, newest_task_to_compute = self.create_n_deposits_with_subtasks(
            2)
        (v, r, s) = newest_task_to_compute.promissory_note_sig

        with mock.patch('core.payments.service.get_deposit_value',
                        return_value=5) as get_deposit_value:
            with mock.patch('core.payments.service.force_subtask_payment',
                            return_value=MOCK_TRANSACTION_HASH
                            ) as force_subtask_payment:
                returned_value = finalize_payment(newest_deposit_claim)

        self.assertEqual(returned_value, MOCK_TRANSACTION_HASH)

        get_deposit_value.assert_called_with(
            client_eth_address=newest_deposit_claim.payer_deposit_account.
            ethereum_address, )
        force_subtask_payment.assert_called_once_with(
            requestor_eth_address=newest_deposit_claim.payer_deposit_account.
            ethereum_address,
            provider_eth_address=newest_deposit_claim.payee_ethereum_address,
            value=newest_task_to_compute.price,
            subtask_id=newest_deposit_claim.subtask_id,
            v=v,
            r=r,
            s=s,
            # 5 - (2 + 2) | deposit_value - sum_of_other_claims
            reimburse_amount=1,
        )

    def create_n_deposits_with_subtasks(self, n=1, amount=2):
        for _ in range(n):
            task_to_compute = self._get_deserialized_task_to_compute(
                provider_public_key=self._get_provider_hex_public_key(),
                requestor_public_key=self._get_requestor_hex_public_key(),
                price=amount,
            )
            store_subtask(
                task_id=task_to_compute.task_id,
                subtask_id=task_to_compute.subtask_id,
                provider_public_key=self.PROVIDER_PUBLIC_KEY,
                requestor_public_key=self.REQUESTOR_PUBLIC_KEY,
                state=Subtask.SubtaskState.ACCEPTED,
                next_deadline=None,
                task_to_compute=task_to_compute,
                report_computed_task=factories.tasks.ReportComputedTaskFactory(
                    task_to_compute=task_to_compute))

            deposit_claim = DepositClaim()
            deposit_claim.subtask_id = task_to_compute.subtask_id
            deposit_claim.payer_deposit_account = self.deposit_account
            deposit_claim.payee_ethereum_address = task_to_compute.provider_ethereum_address
            deposit_claim.concent_use_case = ConcentUseCase.FORCED_ACCEPTANCE
            deposit_claim.amount = amount
            deposit_claim.clean()
            deposit_claim.save()
        return deposit_claim, task_to_compute
示例#5
0
class TestDepositClaimValidation(ConcentIntegrationTestCase):
    def setUp(self):
        super().setUp()
        task_to_compute = self._get_deserialized_task_to_compute()
        self.payer_ethereum_address = task_to_compute.requestor_ethereum_address
        self.payee_ethereum_address = task_to_compute.provider_ethereum_address

        client = Client(public_key_bytes=self.REQUESTOR_PUBLIC_KEY)
        client.clean()
        client.save()

        self.payer_deposit_account = DepositAccount()
        self.payer_deposit_account.client = client
        self.payer_deposit_account.ethereum_address = task_to_compute.requestor_ethereum_address
        self.payer_deposit_account.clean()
        self.payer_deposit_account.save()

        self.deposit_claim = DepositClaim()
        self.deposit_claim.payer_deposit_account = self.payer_deposit_account
        self.deposit_claim.subtask_id = task_to_compute.subtask_id
        self.deposit_claim.payee_ethereum_address = self.payee_ethereum_address
        self.deposit_claim.concent_use_case = ConcentUseCase.FORCED_TASK_RESULT.value
        self.deposit_claim.amount = 1
        self.deposit_claim.tx_hash = encode_hex(MOCK_TRANSACTION.hash)

    def test_that_exception_is_raised_when_subtask_is_null_and_concent_use_case_is_not_forced_payment(
            self):
        self.deposit_claim.subtask_id = None
        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('subtask_id', exception_info.value.error_dict)

    def test_that_exception_is_not_raised_when_subtask_is_null_and_concent_use_case_is_forced_payment(
            self):
        self.deposit_claim.subtask = None
        self.deposit_claim.concent_use_case = ConcentUseCase.FORCED_PAYMENT.value
        self.deposit_claim.closure_time = parse_timestamp_to_utc_datetime(
            get_current_utc_timestamp())
        self.deposit_claim.clean()

    def test_that_exception_is_raised_when_payee_ethereum_address_is_the_same_as_payer_deposit_account_ethereum_address(
            self):
        self.deposit_claim.payee_ethereum_address = self.deposit_claim.payer_deposit_account.ethereum_address

        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('payer_deposit_account', exception_info.value.error_dict)

    def test_that_exception_is_raised_when_amount_is_equal_to_zero(self):
        self.deposit_claim.amount = 0
        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('amount', exception_info.value.error_dict)

    def test_that_exception_is_raised_when_amount_is_less_then_zero(self):
        self.deposit_claim.amount = -1
        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('amount', exception_info.value.error_dict)

    def test_that_exception_is_not_raised_when_amount_is_at_max_length(self):
        self.deposit_claim.amount = int('1' * BIG_ENDIAN_INT_MAX_DIGITS)
        self.deposit_claim.clean()
        self.deposit_claim.save()

    def test_that_exception_is_raised_when_tx_hash_is_not_none_and_not_string(
            self):
        self.deposit_claim.tx_hash = '11'
        self.deposit_claim.clean()
        self.deposit_claim.save()

    def test_that_exception_is_raised_when_closure_time_is_none_in_use_case_forced_payment(
            self):
        self.deposit_claim.concent_use_case = ConcentUseCase.FORCED_PAYMENT.value
        self.deposit_claim.closure_time = None
        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('closure_time', exception_info.value.error_dict)

    def test_that_exception_is_raised_when_closure_time_is_set_in_use_case_other_than_forced_payment(
            self):
        self.deposit_claim.concent_use_case = ConcentUseCase.ADDITIONAL_VERIFICATION.value
        self.deposit_claim.closure_time = parse_timestamp_to_utc_datetime(
            get_current_utc_timestamp())
        with pytest.raises(ValidationError) as exception_info:
            self.deposit_claim.clean()
        self.assertIn('closure_time', exception_info.value.error_dict)

    def test_that_no_exception_is_raised_when_tx_hash_is_none(self):
        self.deposit_claim.tx_hash = None
        self.deposit_claim.clean()
        self.deposit_claim.save()

    def test_that_deposit_account_is_not_removed_when_deposit_claim_is_deleted(
            self):
        self.deposit_claim.clean()
        self.deposit_claim.save()

        DepositClaim.objects.filter(pk=self.deposit_claim.pk).delete()

        self.assertTrue(
            DepositAccount.objects.filter(
                pk=self.payer_deposit_account.pk).exists()  # pylint: disable=no-member
        )

    def test_that_no_exception_is_raised_when_deposit_claim_is_valid(self):
        self.deposit_claim.clean()
        self.deposit_claim.save()