Repository: rotki/rotki

Issue:
PRL token not removable from "ETH tokens to track"
## Problem Definition

added PRL token, wanted to remove it again. Pops up "Token Removal Error" :
EthereumToken(identifier='PRL', name='Oyster', symbol='PRL', active=False, asset_type=, started=1506816000, ended=1545177600, forked=None, swapped_for=None, ethereum_address='0x1844b21593262668B7248d0f57a220CaaBA46ab9', decimals=18).
Appears to be gone from list, but when refreshed, PRL is still there.

related log:
16/08/2019 08:57:07 W. Europe Daylight Time -- DEBUG:rotkehlchen.inquirer:Get usd price from cryptocompare asset=Oyster
16/08/2019 08:57:07 W. Europe Daylight Time -- ERROR:rotkehlchen.inquirer:Cryptocompare usd price query failed asset=Oyster, error=There is no data for the symbol PRL .

### System Description
Windows 1903


Discussion:
Hello @smurfer!

Thanks for using Rotki and opening up an issue.

So a question. If you restart the application is the token still there?
yes...
Hey @smurfer I found the issue with the PRL token. It's a twofold issue.

1. Cryptocompare has no historical price data for it even though it's on the website. I already contacted them about it and they are looking at it.

2. Somehow the price query failing makes the token removal fail. I will fix that soon and the fix will be included in the next release.

Resolving patch:
diff --git a/rotkehlchen/blockchain.py b/rotkehlchen/blockchain.py
--- a/rotkehlchen/blockchain.py
+++ b/rotkehlchen/blockchain.py
@@ -171,8 +171,11 @@ def remove_eth_tokens(self, tokens: List[EthereumToken]) -> BlockchainBalancesUp
                     self.balances[A_ETH][account]['usd_value'] -
                     deleting_usd_value
                 )
-
-            del self.totals[token]
+            # Remove the token from the totals iff existing. May not exist
+            #  if the token price is 0 but is still tracked.
+            # See https://github.com/rotkehlchenio/rotkehlchen/issues/467
+            # for more details
+            self.totals.pop(token, None)
             self.owned_eth_tokens.remove(token)
 
         return {'per_account': self.balances, 'totals': self.totals}


Test patch:
diff --git a/rotkehlchen/tests/test_api.py b/rotkehlchen/tests/test_api.py
--- a/rotkehlchen/tests/test_api.py
+++ b/rotkehlchen/tests/test_api.py
@@ -5,6 +5,7 @@
 import pytest
 
 from rotkehlchen.assets.asset import Asset
+from rotkehlchen.blockchain import Blockchain
 from rotkehlchen.constants.assets import A_BTC, A_ETH, A_EUR, A_USD
 from rotkehlchen.data_handler import VALID_SETTINGS
 from rotkehlchen.db.utils import ROTKEHLCHEN_DB_VERSION
@@ -14,6 +15,7 @@
 from rotkehlchen.tests.utils.mock import MockResponse, MockWeb3
 from rotkehlchen.tests.utils.rotkehlchen import add_starting_balances
 from rotkehlchen.typing import Price, Timestamp
+from rotkehlchen.user_messages import MessagesAggregator
 from rotkehlchen.utils.misc import ts_now
 from rotkehlchen.utils.serialization import rlk_jsonloads_dict
 
@@ -85,7 +87,7 @@ def test_add_remove_blockchain_account(rotkehlchen_server):
 
 @pytest.mark.parametrize('number_of_accounts', [0])
 def test_add_remove_eth_tokens(rotkehlchen_server):
-    """Test for issue 83 https://github.com/rotkehlchenio/rotkehlchen/issues/83"""
+    """Regression test for https://github.com/rotkehlchenio/rotkehlchen/issues/83"""
     # Addition of tokens into the DB fires up balance checks for each account
     # we got. For that reason we give 0 accounts for this test
 
@@ -104,6 +106,37 @@ def test_add_remove_eth_tokens(rotkehlchen_server):
     assert len(response['owned_eth_tokens']) == 1 and response['owned_eth_tokens'][0] == 'RDN'
 
 
+@pytest.mark.parametrize('number_of_accounts', [0])
+def test_remove_eth_token_before_any_queries(rotkehlchen_server, ethchain_client):
+    """Regrestion test for 467"""
+    tokens_to_add = ['PRL']
+    response = rotkehlchen_server.add_owned_eth_tokens(tokens_to_add)
+    assert response['result'] is True
+    # At least for now the PRL token is not in cryptocompare. A token without a
+    # price is not counted in the total
+    assert 'PRL' not in response['totals']
+
+    response = rotkehlchen_server.get_eth_tokens()
+    assert set(tokens_to_add) == set(response['owned_eth_tokens'])
+    assert 'all_eth_tokens' in response
+
+    # Now use a clean blockchain instance to emulate restart where blockchain.totals
+    # has not been populated.
+    rotki = rotkehlchen_server.rotkehlchen
+    rotki.blockchain = Blockchain(
+        blockchain_accounts=rotki.data.db.get_blockchain_accounts(),
+        owned_eth_tokens=rotki.data.db.get_owned_tokens(),
+        ethchain=ethchain_client,
+        msg_aggregator=MessagesAggregator(),
+    )
+
+    response = rotkehlchen_server.remove_owned_eth_tokens(['PRL'])
+    assert response['result'] is True
+    response = rotkehlchen_server.get_eth_tokens()
+    assert 'all_eth_tokens' in response
+    assert len(response['owned_eth_tokens']) == 0
+
+
 def test_periodic_query(rotkehlchen_server):
     """Test that periodic query returns expected dict values"""
     result = rotkehlchen_server.query_periodic_data()