prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Staked Cream price appears incorrectly
  In version 1.13.0 of Rotki the staked Cream price and logo appear incorrectly. The CRM's price and logo show up instead of CREAM's.
  
  The previous version of Rotki was showing the price correctly but the logo was still incorrect.
  
  I think cryptocompare is used as price oracle for CREAM.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `rotkehlchen/icons.py`
  Content:
  ```
  1 import itertools
  2 import logging
  3 from pathlib import Path
  4 from typing import Optional, Set
  5 
  6 import gevent
  7 import requests
  8 from typing_extensions import Literal
  9 
  10 from rotkehlchen.assets.asset import Asset
  11 from rotkehlchen.assets.resolver import AssetResolver, asset_type_mapping
  12 from rotkehlchen.errors import RemoteError
  13 from rotkehlchen.externalapis.coingecko import Coingecko, DELISTED_ASSETS
  14 from rotkehlchen.typing import AssetType
  15 from rotkehlchen.utils.hashing import file_md5
  16 from rotkehlchen.constants.timing import DEFAULT_TIMEOUT_TUPLE
  17 
  18 log = logging.getLogger(__name__)
  19 
  20 
  21 class IconManager():
  22     """
  23     Manages the icons for all the assets of the application
  24 
  25     The get_icon() and the periodic task of query_uncached_icons_batch() may at
  26     a point query the same icon but that's fine and not worth of locking mechanism as
  27     it should be rather rare and worst case scenario once in a blue moon we waste
  28     an API call. In the end the right file would be written on disk.
  29 """
  30 
  31     def __init__(self, data_dir: Path, coingecko: Coingecko) -> None:
  32         self.icons_dir = data_dir / 'icons'
  33         self.coingecko = coingecko
  34         self.icons_dir.mkdir(parents=True, exist_ok=True)
  35         self.failed_assets: Set[Asset] = set()
  36 
  37     def iconfile_path(self, asset: Asset, size: Literal['thumb', 'small', 'large']) -> Path:
  38         return self.icons_dir / f'{asset.identifier}_{size}.png'
  39 
  40     def iconfile_md5(
  41             self,
  42             asset: Asset,
  43             size: Literal['thumb', 'small', 'large'],
  44     ) -> Optional[str]:
  45         path = self.iconfile_path(asset, size)
  46         if not path.is_file():
  47             return None
  48 
  49         return file_md5(path)
  50 
  51     def _query_coingecko_for_icon(self, asset: Asset) -> bool:
  52         """Queries coingecko for icons of an asset
  53 
  54         If query was okay it returns True, else False
  55         """
  56         # Do not bother querying if asset is delisted. Nothing is returned.
  57         # we only keep delisted asset coingecko mappings since historical prices
  58         # can still be queried.
  59         if asset.identifier in DELISTED_ASSETS:
  60             self.failed_assets.add(asset)
  61             return False
  62 
  63         try:
  64             data = self.coingecko.asset_data(asset)
  65         except RemoteError as e:
  66             log.warning(
  67                 f'Problem querying coingecko for asset data of {asset.identifier}: {str(e)}',
  68             )
  69             # If a query fails (99% of fails will be 404s) don't repeat them
  70             self.failed_assets.add(asset)
  71             return False
  72 
  73         for size in ('thumb', 'small', 'large'):
  74             url = getattr(data.images, size)
  75             try:
  76                 response = requests.get(url, timeout=DEFAULT_TIMEOUT_TUPLE)
  77             except requests.exceptions.RequestException:
  78                 # Any problem getting the image skip it: https://github.com/rotki/rotki/issues/1370
  79                 continue
  80 
  81             with open(self.iconfile_path(asset, size), 'wb') as f:  # type: ignore
  82                 f.write(response.content)
  83 
  84         return True
  85 
  86     def get_icon(
  87             self,
  88             asset: Asset, given_size: Literal['thumb', 'small', 'large'],
  89     ) -> Optional[bytes]:
  90         """Returns the byte data of the requested icon
  91 
  92         If the icon can't be found it returns None.
  93 
  94         If the icon is found cached locally it's returned directly.
  95 
  96         If not, all icons of the asset are queried from coingecko and cached
  97         locally before the requested data are returned.
  98         """
  99         if not asset.has_coingecko():
  100             return None
  101 
  102         needed_path = self.iconfile_path(asset, given_size)
  103         if needed_path.is_file():
  104             with open(needed_path, 'rb') as f:
  105                 image_data = f.read()
  106             return image_data
  107 
  108         # else query coingecko for the icons and cache all of them
  109         if self._query_coingecko_for_icon(asset) is False:
  110             return None
  111 
  112         if not needed_path.is_file():
  113             return None
  114 
  115         with open(needed_path, 'rb') as f:
  116             image_data = f.read()
  117         return image_data
  118 
  119     def query_uncached_icons_batch(self, batch_size: int) -> bool:
  120         """Queries a batch of uncached icons for assets
  121 
  122         Returns true if there is more icons left to cache after this batch.
  123         """
  124         coingecko_integrated_assets = []
  125 
  126         for identifier, asset_data in AssetResolver().assets.items():
  127             asset_type = asset_type_mapping[asset_data['type']]
  128             if asset_type != AssetType.FIAT and asset_data['coingecko'] != '':
  129                 coingecko_integrated_assets.append(identifier)
  130 
  131         cached_assets = [
  132             str(x.name)[:-10] for x in self.icons_dir.glob('*_thumb.png') if x.is_file()
  133         ]
  134         uncached_assets = (
  135             set(coingecko_integrated_assets) - set(cached_assets) - self.failed_assets
  136         )
  137         log.info(
  138             f'Periodic task to query coingecko for {batch_size} uncached asset icons. '
  139             f'Uncached assets: {len(uncached_assets)}. Cached assets: {len(cached_assets)}',
  140         )
  141         for asset_name in itertools.islice(uncached_assets, batch_size):
  142             self._query_coingecko_for_icon(Asset(asset_name))
  143 
  144         return len(uncached_assets) > batch_size
  145 
  146     def periodically_query_icons_until_all_cached(
  147             self,
  148             batch_size: int,
  149             sleep_time_secs: float,
  150     ) -> None:
  151         """Periodically query all uncached icons until we have icons cached for all
  152         of the known assets that have coingecko integration"""
  153         if batch_size == 0:
  154             return
  155 
  156         while True:
  157             carry_on = self.query_uncached_icons_batch(batch_size=batch_size)
  158             if not carry_on:
  159                 break
  160             gevent.sleep(sleep_time_secs)
  161
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/rotkehlchen/icons.py b/rotkehlchen/icons.py
  --- a/rotkehlchen/icons.py
  +++ b/rotkehlchen/icons.py
  @@ -26,7 +26,7 @@
       a point query the same icon but that's fine and not worth of locking mechanism as
       it should be rather rare and worst case scenario once in a blue moon we waste
       an API call. In the end the right file would be written on disk.
  -"""
  +    """
   
       def __init__(self, data_dir: Path, coingecko: Coingecko) -> None:
           self.icons_dir = data_dir / 'icons'
  
verification_info: {"golden_diff": "diff --git a/rotkehlchen/icons.py b/rotkehlchen/icons.py\n--- a/rotkehlchen/icons.py\n+++ b/rotkehlchen/icons.py\n@@ -26,7 +26,7 @@\n     a point query the same icon but that's fine and not worth of locking mechanism as\n     it should be rather rare and worst case scenario once in a blue moon we waste\n     an API call. In the end the right file would be written on disk.\n-\"\"\"\n+    \"\"\"\n \n     def __init__(self, data_dir: Path, coingecko: Coingecko) -> None:\n         self.icons_dir = data_dir / 'icons'\n", "issue": "Staked Cream price appears incorrectly\nIn version 1.13.0 of Rotki the staked Cream price and logo appear incorrectly. The CRM's price and logo show up instead of CREAM's.\r\n\r\nThe previous version of Rotki was showing the price correctly but the logo was still incorrect.\r\n\r\nI think cryptocompare is used as price oracle for CREAM.\n", "before_files": [{"content": "import itertools\nimport logging\nfrom pathlib import Path\nfrom typing import Optional, Set\n\nimport gevent\nimport requests\nfrom typing_extensions import Literal\n\nfrom rotkehlchen.assets.asset import Asset\nfrom rotkehlchen.assets.resolver import AssetResolver, asset_type_mapping\nfrom rotkehlchen.errors import RemoteError\nfrom rotkehlchen.externalapis.coingecko import Coingecko, DELISTED_ASSETS\nfrom rotkehlchen.typing import AssetType\nfrom rotkehlchen.utils.hashing import file_md5\nfrom rotkehlchen.constants.timing import DEFAULT_TIMEOUT_TUPLE\n\nlog = logging.getLogger(__name__)\n\n\nclass IconManager():\n    \"\"\"\n    Manages the icons for all the assets of the application\n\n    The get_icon() and the periodic task of query_uncached_icons_batch() may at\n    a point query the same icon but that's fine and not worth of locking mechanism as\n    it should be rather rare and worst case scenario once in a blue moon we waste\n    an API call. In the end the right file would be written on disk.\n\"\"\"\n\n    def __init__(self, data_dir: Path, coingecko: Coingecko) -> None:\n        self.icons_dir = data_dir / 'icons'\n        self.coingecko = coingecko\n        self.icons_dir.mkdir(parents=True, exist_ok=True)\n        self.failed_assets: Set[Asset] = set()\n\n    def iconfile_path(self, asset: Asset, size: Literal['thumb', 'small', 'large']) -> Path:\n        return self.icons_dir / f'{asset.identifier}_{size}.png'\n\n    def iconfile_md5(\n            self,\n            asset: Asset,\n            size: Literal['thumb', 'small', 'large'],\n    ) -> Optional[str]:\n        path = self.iconfile_path(asset, size)\n        if not path.is_file():\n            return None\n\n        return file_md5(path)\n\n    def _query_coingecko_for_icon(self, asset: Asset) -> bool:\n        \"\"\"Queries coingecko for icons of an asset\n\n        If query was okay it returns True, else False\n        \"\"\"\n        # Do not bother querying if asset is delisted. Nothing is returned.\n        # we only keep delisted asset coingecko mappings since historical prices\n        # can still be queried.\n        if asset.identifier in DELISTED_ASSETS:\n            self.failed_assets.add(asset)\n            return False\n\n        try:\n            data = self.coingecko.asset_data(asset)\n        except RemoteError as e:\n            log.warning(\n                f'Problem querying coingecko for asset data of {asset.identifier}: {str(e)}',\n            )\n            # If a query fails (99% of fails will be 404s) don't repeat them\n            self.failed_assets.add(asset)\n            return False\n\n        for size in ('thumb', 'small', 'large'):\n            url = getattr(data.images, size)\n            try:\n                response = requests.get(url, timeout=DEFAULT_TIMEOUT_TUPLE)\n            except requests.exceptions.RequestException:\n                # Any problem getting the image skip it: https://github.com/rotki/rotki/issues/1370\n                continue\n\n            with open(self.iconfile_path(asset, size), 'wb') as f:  # type: ignore\n                f.write(response.content)\n\n        return True\n\n    def get_icon(\n            self,\n            asset: Asset, given_size: Literal['thumb', 'small', 'large'],\n    ) -> Optional[bytes]:\n        \"\"\"Returns the byte data of the requested icon\n\n        If the icon can't be found it returns None.\n\n        If the icon is found cached locally it's returned directly.\n\n        If not, all icons of the asset are queried from coingecko and cached\n        locally before the requested data are returned.\n        \"\"\"\n        if not asset.has_coingecko():\n            return None\n\n        needed_path = self.iconfile_path(asset, given_size)\n        if needed_path.is_file():\n            with open(needed_path, 'rb') as f:\n                image_data = f.read()\n            return image_data\n\n        # else query coingecko for the icons and cache all of them\n        if self._query_coingecko_for_icon(asset) is False:\n            return None\n\n        if not needed_path.is_file():\n            return None\n\n        with open(needed_path, 'rb') as f:\n            image_data = f.read()\n        return image_data\n\n    def query_uncached_icons_batch(self, batch_size: int) -> bool:\n        \"\"\"Queries a batch of uncached icons for assets\n\n        Returns true if there is more icons left to cache after this batch.\n        \"\"\"\n        coingecko_integrated_assets = []\n\n        for identifier, asset_data in AssetResolver().assets.items():\n            asset_type = asset_type_mapping[asset_data['type']]\n            if asset_type != AssetType.FIAT and asset_data['coingecko'] != '':\n                coingecko_integrated_assets.append(identifier)\n\n        cached_assets = [\n            str(x.name)[:-10] for x in self.icons_dir.glob('*_thumb.png') if x.is_file()\n        ]\n        uncached_assets = (\n            set(coingecko_integrated_assets) - set(cached_assets) - self.failed_assets\n        )\n        log.info(\n            f'Periodic task to query coingecko for {batch_size} uncached asset icons. '\n            f'Uncached assets: {len(uncached_assets)}. Cached assets: {len(cached_assets)}',\n        )\n        for asset_name in itertools.islice(uncached_assets, batch_size):\n            self._query_coingecko_for_icon(Asset(asset_name))\n\n        return len(uncached_assets) > batch_size\n\n    def periodically_query_icons_until_all_cached(\n            self,\n            batch_size: int,\n            sleep_time_secs: float,\n    ) -> None:\n        \"\"\"Periodically query all uncached icons until we have icons cached for all\n        of the known assets that have coingecko integration\"\"\"\n        if batch_size == 0:\n            return\n\n        while True:\n            carry_on = self.query_uncached_icons_batch(batch_size=batch_size)\n            if not carry_on:\n                break\n            gevent.sleep(sleep_time_secs)\n", "path": "rotkehlchen/icons.py"}], "after_files": [{"content": "import itertools\nimport logging\nfrom pathlib import Path\nfrom typing import Optional, Set\n\nimport gevent\nimport requests\nfrom typing_extensions import Literal\n\nfrom rotkehlchen.assets.asset import Asset\nfrom rotkehlchen.assets.resolver import AssetResolver, asset_type_mapping\nfrom rotkehlchen.errors import RemoteError\nfrom rotkehlchen.externalapis.coingecko import Coingecko, DELISTED_ASSETS\nfrom rotkehlchen.typing import AssetType\nfrom rotkehlchen.utils.hashing import file_md5\nfrom rotkehlchen.constants.timing import DEFAULT_TIMEOUT_TUPLE\n\nlog = logging.getLogger(__name__)\n\n\nclass IconManager():\n    \"\"\"\n    Manages the icons for all the assets of the application\n\n    The get_icon() and the periodic task of query_uncached_icons_batch() may at\n    a point query the same icon but that's fine and not worth of locking mechanism as\n    it should be rather rare and worst case scenario once in a blue moon we waste\n    an API call. In the end the right file would be written on disk.\n    \"\"\"\n\n    def __init__(self, data_dir: Path, coingecko: Coingecko) -> None:\n        self.icons_dir = data_dir / 'icons'\n        self.coingecko = coingecko\n        self.icons_dir.mkdir(parents=True, exist_ok=True)\n        self.failed_assets: Set[Asset] = set()\n\n    def iconfile_path(self, asset: Asset, size: Literal['thumb', 'small', 'large']) -> Path:\n        return self.icons_dir / f'{asset.identifier}_{size}.png'\n\n    def iconfile_md5(\n            self,\n            asset: Asset,\n            size: Literal['thumb', 'small', 'large'],\n    ) -> Optional[str]:\n        path = self.iconfile_path(asset, size)\n        if not path.is_file():\n            return None\n\n        return file_md5(path)\n\n    def _query_coingecko_for_icon(self, asset: Asset) -> bool:\n        \"\"\"Queries coingecko for icons of an asset\n\n        If query was okay it returns True, else False\n        \"\"\"\n        # Do not bother querying if asset is delisted. Nothing is returned.\n        # we only keep delisted asset coingecko mappings since historical prices\n        # can still be queried.\n        if asset.identifier in DELISTED_ASSETS:\n            self.failed_assets.add(asset)\n            return False\n\n        try:\n            data = self.coingecko.asset_data(asset)\n        except RemoteError as e:\n            log.warning(\n                f'Problem querying coingecko for asset data of {asset.identifier}: {str(e)}',\n            )\n            # If a query fails (99% of fails will be 404s) don't repeat them\n            self.failed_assets.add(asset)\n            return False\n\n        for size in ('thumb', 'small', 'large'):\n            url = getattr(data.images, size)\n            try:\n                response = requests.get(url, timeout=DEFAULT_TIMEOUT_TUPLE)\n            except requests.exceptions.RequestException:\n                # Any problem getting the image skip it: https://github.com/rotki/rotki/issues/1370\n                continue\n\n            with open(self.iconfile_path(asset, size), 'wb') as f:  # type: ignore\n                f.write(response.content)\n\n        return True\n\n    def get_icon(\n            self,\n            asset: Asset, given_size: Literal['thumb', 'small', 'large'],\n    ) -> Optional[bytes]:\n        \"\"\"Returns the byte data of the requested icon\n\n        If the icon can't be found it returns None.\n\n        If the icon is found cached locally it's returned directly.\n\n        If not, all icons of the asset are queried from coingecko and cached\n        locally before the requested data are returned.\n        \"\"\"\n        if not asset.has_coingecko():\n            return None\n\n        needed_path = self.iconfile_path(asset, given_size)\n        if needed_path.is_file():\n            with open(needed_path, 'rb') as f:\n                image_data = f.read()\n            return image_data\n\n        # else query coingecko for the icons and cache all of them\n        if self._query_coingecko_for_icon(asset) is False:\n            return None\n\n        if not needed_path.is_file():\n            return None\n\n        with open(needed_path, 'rb') as f:\n            image_data = f.read()\n        return image_data\n\n    def query_uncached_icons_batch(self, batch_size: int) -> bool:\n        \"\"\"Queries a batch of uncached icons for assets\n\n        Returns true if there is more icons left to cache after this batch.\n        \"\"\"\n        coingecko_integrated_assets = []\n\n        for identifier, asset_data in AssetResolver().assets.items():\n            asset_type = asset_type_mapping[asset_data['type']]\n            if asset_type != AssetType.FIAT and asset_data['coingecko'] != '':\n                coingecko_integrated_assets.append(identifier)\n\n        cached_assets = [\n            str(x.name)[:-10] for x in self.icons_dir.glob('*_thumb.png') if x.is_file()\n        ]\n        uncached_assets = (\n            set(coingecko_integrated_assets) - set(cached_assets) - self.failed_assets\n        )\n        log.info(\n            f'Periodic task to query coingecko for {batch_size} uncached asset icons. '\n            f'Uncached assets: {len(uncached_assets)}. Cached assets: {len(cached_assets)}',\n        )\n        for asset_name in itertools.islice(uncached_assets, batch_size):\n            self._query_coingecko_for_icon(Asset(asset_name))\n\n        return len(uncached_assets) > batch_size\n\n    def periodically_query_icons_until_all_cached(\n            self,\n            batch_size: int,\n            sleep_time_secs: float,\n    ) -> None:\n        \"\"\"Periodically query all uncached icons until we have icons cached for all\n        of the known assets that have coingecko integration\"\"\"\n        if batch_size == 0:\n            return\n\n        while True:\n            carry_on = self.query_uncached_icons_batch(batch_size=batch_size)\n            if not carry_on:\n                break\n            gevent.sleep(sleep_time_secs)\n", "path": "rotkehlchen/icons.py"}]}