Exemple #1
0
    def test_errors_from_stellar_tx(self, instruction_index, exp_op_index, exp_payment_index):
        acc1 = gen_account_id()
        acc2 = gen_account_id()
        operations = [
            gen_create_op(acc1, acc2),
            gen_payment_op(acc2, amount=15),
            gen_payment_op(acc1, amount=15),
            gen_create_op(acc1, acc2),
        ]
        memo = AgoraMemo.new(1, TransactionType.EARN, 1, b'')
        hash_memo = gen_hash_memo(memo.val)
        envelope_xdr = gen_tx_envelope_xdr(acc1, 1, operations, hash_memo)
        env = te.TransactionEnvelope.from_xdr(base64.b64encode(envelope_xdr))

        errors = TransactionErrors.from_stellar_tx(env, model_pbv4.TransactionError(
            reason=model_pbv4.TransactionError.Reason.INSUFFICIENT_FUNDS,
            instruction_index=instruction_index,
        ), b'tx_hash')
        assert isinstance(errors.tx_error, InsufficientBalanceError)
        assert len(errors.op_errors) == 4
        for i in range(0, len(errors.op_errors)):
            if i == exp_op_index:
                assert isinstance(errors.op_errors[i], InsufficientBalanceError)
            else:
                assert not errors.op_errors[i]

        if exp_payment_index > -1:
            assert len(errors.payment_errors) == 2
            for i in range(0, len(errors.payment_errors)):
                if i == exp_payment_index:
                    assert isinstance(errors.payment_errors[i], InsufficientBalanceError)
                else:
                    assert not errors.payment_errors[i]
        else:
            assert not errors.payment_errors
Exemple #2
0
    def test_payments_from_envelope(self):
        acc1 = gen_account_id()
        acc2 = gen_account_id()
        acc3 = gen_account_id()
        operations = [
            gen_payment_op(acc2, amount=20),
            gen_payment_op(acc3, src=acc2, amount=40)
        ]
        envelope_xdr = gen_tx_envelope_xdr(acc1, 1, operations,
                                           gen_text_memo(b'somememo'))
        env = te.TransactionEnvelope.from_xdr(base64.b64encode(envelope_xdr))

        payments = ReadOnlyPayment.payments_from_envelope(env)

        assert len(payments) == 2

        assert payments[0].sender.raw == acc1.ed25519
        assert payments[0].destination.raw == acc2.ed25519
        assert payments[0].tx_type == TransactionType.UNKNOWN
        assert payments[0].quarks == 20
        assert not payments[0].invoice
        assert payments[0].memo == 'somememo'

        assert payments[1].sender.raw == acc2.ed25519
        assert payments[1].destination.raw == acc3.ed25519
        assert payments[1].tx_type == TransactionType.UNKNOWN
        assert payments[1].quarks == 40
        assert not payments[1].invoice
        assert payments[1].memo == 'somememo'
def _generate_envelope():
    acc1 = gen_account_id()
    acc2 = gen_account_id()
    operations = [gen_payment_op(acc2)]
    envelope_xdr = gen_tx_envelope_xdr(acc1, 1, operations,
                                       gen_text_memo(b'somememo'))
    return te.TransactionEnvelope.from_xdr(base64.b64encode(envelope_xdr))
Exemple #4
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'
Exemple #5
0
def _generate_kin_2_envelope():
    acc1 = gen_account_id()
    acc2 = gen_account_id()
    operations = [gen_kin_2_payment_op(acc2)]
    envelope_xdr = gen_tx_envelope_xdr(acc1, 1, operations,
                                       gen_text_memo(b'somememo'))
    return envelope_from_xdr(KIN_2_TEST_NETWORK, base64.b64encode(envelope_xdr))
Exemple #6
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
Exemple #7
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
Exemple #8
0
    def test_payments_from_envelope_with_invoice_list(self):
        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, amount=20),
                      gen_payment_op(acc3, src=acc2, amount=40)]
        envelope_xdr = gen_tx_envelope_xdr(acc1, 1, operations, hash_memo)
        env = te.TransactionEnvelope.from_xdr(base64.b64encode(envelope_xdr))

        payments = ReadOnlyPayment.payments_from_envelope(env, il)

        assert len(payments) == 2

        assert payments[0].sender.raw == acc1.ed25519
        assert payments[0].destination.raw == acc2.ed25519
        assert payments[0].tx_type == TransactionType.P2P
        assert payments[0].quarks == 20
        assert payments[0].invoice == Invoice.from_proto(il.invoices[0])
        assert not payments[0].memo

        assert payments[1].sender.raw == acc2.ed25519
        assert payments[1].destination.raw == acc3.ed25519
        assert payments[1].tx_type == TransactionType.P2P
        assert payments[1].quarks == 40
        assert payments[1].invoice == Invoice.from_proto(il.invoices[1])
        assert not payments[1].memo
    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'
Exemple #10
0
    def test_handle_sign_transaction(self):
        secret = 'secret'
        handler = WebhookHandler(secret=secret)

        acc1 = gen_account_id()
        acc2 = gen_account_id()
        operations = [gen_payment_op(acc2)]
        envelope_xdr = gen_tx_envelope_xdr(acc1, 1, operations,
                                           gen_text_memo(b'somememo'))
        data = {
            'kin_version': 3,
            'envelope_xdr': base64.b64encode(envelope_xdr).decode()
        }
        req_body = json.dumps(data)
        sig = base64.b64encode(hmac.new(secret.encode(), req_body.encode(), hashlib.sha256).digest())
        text_sig = base64.b64encode(hmac.new(secret.encode(), b'someotherdata', hashlib.sha256).digest())

        # invalid signature
        status_code, resp_body = handler.handle_sign_transaction(self._sign_tx_success, text_sig, req_body)
        assert status_code == 401
        assert resp_body == ''

        # invalid req body
        status_code, resp_body = handler.handle_sign_transaction(self._sign_tx_success, text_sig,
                                                                 'someotherdata')
        assert status_code == 400
        assert resp_body == 'invalid request body'

        # webhook request error
        status_code, resp_body = handler.handle_sign_transaction(self._sign_tx_raise_webhook_request_error, sig,
                                                                 req_body)
        assert status_code == 400
        assert resp_body == 'some error'

        # other error
        status_code, resp_body = handler.handle_sign_transaction(self._sign_tx_raise_other_error, sig, req_body)
        assert status_code == 500
        assert resp_body == 'bad stuff'

        # rejected
        status_code, resp_body = handler.handle_sign_transaction(self._sign_tx_return_rejected, sig, req_body)
        assert status_code == 403
        assert json.loads(resp_body) == {
            'invoice_errors': [
                {'operation_index': 0, 'reason': InvoiceErrorReason.UNKNOWN.to_lowercase()}
            ]
        }

        # successful
        status_code, resp_body = handler.handle_sign_transaction(self._sign_tx_success, sig, req_body)
        assert status_code == 200

        actual_env = te.TransactionEnvelope.from_xdr(json.loads(resp_body)['envelope_xdr'])
        _TEST_PRIVATE_KEY.verify(actual_env.hash_meta(), actual_env.signatures[-1].signature)

        # fake signature with no webhook secret should result in a successful response
        handler = WebhookHandler()
        status_code, resp_body = handler.handle_sign_transaction(self._sign_tx_success, "fakesig", req_body)
        assert status_code == 200

        actual_env = te.TransactionEnvelope.from_xdr(json.loads(resp_body)['envelope_xdr'])
        _TEST_PRIVATE_KEY.verify(actual_env.hash_meta(), actual_env.signatures[-1].signature)