def test_query_all_balances_async( rotkehlchen_api_server_with_exchanges, ethereum_accounts, btc_accounts, ): """Test that using the query all balances endpoint works with async call""" # Disable caching of query results rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen rotki.chain_manager.cache_ttl_secs = 0 setup = setup_balances(rotki, ethereum_accounts, btc_accounts) # Test all balances request by requesting to not save the data with ExitStack() as stack: setup.enter_all_patches(stack) response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), json={'async_query': True}, ) task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server_with_exchanges, task_id) assert_all_balances( data=outcome, db=rotki.data.db, expected_data_in_db=True, setup=setup, )
def test_query_all_balances_with_manually_tracked_balances( rotkehlchen_api_server_with_exchanges, ethereum_accounts, btc_accounts, manually_tracked_balances, ): """Test that using the query all balances endpoint also includes manually tracked balances""" # Disable caching of query results rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen rotki.chain_manager.cache_ttl_secs = 0 setup = setup_balances( rotki=rotki, ethereum_accounts=ethereum_accounts, btc_accounts=btc_accounts, manually_tracked_balances=manually_tracked_balances, ) # now do the same but save the data in the DB and test it works # `save_data` is False by default but data will save since this is a fresh account with ExitStack() as stack: setup.enter_all_patches(stack) response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), ) assert_proper_response(response) json_data = response.json() assert_all_balances( data=json_data, db=rotki.data.db, expected_data_in_db=True, setup=setup, )
def test_query_owned_assets( rotkehlchen_api_server_with_exchanges, ethereum_accounts, btc_accounts, number_of_eth_accounts, ): """Test that using the query all owned assets endpoint works""" # Disable caching of query results rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen rotki.chain_manager.cache_ttl_secs = 0 setup = setup_balances(rotki, ethereum_accounts, btc_accounts) # Get all our mocked balances and save them in the DB with setup.poloniex_patch, setup.binance_patch, setup.etherscan_patch, setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), json={'save_data': True}, ) assert_proper_response(response) # And now check that the query owned assets endpoint works with setup.poloniex_patch, setup.binance_patch, setup.etherscan_patch, setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "ownedassetsresource", ), ) assert_proper_response(response) data = response.json() assert data['message'] == '' assert set(data['result']) == {'ETH', 'BTC', 'EUR', 'RDN'}
def test_removing_ethereum_tokens_async( rotkehlchen_api_server, ethereum_accounts, number_of_eth_accounts, ): """Test that the rest api endpoint to add new ethereum tokens works properly""" rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, token_balances={ 'RDN': ['0', '0'], 'DAI': ['50000000', '0'], 'GNO': ['0', '0'], }, btc_accounts=[], ) # Remove GNO and RDN as tracked tokens and make sure that the dai balance checks out with setup.etherscan_patch, setup.alethio_patch: response = requests.delete(api_url_for( rotkehlchen_api_server, "ethereumtokensresource", ), json={'eth_tokens': ['GNO', 'RDN'], 'async_query': True}) task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert_modifying_ethereum_tokens( rotkehlchen_api_server, outcome, ethereum_accounts, setup, ['DAI'], )
def test_query_statistics_netvalue( rotkehlchen_api_server_with_exchanges, ethereum_accounts, btc_accounts, ): """Test that using the statistics netvalue over time endpoint works""" # Disable caching of query results rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen rotki.chain_manager.cache_ttl_secs = 0 setup = setup_balances(rotki, ethereum_accounts, btc_accounts) # query balances and save data in DB to have data to test the statistics endpoint with ExitStack() as stack: setup.enter_all_patches(stack) response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), json={'save_data': True}, ) assert_proper_response(response) # and now test that statistics work fine response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "statisticsnetvalueresource", ), ) result = assert_proper_response_with_result(response) assert len(result) == 2 assert len(result['times']) == 1 assert len(result['data']) == 1
def test_get_sushiswap_trades_history( rotkehlchen_api_server, ethereum_accounts, # pylint: disable=unused-argument ): """Test that the last 11/23 sushiswap trades of the account since 1605437542 are parsed and returned correctly Also test that data are written in the DB and properly retrieved afterwards """ async_query = random.choice([False, True]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, eth_balances=['33000030003'], token_balances={}, btc_accounts=None, original_queries=['zerion', 'logs', 'blocknobytime'], ) _query_and_assert_simple_sushiswap_trades(setup, rotkehlchen_api_server, async_query) # make sure data are written in the DB db_trades = rotki.data.db.get_amm_swaps() assert len(db_trades) == 11 # Query a 2nd time to make sure that when retrieving from the database everything works fine _query_and_assert_simple_sushiswap_trades(setup, rotkehlchen_api_server, async_query)
def test_query_aave_history_with_borrowing(rotkehlchen_api_server, ethereum_accounts, aave_use_graph): # pylint: disable=unused-argument # noqa: E501 """Check querying the aave histoy endpoint works. Uses real data.""" rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, original_queries=['zerion', 'logs', 'blocknobytime'], ) _query_borrowing_aave_history_test(setup, rotkehlchen_api_server) # Run it 2 times to make sure that data can be queried properly from the DB _query_borrowing_aave_history_test(setup, rotkehlchen_api_server) # Make sure events end up in the DB assert len(rotki.data.db.get_aave_events(AAVE_TEST_ACC_3)) != 0 # test aave data purging from the db works response = requests.delete( api_url_for( rotkehlchen_api_server, 'namedethereummoduledataresource', module_name='aave', )) assert_simple_ok_response(response) assert len(rotki.data.db.get_aave_events(AAVE_TEST_ACC_3)) == 0
def test_query_yearn_vault_history(rotkehlchen_api_server, ethereum_accounts): """Check querying the yearn vaults history endpoint works. Uses real data.""" async_query = random.choice([True, False]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, original_queries=['zerion', 'logs', 'blocknobytime'], ) for _ in range(2): # Run 2 times to make sure that loading data from DB the 2nd time works fine with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens (not needed with infura) setup.enter_ethereum_patches(stack) response = requests.get(api_url_for( rotkehlchen_api_server, "yearnvaultshistoryresource", ), json={'async_query': async_query}) if async_query: task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id, timeout=600) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) # Make sure some data was saved in the DB after first call events = rotki.data.db.get_yearn_vaults_events( TEST_ACC1, YEARN_VAULTS['yyDAI+yUSDC+yUSDT+yTUSD'], ) assert len(events) >= 11 result = result[TEST_ACC1] check_vault_history('YALINK Vault', EXPECTED_HISTORY, result) check_vault_history('YCRV Vault', EXPECTED_HISTORY, result) check_vault_history('YSRENCURVE Vault', EXPECTED_HISTORY, result) check_vault_history('YUSDC Vault', EXPECTED_HISTORY, result) check_vault_history('YUSDT Vault', EXPECTED_HISTORY, result) check_vault_history('YYFI Vault', EXPECTED_HISTORY, result) # Make sure events end up in the DB # test yearn vault data purging from the db works response = requests.delete( api_url_for( rotkehlchen_api_server, 'ethereummoduledataresource', module_name='yearn_vaults', )) assert_simple_ok_response(response) events = rotki.data.db.get_yearn_vaults_events( TEST_ACC1, YEARN_VAULTS['yyDAI+yUSDC+yUSDT+yTUSD'], ) assert len(events) == 0
def test_query_aave_balances_module_not_activated( rotkehlchen_api_server, ethereum_accounts, ): async_query = random.choice([False, True]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances(rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None) with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get(api_url_for( rotkehlchen_api_server, "aavebalancesresource", ), json={'async_query': async_query}) if async_query: task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert outcome['result'] is None assert outcome['message'] == 'aave module is not activated' else: assert_error_response( response=response, contained_in_msg='aave module is not activated', status_code=HTTPStatus.CONFLICT, )
def test_query_periodic(rotkehlchen_api_server_with_exchanges): rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen rotki.chain_manager.cache_ttl_secs = 0 setup = setup_balances(rotki, ethereum_accounts=[], btc_accounts=[]) start_ts = ts_now() # Query trades of an exchange to get them saved in the DB with setup.binance_patch, setup.poloniex_patch: response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), json={'save_data': True}, ) assert_proper_response(response) response = requests.get( api_url_for(rotkehlchen_api_server_with_exchanges, "periodicdataresource"), ) assert_proper_response(response) data = response.json() assert data['message'] == '' assert len(data['result']) == 3 assert data['result']['last_balance_save'] >= start_ts assert data['result']['eth_node_connection'] is False # Non -1 value tests for these exist in test_history.py::test_query_history_timerange assert data['result']['last_data_upload_ts'] == 0
def test_query_yearn_vault_balances(rotkehlchen_api_server, ethereum_accounts): async_query = random.choice([True, False]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, original_queries=['zerion'], ) with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get(api_url_for( rotkehlchen_api_server, 'yearnvaultsbalancesresource', ), json={'async_query': async_query}) if async_query: task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) for _, vault in result[TEST_ACC1].items(): assert '%' in vault['roi'] assert FVal(vault['vault_value']['amount']) > ZERO assert FVal(vault['vault_value']['usd_value']) > ZERO assert FVal(vault['underlying_value']['amount']) > ZERO assert FVal(vault['underlying_value']['usd_value']) > ZERO
def test_get_trades_history( rotkehlchen_api_server, ethereum_accounts, # pylint: disable=unused-argument rotki_premium_credentials, # pylint: disable=unused-argument start_with_valid_premium, # pylint: disable=unused-argument ): """Test get the trades history for premium users works as expected. This test will fetch the first 75 swaps, from 1606921757 to 1607015339. Then it will check the resulting trades from 1607008178 (swap 68) to 1607015339 (swap 75). This particular time range has swaps with the timestamp. Swaps 68 to 75 (the endpoint returns them in desc order): 1607008178 - Trade 1 1607008178 - Trade 2 1607008218 - Trade 3 1607009877 - Trade 4 1607010888 - Trade 5 1607015059 - Trade 6 1607015339 - Trade 7 1607015339 - Trade 8 """ async_query = random.choice([False, True]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, original_queries=['zerion', 'logs', 'blocknobytime'], ) with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get( api_url_for(rotkehlchen_api_server, 'balancertradeshistoryresource'), json={ 'async_query': async_query, 'from_timestamp': 0, 'to_timestamp': 1607015339, }, ) if async_query: task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) db_trades = rotki.data.db.get_amm_swaps() assert len(db_trades) == 75 address_trades = result[BALANCER_TEST_ADDR2] assert len(address_trades) == 75 expected_trades = get_balancer_test_addr2_expected_trades()[::-1] filtered_trades = address_trades[:len(expected_trades)] for trade, expected_trade in zip(filtered_trades, expected_trades): assert trade == expected_trade.serialize()
def test_removing_ethereum_tokens( rotkehlchen_api_server, ethereum_accounts, ): """Test that the rest api endpoint to add new ethereum tokens works properly""" rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, token_balances={ A_RDN: ['0', '0'], A_DAI: ['50000000', '0'], A_GNO: ['0', '0'], }, btc_accounts=[], ) # Remove GNO and RDN as tracked tokens and make sure that the dai balance checks out with setup.etherscan_patch, setup.alethio_patch: response = requests.delete(api_url_for( rotkehlchen_api_server, "ethereumtokensresource", ), json={'eth_tokens': ['GNO', 'RDN']}) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_modifying_ethereum_tokens( rotkehlchen_api_server, json_data, ethereum_accounts, setup, ['DAI'], )
def test_query_eth2_info(rotkehlchen_api_server, ethereum_accounts): """This test uses real data and queries the eth2 deposit contract logs""" async_query = random.choice([False, True]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=[], original_queries=['logs', 'transactions', 'blocknobytime'], ) with ExitStack() as stack: setup.enter_blockchain_patches(stack) response = requests.get( api_url_for( rotkehlchen_api_server, 'eth2stakeresource', ), json={'async_query': async_query}, ) if async_query: task_id = assert_ok_async_response(response) outcome = wait_for_async_task( rotkehlchen_api_server, task_id, timeout=ASYNC_TASK_WAIT_TIMEOUT * 5, ) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) assert result['deposits'][0] == { 'from_address': '0xfeF0E7635281eF8E3B705e9C5B86e1d3B0eAb397', 'log_index': 22, 'pubkey': '0xb016e31f633a21fbe42a015152399361184f1e2c0803d89823c224994af74a561c4ad8cfc94b18781d589d03e952cd5b', # noqa: E501 'timestamp': 1604506685, 'tx_hash': '0xd9eca1c2a0c5ff2f25071713432b21cc4d0ff2e8963edc63a48478e395e08db1', 'validator_index': 9, 'value': { 'amount': '32', 'usd_value': '0' }, 'withdrawal_credentials': '0x004c7691c2085648f394ffaef851f3b1d51b95f7263114bc923fc5338f5fc499', # noqa: E501 } assert FVal(result['details'][0]['balance']['amount']) >= ZERO assert FVal(result['details'][0]['balance']['usd_value']) >= ZERO assert result['details'][0][ 'eth1_depositor'] == '0xfeF0E7635281eF8E3B705e9C5B86e1d3B0eAb397' # noqa: E501 assert result['details'][0]['index'] == 9 for duration in ('1d', '1w', '1m', '1y'): performance = result['details'][0][f'performance_{duration}'] assert FVal(performance['amount']) >= ZERO assert FVal(performance['usd_value']) >= ZERO
def test_eth2_add_eth1_account(rotkehlchen_api_server): """This test uses real data and tests that adding an ETH1 address with ETH2 deposits properly detects validators""" new_account = '0xa966B0eabCD717fa28Bd165F1cE160E7057FA369' async_query = random.choice([False, True]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=[new_account], btc_accounts=[], original_queries=['logs', 'transactions', 'blocknobytime', 'beaconchain'], ) with ExitStack() as stack: setup.enter_blockchain_patches(stack) data = {'accounts': [{'address': new_account}], 'async_query': async_query} response = requests.put(api_url_for( rotkehlchen_api_server, 'blockchainsaccountsresource', blockchain='ETH', ), json=data) if async_query: task_id = assert_ok_async_response(response) result = wait_for_async_task_with_result( rotkehlchen_api_server, task_id, timeout=ASYNC_TASK_WAIT_TIMEOUT * 4, ) else: result = assert_proper_response_with_result(response) # now get all detected validators response = requests.get( api_url_for( rotkehlchen_api_server, 'eth2validatorsresource', ), ) result = assert_proper_response_with_result(response) # That address has only 1 validator. If that changes in the future this # test will fail and we will need to adjust the test validator_pubkey = '0x800199f8f3af15a22c42ccd7185948870eceeba2d06199ea30e7e28eb976a69284e393ba2f401e8983d011534b303a57' # noqa: E501 assert len(result['entries']) == 1 assert result['entries'][0] == { 'validator_index': 227858, 'public_key': validator_pubkey, 'ownership_percentage': '100.00', } response = requests.get(api_url_for( rotkehlchen_api_server, 'blockchainbalancesresource', ), json={'blockchain': 'eth2'}) result = assert_proper_response_with_result(response) per_acc = result['per_account'] assert FVal(per_acc['ETH'][new_account]['assets']['ETH']['amount']) > ZERO assert FVal(per_acc['ETH2'][validator_pubkey]['assets']['ETH2']['amount']) > FVal('32.54') totals = result['totals']['assets'] assert FVal(totals['ETH']['amount']) > ZERO assert FVal(totals['ETH2']['amount']) > FVal('32.54')
def test_get_trade_with_1_token_pool( rotkehlchen_api_server, ethereum_accounts, # pylint: disable=unused-argument rotki_premium_credentials, # pylint: disable=unused-argument start_with_valid_premium, # pylint: disable=unused-argument ): """ Test the special case of a swap within an 1 token pool. This can probably happen if the controller has since removed tokens from the pool. """ rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, original_queries=['zerion', 'logs', 'blocknobytime'], ) with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get( api_url_for(rotkehlchen_api_server, 'balancertradeshistoryresource'), json={ 'from_timestamp': 1621358338, 'to_timestamp': 1621358340, }, ) result = assert_proper_response_with_result(response) db_trades = rotki.data.db.get_amm_swaps() assert len(db_trades) == 29 address_trades = result[BALANCER_TEST_ADDR4] assert len(address_trades) == 1 assert address_trades[0] == AMMTrade( trade_type=TradeType.BUY, base_asset=A_WETH, quote_asset=A_WBTC, amount=AssetAmount(FVal('0.205421420618533148')), rate=Price(FVal('0.07606382992071615428519015532')), trade_index=0, swaps=[ AMMSwap( tx_hash='0x4f9e0d8aa660a5d3db276a1ade038f7027f29838dd22d5276571d2e4ea7131ae', # noqa: E501 log_index=84, address=string_to_ethereum_address(BALANCER_TEST_ADDR4), # noqa: E501 from_address=string_to_ethereum_address('0xFD3dFB524B2dA40c8a6D703c62BE36b5D8540626'), # noqa: E501 to_address=string_to_ethereum_address('0x582818356331877553F3E9Cf9557b48e5DdbD54a'), # noqa: E501 timestamp=Timestamp(1621358339), location=Location.BALANCER, token0=A_WBTC, token1=A_WETH, amount0_in=AssetAmount(FVal('0.01562514')), amount1_in=AssetAmount(ZERO), amount0_out=AssetAmount(ZERO), amount1_out=AssetAmount(FVal('0.205421420618533148')), ), ], ).serialize()
def test_query_yearn_vault_v2_history(rotkehlchen_api_server, ethereum_accounts): """Check querying the yearn vaults v2 history endpoint works. Uses real data.""" async_query = random.choice([True, False]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, token_balances={ '0x5f18C75AbDAe578b483E5F43f12a39cF75b973a9': ['70000000'], '0xB8C3B7A2A618C552C23B1E4701109a9E756Bab67': ['2550000000000000000000'], }, original_queries=['blocknobytime'], ) with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get(api_url_for( rotkehlchen_api_server, "yearnvaultsv2historyresource", ), json={'async_query': async_query}) if async_query: task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) # Make sure some data was saved in the DB after first call events = rotki.data.db.get_yearn_vaults_v2_events(TEST_V2_ACC2, 0, 12770065) assert len(events) >= 11 result = result[TEST_V2_ACC2] check_vault_history( '_ceth_0x1C6a9783F812b3Af3aBbf7de64c3cD7CC7D1af44', EXPECTED_V2_HISTORY, result, ) # Make sure events end up in the DB # test yearn vault data purging from the db works response = requests.delete( api_url_for( rotkehlchen_api_server, 'ethereummoduledataresource', module_name='yearn_vaults_v2', )) assert_simple_ok_response(response) events = rotki.data.db.get_yearn_vaults_v2_events(TEST_V2_ACC2, 0, 12770065) assert len(events) == 0
def test_balances_caching_mixup( rotkehlchen_api_server, ethereum_accounts, ): """Test that querying the balances in a specific order does not mix up the caches. This tests for the problem seen where the bitcoin balances being empty and queried first returned an empty result for the ethereum balances. """ rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, eth_balances=['1000000000000000000'], token_balances={A_RDN: ['2000000000000000000']}, original_queries=['zerion'], ) # Test all balances request by requesting to not save the data with ExitStack() as stack: setup.enter_blockchain_patches(stack) response_btc = requests.get(api_url_for( rotkehlchen_api_server, "named_blockchain_balances_resource", blockchain='BTC', ), json={'async_query': True}) response_eth = requests.get(api_url_for( rotkehlchen_api_server, "named_blockchain_balances_resource", blockchain='ETH', ), json={'async_query': True}) task_id_btc = assert_ok_async_response(response_btc) task_id_eth = assert_ok_async_response(response_eth) result_btc = wait_for_async_task_with_result( rotkehlchen_api_server, task_id_btc, ) result_eth = wait_for_async_task_with_result( server=rotkehlchen_api_server, task_id=task_id_eth, timeout=ASYNC_TASK_WAIT_TIMEOUT * 2, ) assert result_eth['per_account']['ETH'][ethereum_accounts[0]][ 'assets']['ETH']['amount'] == '1' # noqa: E501 assert result_eth['per_account']['ETH'][ethereum_accounts[0]][ 'assets'][A_RDN.identifier]['amount'] == '2' # noqa: E501 assert result_eth['totals']['assets']['ETH']['amount'] == '1' assert result_eth['totals']['assets'][ A_RDN.identifier]['amount'] == '2' assert result_eth['per_account']['ETH'][ethereum_accounts[0]][ 'assets'][A_RDN.identifier]['amount'] == '2' # noqa: E501 assert result_btc['per_account'] == {} assert result_btc['totals']['assets'] == {} assert result_btc['totals']['liabilities'] == {}
def test_query_aave_history_with_borrowing_v2(rotkehlchen_api_server, ethereum_accounts): # pylint: disable=unused-argument # noqa: E501 """Check querying the aave histoy endpoint works. Uses real data.""" rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, original_queries=['zerion', 'logs', 'blocknobytime'], ) _query_simple_aave_history_test_v2(setup, rotkehlchen_api_server, False)
def test_query_compound_balances(rotkehlchen_api_server, ethereum_accounts): """Check querying the compound balances endpoint works. Uses real data. TODO: Here we should use a test account for which we will know what balances it has and we never modify """ async_query = random.choice([False, True]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, original_queries=['zerion'], ) with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get(api_url_for( rotkehlchen_api_server, "compoundbalancesresource", ), json={'async_query': async_query}) if async_query: task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id, timeout=60) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) if len(result) != 1: test_warnings.warn( UserWarning(f'Test account {TEST_ACC1} has no compound balances')) return lending = result[TEST_ACC1]['lending'] for _, entry in lending.items(): assert len(entry) == 2 assert len(entry['balance']) == 2 assert 'amount' in entry['balance'] assert 'usd_value' in entry['balance'] assert '%' in entry['apy'] borrowing = result[TEST_ACC1]['borrowing'] for _, entry in borrowing.items(): assert len(entry) == 2 assert len(entry['balance']) == 2 assert 'amount' in entry['balance'] assert 'usd_value' in entry['balance'] assert '%' in entry['apy'] rewards = result[TEST_ACC1]['rewards'] if len(rewards) != 0: assert len(rewards) == 1 assert A_COMP.identifier in rewards
def test_get_balances( rotkehlchen_api_server, ethereum_accounts, # pylint: disable=unused-argument rotki_premium_credentials, # pylint: disable=unused-argument start_with_valid_premium, # pylint: disable=unused-argument ): """Test get the balances for premium users works as expected""" async_query = random.choice([False, True]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, original_queries=['zerion', 'logs', 'blocknobytime'], ) with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get( api_url_for(rotkehlchen_api_server, 'balancerbalancesresource'), json={'async_query': async_query}, ) if async_query: task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) if len(result) != 1: test_warnings.warn( UserWarning(f'Test account {BALANCER_TEST_ADDR1} has no balances'), ) return for pool_share in result[BALANCER_TEST_ADDR1]: assert pool_share['address'] is not None assert FVal(pool_share['total_amount']) >= ZERO assert FVal(pool_share['user_balance']['amount']) >= ZERO assert FVal(pool_share['user_balance']['usd_value']) >= ZERO for pool_token in pool_share['tokens']: assert pool_token['token'] is not None # UnknownEthereumToken if isinstance(pool_token['token'], dict): assert pool_token['token']['ethereum_address'] is not None assert pool_token['token']['name'] is not None assert pool_token['token']['symbol'] is not None assert pool_token['total_amount'] is not None assert FVal(pool_token['user_balance']['amount']) >= ZERO assert FVal(pool_token['user_balance']['usd_value']) >= ZERO assert FVal(pool_token['usd_price']) >= ZERO assert FVal(pool_token['weight']) >= ZERO
def test_get_events_history_get_all_events( rotkehlchen_api_server, ethereum_accounts, # pylint: disable=unused-argument rotki_premium_credentials, # pylint: disable=unused-argument start_with_valid_premium, # pylint: disable=unused-argument ): """Test get all the events balances LPs involved by the address: minimum 6 By calling the endpoint without a specific time range: - All the events are queried. - The events balances factorise in the current balances in the protocol (do not assert amounts). As the structures are already tested in the tests above, only the response length is tested. """ async_query = random.choice([False, True]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen # Set module premium is required for calling `get_balances()` premium = None if start_with_valid_premium: premium = Premium(rotki_premium_credentials) rotki.chain_manager.uniswap.premium = premium setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, eth_balances=['33000030003'], token_balances={}, btc_accounts=None, original_queries=['zerion', 'logs', 'blocknobytime'], ) with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get(api_url_for( rotkehlchen_api_server, 'uniswapeventshistoryresource'), json={'async_query': async_query}, ) if async_query: task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id, timeout=120) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) events_balances = result[AAVE_TEST_ACC_1] assert len(events_balances) >= 6
def test_get_balances_premium( rotkehlchen_api_server, ethereum_accounts, # pylint: disable=unused-argument rotki_premium_credentials, # pylint: disable=unused-argument start_with_valid_premium, # pylint: disable=unused-argument ): """Test get balances for premium users works as expected """ async_query = random.choice([False, True]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen # Set module premium is required for calling `get_balances()` premium = None if start_with_valid_premium: premium = Premium(rotki_premium_credentials) rotki.chain_manager.adex.premium = premium setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, original_queries=['zerion', 'logs', 'blocknobytime'], ) with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get(api_url_for( rotkehlchen_api_server, 'adexbalancesresource'), json={'async_query': async_query}, ) if async_query: task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) if len(result) != 1: test_warnings.warn( UserWarning(f'Test account {ADEX_TEST_ADDR} has no balances'), ) return for staking_balance in result[ADEX_TEST_ADDR]: assert staking_balance['pool_id'] is not None assert 'pool_name' in staking_balance assert staking_balance['contract_address'] is not None assert staking_balance['adx_balance']['amount'] assert staking_balance['adx_balance']['usd_value'] assert staking_balance['dai_unclaimed_balance']['amount'] assert staking_balance['dai_unclaimed_balance']['usd_value']
def test_query_aave_history_no_duplicates(rotkehlchen_api_server, ethereum_accounts): # pylint: disable=unused-argument # noqa: E501 """Check querying the aave histoy avoids duplicate event data and keeps totals positive""" rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, original_queries=['zerion', 'logs', 'blocknobytime'], ) _test_for_duplicates_and_negatives(setup, rotkehlchen_api_server) # Test that we still don't get duplicates at the 2nd query which hits the DB _test_for_duplicates_and_negatives(setup, rotkehlchen_api_server)
def test_query_aave_history_with_borrowing(rotkehlchen_api_server, ethereum_accounts, aave_use_graph): # pylint: disable=unused-argument # noqa: E501 """Check querying the aave histoy endpoint works. Uses real data.""" rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, original_queries=['zerion', 'logs', 'blocknobytime'], ) _query_borrowing_aave_history_test(setup, rotkehlchen_api_server) # Run it 2 times to make sure that data can be queried properly from the DB _query_borrowing_aave_history_test(setup, rotkehlchen_api_server)
def test_query_all_balances( rotkehlchen_api_server_with_exchanges, ethereum_accounts, btc_accounts, number_of_eth_accounts, ): """Test that using the query all balances endpoint works Test that balances from various sources are returned. Such as exchanges, blockchain and FIAT""" # Disable caching of query results rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen rotki.chain_manager.cache_ttl_secs = 0 setup = setup_balances(rotki, ethereum_accounts, btc_accounts) # Test all balances request by requesting to not save the data with ExitStack() as stack: setup.enter_all_patches(stack) response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), json={'save_data': False}, ) assert_proper_response(response) json_data = response.json() assert_all_balances( data=json_data, db=rotki.data.db, expected_data_in_db=False, setup=setup, ) # now do the same but save the data in the DB and test it works # Omit the argument to test that default value of save_data is True with ExitStack() as stack: setup.enter_all_patches(stack) response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), ) assert_proper_response(response) json_data = response.json() assert_all_balances( data=json_data, db=rotki.data.db, expected_data_in_db=True, setup=setup, )
def test_query_aave_balances(rotkehlchen_api_server, ethereum_accounts, async_query): """Check querying the aave balances endpoint works. Uses real data. TODO: Here we should use a test account for which we will know what balances it has and we never modify """ rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, original_queries=['zerion'], ) with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get(api_url_for( rotkehlchen_api_server, "aavebalancesresource", ), json={'async_query': async_query}) if async_query: task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) if len(result) != 1: test_warnings.warn( UserWarning( f'Test account {AAVE_TEST_ACC_1} has no aave balances')) return lending = result[AAVE_TEST_ACC_1]['lending'] for _, entry in lending.items(): assert len(entry) == 2 assert len(entry['balance']) == 2 assert 'amount' in entry['balance'] assert 'usd_value' in entry['balance'] assert '%' in entry['apy'] borrowing = result[AAVE_TEST_ACC_1]['borrowing'] for _, entry in borrowing.items(): assert len(entry) == 3 assert len(entry['balance']) == 2 assert 'amount' in entry['balance'] assert 'usd_value' in entry['balance'] assert '%' in entry['variable_apr'] assert '%' in entry['stable_apr']
def test_get_events_history_2( rotkehlchen_api_server, ethereum_accounts, # pylint: disable=unused-argument rotki_premium_credentials, # pylint: disable=unused-argument start_with_valid_premium, # pylint: disable=unused-argument ): """Test POOL2 (BAT-LINK-LEND-MKR-SNX-WETH-KNC) events balance for ADDR3""" async_query = random.choice([False, True]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, original_queries=['zerion', 'logs', 'blocknobytime'], ) with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get( api_url_for(rotkehlchen_api_server, 'balancereventshistoryresource'), json={ 'async_query': async_query, 'from_timestamp': 1598376244, 'to_timestamp': 1598377474, }, ) if async_query: task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) address_pool_events_balances = result[BALANCER_TEST_ADDR3] assert len(address_pool_events_balances) == 2 pool_event_balances = [ pool_events_balance for pool_events_balance in address_pool_events_balances if pool_events_balance['pool_address'] == BALANCER_TEST_ADDR3_POOL2.ethereum_address ] assert len(pool_event_balances) == 1 pool_events_balance = pool_event_balances[0] assert pool_events_balance == BALANCER_TEST_ADDR3_EXPECTED_HISTORY_POOL2.serialize( )
def test_query_avax_balances(rotkehlchen_api_server): """Test query the AVAX balances when multiple accounts are set up works as expected. """ async_query = random.choice([False, True]) setup = setup_balances( rotki=rotkehlchen_api_server.rest_api.rotkehlchen, ethereum_accounts=None, btc_accounts=None, eth_balances=None, token_balances=None, btc_balances=None, ) with ExitStack() as stack: setup.enter_blockchain_patches(stack) response = requests.get( api_url_for( rotkehlchen_api_server, 'named_blockchain_balances_resource', blockchain=SupportedBlockchain.AVALANCHE.value, ), json={'async_query': async_query}, ) if async_query: task_id = assert_ok_async_response(response) result = wait_for_async_task_with_result(rotkehlchen_api_server, task_id) else: result = assert_proper_response_with_result(response) # Check per account account_1_balances = result['per_account']['AVAX'][ AVALANCHE_ACC1_AVAX_ADDR] assert 'liabilities' in account_1_balances asset_avax = account_1_balances['assets']['AVAX'] assert FVal(asset_avax['amount']) >= ZERO assert FVal(asset_avax['usd_value']) >= ZERO account_2_balances = result['per_account']['AVAX'][ AVALANCHE_ACC2_AVAX_ADDR] assert 'liabilities' in account_2_balances asset_avax = account_2_balances['assets']['AVAX'] assert FVal(asset_avax['amount']) >= ZERO assert FVal(asset_avax['usd_value']) >= ZERO # Check totals assert 'liabilities' in result['totals'] total_avax = result['totals']['assets']['AVAX'] assert FVal(total_avax['amount']) >= ZERO assert FVal(total_avax['usd_value']) >= ZERO
def test_get_balances_premium( rotkehlchen_api_server, ethereum_accounts, # pylint: disable=unused-argument rotki_premium_credentials, # pylint: disable=unused-argument start_with_valid_premium, # pylint: disable=unused-argument ): """Test get balances for premium users works as expected """ async_query = random.choice([False, True]) rotki = rotkehlchen_api_server.rest_api.rotkehlchen # Set module premium is required for calling `get_balances()` premium = None if start_with_valid_premium: premium = Premium(rotki_premium_credentials) adex = rotki.chain_manager.get_module('adex') adex.premium = premium setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=None, # original_queries=['adex_staking'], extra_flags=['mocked_adex_staking_balance'], ) with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get( api_url_for(rotkehlchen_api_server, 'adexbalancesresource'), json={'async_query': async_query}, ) if async_query: task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) if len(result) != 1: test_warnings.warn( UserWarning(f'Test account {ADEX_TEST_ADDR} has no balances'), ) return assert FVal(result[ADEX_TEST_ADDR][0]['adx_balance']['amount']) == FVal( '113547.9817118382760270384899') # noqa: E501 assert result[ADEX_TEST_ADDR][0]['adx_balance']['usd_value'] is not None