示例#1
0
    def test_get_transaction(self, grpc_channel, executor, no_retry_client):
        source, dest = [key.public_key for key in generate_keys(2)]
        transaction_id = b'someid'
        future = executor.submit(no_retry_client.get_transaction,
                                 transaction_id)

        agora_memo = AgoraMemo.new(1, TransactionType.SPEND, 0, b'')
        tx = Transaction.new(PrivateKey.random().public_key, [
            memo.memo_instruction(
                base64.b64encode(agora_memo.val).decode('utf-8')),
            token.transfer(source, dest,
                           PrivateKey.random().public_key, 100),
        ])

        resp = tx_pb_v4.GetTransactionResponse(
            state=tx_pb_v4.GetTransactionResponse.State.SUCCESS,
            item=tx_pb_v4.HistoryItem(
                transaction_id=model_pb_v4.TransactionId(
                    value=transaction_id, ),
                solana_transaction=model_pb_v4.Transaction(
                    value=tx.marshal(), ),
                payments=[
                    tx_pb_v4.HistoryItem.Payment(
                        source=model_pb_v4.SolanaAccountId(value=source.raw),
                        destination=model_pb_v4.SolanaAccountId(
                            value=dest.raw),
                        amount=100,
                    )
                ],
                invoice_list=model_pb_v3.InvoiceList(invoices=[
                    model_pb_v3.Invoice(items=[
                        model_pb_v3.Invoice.LineItem(title='t1', amount=15),
                    ]),
                ])),
        )
        req = self._set_get_transaction_resp(grpc_channel, resp)
        assert req.transaction_id.value == transaction_id

        tx_data = future.result()
        assert tx_data.tx_id == transaction_id
        assert tx_data.transaction_state == TransactionState.SUCCESS
        assert len(tx_data.payments) == 1
        assert not tx_data.error

        p = tx_data.payments[0]
        assert p.sender.raw == source.raw
        assert p.destination.raw == dest.raw
        assert p.tx_type == TransactionType.SPEND
        assert p.quarks == 100
        assert p.invoice.to_proto().SerializeToString(
        ) == resp.item.invoice_list.invoices[0].SerializeToString()
        assert not p.memo
示例#2
0
 def _resolve():
     return self._account_stub_v4.ResolveTokenAccounts(
         account_pb.ResolveTokenAccountsRequest(
             account_id=model_pb.SolanaAccountId(value=public_key.raw),
             include_account_info=include_account_info,
         ),
         metadata=self._metadata,
         timeout=_GRPC_TIMEOUT_SECONDS)
示例#3
0
        def _call_resolve():
            response = self._account_stub.ResolveTokenAccounts(
                account_pb.ResolveTokenAccountsRequest(
                    account_id=model_pb.SolanaAccountId(value=public_key.raw)))
            if not response.token_accounts:
                raise NoTokenAccountsError()

            return response
示例#4
0
        def _submit_request():
            resp = self._account_stub_v4.GetAccountInfo(
                account_pb.GetAccountInfoRequest(
                    account_id=model_pb.SolanaAccountId(value=public_key.raw),
                    commitment=commitment.to_proto(),
                ),
                metadata=self._metadata,
                timeout=_GRPC_TIMEOUT_SECONDS)
            if resp.result == account_pb.GetAccountInfoResponse.Result.NOT_FOUND:
                raise AccountNotFoundError

            return AccountInfo.from_proto(resp.account_info)
    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'
    def test_from_proto_solana_text_memo(self):
        source, dest, token_program = [
            key.public_key for key in generate_keys(3)
        ]
        tx = Transaction.new(PrivateKey.random().public_key, [
            memo_instruction('somememo'),
            transfer(source, dest,
                     PrivateKey.random().public_key, 20),
        ])

        history_item = tx_pb.HistoryItem(
            transaction_id=model_pb.TransactionId(value=b'somehash'),
            cursor=tx_pb.Cursor(value=b'cursor1'),
            solana_transaction=model_pb.Transaction(value=tx.marshal(), ),
            payments=[
                tx_pb.HistoryItem.Payment(
                    source=model_pb.SolanaAccountId(value=source.raw),
                    destination=model_pb.SolanaAccountId(value=dest.raw),
                    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 == source.raw
        assert payment.destination.raw == dest.raw
        assert payment.tx_type == TransactionType.UNKNOWN
        assert payment.quarks == 20
        assert not payment.invoice
        assert payment.memo == 'somememo'
示例#7
0
    def test_get_account_info(self, grpc_channel, executor, no_retry_client):
        private_key = PrivateKey.random()
        future = executor.submit(no_retry_client.get_solana_account_info,
                                 private_key.public_key)

        resp = account_pb_v4.GetAccountInfoResponse(
            account_info=account_pb_v4.AccountInfo(
                account_id=model_pb_v4.SolanaAccountId(
                    value=private_key.public_key.raw),
                balance=10,
            ))
        req = self._set_get_account_info_resp(grpc_channel, resp)
        assert req.account_id.value == private_key.public_key.raw

        account_info = future.result()
        assert account_info.account_id == private_key.public_key
        assert account_info.balance == 10
示例#8
0
        def _request_airdrop():
            resp = self._airdrop_stub_v4.RequestAirdrop(
                airdrop_pb.RequestAirdropRequest(
                    account_id=model_pb.SolanaAccountId(value=public_key.raw),
                    quarks=quarks,
                    commitment=commitment.to_proto(),
                ),
                metadata=self._metadata,
                timeout=_GRPC_TIMEOUT_SECONDS)
            if resp.result == airdrop_pb.RequestAirdropResponse.Result.OK:
                return resp.signature.value
            if resp.result == airdrop_pb.RequestAirdropResponse.Result.NOT_FOUND:
                raise AccountNotFoundError()
            if resp.result == airdrop_pb.RequestAirdropResponse.INSUFFICIENT_KIN:
                raise InsufficientBalanceError()

            raise Error(
                f'unexpected response from airdrop service: {resp.result}')
示例#9
0
    def test_all(self, grpc_channel, executor):
        resolver = TokenAccountResolver(
            account_stub=account_pb_grpc.AccountStub(grpc_channel))

        owner, token1, token2 = [key.public_key for key in generate_keys(3)]
        future = executor.submit(resolver.resolve_token_accounts, owner)

        md, request, rpc = grpc_channel.take_unary_unary(
            account_pb.DESCRIPTOR.services_by_name['Account'].
            methods_by_name['ResolveTokenAccounts'])
        rpc.terminate(
            account_pb.ResolveTokenAccountsResponse(token_accounts=[
                model_pb.SolanaAccountId(value=key.raw)
                for key in [token1, token2]
            ]), (), grpc.StatusCode.OK, '')

        assert future.result() == [token1, token2]

        # ensure it's cached
        assert resolver.resolve_token_accounts(owner) == [token1, token2]
示例#10
0
 def _resolve():
     return self._account_stub_v4.ResolveTokenAccounts(
         account_pb_v4.ResolveTokenAccountsRequest(
             account_id=model_pb_v4.SolanaAccountId(
                 value=public_key.raw)))
示例#11
0
    def test_create_account_no_service_subsidizer(self, grpc_channel, executor,
                                                  no_retry_client):
        private_key = PrivateKey.random()

        no_retry_client._response_cache.clear_all()
        future = executor.submit(no_retry_client.create_solana_account,
                                 private_key)

        md, request, rpc = grpc_channel.take_unary_unary(
            tx_pb_v4.DESCRIPTOR.services_by_name['Transaction'].
            methods_by_name['GetServiceConfig'])
        rpc.terminate(
            tx_pb_v4.GetServiceConfigResponse(
                token=model_pb_v4.SolanaAccountId(value=_token.raw),
                token_program=model_pb_v4.SolanaAccountId(
                    value=_token_program.raw),
            ), (), grpc.StatusCode.OK, '')

        TestInternalClientV4._assert_metadata(md)

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

        subsidizer = PrivateKey.random()
        future = executor.submit(no_retry_client.create_solana_account,
                                 private_key,
                                 subsidizer=subsidizer)

        self._set_get_recent_blockhash_resp(grpc_channel)
        self._set_get_min_balance_response(grpc_channel)

        req = self._set_create_account_resp(
            grpc_channel, account_pb_v4.CreateAccountResponse())

        tx = Transaction.unmarshal(req.transaction.value)
        assert len(tx.signatures) == 2
        assert subsidizer.public_key.verify(tx.message.marshal(),
                                            tx.signatures[0])
        assert private_key.public_key.verify(tx.message.marshal(),
                                             tx.signatures[1])

        sys_create = decompile_create_account(tx.message, 0)
        assert sys_create.funder == subsidizer.public_key
        assert sys_create.address == private_key.public_key
        assert sys_create.owner == _token_program
        assert sys_create.lamports == _min_balance
        assert sys_create.size == token.ACCOUNT_SIZE

        token_init = decompile_initialize_account(tx.message, 1,
                                                  _token_program)
        assert token_init.account == private_key.public_key
        assert token_init.mint == _token
        assert token_init.owner == private_key.public_key

        token_set_auth = decompile_set_authority(tx.message, 2, _token_program)
        assert token_set_auth.account == private_key.public_key
        assert token_set_auth.current_authority == private_key.public_key
        assert token_set_auth.authority_type == token.AuthorityType.CloseAccount
        assert token_set_auth.new_authority == subsidizer.public_key

        assert not future.result()
示例#12
0
from agora.version import VERSION
from tests.utils import generate_keys

_recent_blockhash = bytes(HASH_LENGTH)
_recent_blockhash_resp = tx_pb_v4.GetRecentBlockhashResponse(
    blockhash=model_pb_v4.Blockhash(value=_recent_blockhash))

_min_balance = 2039280
_min_balance_resp = tx_pb_v4.GetMinimumBalanceForRentExemptionResponse(
    lamports=_min_balance)

_subsidizer = PrivateKey.random().public_key
_token = PrivateKey.random().public_key
_token_program = PrivateKey.random().public_key
_service_config_resp = tx_pb_v4.GetServiceConfigResponse(
    subsidizer_account=model_pb_v4.SolanaAccountId(value=_subsidizer.raw),
    token=model_pb_v4.SolanaAccountId(value=_token.raw),
    token_program=model_pb_v4.SolanaAccountId(value=_token_program.raw),
)


@pytest.fixture(scope='class')
def grpc_channel():
    return grpc_testing.channel([
        account_pb_v4.DESCRIPTOR.services_by_name['Account'],
        airdrop_pb_v4.DESCRIPTOR.services_by_name['Airdrop'],
        tx_pb_v4.DESCRIPTOR.services_by_name['Transaction'],
    ], grpc_testing.strict_real_time)


@pytest.fixture(scope='class', autouse=True)
示例#13
0
    def test_from_proto_stellar_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_pb_v3.InvoiceList(invoices=[
            model_pb_v3.Invoice(items=[
                model_pb_v3.Invoice.LineItem(title='t1', amount=10),
            ]),
            model_pb_v3.Invoice(items=[
                model_pb_v3.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(
            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=acc1.ed25519),
                    destination=model_pb.SolanaAccountId(value=acc2.ed25519),
                    amount=10,
                ),
                tx_pb.HistoryItem.Payment(
                    source=model_pb.SolanaAccountId(value=acc2.ed25519),
                    destination=model_pb.SolanaAccountId(value=acc1.ed25519),
                    amount=15,
                ),
            ],
            invoice_list=il,
        )

        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) == 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
示例#14
0
    def test_from_proto_solana_agora_memo(self):
        acc1, acc2, token_program = [
            key.public_key for key in generate_keys(3)
        ]
        il = model_pb_v3.InvoiceList(invoices=[
            model_pb_v3.Invoice(items=[
                model_pb_v3.Invoice.LineItem(title='t1', amount=10),
            ]),
            model_pb_v3.Invoice(items=[
                model_pb_v3.Invoice.LineItem(title='t1', amount=15),
            ]),
        ])
        fk = InvoiceList.from_proto(il).get_sha_224_hash()
        agora_memo = AgoraMemo.new(1, TransactionType.P2P, 0, fk)

        tx = Transaction.new(PrivateKey.random().public_key, [
            memo_instruction(base64.b64encode(agora_memo.val).decode('utf-8')),
            transfer(acc1, acc2,
                     PrivateKey.random().public_key, 10),
            transfer(acc2, acc1,
                     PrivateKey.random().public_key, 15),
        ])

        history_item = tx_pb.HistoryItem(
            transaction_id=model_pb.TransactionId(value=b'somehash'),
            cursor=tx_pb.Cursor(value=b'cursor1'),
            solana_transaction=model_pb.Transaction(value=tx.marshal(), ),
            payments=[
                tx_pb.HistoryItem.Payment(
                    source=model_pb.SolanaAccountId(value=acc1.raw),
                    destination=model_pb.SolanaAccountId(value=acc2.raw),
                    amount=10,
                ),
                tx_pb.HistoryItem.Payment(
                    source=model_pb.SolanaAccountId(value=acc2.raw),
                    destination=model_pb.SolanaAccountId(value=acc1.raw),
                    amount=15,
                ),
            ],
            invoice_list=il,
        )

        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) == 2

        payment1 = data.payments[0]
        assert payment1.sender.raw == acc1.raw
        assert payment1.destination.raw == acc2.raw
        assert payment1.tx_type == TransactionType.P2P
        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.raw
        assert payment2.destination.raw == acc1.raw
        assert payment2.tx_type == TransactionType.P2P
        assert payment2.quarks == 15
        assert (payment2.invoice.to_proto().SerializeToString() ==
                il.invoices[1].SerializeToString())
        assert not payment2.memo
示例#15
0
    def test_resolve_token_accounts(self, grpc_channel, executor,
                                    no_retry_client):
        owner = PrivateKey.random().public_key
        close_authority = PrivateKey.random().public_key
        token_accounts = [priv.public_key for priv in generate_keys(2)]

        # account info not requested, only IDs available
        future = executor.submit(no_retry_client.resolve_token_accounts, owner,
                                 False)
        resp = account_pb_v4.ResolveTokenAccountsResponse(token_accounts=[
            model_pb_v4.SolanaAccountId(value=token_account.raw)
            for token_account in token_accounts
        ])
        req = self._set_resolve_token_accounts_resp(grpc_channel, resp)
        assert req.account_id.value == owner.raw
        assert not req.include_account_info

        token_account_infos = future.result()
        assert len(token_account_infos) == 2
        for idx, token_account in enumerate(token_accounts):
            account_info = token_account_infos[idx]
            assert account_info.account_id == token_account
            assert not account_info.balance
            assert not account_info.owner
            assert not account_info.close_authority

        # account info not requested, account infos available
        future = executor.submit(no_retry_client.resolve_token_accounts, owner,
                                 False)
        resp = account_pb_v4.ResolveTokenAccountsResponse(
            token_account_infos=[
                account_pb_v4.AccountInfo(
                    account_id=model_pb_v4.SolanaAccountId(
                        value=token_account.raw), )
                for token_account in token_accounts
            ],
            token_accounts=[
                model_pb_v4.SolanaAccountId(value=token_account.raw)
                for token_account in token_accounts
            ])
        req = self._set_resolve_token_accounts_resp(grpc_channel, resp)
        assert req.account_id.value == owner.raw
        assert not req.include_account_info

        token_account_infos = future.result()
        assert len(token_account_infos) == 2
        for idx, token_account in enumerate(token_accounts):
            account_info = token_account_infos[idx]
            assert account_info.account_id == token_account
            assert not account_info.balance
            assert not account_info.owner
            assert not account_info.close_authority

        # account info requested
        future = executor.submit(no_retry_client.resolve_token_accounts, owner,
                                 True)
        resp = account_pb_v4.ResolveTokenAccountsResponse(token_account_infos=[
            account_pb_v4.AccountInfo(
                account_id=model_pb_v4.SolanaAccountId(
                    value=token_account.raw),
                balance=10 + idx,
                owner=model_pb_v4.SolanaAccountId(value=owner.raw, ),
                close_authority=model_pb_v4.SolanaAccountId(
                    value=close_authority.raw))
            for idx, token_account in enumerate(token_accounts)
        ], )
        req = self._set_resolve_token_accounts_resp(grpc_channel, resp)
        assert req.account_id.value == owner.raw
        assert req.include_account_info

        token_account_infos = future.result()
        assert len(token_account_infos) == 2
        for idx, token_account in enumerate(token_accounts):
            account_info = token_account_infos[idx]
            assert account_info.account_id == token_account
            assert account_info.balance == 10 + idx
            assert account_info.owner == owner
            assert account_info.close_authority == close_authority

        # account info requested but not available
        future = executor.submit(no_retry_client.resolve_token_accounts, owner,
                                 True)
        resp = account_pb_v4.ResolveTokenAccountsResponse(token_accounts=[
            model_pb_v4.SolanaAccountId(value=token_account.raw)
            for token_account in token_accounts
        ], )
        req = self._set_resolve_token_accounts_resp(grpc_channel, resp)
        assert req.account_id.value == owner.raw
        assert req.include_account_info

        with pytest.raises(Error) as e:
            future.result()
        assert 'account info' in str(e)