Repository: rotki/rotki

Issue:
Failed to deserialize at Generate report
## Problem Definition
Binance and Kraken is setup
Tax report from 2010 till 2019.
Click Generate report
```
Querying trade history died because of: Failed to deserialize 1558090954.7199 kraken timestamp entry from an FVal. Check the logs for more details
```
### System Description

Rotkehlchen 1.0.1

```
18.2.0 Darwin Kernel Version 18.2.0: Thu Dec 20 20:46:53 PST 2018; root:xnu-4903.241.1~1/RELEASE_X86_64 x86_64
```



Discussion:
Ah that looks like something. Let me try to reproduce. I think I have an idea.
Confirming this as a reproducible bug. Will provide a fix soon.

Resolving patch:
diff --git a/rotkehlchen/kraken.py b/rotkehlchen/kraken.py
--- a/rotkehlchen/kraken.py
+++ b/rotkehlchen/kraken.py
@@ -165,6 +165,7 @@ def trade_from_kraken(kraken_trade: Dict[str, Any]) -> Trade:
     """
     currency_pair = kraken_to_world_pair(kraken_trade['pair'])
     quote_currency = get_pair_position_asset(currency_pair, 'second')
+
     timestamp = deserialize_timestamp_from_kraken(kraken_trade['time'])
     amount = deserialize_asset_amount(kraken_trade['vol'])
     cost = deserialize_price(kraken_trade['cost'])
diff --git a/rotkehlchen/serializer.py b/rotkehlchen/serializer.py
--- a/rotkehlchen/serializer.py
+++ b/rotkehlchen/serializer.py
@@ -166,7 +166,7 @@ def deserialize_timestamp_from_kraken(time: Union[str, FVal]) -> Timestamp:
             raise DeserializationError(f'Failed to deserialize {time} kraken timestamp entry')
     elif isinstance(time, FVal):
         try:
-            return Timestamp(time.to_int(exact=True))
+            return Timestamp(time.to_int(exact=False))
         except ValueError:
             raise DeserializationError(
                 f'Failed to deserialize {time} kraken timestamp entry from an FVal',


Test patch:
diff --git a/rotkehlchen/tests/fixtures/exchanges/kraken.py b/rotkehlchen/tests/fixtures/exchanges/kraken.py
--- a/rotkehlchen/tests/fixtures/exchanges/kraken.py
+++ b/rotkehlchen/tests/fixtures/exchanges/kraken.py
@@ -296,7 +296,7 @@ def query_private(self, method: str, req: Optional[dict] = None) -> dict:
                     tradeable_pairs=list(self.tradeable_pairs.keys()),
                 )
             # else
-            return KRAKEN_SPECIFIC_TRADES_HISTORY_RESPONSE
+            return rlk_jsonloads(KRAKEN_SPECIFIC_TRADES_HISTORY_RESPONSE)
         elif method == 'Ledgers':
             if self.random_ledgers_data:
                 return generate_random_kraken_ledger_data(
diff --git a/rotkehlchen/tests/test_kraken.py b/rotkehlchen/tests/test_kraken.py
--- a/rotkehlchen/tests/test_kraken.py
+++ b/rotkehlchen/tests/test_kraken.py
@@ -1,4 +1,3 @@
-from copy import deepcopy
 from unittest.mock import patch
 
 import pytest
@@ -148,13 +147,14 @@ def test_trade_from_kraken_unexpected_data(function_scope_kraken):
     kraken.random_ledgers_data = False
     kraken.cache_ttl_secs = 0
 
-    TEST_TRADES = {
+    # Important: Testing with a time floating point that has other than zero after decimal
+    TEST_TRADES = """{
         "trades": {
             "1": {
                 "ordertxid": "1",
                 "postxid": 1,
                 "pair": "XXBTZEUR",
-                "time": '1458994442.0000',
+                "time": "1458994442.2353",
                 "type": "buy",
                 "ordertype": "market",
                 "price": "100",
@@ -162,11 +162,11 @@ def test_trade_from_kraken_unexpected_data(function_scope_kraken):
                 "fee": "0.1",
                 "cost": "100",
                 "margin": "0.0",
-                "misc": "",
-            },
+                "misc": ""
+            }
         },
-        "count": 1,
-    }
+        "count": 1
+    }"""
 
     def query_kraken_and_test(input_trades, expected_warnings_num, expected_errors_num):
         with patch(target, new=input_trades):
@@ -191,35 +191,35 @@ def query_kraken_and_test(input_trades, expected_warnings_num, expected_errors_n
     query_kraken_and_test(TEST_TRADES, expected_warnings_num=0, expected_errors_num=0)
 
     # From here and on let's check trades with unexpected data
-    input_trades = deepcopy(TEST_TRADES)
-    input_trades['trades']['1']['pair'] = 'aadda'
+    input_trades = TEST_TRADES
+    input_trades = input_trades.replace('"pair": "XXBTZEUR"', '"pair": "aadda"')
     query_kraken_and_test(input_trades, expected_warnings_num=0, expected_errors_num=1)
 
-    input_trades = deepcopy(TEST_TRADES)
-    input_trades['trades']['1']['time'] = 'dsdsad'
+    input_trades = TEST_TRADES
+    input_trades = input_trades.replace('"time": "1458994442.2353"', '"time": "dsdsad"')
     query_kraken_and_test(input_trades, expected_warnings_num=0, expected_errors_num=1)
 
-    input_trades = deepcopy(TEST_TRADES)
-    input_trades['trades']['1']['vol'] = 'dsdsad'
+    input_trades = TEST_TRADES
+    input_trades = input_trades.replace('"vol": "1"', '"vol": "dsdsad"')
     query_kraken_and_test(input_trades, expected_warnings_num=0, expected_errors_num=1)
 
-    input_trades = deepcopy(TEST_TRADES)
-    input_trades['trades']['1']['cost'] = None
+    input_trades = TEST_TRADES
+    input_trades = input_trades.replace('"cost": "100"', '"cost": null')
     query_kraken_and_test(input_trades, expected_warnings_num=0, expected_errors_num=1)
 
-    input_trades = deepcopy(TEST_TRADES)
-    input_trades['trades']['1']['fee'] = 'dsdsad'
+    input_trades = TEST_TRADES
+    input_trades = input_trades.replace('"fee": "0.1"', '"fee": "dsdsad"')
     query_kraken_and_test(input_trades, expected_warnings_num=0, expected_errors_num=1)
 
-    input_trades = deepcopy(TEST_TRADES)
-    input_trades['trades']['1']['type'] = 'not existing type'
+    input_trades = TEST_TRADES
+    input_trades = input_trades.replace('"type": "buy"', '"type": "not existing type"')
     query_kraken_and_test(input_trades, expected_warnings_num=0, expected_errors_num=1)
 
-    input_trades = deepcopy(TEST_TRADES)
-    input_trades['trades']['1']['price'] = 'dsadsda'
+    input_trades = TEST_TRADES
+    input_trades = input_trades.replace('"price": "100"', '"price": "dsadsda"')
     query_kraken_and_test(input_trades, expected_warnings_num=0, expected_errors_num=1)
 
     # Also test key error
-    input_trades = deepcopy(TEST_TRADES)
-    del input_trades['trades']['1']['vol']
+    input_trades = TEST_TRADES
+    input_trades = input_trades.replace('"vol": "1",', '')
     query_kraken_and_test(input_trades, expected_warnings_num=0, expected_errors_num=1)
diff --git a/rotkehlchen/tests/utils/exchanges.py b/rotkehlchen/tests/utils/exchanges.py
--- a/rotkehlchen/tests/utils/exchanges.py
+++ b/rotkehlchen/tests/utils/exchanges.py
@@ -12,13 +12,13 @@
 }"""
 
 
-KRAKEN_SPECIFIC_TRADES_HISTORY_RESPONSE = {
+KRAKEN_SPECIFIC_TRADES_HISTORY_RESPONSE = """{
     "trades": {
         "1": {
             "ordertxid": "1",
             "postxid": 1,
             "pair": "XXBTZEUR",
-            "time": '1458994442.0000',
+            "time": "1458994442.0000",
             "type": "buy",
             "ordertype": "market",
             "price": "100",
@@ -31,7 +31,7 @@
             "ordertxid": "2",
             "postxid": 2,
             "pair": "XETHZEUR",
-            "time": '1456994442.0000',
+            "time": "1456994442.0000",
             "type": "buy",
             "ordertype": "market",
             "price": "100",
@@ -44,7 +44,7 @@
             "ordertxid": "3",
             "postxid": 3,
             "pair": "IDONTEXISTZEUR",
-            "time": '1458994442.0000',
+            "time": "1458994442.0000",
             "type": "buy",
             "ordertype": "market",
             "price": "100",
@@ -52,13 +52,13 @@
             "fee": "0.1",
             "cost": "100",
             "margin": "0.0",
-            "misc": "",
+            "misc": ""
         },
         "4": {
             "ordertxid": "4",
             "postxid": 4,
             "pair": "XETHIDONTEXISTTOO",
-            "time": '1458994442.0000',
+            "time": "1458994442.0000",
             "type": "buy",
             "ordertype": "market",
             "price": "100",
@@ -66,13 +66,13 @@
             "fee": "0.1",
             "cost": "100",
             "margin": "0.0",
-            "misc": "",
+            "misc": ""
         },
         "5": {
             "ordertxid": "5",
             "postxid": 5,
             "pair": "%$#%$#%$#%$#%$#%",
-            "time": '1458994442.0000',
+            "time": "1458994442.0000",
             "type": "buy",
             "ordertype": "market",
             "price": "100",
@@ -80,7 +80,7 @@
             "fee": "0.1",
             "cost": "100",
             "margin": "0.0",
-            "misc": "",
+            "misc": ""
         }},
-    "count": 5,
-}
+    "count": 5
+}"""