backend-replacement icon indicating copy to clipboard operation
backend-replacement copied to clipboard

Gracefully handle missing token contract functions that are optional

Open mmhh1910 opened this issue 7 years ago • 2 comments

Backend assumes that fuctions like decimals are always implemented in token contracts. This is not the case and some functions are optional per: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md

We should handle all contract calls for these optional functions gracefully.

Example calls stack on exception:

  File "/usr/local/lib/python3.6/site-packages/engineio/asyncio_server.py", line 266, in _trigger_event
    ret = await self.handlers[event](*args)
  File "/usr/local/lib/python3.6/site-packages/socketio/asyncio_server.py", line 364, in _handle_eio_message
    await self._handle_event(sid, pkt.namespace, pkt.id, pkt.data)
  File "/usr/local/lib/python3.6/site-packages/socketio/asyncio_server.py", line 294, in _handle_event
    await self._handle_event_internal(self, sid, data, namespace, id)
  File "/usr/local/lib/python3.6/site-packages/socketio/asyncio_server.py", line 297, in _handle_event_internal
    r = await server._trigger_event(data[0], namespace, sid, *data[1:])
  File "/usr/local/lib/python3.6/site-packages/socketio/asyncio_server.py", line 325, in _trigger_event
    ret = await self.handlers[namespace][event](*args)
  File "/usr/src/app/app/services/websocket_server.py", line 372, in get_market
    "sells": [format_order(order) for order in orders_sells]
  File "/usr/src/app/app/services/websocket_server.py", line 372, in <listcomp>
    "sells": [format_order(order) for order in orders_sells]
  File "/usr/src/app/app/services/websocket_server.py", line 277, in format_order
    price = base_contract.denormalize_value(record["amount_get"]) / coin_contract.denormalize_value(record["amount_give"])
  File "/usr/src/app/app/src/erc20_token.py", line 31, in denormalize_value
    return value * Decimal(10.0 ** -self.decimals)
  File "/usr/src/app/app/src/erc20_token.py", line 42, in decimals
    cache[self.addr] = self._call_decimals()
  File "/usr/src/app/app/src/erc20_token.py", line 53, in _call_decimals
    raise ValueError(error_msg)
ValueError: Contract 0xb15fe5a123e647ba594cea7a1e648646f95eb4aa does not support method`decimals()', returned '0x'

mmhh1910 avatar Mar 07 '18 16:03 mmhh1910

Took the liberty of formatting the code block :)

freeatnet avatar Mar 07 '18 16:03 freeatnet

freeatnet:

I think we should support DECIMALS and potentially support an alternate method of getting decimals (etherscan?), but yes, in the updates thread, we should catch, log, and discard exceptions on a per-record basis

mmhh1910 avatar Mar 09 '18 10:03 mmhh1910