Esempio n. 1
0
 def add_payment(self, payment_info):
     """ Add new payment to the database.
     :param payment_info:
     """
     Payment.create(subtask=payment_info.subtask_id,
                    payee=payment_info.computer.eth_account.address,
                    value=payment_info.value)
Esempio n. 2
0
 def test_payment_big_value(self):
     value = 10000 * 10**18
     assert value > 2**64
     Payment.create(payee="me",
                    subtask="T1000",
                    value=value,
                    status=PaymentStatus.sent)
Esempio n. 3
0
 def test_invalid_value_type(self):
     with self.assertRaises(TypeError):
         Payment.create(payee="XX",
                        subtask="float",
                        value=5.5,
                        status=PaymentStatus.sent)
     with self.assertRaises(TypeError):
         Payment.create(payee="XX",
                        subtask="str",
                        value="500",
                        status=PaymentStatus.sent)
Esempio n. 4
0
    def test_failed_transaction(self):
        balance_eth = 1 * denoms.ether
        balance_gntb = 99 * denoms.ether
        self.sci.get_eth_balance.return_value = balance_eth
        self.sci.get_gntb_balance.return_value = balance_gntb

        gnt_value = 10**17
        p = Payment.create(subtask="p1", payee=urandom(20), value=gnt_value)
        self.pp.add(p)

        self.pp.CLOSURE_TIME_DELAY = 0
        tx_hash = '0xdead'
        self.sci.batch_transfer.return_value = tx_hash
        assert self.pp.sendout(0)

        tx_block_number = 1337
        receipt = TransactionReceipt({
            'transactionHash': HexBytes(tx_hash),
            'blockNumber': tx_block_number,
            'blockHash': HexBytes('0x' + 64 * 'f'),
            'gasUsed': 55001,
            'status': 0,
        })
        with mock.patch('golem.ethereum.paymentprocessor.threads') as threads:
            self.sci.on_transaction_confirmed.call_args[0][1](receipt)
            threads.deferToThread.assert_called_once_with(
                self.pp._on_batch_confirmed,
                [p],
                receipt,
            )
            self.pp._on_batch_confirmed([p], receipt)
        self.assertEqual(p.status, PaymentStatus.awaiting)
        assert len(self.pp._awaiting) == 1
    def test_single_payment(self, *_):
        self.pp._run()
        self.gnt.create(sender=self.privkey)
        self.state.mine()
        self.check_synchronized()
        assert self.pp.gnt_balance() == 1000 * denoms.ether

        payee = urandom(20)
        b = self.pp.gnt_balance()
        # FIXME: Big values does not fit into the database
        value = random.randint(0, b / 1000)
        p1 = Payment.create(subtask="p1", payee=payee, value=value)
        assert self.pp._gnt_available() == b
        assert self.pp._gnt_reserved() == 0
        self.pp.add(p1)
        assert self.pp._gnt_available() == b - value
        assert self.pp._gnt_reserved() == value

        # Sendout.
        self.pp.deadline = int(time.time())
        self.pp._run()
        assert self.pp.gnt_balance(True) == b - value
        assert self.pp._gnt_available() == b - value
        assert self.pp._gnt_reserved() == 0

        assert self.gnt.balanceOf(payee) == value
        assert self.gnt.balanceOf(tester.a1) == self.pp._gnt_available()

        # Confirm.
        assert self.pp.gnt_balance(True) == b - value
        assert self.pp._gnt_reserved() == 0
Esempio n. 6
0
 def test_load_from_db_sent(self):
     tx_hash1 = encode_hex(urandom(32))
     tx_hash2 = encode_hex(urandom(32))
     value = 10
     payee = urandom(20)
     sent_payment11 = Payment.create(
         subtask=str(uuid.uuid4()),
         payee=payee,
         value=value,
         details=PaymentDetails(tx=tx_hash1[2:]),
         status=PaymentStatus.sent)
     sent_payment12 = Payment.create(
         subtask=str(uuid.uuid4()),
         payee=payee,
         value=value,
         details=PaymentDetails(tx=tx_hash1[2:]),
         status=PaymentStatus.sent)
     sent_payment21 = Payment.create(
         subtask=str(uuid.uuid4()),
         payee=payee,
         value=value,
         details=PaymentDetails(tx=tx_hash2[2:]),
         status=PaymentStatus.sent)
     self.pp.load_from_db()
     self.assertEqual(3 * value, self.pp.reserved_gntb)
     self.assertEqual(0, self.pp.recipients_count)
     assert self.sci.on_transaction_confirmed.call_count == 2
     assert self.sci.on_transaction_confirmed.call_args_list[0][0][0] == \
         tx_hash1
     assert self.sci.on_transaction_confirmed.call_args_list[1][0][0] == \
         tx_hash2
     with mock.patch('golem.ethereum.paymentprocessor.threads') as threads:
         self.sci.on_transaction_confirmed.call_args_list[0][0][1](
             mock.Mock())
         threads.deferToThread.assert_called_once_with(
             self.pp._on_batch_confirmed,
             [sent_payment11, sent_payment12],
             mock.ANY,
         )
         threads.reset_mock()
         self.sci.on_transaction_confirmed.call_args_list[1][0][1](
             mock.Mock())
         threads.deferToThread.assert_called_once_with(
             self.pp._on_batch_confirmed,
             [sent_payment21],
             mock.ANY,
         )
    def test_no_gnt_available(self):
        self.pp.start()
        self.gnt.create(sender=self.privkey)
        self.state.mine()
        self.check_synchronized()
        assert self.pp.gnt_balance() == 1000 * denoms.ether

        payee = urandom(20)
        b = self.pp.gnt_balance()
        value = b / 5 - 100
        for i in range(5):
            subtask_id = 's{}'.format(i)
            p = Payment.create(subtask=subtask_id, payee=payee, value=value)
            assert self.pp.add(p)

        q = Payment.create(subtask='F', payee=payee, value=value)
        assert not self.pp.add(q)
    def test_add_failure(self):
        a1 = urandom(20)
        a2 = urandom(20)
        p1 = Payment.create(subtask="p1", payee=a1, value=1)
        p2 = Payment.create(subtask="p2", payee=a2, value=2)

        assert p1.status is PaymentStatus.awaiting
        assert p2.status is PaymentStatus.awaiting

        self.client.get_balance.return_value = 0
        assert self.pp.add(p1) is False
        assert self.pp.add(p2) is False
        self.client.get_balance.assert_called_once_with(
            '0x' + self.addr.encode('hex'))

        assert p1.status is PaymentStatus.awaiting
        assert p2.status is PaymentStatus.awaiting
    def test_payment_deadline(self):
        a1 = urandom(20)
        a2 = urandom(20)
        a3 = urandom(20)

        self.client.get_balance.return_value = 100 * denoms.ether
        self.client.call.return_value = hex(100 * denoms.ether)[:-1]

        now = int(time.time())
        assert self.pp.add(Payment.create(subtask="p1", payee=a1, value=1))
        assert check_deadline(self.pp.deadline, now + self.pp.DEFAULT_DEADLINE)

        assert self.pp.add(Payment.create(subtask="p2", payee=a2, value=1),
                           deadline=20000)
        assert check_deadline(self.pp.deadline, now + self.pp.DEFAULT_DEADLINE)

        assert self.pp.add(Payment.create(subtask="p3", payee=a2, value=1),
                           deadline=1)
        assert check_deadline(self.pp.deadline, now + 1)

        assert self.pp.add(Payment.create(subtask="p4", payee=a3, value=1))
        assert check_deadline(self.pp.deadline, now + 1)

        assert self.pp.add(Payment.create(subtask="p5", payee=a3, value=1),
                           deadline=1)
        assert check_deadline(self.pp.deadline, now + 1)

        assert self.pp.add(Payment.create(subtask="p6", payee=a3, value=1),
                           deadline=0)
        assert check_deadline(self.pp.deadline, now)

        assert self.pp.add(Payment.create(subtask="p7", payee=a3, value=1),
                           deadline=-1)
        assert check_deadline(self.pp.deadline, now - 1)
Esempio n. 10
0
    def test_add_invalid_payment_status(self):
        a1 = urandom(20)
        p1 = Payment.create(subtask="p1",
                            payee=a1,
                            value=1,
                            status=PaymentStatus.confirmed)
        assert p1.status is PaymentStatus.confirmed

        with self.assertRaises(RuntimeError):
            self.pp.add(p1)
Esempio n. 11
0
    def test_payment_timestamp(self):
        self.sci.get_eth_balance.return_value = denoms.ether

        ts = 7000000
        p = Payment.create(subtask="p1", payee=urandom(20), value=1)
        with freeze_time(timestamp_to_datetime(ts)):
            self.pp.add(p)
        self.assertEqual(ts, p.processed_ts)

        new_ts = 900000
        with freeze_time(timestamp_to_datetime(new_ts)):
            self.pp.add(p)
        self.assertEqual(ts, p.processed_ts)
Esempio n. 12
0
    def test_monitor_progress(self):
        balance_eth = 1 * denoms.ether
        balance_gntb = 99 * denoms.ether
        gas_price = 10**9
        self.sci.get_eth_balance.return_value = balance_eth
        self.sci.get_gntb_balance.return_value = balance_gntb
        self.sci.get_transaction_gas_price.return_value = gas_price
        self.pp.CLOSURE_TIME_DELAY = 0

        assert self.pp.reserved_gntb == 0
        assert self.pp.recipients_count == 0

        gnt_value = 10**17
        p = Payment.create(subtask="p1", payee=urandom(20), value=gnt_value)
        self.pp.add(p)
        assert self.pp.reserved_gntb == gnt_value
        assert self.pp.recipients_count == 1

        tx_hash = '0xdead'
        self.sci.batch_transfer.return_value = tx_hash
        assert self.pp.sendout(0)
        assert self.sci.batch_transfer.call_count == 1
        self.sci.on_transaction_confirmed.assert_called_once_with(
            tx_hash,
            mock.ANY,
        )

        tx_block_number = 1337
        self.sci.get_block_number.return_value = tx_block_number
        receipt = TransactionReceipt({
            'transactionHash': HexBytes(tx_hash),
            'blockNumber': tx_block_number,
            'blockHash': HexBytes('0x' + 64 * 'f'),
            'gasUsed': 55001,
            'status': 1,
        })
        with mock.patch('golem.ethereum.paymentprocessor.threads') as threads:
            self.sci.on_transaction_confirmed.call_args[0][1](receipt)
            threads.deferToThread.assert_called_once_with(
                self.pp._on_batch_confirmed,
                [p],
                receipt,
            )
            self.pp._on_batch_confirmed([p], receipt)

        self.assertEqual(p.status, PaymentStatus.confirmed)
        self.assertEqual(p.details.block_number, tx_block_number)
        self.assertEqual(p.details.block_hash, 64 * 'f')
        self.assertEqual(p.details.fee, 55001 * gas_price)
        self.assertEqual(self.pp.reserved_gntb, 0)
Esempio n. 13
0
 def add_payment_info(self, task_id, subtask_id, value, account_info):
     """ Add to payment keeper information about new payment for subtask.
     :param str task_id:    ID if a task the payment is related to.
     :param str subtask_id: the id of the compleated
                            subtask this payment is for.
     :param int value:      Aggreed value of the computed subtask.
     :param AccountInfo account_info: Billing account.
     :raise ValueError:     In case of incorrect payee address
     """
     payee = account_info.eth_account.address
     if len(payee) != 20:
         raise ValueError(
             "Incorrect 'payee' length: {}. Should be 20".format(
                 len(payee)))
     return Payment.create(subtask=subtask_id, payee=payee, value=value)
Esempio n. 14
0
    def test_load_from_db_awaiting(self):
        self.assertEqual([], self.pp._awaiting)

        value = 10
        payment = Payment.create(
            subtask=str(uuid.uuid4()),
            payee=urandom(20),
            value=value,
        )

        self.pp.load_from_db()
        expected = [payment]
        self.assertEqual(expected, self.pp._awaiting)
        self.assertEqual(value, self.pp.reserved_gntb)
        self.assertLess(0, self.pp.recipients_count)
Esempio n. 15
0
    def test_payment_deadline_not_reached(self):
        a1 = urandom(20)

        self.client.get_balance.return_value = 100 * denoms.ether
        self.client.call.return_value = hex(100 * denoms.ether)[:-1]

        now = int(time.time())
        inf = now + 12 * 30 * 24 * 60 * 60
        deadline = self.pp.deadline
        assert self.pp.deadline > inf
        assert not self.pp.sendout()
        assert self.pp.deadline == deadline

        p = Payment.create(subtask="p1", payee=a1, value=1111)
        assert self.pp.add(p, deadline=1111)
        assert check_deadline(self.pp.deadline, now + 1111)
        assert not self.pp.sendout()
        assert check_deadline(self.pp.deadline, now + 1111)
Esempio n. 16
0
    def test_create(self):
        p = Payment(payee="DEF",
                    subtask="xyz",
                    value=5,
                    status=PaymentStatus.awaiting)
        self.assertEquals(p.save(force_insert=True), 1)
        with self.assertRaises(IntegrityError):
            Payment.create(payee="DEF",
                           subtask="xyz",
                           value=5,
                           status=PaymentStatus.awaiting)
        Payment.create(payee="DEF",
                       subtask="xyz2",
                       value=4,
                       status=PaymentStatus.confirmed)
        Payment.create(payee="DEF2",
                       subtask="xyz4",
                       value=5,
                       status=PaymentStatus.sent)

        self.assertEqual(3, len([payment for payment in Payment.select()]))
Esempio n. 17
0
    def test_payment_aggregation(self):
        a1 = urandom(20)
        a2 = urandom(20)
        a3 = urandom(20)

        self.client.get_balance.return_value = 100 * denoms.ether
        self.client.call.return_value = hex(100 * denoms.ether)[:-1]

        assert self.pp.add(Payment.create(subtask="p1", payee=a1, value=1))
        assert self.pp.add(Payment.create(subtask="p2", payee=a2, value=1))
        assert self.pp.add(Payment.create(subtask="p3", payee=a2, value=1))
        assert self.pp.add(Payment.create(subtask="p4", payee=a3, value=1))
        assert self.pp.add(Payment.create(subtask="p5", payee=a3, value=1))
        assert self.pp.add(Payment.create(subtask="p6", payee=a3, value=1))

        self.pp.deadline = int(time.time())
        assert self.pp.sendout()
        assert self.client.send.call_count == 1
        tx = self.client.send.call_args[0][0]
        assert tx.value == 0
        assert len(
            tx.data) == 4 + 2 * 32 + 3 * 32  # Id + array abi + bytes32[3]
Esempio n. 18
0
 def add_payment(subtask_id: str, eth_address: bytes, value: int):
     """ Add new payment to the database.
     :param payment_info:
     """
     Payment.create(subtask=subtask_id, payee=eth_address, value=value)
Esempio n. 19
0
    def test_monitor_progress(self):
        a1 = urandom(20)

        inprogress = self.pp._inprogress

        # Give 1 ETH and 99 GNT
        balance_eth = 1 * denoms.ether
        balance_gnt = 99 * denoms.ether
        self.client.get_balance.return_value = balance_eth
        self.client.call.return_value = hex(balance_gnt)[:-1]  # Skip L suffix.

        assert self.pp._gnt_reserved() == 0
        assert self.pp._gnt_available() == balance_gnt
        assert self.pp._eth_reserved() == 0
        assert self.pp._eth_available() == balance_eth

        gnt_value = 10**17
        p = Payment.create(subtask="p1", payee=a1, value=gnt_value)
        assert self.pp.add(p)
        assert self.pp._gnt_reserved() == gnt_value
        assert self.pp._gnt_available() == balance_gnt - gnt_value
        assert self.pp._eth_reserved(
        ) == PaymentProcessor.SINGLE_PAYMENT_ETH_COST
        assert self.pp._eth_available(
        ) == balance_eth - PaymentProcessor.SINGLE_PAYMENT_ETH_COST

        self.pp.deadline = int(time.time())
        assert self.pp.sendout()
        assert self.client.send.call_count == 1
        tx = self.client.send.call_args[0][0]
        assert tx.value == 0
        assert len(tx.data) == 4 + 2 * 32 + 32  # Id + array abi + bytes32[1]

        assert len(inprogress) == 1
        assert tx.hash in inprogress
        assert inprogress[tx.hash] == [p]

        # Check payment status in the Blockchain
        self.client.get_transaction_receipt.return_value = None
        self.client.call.return_value = hex(balance_gnt -
                                            gnt_value)[:-1]  # Skip L suffix.
        self.pp.monitor_progress()
        assert len(inprogress) == 1
        assert tx.hash in inprogress
        assert inprogress[tx.hash] == [p]
        assert self.pp.gnt_balance(True) == balance_gnt - gnt_value
        assert self.pp._gnt_reserved() == 0
        assert self.pp._gnt_available() == balance_gnt - gnt_value
        assert self.pp._eth_reserved(
        ) == PaymentProcessor.SINGLE_PAYMENT_ETH_COST
        assert self.pp._eth_available(
        ) == balance_eth - PaymentProcessor.SINGLE_PAYMENT_ETH_COST

        self.pp.monitor_progress()
        assert len(inprogress) == 1
        assert self.pp._gnt_reserved() == 0
        assert self.pp._gnt_available() == balance_gnt - gnt_value
        assert self.pp._eth_reserved(
        ) == PaymentProcessor.SINGLE_PAYMENT_ETH_COST
        assert self.pp._eth_available(
        ) == balance_eth - PaymentProcessor.SINGLE_PAYMENT_ETH_COST

        receipt = {
            'blockNumber': 8214,
            'blockHash': '0x' + 64 * 'f',
            'gasUsed': 55001
        }
        self.client.get_transaction_receipt.return_value = receipt
        self.pp.monitor_progress()
        assert len(inprogress) == 0
        assert p.status == PaymentStatus.confirmed
        assert p.details['block_number'] == 8214
        assert p.details['block_hash'] == 64 * 'f'
        assert p.details['fee'] == 55001 * self.pp.GAS_PRICE
        assert self.pp._gnt_reserved() == 0
Esempio n. 20
0
 def test_invalid_status(self):
     with self.assertRaises(TypeError):
         Payment.create(payee="XX", subtask="zz", value=5, status=1)