Exemplo n.º 1
0
def test_exchange_query_balances_ignore_cache(
        rotkehlchen_api_server_with_exchanges):
    """Test that using the exchange balances query endpoint can ignore cache"""
    server = rotkehlchen_api_server_with_exchanges
    binance = server.rest_api.rotkehlchen.exchange_manager.connected_exchanges[
        'binance']
    binance_patch = patch_binance_balances_query(binance)
    binance_api_query = patch.object(binance,
                                     'api_query_dict',
                                     wraps=binance.api_query_dict)

    with binance_patch, binance_api_query as bn:
        # Query balances for the first time
        response = requests.get(
            api_url_for(
                server,
                "named_exchanges_balances_resource",
                name='binance',
            ))
        assert_proper_response(response)
        json_data = response.json()
        assert json_data['message'] == ''
        assert_binance_balances_result(json_data['result'])
        assert bn.call_count == 3
        # Do the query again. Cache should be used.
        binance_patch = patch_binance_balances_query(binance)
        response = requests.get(
            api_url_for(
                server,
                "named_exchanges_balances_resource",
                name='binance',
            ))
        assert_proper_response(response)
        json_data = response.json()
        assert json_data['message'] == ''
        assert_binance_balances_result(json_data['result'])
        assert bn.call_count == 3, 'call count should not have changed. Cache must have been used'
        # Finally do the query and request ignoring of the cache
        binance_patch = patch_binance_balances_query(binance)
        response = requests.get(api_url_for(
            server,
            "named_exchanges_balances_resource",
            name='binance',
        ),
                                json={'ignore_cache': True})
        assert_proper_response(response)
        json_data = response.json()
        assert json_data['message'] == ''
        assert_binance_balances_result(json_data['result'])
        assert bn.call_count == 6, 'call count should have changed. Cache should have been ignored'
Exemplo n.º 2
0
def test_exchange_query_balances_ignore_cache(
        rotkehlchen_api_server_with_exchanges):
    """Test that using the exchange balances query endpoint can ignore cache"""
    server = rotkehlchen_api_server_with_exchanges
    rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen
    binance = try_get_first_exchange(rotki.exchange_manager, Location.BINANCE)
    binance_patch = patch_binance_balances_query(binance)
    binance_api_query = patch.object(binance,
                                     'api_query_dict',
                                     wraps=binance.api_query_dict)

    with binance_patch, binance_api_query as bn:
        # Query balances for the first time
        response = requests.get(
            api_url_for(
                server,
                'named_exchanges_balances_resource',
                location='binance',
            ))
        result = assert_proper_response_with_result(response)
        assert_binance_balances_result(result)
        assert bn.call_count == 3
        # Do the query again. Cache should be used.
        binance_patch = patch_binance_balances_query(binance)
        response = requests.get(
            api_url_for(
                server,
                'named_exchanges_balances_resource',
                location='binance',
            ))
        result = assert_proper_response_with_result(response)
        assert_binance_balances_result(result)
        assert bn.call_count == 3, 'call count should not have changed. Cache must have been used'
        # Finally do the query and request ignoring of the cache
        binance_patch = patch_binance_balances_query(binance)
        response = requests.get(api_url_for(
            server,
            'named_exchanges_balances_resource',
            location='binance',
        ),
                                json={'ignore_cache': True})
        result = assert_proper_response_with_result(response)
        assert_binance_balances_result(result)
        assert bn.call_count == 6, 'call count should have changed. Cache should have been ignored'
Exemplo n.º 3
0
def test_exchange_query_balances_async(rotkehlchen_api_server_with_exchanges):
    """Test that using the exchange balances query endpoint works fine for async calls"""
    # async query balances of one specific exchange
    server = rotkehlchen_api_server_with_exchanges
    binance = server.rest_api.rotkehlchen.exchange_manager.connected_exchanges[
        'binance']

    binance_patch = patch_binance_balances_query(binance)
    with binance_patch:
        response = requests.get(api_url_for(
            server,
            "named_exchanges_balances_resource",
            name='binance',
        ),
                                json={'async_query': True})
        task_id = assert_ok_async_response(response)
        outcome = wait_for_async_task(server, task_id)
    assert_binance_balances_result(outcome['result'])

    # async query of one exchange with querystring parameters
    poloniex = server.rest_api.rotkehlchen.exchange_manager.connected_exchanges[
        'poloniex']

    poloniex_patch = patch_poloniex_balances_query(poloniex)
    with poloniex_patch:
        response = requests.get(
            api_url_for(
                server,
                "named_exchanges_balances_resource",
                name='poloniex',
            ) + '?async_query=true')
        task_id = assert_ok_async_response(response)
        outcome = wait_for_async_task(server, task_id)
    assert_poloniex_balances_result(outcome['result'])

    # async query balances of all setup exchanges
    with binance_patch, poloniex_patch:
        response = requests.get(
            api_url_for(server, "exchangebalancesresource"),
            json={'async_query': True},
        )
        task_id = assert_ok_async_response(response)
        outcome = wait_for_async_task(server, task_id)
    result = outcome['result']
    assert_binance_balances_result(result['binance'])
    assert_poloniex_balances_result(result['poloniex'])
Exemplo n.º 4
0
def test_exchange_query_balances(rotkehlchen_api_server_with_exchanges):
    """Test that using the exchange balances query endpoint works fine"""
    async_query = random.choice([False, True])
    # query balances of one specific exchange
    server = rotkehlchen_api_server_with_exchanges
    binance = server.rest_api.rotkehlchen.exchange_manager.connected_exchanges[
        'binance']

    binance_patch = patch_binance_balances_query(binance)
    with binance_patch:
        response = requests.get(api_url_for(
            server,
            "named_exchanges_balances_resource",
            name='binance',
        ),
                                json={'async_query': async_query})
        if async_query:
            task_id = assert_ok_async_response(response)
            outcome = wait_for_async_task_with_result(server, task_id)
        else:
            outcome = assert_proper_response_with_result(response)
    assert_binance_balances_result(outcome)

    # query balances of all setup exchanges
    poloniex = server.rest_api.rotkehlchen.exchange_manager.connected_exchanges[
        'poloniex']

    poloniex_patch = patch_poloniex_balances_query(poloniex)
    with binance_patch, poloniex_patch:
        response = requests.get(
            api_url_for(server, "exchangebalancesresource"),
            json={'async_query': async_query},
        )
        if async_query:
            task_id = assert_ok_async_response(response)
            result = wait_for_async_task_with_result(server, task_id)
        else:
            result = assert_proper_response_with_result(response)

    assert_binance_balances_result(result['binance'])
    assert_poloniex_balances_result(result['poloniex'])
Exemplo n.º 5
0
def test_exchange_query_balances(rotkehlchen_api_server_with_exchanges):
    """Test that using the exchange balances query endpoint works fine"""

    # query balances of one specific exchange
    server = rotkehlchen_api_server_with_exchanges
    binance = server.rest_api.rotkehlchen.exchange_manager.connected_exchanges[
        'binance']

    binance_patch = patch_binance_balances_query(binance)
    with binance_patch:
        response = requests.get(
            api_url_for(
                server,
                "named_exchanges_balances_resource",
                name='binance',
            ))
    assert_proper_response(response)
    json_data = response.json()
    assert json_data['message'] == ''
    result = json_data['result']
    assert_binance_balances_result(json_data['result'])

    # query balances of all setup exchanges
    poloniex = server.rest_api.rotkehlchen.exchange_manager.connected_exchanges[
        'poloniex']

    poloniex_patch = patch_poloniex_balances_query(poloniex)
    with binance_patch, poloniex_patch:
        response = requests.get(api_url_for(server,
                                            "exchangebalancesresource"))
    assert_proper_response(response)
    json_data = response.json()
    assert json_data['message'] == ''
    result = json_data['result']
    assert_binance_balances_result(result['binance'])
    assert_poloniex_balances_result(result['poloniex'])
Exemplo n.º 6
0
def setup_balances(
    rotki,
    ethereum_accounts: Optional[List[ChecksumEthAddress]],
    btc_accounts: Optional[List[BTCAddress]],
    eth_balances: Optional[List[str]] = None,
    token_balances: Optional[Dict[str, List[str]]] = None,
    btc_balances: Optional[List[str]] = None,
    use_alethio: bool = False,
) -> BalancesTestSetup:
    """Setup the blockchain, exchange and fiat balances for some tests

    When eth_balances, token_balances and btc_balances are not provided some
    default values are provided.

    If use_alethio is not True the alethio queries are properly tested. If not
    then an error is returned with each query so the tests revert to etherscan
    """
    if ethereum_accounts is None:
        ethereum_accounts = []
    if btc_accounts is None:
        btc_accounts = []

    # Sanity checks for setup input
    if eth_balances is not None:
        msg = ('The eth balances should be a list with each '
               'element representing balance of an account')
        assert len(eth_balances) == len(ethereum_accounts)
    else:
        # Default test values
        if len(ethereum_accounts) != 0:
            eth_balances = ['1000000', '2000000']
        else:
            eth_balances = []
    if token_balances is not None:
        msg = 'token balances length does not match number of owned eth tokens'
        # We use >= here since the test may add more tokens to the owned eth tokens
        # at later points after setup
        assert len(token_balances) >= len(
            rotki.chain_manager.owned_eth_tokens), msg
        for _, balances in token_balances.items():
            msg = ('The token balances should be a list with each '
                   'element representing balance of an account')
            assert len(balances) == len(ethereum_accounts), msg
    else:
        # Default test values
        if len(ethereum_accounts) != 0:
            token_balances = {'RDN': ['0', '4000000']}
        else:
            token_balances = {}
    if btc_balances is not None:
        msg = ('The btc balances should be a list with each '
               'element representing balance of an account')
        assert len(btc_balances) == len(btc_accounts)
    else:
        # Default test values
        if len(btc_accounts) != 0:
            btc_balances = ['3000000', '5000000']
        else:
            btc_balances = []

    eth_map = {}
    for idx, acc in enumerate(ethereum_accounts):
        eth_map[acc] = {}
        eth_map[acc]['ETH'] = eth_balances[idx]
        for symbol in token_balances:
            eth_map[acc][symbol] = token_balances[symbol][idx]

    btc_map = {}
    for idx, acc in enumerate(btc_accounts):
        btc_map[acc] = btc_balances[idx]

    eur_balance = FVal('1550')

    rotki.data.db.add_fiat_balance(A_EUR, eur_balance)
    binance = rotki.exchange_manager.connected_exchanges.get('binance', None)
    binance_patch = patch_binance_balances_query(binance) if binance else None
    poloniex = rotki.exchange_manager.connected_exchanges.get('poloniex', None)
    poloniex_patch = patch_poloniex_balances_query(
        poloniex) if poloniex else None
    etherscan_patch = mock_etherscan_balances_query(
        eth_map=eth_map,
        etherscan=rotki.etherscan,
        original_requests_get=requests.get,
    )
    alethio_patch = mock_alethio_balances_query(
        eth_map=eth_map,
        alethio=rotki.chain_manager.alethio,
        use_alethio=use_alethio,
        original_requests_get=requests.get,
    )
    bitcoin_patch = mock_bitcoin_balances_query(
        btc_map=btc_map,
        original_requests_get=requests.get,
    )
    # Taken from BINANCE_BALANCES_RESPONSE from tests.utils.exchanges
    binance_balances = {
        'ETH': FVal('4763368.68006011'),
        'BTC': FVal('4723846.89208129')
    }
    # Taken from POLONIEX_BALANCES_RESPONSE from tests.utils.exchanges
    poloniex_balances = {'ETH': FVal('11.0'), 'BTC': FVal('5.5')}

    return BalancesTestSetup(
        eth_balances=eth_balances,
        btc_balances=btc_balances,
        token_balances=token_balances,
        fiat_balances={A_EUR: eur_balance},
        binance_balances=binance_balances,
        poloniex_balances=poloniex_balances,
        poloniex_patch=poloniex_patch,
        binance_patch=binance_patch,
        etherscan_patch=etherscan_patch,
        alethio_patch=alethio_patch,
        bitcoin_patch=bitcoin_patch,
    )
Exemplo n.º 7
0
def setup_balances(
    rotki,
    ethereum_accounts: Optional[List[ChecksumEthAddress]],
    btc_accounts: Optional[List[BTCAddress]],
    eth_balances: Optional[List[str]] = None,
    token_balances: Optional[Dict[EthereumToken, List[str]]] = None,
    liabilities: Optional[Dict[EthereumToken, List[str]]] = None,
    btc_balances: Optional[List[str]] = None,
    manually_tracked_balances: Optional[List[ManuallyTrackedBalance]] = None,
    original_queries: Optional[List[str]] = None,
    extra_flags: Optional[List[str]] = None,
) -> BalancesTestSetup:
    """Setup the blockchain, exchange and fiat balances for some tests

    When eth_balances, token_balances and btc_balances are not provided some
    default values are provided.
    """
    if ethereum_accounts is None:
        ethereum_accounts = []
    if btc_accounts is None:
        btc_accounts = []

    # Sanity checks for setup input
    if eth_balances is not None:
        msg = ('The eth balances should be a list with each '
               'element representing balance of an account')
        assert len(eth_balances) == len(ethereum_accounts)
    else:
        # Default test values
        if len(ethereum_accounts) != 0:
            eth_balances = ['1000000', '2000000']
        else:
            eth_balances = []
    if token_balances is not None:
        msg = 'token balances length does not match number of owned eth tokens'
        for _, balances in token_balances.items():
            msg = ('The token balances should be a list with each '
                   'element representing balance of an account')
            assert len(balances) == len(ethereum_accounts), msg
    else:
        # Default test values
        if len(ethereum_accounts) != 0:
            token_balances = {A_RDN: ['0', '4000000']}
        else:
            token_balances = {}
    if btc_balances is not None:
        msg = ('The btc balances should be a list with each '
               'element representing balance of an account')
        assert len(btc_balances) == len(btc_accounts)
    else:
        # Default test values
        if len(btc_accounts) != 0:
            btc_balances = ['3000000', '5000000']
        else:
            btc_balances = []

    eth_map: Dict[ChecksumEthAddress, Dict[Union[str, EthereumToken],
                                           Any]] = {}
    for idx, acc in enumerate(ethereum_accounts):
        eth_map[acc] = {}
        eth_map[acc]['ETH'] = eth_balances[idx]
        for token in token_balances:
            eth_map[acc][token] = token_balances[token][idx]

    defi_balances_patch = None
    if liabilities is not None:

        def mock_add_defi_balances_to_token_and_totals():
            # super hacky way of mocking this but well f**k it
            if len(rotki.chain_manager.balances.eth) == 4:
                d_liabilities = liabilities.copy()
            else:  # we know the only test this is used removes index 0 and 2
                msg = 'Should be at removal of accounts and only have 2 left'
                assert len(rotki.chain_manager.balances.eth) == 2, msg
                d_liabilities = {
                    k: [x for idx, x in enumerate(v) if idx not in (0, 2)]
                    for k, v in liabilities.items()
                }

            for token, balances in d_liabilities.items():
                for idx, balance in enumerate(balances):
                    balance = FVal(balance)
                    if balance == ZERO:
                        continue

                    account = ethereum_accounts[idx]
                    rotki.chain_manager.balances.eth[account].liabilities[
                        token] = Balance(balance)
                    rotki.chain_manager.totals.liabilities[token] += Balance(
                        balance)

        defi_balances_patch = patch.object(
            rotki.chain_manager,
            'add_defi_balances_to_token_and_totals',
            side_effect=mock_add_defi_balances_to_token_and_totals,
        )

    btc_map: Dict[BTCAddress, str] = {}
    for idx, btc_acc in enumerate(btc_accounts):
        btc_map[btc_acc] = btc_balances[idx]

    binance = try_get_first_exchange(rotki.exchange_manager, Location.BINANCE)
    binance_patch = patch_binance_balances_query(
        binance) if binance else None  # type: ignore
    poloniex = try_get_first_exchange(rotki.exchange_manager,
                                      Location.POLONIEX)
    poloniex_patch = patch_poloniex_balances_query(
        poloniex) if poloniex else None  # type: ignore
    etherscan_patch = mock_etherscan_query(
        eth_map=eth_map,
        etherscan=rotki.etherscan,
        original_queries=original_queries,
        original_requests_get=requests.get,
        extra_flags=extra_flags,
    )
    beaconchain_patch = mock_beaconchain(
        beaconchain=rotki.chain_manager.beaconchain,
        original_queries=original_queries,
        original_requests_get=requests.get,
    )
    # For ethtoken detection we can have bigger chunk length during tests since it's mocked anyway
    ethtokens_max_chunks_patch = patch(
        'rotkehlchen.chain.ethereum.tokens.ETHERSCAN_MAX_TOKEN_CHUNK_LENGTH',
        new=800,
    )

    bitcoin_patch = mock_bitcoin_balances_query(
        btc_map=btc_map,
        original_requests_get=requests.get,
    )
    # Taken from BINANCE_BALANCES_RESPONSE from tests.utils.exchanges
    binance_balances = {
        A_ETH: FVal('4763368.68006011'),
        A_BTC: FVal('4723846.89208129')
    }
    # Taken from POLONIEX_BALANCES_RESPONSE from tests.utils.exchanges
    poloniex_balances = {A_ETH: FVal('11.0'), A_BTC: FVal('5.5')}

    if manually_tracked_balances is None:
        manually_tracked_balances = []
    rotki.data.db.add_manually_tracked_balances(manually_tracked_balances)

    return BalancesTestSetup(
        eth_balances=eth_balances,
        btc_balances=btc_balances,
        token_balances=token_balances,
        binance_balances=binance_balances,
        poloniex_balances=poloniex_balances,
        manually_tracked_balances=manually_tracked_balances,
        poloniex_patch=poloniex_patch,
        binance_patch=binance_patch,
        etherscan_patch=etherscan_patch,
        ethtokens_max_chunks_patch=ethtokens_max_chunks_patch,
        bitcoin_patch=bitcoin_patch,
        beaconchain_patch=beaconchain_patch,
        defi_balances_patch=defi_balances_patch,
    )
Exemplo n.º 8
0
def setup_balances(
    rotki,
    ethereum_accounts: Optional[List[ChecksumEthAddress]],
    btc_accounts: Optional[List[BTCAddress]],
    eth_balances: Optional[List[str]] = None,
    token_balances: Optional[Dict[EthereumToken, List[str]]] = None,
    btc_balances: Optional[List[str]] = None,
    manually_tracked_balances: Optional[List[ManuallyTrackedBalance]] = None,
    original_queries: Optional[List[str]] = None,
) -> BalancesTestSetup:
    """Setup the blockchain, exchange and fiat balances for some tests

    When eth_balances, token_balances and btc_balances are not provided some
    default values are provided.
    """
    if ethereum_accounts is None:
        ethereum_accounts = []
    if btc_accounts is None:
        btc_accounts = []

    # Sanity checks for setup input
    if eth_balances is not None:
        msg = ('The eth balances should be a list with each '
               'element representing balance of an account')
        assert len(eth_balances) == len(ethereum_accounts)
    else:
        # Default test values
        if len(ethereum_accounts) != 0:
            eth_balances = ['1000000', '2000000']
        else:
            eth_balances = []
    if token_balances is not None:
        msg = 'token balances length does not match number of owned eth tokens'
        for _, balances in token_balances.items():
            msg = ('The token balances should be a list with each '
                   'element representing balance of an account')
            assert len(balances) == len(ethereum_accounts), msg
    else:
        # Default test values
        if len(ethereum_accounts) != 0:
            token_balances = {A_RDN: ['0', '4000000']}
        else:
            token_balances = {}
    if btc_balances is not None:
        msg = ('The btc balances should be a list with each '
               'element representing balance of an account')
        assert len(btc_balances) == len(btc_accounts)
    else:
        # Default test values
        if len(btc_accounts) != 0:
            btc_balances = ['3000000', '5000000']
        else:
            btc_balances = []

    eth_map: Dict[ChecksumEthAddress, Dict[Union[str, EthereumToken],
                                           Any]] = {}
    for idx, acc in enumerate(ethereum_accounts):
        eth_map[acc] = {}
        eth_map[acc]['ETH'] = eth_balances[idx]
        for token in token_balances:
            eth_map[acc][token] = token_balances[token][idx]

    btc_map: Dict[BTCAddress, str] = {}
    for idx, btc_acc in enumerate(btc_accounts):
        btc_map[btc_acc] = btc_balances[idx]

    binance = rotki.exchange_manager.connected_exchanges.get('binance', None)
    binance_patch = patch_binance_balances_query(binance) if binance else None
    poloniex = rotki.exchange_manager.connected_exchanges.get('poloniex', None)
    poloniex_patch = patch_poloniex_balances_query(
        poloniex) if poloniex else None
    etherscan_patch = mock_etherscan_query(
        eth_map=eth_map,
        etherscan=rotki.etherscan,
        original_queries=original_queries,
        original_requests_get=requests.get,
    )
    beaconchain_patch = mock_beaconchain(
        beaconchain=rotki.chain_manager.beaconchain,
        original_queries=original_queries,
        original_requests_get=requests.get,
    )
    # For ethtoken detection we can have bigger chunk length during tests since it's mocked anyway
    ethtokens_max_chunks_patch = patch(
        'rotkehlchen.chain.ethereum.tokens.ETHERSCAN_MAX_TOKEN_CHUNK_LENGTH',
        new=800,
    )

    bitcoin_patch = mock_bitcoin_balances_query(
        btc_map=btc_map,
        original_requests_get=requests.get,
    )
    # Taken from BINANCE_BALANCES_RESPONSE from tests.utils.exchanges
    binance_balances = {
        'ETH': FVal('4763368.68006011'),
        'BTC': FVal('4723846.89208129')
    }
    # Taken from POLONIEX_BALANCES_RESPONSE from tests.utils.exchanges
    poloniex_balances = {'ETH': FVal('11.0'), 'BTC': FVal('5.5')}

    if manually_tracked_balances is None:
        manually_tracked_balances = []
    rotki.data.db.add_manually_tracked_balances(manually_tracked_balances)

    return BalancesTestSetup(
        eth_balances=eth_balances,
        btc_balances=btc_balances,
        token_balances=token_balances,
        binance_balances=binance_balances,
        poloniex_balances=poloniex_balances,
        manually_tracked_balances=manually_tracked_balances,
        poloniex_patch=poloniex_patch,
        binance_patch=binance_patch,
        etherscan_patch=etherscan_patch,
        ethtokens_max_chunks_patch=ethtokens_max_chunks_patch,
        bitcoin_patch=bitcoin_patch,
        beaconchain_patch=beaconchain_patch,
    )