Repository: rotki/rotki

Issue:
Calling endpoint balances/blockchains/btc causes an internal server error
## Problem Definition

Making an API call to `balances/blockchains/btc` when you have no BTC wallets/addresses assigned to the current user causes an internal server error whereas it should return a standard API response with result containing empty `per_account` and `totals` objects.

**Steps to reproduce:**
* Make a simple HTTP GET call to `http://127.0.0.1:5042/api/1/balances/blockchains/eth`, you should get a response like:
``{"result": {"per_account": {}, "totals": {}}, "message": ""}``

* Make a simple HTTP GET call to `http://127.0.0.1:5042/api/1/balances/blockchains/btc`, you will get the response:
``{"message": "Internal Server Error"}``

Relevant `rotkehlchen.log` output:
```
06/04/2020 19:32:00 W. Europe Daylight Time -- ERROR:rotkehlchen.api.server:Exception on /api/1/balances/blockchains/btc [GET]
Traceback (most recent call last):
  File "C:\Users\Gebruiker\Envs\rotkehlchen\lib\site-packages\flask\app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\Gebruiker\Envs\rotkehlchen\lib\site-packages\flask\app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\Gebruiker\Envs\rotkehlchen\lib\site-packages\flask_restful\__init__.py", line 458, in wrapper
    resp = resource(*args, **kwargs)
  File "C:\Users\Gebruiker\Envs\rotkehlchen\lib\site-packages\flask\views.py", line 89, in view
    return self.dispatch_request(*args, **kwargs)
  File "C:\Users\Gebruiker\Envs\rotkehlchen\lib\site-packages\flask_restful\__init__.py", line 573, in dispatch_request
    resp = meth(*args, **kwargs)
  File "C:\Users\Gebruiker\Envs\rotkehlchen\lib\site-packages\webargs\core.py", line 366, in wrapper
    return func(*args, **kwargs)
  File "C:\Users\Gebruiker\Source\Repos\rotki\rotkehlchen\api\v1\resources.py", line 302, in get
    ignore_cache=ignore_cache,
  File "C:\Users\Gebruiker\Source\Repos\rotki\rotkehlchen\api\rest.py", line 101, in wrapper
    return f(wrappingobj, *args, **kwargs)
  File "C:\Users\Gebruiker\Source\Repos\rotki\rotkehlchen\api\rest.py", line 575, in query_blockchain_balances
    ignore_cache=ignore_cache,
  File "C:\Users\Gebruiker\Source\Repos\rotki\rotkehlchen\api\rest.py", line 553, in _query_blockchain_balances
    per_account = {'BTC': result['per_account']['BTC']}
KeyError: 'BTC'
06/04/2020 19:32:00 W. Europe Daylight Time -- INFO:rotkehlchen.api.server.pywsgi:127.0.0.1 - - [2020-04-06 19:32:00] "GET /api/1/balances/blockchains/btc HTTP/1.1" 500 164 0.001981
```
### System Description

```
System: Windows 10 64-bit
Rotkehlchen version: 1.3.1 (develop)
```



Discussion:
Thank you for the bug report @isidorosp. Very nice find! Fix will be done shortly and included in v1.4.0

Resolving patch:
diff --git a/rotkehlchen/api/rest.py b/rotkehlchen/api/rest.py
--- a/rotkehlchen/api/rest.py
+++ b/rotkehlchen/api/rest.py
@@ -550,8 +550,10 @@ def _query_blockchain_balances(
                 result['per_account'].pop('BTC', None)
                 result['totals'].pop('BTC', None)
             elif blockchain == SupportedBlockchain.BITCOIN:
-                per_account = {'BTC': result['per_account']['BTC']}
-                totals = {'BTC': result['totals']['BTC']}
+                val = result['per_account'].get('BTC', None)
+                per_account = {'BTC': val} if val else {}
+                val = result['totals'].get('BTC', None)
+                totals = {'BTC': val} if val else {}
                 result = {'per_account': per_account, 'totals': totals}
 
         return {'result': result, 'message': msg, 'status_code': status_code}


Test patch:
diff --git a/rotkehlchen/tests/api/test_blockchain.py b/rotkehlchen/tests/api/test_blockchain.py
--- a/rotkehlchen/tests/api/test_blockchain.py
+++ b/rotkehlchen/tests/api/test_blockchain.py
@@ -27,6 +27,42 @@
 from rotkehlchen.tests.utils.rotkehlchen import setup_balances
 
 
+@pytest.mark.parametrize('number_of_eth_accounts', [0])
+def test_query_empty_blockchain_balances(rotkehlchen_api_server):
+    """Make sure that querying balances for all blockchains works when no accounts are tracked
+
+    Regression test for https://github.com/rotki/rotki/issues/848
+    """
+    response = requests.get(api_url_for(
+        rotkehlchen_api_server,
+        "named_blockchain_balances_resource",
+        blockchain='ETH',
+    ))
+    assert_proper_response(response)
+    data = response.json()
+    assert data['message'] == ''
+    assert data['result'] == {'per_account': {}, 'totals': {}}
+
+    response = requests.get(api_url_for(
+        rotkehlchen_api_server,
+        "named_blockchain_balances_resource",
+        blockchain='BTC',
+    ))
+    assert_proper_response(response)
+    data = response.json()
+    assert data['message'] == ''
+    assert data['result'] == {'per_account': {}, 'totals': {}}
+
+    response = requests.get(api_url_for(
+        rotkehlchen_api_server,
+        "blockchainbalancesresource",
+    ))
+    assert_proper_response(response)
+    data = response.json()
+    assert data['message'] == ''
+    assert data['result'] == {'per_account': {}, 'totals': {}}
+
+
 @pytest.mark.parametrize('number_of_eth_accounts', [2])
 @pytest.mark.parametrize('btc_accounts', [[UNIT_BTC_ADDRESS1, UNIT_BTC_ADDRESS2]])
 @pytest.mark.parametrize('owned_eth_tokens', [[A_RDN]])