Esempio n. 1
0
    def test_submit_earn_batch_with_whitelisting(self, grpc_channel, executor, whitelisting_client):
        sender = PrivateKey.random()
        earns = [Earn(PrivateKey.random().public_key, 100000)]

        future = executor.submit(whitelisting_client.submit_earn_batch, sender, earns)

        account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10)

        result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)])
        submit_req = self._set_successful_submit_transaction_response(grpc_channel, b'somehash', result_xdr)

        batch_earn_result = future.result()
        assert len(batch_earn_result.succeeded) == 1
        assert len(batch_earn_result.failed) == 0

        earn_result = batch_earn_result.succeeded[0]
        assert earn_result.earn == earns[0]
        assert earn_result.tx_hash == b'somehash'
        assert not earn_result.error

        assert account_req.account_id.value == sender.public_key.stellar_address

        expected_signers = [sender, whitelisting_client.whitelist_key]
        expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, b'').val)
        self._assert_earn_batch_envelope(submit_req.envelope_xdr, expected_signers, sender, 100, 11, expected_memo,
                                         sender, earns)
Esempio n. 2
0
    def test_submit_payment_tx_failed(self, grpc_channel, executor, app_index_client):
        sender = PrivateKey.random()
        dest = PrivateKey.random().public_key
        payment = Payment(sender, dest, TransactionType.EARN, 100000)

        future = executor.submit(app_index_client.submit_payment, payment)

        account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10)

        result_xdr = gen_result_xdr(xdr_const.txFAILED, [gen_payment_op_result(xdr_const.PAYMENT_UNDERFUNDED)])
        resp = tx_pb.SubmitTransactionResponse(
            result=tx_pb.SubmitTransactionResponse.Result.FAILED,
            hash=model_pb2.TransactionHash(value=b'somehash'),
            ledger=10,
            result_xdr=result_xdr,
        )
        submit_req = self._set_submit_transaction_response(grpc_channel, resp)

        with pytest.raises(InsufficientBalanceError):
            future.result()

        assert account_req.account_id.value == sender.public_key.stellar_address

        expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, b'').val)
        self._assert_payment_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo, payment)
        assert len(submit_req.invoice_list.invoices) == 0
Esempio n. 3
0
    def test_error_from_result_other_op(self):
        op_result = gen_merge_op_result(xdr_const.ACCOUNT_MERGE_MALFORMED)
        result_xdr = gen_result_xdr(xdr_const.txFAILED, [op_result])

        te = TransactionErrors.from_result(result_xdr)
        assert isinstance(te.tx_error, Error)
        assert isinstance(te.op_errors[0], Error)
Esempio n. 4
0
    def test_submit_earn_batch_with_memo(self, grpc_channel, executor, app_index_client):
        sender = PrivateKey.random()
        earns = [Earn(PrivateKey.random().public_key, 100000)]

        future = executor.submit(app_index_client.submit_earn_batch, sender, earns, memo="somememo")

        account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10)

        result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)])
        submit_req = self._set_successful_submit_transaction_response(grpc_channel, b'somehash', result_xdr)

        batch_earn_result = future.result()
        assert len(batch_earn_result.succeeded) == 1
        assert len(batch_earn_result.failed) == 0

        earn_result = batch_earn_result.succeeded[0]
        assert earn_result.earn == earns[0]
        assert earn_result.tx_hash == b'somehash'
        assert not earn_result.error

        assert account_req.account_id.value == sender.public_key.stellar_address

        expected_memo = memo.TextMemo('somememo')
        self._assert_earn_batch_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo,
                                         sender, earns)
        assert len(submit_req.invoice_list.invoices) == 0
Esempio n. 5
0
    def test_submit_earn_batch_with_invoices(self, grpc_channel, executor, app_index_client):
        sender = PrivateKey.random()
        earns = [
            Earn(PrivateKey.random().public_key, 100000,
                 invoice=Invoice([LineItem('title1', 100000, 'description1', b'somesku')])),
            Earn(PrivateKey.random().public_key, 100000,
                 invoice=Invoice([LineItem('title2', 100000, 'description2', b'somesku')])),
        ]

        future = executor.submit(app_index_client.submit_earn_batch, sender, earns)

        account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10)

        result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)])
        submit_req = self._set_successful_submit_transaction_response(grpc_channel, b'somehash', result_xdr)

        batch_earn_result = future.result()
        assert len(batch_earn_result.succeeded) == 2
        assert len(batch_earn_result.failed) == 0

        for idx, earn_result in enumerate(batch_earn_result.succeeded):
            assert earn_result.tx_hash == b'somehash'
            assert earn_result.earn == earns[idx]
            assert not earn_result.error

        assert account_req.account_id.value == sender.public_key.stellar_address

        il = InvoiceList([earn.invoice for earn in earns])
        expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, il.get_sha_224_hash()).val)
        self._assert_earn_batch_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo, sender,
                                         earns)
        assert len(submit_req.invoice_list.invoices) == 2
        assert submit_req.invoice_list.SerializeToString() == il.to_proto().SerializeToString()
Esempio n. 6
0
    def test_from_proto_text_memo(self):
        op_result = gen_payment_op_result(xdr_const.PAYMENT_UNDERFUNDED)
        result_xdr = gen_result_xdr(xdr_const.txFAILED, [op_result])

        tx_src = gen_account_id()
        dest = gen_account_id()
        operations = [gen_payment_op(dest, amount=20)]
        envelope_xdr = gen_tx_envelope_xdr(tx_src, 1, operations,
                                           gen_text_memo(b'somememo'))

        history_item = tx_pb.HistoryItem(
            hash=model_pb2.TransactionHash(value=b'somehash'),
            result_xdr=result_xdr,
            envelope_xdr=envelope_xdr,
            cursor=tx_pb.Cursor(value=b'cursor1'),
        )

        data = TransactionData.from_proto(history_item)
        assert data.tx_hash == b'somehash'
        assert len(data.payments) == 1

        payment = data.payments[0]
        assert payment.sender.raw == tx_src.ed25519
        assert payment.destination.raw == dest.ed25519
        assert payment.tx_type == TransactionType.UNKNOWN
        assert payment.quarks == 20
        assert not payment.invoice
        assert payment.memo == 'somememo'
Esempio n. 7
0
    def test_submit_earn_batch_multiple(self, grpc_channel, executor, app_index_client):
        sender = PrivateKey.random()
        all_earns = [Earn(PrivateKey.random().public_key, i) for i in range(250)]

        future = executor.submit(app_index_client.submit_earn_batch, sender, all_earns)

        account_reqs = []
        submit_reqs = []
        tx_hashes = []
        result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)])
        starting_seq = 10

        for i in range(3):
            account_reqs.append(self._set_successful_get_account_info_response(grpc_channel, sender, starting_seq + i))
            tx_hash = 'somehash{}'.format(i).encode()
            submit_reqs.append(self._set_successful_submit_transaction_response(grpc_channel, tx_hash, result_xdr))
            tx_hashes.append(tx_hash)

        batch_earn_result = future.result()
        assert len(batch_earn_result.succeeded) == 250
        assert len(batch_earn_result.failed) == 0

        for account_req in account_reqs:
            assert account_req.account_id.value == sender.public_key.stellar_address

        earn_batches = partition(all_earns, 100)
        for idx, submit_req in enumerate(submit_reqs):
            expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, b'').val)
            self._assert_earn_batch_envelope(submit_req.envelope_xdr, [sender], sender, 100, starting_seq + idx + 1,
                                             expected_memo, sender, earn_batches[idx])
            assert len(submit_req.invoice_list.invoices) == 0
Esempio n. 8
0
    def test_submit_payment_with_nonce_retry(self, grpc_channel, executor, nonce_retry_client):
        sender = PrivateKey.random()
        dest = PrivateKey.random().public_key
        payment = Payment(sender, dest, TransactionType.EARN, 100000)

        future = executor.submit(nonce_retry_client.submit_payment, payment)

        result_xdr = gen_result_xdr(xdr_const.txBAD_SEQ, [])
        resp = tx_pb.SubmitTransactionResponse(
            result=tx_pb.SubmitTransactionResponse.Result.FAILED,
            hash=model_pb2.TransactionHash(value=b'somehash'),
            ledger=10,
            result_xdr=result_xdr,
        )

        account_reqs = []
        submit_reqs = []
        for i in range(_config_with_nonce_retry.max_nonce_refreshes + 1):
            # this blocks until the system under test invokes the RPC, so if the test completes then the RPC was called
            # the expected number of times.
            account_reqs.append(self._set_successful_get_account_info_response(grpc_channel, sender, 10))
            submit_reqs.append(self._set_submit_transaction_response(grpc_channel, resp))

        with pytest.raises(BadNonceError):
            future.result()

        for account_req in account_reqs:
            assert account_req.account_id.value == sender.public_key.stellar_address

        expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, b'').val)
        for submit_req in submit_reqs:
            self._assert_payment_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo, payment)
            assert len(submit_req.invoice_list.invoices) == 0
Esempio n. 9
0
    def test_get_transaction(self, grpc_channel, executor, app_index_client):
        tx_hash = b'somehash'
        future = executor.submit(app_index_client.get_transaction, tx_hash)

        _, request, rpc = grpc_channel.take_unary_unary(
            tx_pb.DESCRIPTOR.services_by_name['Transaction'].methods_by_name['GetTransaction']
        )

        # Create full response
        op_result = gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)
        result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [op_result, op_result])

        il = model_pb2.InvoiceList(invoices=[
            model_pb2.Invoice(
                items=[
                    model_pb2.Invoice.LineItem(title='t1', amount=15),
                ]
            ),
        ])
        fk = InvoiceList.from_proto(il).get_sha_224_hash()
        memo = AgoraMemo.new(1, TransactionType.EARN, 1, fk)
        hash_memo = gen_hash_memo(memo.val)

        acc1 = gen_account_id()
        acc2 = gen_account_id()
        operations = [gen_payment_op(acc2, amount=15)]
        envelope_xdr = gen_tx_envelope_xdr(acc1, 1, operations, hash_memo)

        history_item = tx_pb.HistoryItem(
            hash=model_pb2.TransactionHash(value=tx_hash),
            result_xdr=result_xdr,
            envelope_xdr=envelope_xdr,
            cursor=tx_pb.Cursor(value=b'cursor1'),
            invoice_list=il,
        )
        resp = tx_pb.GetTransactionResponse(
            state=tx_pb.GetTransactionResponse.State.SUCCESS,
            ledger=10,
            item=history_item,
        )
        rpc.terminate(resp, (), grpc.StatusCode.OK, '')

        tx_data = future.result()
        assert tx_data.tx_hash == tx_hash
        assert len(tx_data.payments) == 1
        assert not tx_data.error

        payment1 = tx_data.payments[0]
        assert payment1.sender.raw == acc1.ed25519
        assert payment1.destination.raw == acc2.ed25519
        assert payment1.tx_type == memo.tx_type()
        assert payment1.quarks == 15
        assert (payment1.invoice.to_proto().SerializeToString() == il.invoices[0].SerializeToString())
        assert not payment1.memo

        assert request.transaction_hash.value == tx_hash
Esempio n. 10
0
    def test_from_proto_agora_memo(self):
        op_result = gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)
        result_xdr = gen_result_xdr(xdr_const.txSUCCESS,
                                    [op_result, op_result])

        il = model_pb2.InvoiceList(invoices=[
            model_pb2.Invoice(items=[
                model_pb2.Invoice.LineItem(title='t1', amount=10),
            ]),
            model_pb2.Invoice(items=[
                model_pb2.Invoice.LineItem(title='t1', amount=15),
            ]),
        ])
        fk = InvoiceList.from_proto(il).get_sha_224_hash()
        memo = AgoraMemo.new(1, TransactionType.P2P, 0, fk)
        hash_memo = gen_hash_memo(memo.val)

        acc1 = gen_account_id()
        acc2 = gen_account_id()
        acc3 = gen_account_id()
        operations = [
            gen_payment_op(acc2, src=acc1, amount=10),
            gen_payment_op(acc1, src=acc2, amount=15),
        ]
        envelope_xdr = gen_tx_envelope_xdr(acc3, 1, operations, hash_memo)

        history_item = tx_pb.HistoryItem(
            hash=model_pb2.TransactionHash(value=b'somehash'),
            result_xdr=result_xdr,
            envelope_xdr=envelope_xdr,
            cursor=tx_pb.Cursor(value=b'cursor1'),
            invoice_list=il,
        )

        data = TransactionData.from_proto(history_item)
        assert data.tx_hash == b'somehash'
        assert len(data.payments) == 2

        payment1 = data.payments[0]
        assert payment1.sender.raw == acc1.ed25519
        assert payment1.destination.raw == acc2.ed25519
        assert payment1.tx_type == memo.tx_type()
        assert payment1.quarks == 10
        assert (payment1.invoice.to_proto().SerializeToString() ==
                il.invoices[0].SerializeToString())
        assert not payment1.memo

        payment2 = data.payments[1]
        assert payment2.sender.raw == acc2.ed25519
        assert payment2.destination.raw == acc1.ed25519
        assert payment2.tx_type == TransactionType.P2P
        assert payment2.quarks == 15
        assert (payment2.invoice.to_proto().SerializeToString() ==
                il.invoices[1].SerializeToString())
        assert not payment2.memo
Esempio n. 11
0
    def test_error_from_result_multi_op(self):
        op_results = [
            gen_create_op_result(xdr_const.CREATE_ACCOUNT_SUCCESS),
            gen_create_op_result(xdr_const.CREATE_ACCOUNT_MALFORMED),
            gen_payment_op_result(xdr_const.PAYMENT_UNDERFUNDED),
        ]

        result_xdr = gen_result_xdr(xdr_const.txFAILED, op_results)

        te = TransactionErrors.from_result(result_xdr)
        assert isinstance(te.tx_error, Error)
        assert not te.op_errors[0]
        assert isinstance(te.op_errors[1], TransactionMalformedError)
        assert isinstance(te.op_errors[2], InsufficientBalanceError)
Esempio n. 12
0
    def test_from_result_tx_failed(self, tx_result_code: int, op_type: int,
                                   op_result_code: int, op_error_type: type):
        """ Tests conversion of error types with transaction results containing only one operation result.
        """
        if op_type == xdr_const.CREATE_ACCOUNT:
            op_result = gen_create_op_result(op_result_code)
        elif op_type == xdr_const.PAYMENT:
            op_result = gen_payment_op_result(op_result_code)
        else:
            raise ValueError('invalid op_type')

        result_xdr = gen_result_xdr(tx_result_code,
                                    [op_result] if op_result else [])

        te = TransactionErrors.from_result(result_xdr)
        assert isinstance(te.tx_error, Error)
        assert isinstance(te.op_errors[0], op_error_type)
Esempio n. 13
0
    def test_submit_payment_with_memo(self, grpc_channel, executor, app_index_client):
        sender = PrivateKey.random()
        dest = PrivateKey.random().public_key
        payment = Payment(sender, dest, TransactionType.EARN, 100000, memo='somememo')

        future = executor.submit(app_index_client.submit_payment, payment)

        account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10)

        result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)])
        submit_req = self._set_successful_submit_transaction_response(grpc_channel, b'somehash', result_xdr)

        assert future.result() == b'somehash'

        assert account_req.account_id.value == sender.public_key.stellar_address

        expected_memo = memo.TextMemo('somememo')
        self._assert_payment_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo, payment)
        assert len(submit_req.invoice_list.invoices) == 0
Esempio n. 14
0
    def test_from_proto_stellar_text_memo(self):
        op_result = gen_payment_op_result(xdr_const.PAYMENT_UNDERFUNDED)
        result_xdr = gen_result_xdr(xdr_const.txFAILED, [op_result])

        tx_src = gen_account_id()
        dest = gen_account_id()
        operations = [gen_payment_op(dest, amount=20)]
        envelope_xdr = gen_tx_envelope_xdr(tx_src, 1, operations,
                                           gen_text_memo(b'somememo'))

        history_item = tx_pb.HistoryItem(
            transaction_id=model_pb.TransactionId(value=b'somehash'),
            cursor=tx_pb.Cursor(value=b'cursor1'),
            stellar_transaction=model_pb.StellarTransaction(
                result_xdr=result_xdr,
                envelope_xdr=envelope_xdr,
            ),
            payments=[
                tx_pb.HistoryItem.Payment(
                    source=model_pb.SolanaAccountId(value=tx_src.ed25519),
                    destination=model_pb.SolanaAccountId(value=dest.ed25519),
                    amount=20,
                ),
            ],
        )

        data = TransactionData.from_proto(
            history_item, tx_pb.GetTransactionResponse.State.SUCCESS)
        assert data.tx_id == b'somehash'
        assert data.transaction_state == TransactionState.SUCCESS
        assert len(data.payments) == 1

        payment = data.payments[0]
        assert payment.sender.raw == tx_src.ed25519
        assert payment.destination.raw == dest.ed25519
        assert payment.tx_type == TransactionType.UNKNOWN
        assert payment.quarks == 20
        assert not payment.invoice
        assert payment.memo == 'somememo'
Esempio n. 15
0
    def test_submit_payment_with_invoice(self, grpc_channel, executor, app_index_client):
        sender = PrivateKey.random()
        dest = PrivateKey.random().public_key
        invoice = Invoice([LineItem('title1', 100000, 'description1', b'somesku')])
        payment = Payment(sender, dest, TransactionType.EARN, 100000, invoice=invoice)

        future = executor.submit(app_index_client.submit_payment, payment)

        account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10)

        result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)])
        submit_req = self._set_successful_submit_transaction_response(grpc_channel, b'somehash', result_xdr)

        assert future.result() == b'somehash'

        assert account_req.account_id.value == sender.public_key.stellar_address

        expected_memo = memo.HashMemo(
            AgoraMemo.new(1, TransactionType.EARN, 1, InvoiceList([invoice]).get_sha_224_hash()).val)
        self._assert_payment_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo, payment)
        assert len(submit_req.invoice_list.invoices) == 1
        assert submit_req.invoice_list.invoices[0].SerializeToString() == invoice.to_proto().SerializeToString()
Esempio n. 16
0
    def test_submit_earn_batch_same_dest(self, grpc_channel, executor, app_index_client):
        sender = PrivateKey.random()
        dest = PrivateKey.random().public_key
        all_earns = [Earn(dest, i) for i in range(5)]

        future = executor.submit(app_index_client.submit_earn_batch, sender, all_earns)

        result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [gen_payment_op_result(xdr_const.PAYMENT_SUCCESS)])

        account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10)
        tx_hash = 'somehash'.encode()
        submit_req = self._set_successful_submit_transaction_response(grpc_channel, tx_hash, result_xdr)

        batch_earn_result = future.result()
        assert len(batch_earn_result.succeeded) == 5
        assert len(batch_earn_result.failed) == 0

        assert account_req.account_id.value == sender.public_key.stellar_address

        expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, b'').val)
        self._assert_earn_batch_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11,
                                         expected_memo, sender, all_earns)
        assert len(submit_req.invoice_list.invoices) == 0
Esempio n. 17
0
    def test_submit_earn_batch_tx_failed(self, grpc_channel, executor, app_index_client):
        sender = PrivateKey.random()
        earns = [
            Earn(PrivateKey.random().public_key, 100000),
            Earn(PrivateKey.random().public_key, 100000),
        ]

        future = executor.submit(app_index_client.submit_earn_batch, sender, earns)

        account_req = self._set_successful_get_account_info_response(grpc_channel, sender, 10)

        result_xdr = gen_result_xdr(xdr_const.txFAILED, [gen_payment_op_result(xdr_const.PAYMENT_UNDERFUNDED),
                                                         gen_payment_op_result(xdr_const.PAYMENT_NO_DESTINATION)])
        resp = tx_pb.SubmitTransactionResponse(
            result=tx_pb.SubmitTransactionResponse.Result.FAILED,
            hash=model_pb2.TransactionHash(value=b'somehash'),
            ledger=10,
            result_xdr=result_xdr,
        )
        submit_req = self._set_submit_transaction_response(grpc_channel, resp)

        batch_earn_result = future.result()
        assert len(batch_earn_result.succeeded) == 0
        assert len(batch_earn_result.failed) == 2

        expected_errors = [InsufficientBalanceError, DestinationDoesNotExistError]
        for idx, earn_result in enumerate(batch_earn_result.failed):
            assert earn_result.earn == earns[idx]
            assert earn_result.tx_hash  # make sure it's set
            assert isinstance(earn_result.error, expected_errors[idx])

        assert account_req.account_id.value == sender.public_key.stellar_address

        expected_memo = memo.HashMemo(AgoraMemo.new(1, TransactionType.EARN, 1, b'').val)
        self._assert_earn_batch_envelope(submit_req.envelope_xdr, [sender], sender, 100, 11, expected_memo, sender,
                                         earns)
        assert len(submit_req.invoice_list.invoices) == 0
Esempio n. 18
0
 def test_error_from_result_no_op(self, tx_result_code: int,
                                  exception_type: type):
     result_xdr = gen_result_xdr(tx_result_code, [])
     assert isinstance(
         TransactionErrors.from_result(result_xdr).tx_error, exception_type)
Esempio n. 19
0
 def test_from_result_success(self):
     op_result = gen_create_op_result(xdr_const.CREATE_ACCOUNT_SUCCESS)
     result_xdr = gen_result_xdr(xdr_const.txSUCCESS,
                                 [op_result] if op_result else [])
     assert not TransactionErrors.from_result(result_xdr)