Repository: rotki/rotki

Issue:
ENS label_hash values starting with 0 get truncated
## Problem Definition

If the labelhash value of an ENS record starts with 0, the leading 0, possibly 0s are truncated and missing, leading to an incorrect length value, halting transaction decoding.

In the example shared below in Logs, querying Graph adding a 0 in front of 126... resolves their ens correctly afterwards

I have a suggested PR to come that fixes this on line 201 of ens/decoder.py 

## Logs

Borrowing from another user's report in Discord:

`decode 246 ethereum trasactions died with exception: The Graph query to query{domains(first:1, where:{labelhash:"0x126792ee6b36f6e438e270b25a6f7e91acddfcb032104dbcb681371a902802b"}){labelName}} failed due to {'message': 'Failed to decode `Bytes` value: `Odd number of digits`'}. No retries left.. Check the logs for more details
`

-->


### System Description


Operating system:  LFS Linux and Mac
Rotki version: v1.30.1



Discussion:

Resolving patch:
diff --git a/rotkehlchen/chain/ethereum/modules/ens/decoder.py b/rotkehlchen/chain/ethereum/modules/ens/decoder.py
--- a/rotkehlchen/chain/ethereum/modules/ens/decoder.py
+++ b/rotkehlchen/chain/ethereum/modules/ens/decoder.py
@@ -1,5 +1,4 @@
 import logging
-from multiprocessing.managers import RemoteError
 from typing import TYPE_CHECKING, Any, Optional
 
 import content_hash
@@ -23,6 +22,7 @@
 from rotkehlchen.chain.evm.types import string_to_evm_address
 from rotkehlchen.constants.assets import A_ETH
 from rotkehlchen.constants.misc import ZERO
+from rotkehlchen.errors.misc import RemoteError
 from rotkehlchen.errors.serialization import DeserializationError
 from rotkehlchen.logging import RotkehlchenLogsAdapter
 from rotkehlchen.types import ChecksumEvmAddress, DecoderEventMappingType, EvmTokenKind
@@ -127,6 +127,7 @@ def _decode_name_registered(self, context: DecoderContext) -> DecodingOutput:
                 if event.balance.amount != expected_amount:
                     return DEFAULT_DECODING_OUTPUT  # registration amount did not match
 
+                event.balance.amount = amount  # adjust the spent amount too, after refund
                 event.event_type = HistoryEventType.TRADE
                 event.event_subtype = HistoryEventSubType.SPEND
                 event.counterparty = CPT_ENS
@@ -198,7 +199,7 @@ def _decode_name_transfer(self, context: DecoderContext) -> DecodingOutput:
             log.error(f'Could not decode an ERC721 transfer for an ENS name transfer: {context.transaction.tx_hash.hex()}')  # noqa: E501
             return DEFAULT_DECODING_OUTPUT
 
-        label_hash = hex(transfer_event.extra_data['token_id'])  # type: ignore[index]  # noqa: E501  # ERC721 transfer always has extra data
+        label_hash = '0x{:064x}'.format(transfer_event.extra_data['token_id'])  # type: ignore[index]  # noqa: E501  # ERC721 transfer always has extra data
         try:
             result = self.graph.query(
                 querystr=f'query{{domains(first:1, where:{{labelhash:"{label_hash}"}}){{labelName}}}}')  # noqa: E501
diff --git a/rotkehlchen/tasks/utils.py b/rotkehlchen/tasks/utils.py
--- a/rotkehlchen/tasks/utils.py
+++ b/rotkehlchen/tasks/utils.py
@@ -1,11 +1,11 @@
 import logging
-from multiprocessing.managers import RemoteError
 from typing import TYPE_CHECKING, Literal, Optional
+
 from rotkehlchen.constants.assets import A_USD
+from rotkehlchen.errors.misc import RemoteError
 from rotkehlchen.errors.price import NoPriceForGivenTimestamp
 from rotkehlchen.history.price import PriceHistorian
 from rotkehlchen.logging import RotkehlchenLogsAdapter
-
 from rotkehlchen.serialization.deserialize import deserialize_timestamp
 from rotkehlchen.utils.misc import ts_now
 


Test patch:
diff --git a/rotkehlchen/tests/unit/decoders/test_ens.py b/rotkehlchen/tests/unit/decoders/test_ens.py
--- a/rotkehlchen/tests/unit/decoders/test_ens.py
+++ b/rotkehlchen/tests/unit/decoders/test_ens.py
@@ -6,6 +6,7 @@
 from rotkehlchen.assets.asset import Asset
 from rotkehlchen.assets.utils import get_or_create_evm_token
 from rotkehlchen.chain.ethereum.modules.ens.constants import CPT_ENS
+from rotkehlchen.chain.ethereum.modules.ens.decoder import ENS_REGISTRAR_CONTROLLER_1
 from rotkehlchen.chain.evm.decoding.constants import CPT_GAS
 from rotkehlchen.chain.evm.structures import EvmTxReceipt, EvmTxReceiptLog
 from rotkehlchen.chain.evm.types import string_to_evm_address
@@ -41,11 +42,13 @@ def test_mint_ens_name(database, ethereum_inquirer):
         tx_hash=tx_hash,
     )
     expires_timestamp = 2142055301
+    timestamp = TimestampMS(1637144069000)
+    register_fee_str = '0.019345192039577752'
     expected_events = [
         EvmEvent(
             tx_hash=tx_hash,
             sequence_index=0,
-            timestamp=1637144069000,
+            timestamp=timestamp,
             location=Location.ETHEREUM,
             event_type=HistoryEventType.SPEND,
             event_subtype=HistoryEventSubType.FEE,
@@ -57,14 +60,14 @@ def test_mint_ens_name(database, ethereum_inquirer):
         ), EvmEvent(
             tx_hash=tx_hash,
             sequence_index=2,
-            timestamp=1637144069000,
+            timestamp=timestamp,
             location=Location.ETHEREUM,
             event_type=HistoryEventType.TRADE,
             event_subtype=HistoryEventSubType.SPEND,
             asset=A_ETH,
-            balance=Balance(amount=FVal('0.021279711243535527')),
+            balance=Balance(amount=FVal(register_fee_str)),
             location_label=ADDY,
-            notes=f'Register ENS name hania.eth for 0.019345192039577752 ETH until {decoder.decoders["Ens"].timestamp_to_date(expires_timestamp)}',  # noqa: E501
+            notes=f'Register ENS name hania.eth for {register_fee_str} ETH until {decoder.decoders["Ens"].timestamp_to_date(expires_timestamp)}',  # noqa: E501
             counterparty=CPT_ENS,
             address=string_to_evm_address('0x283Af0B28c62C092C9727F1Ee09c02CA627EB7F5'),
         )]
@@ -608,3 +611,77 @@ def test_transfer_ens_name(database, ethereum_inquirer, action, ethereum_account
         },
     ))
     assert events == expected_events
+
+
+@pytest.mark.vcr()
+@pytest.mark.parametrize('ethereum_accounts', [['0x5f0eb172CaA67d45865AAd955FA77654Da33196F']])
+def test_for_truncated_labelhash(database, ethereum_inquirer, ethereum_accounts):
+    """Test for https://github.com/rotki/rotki/issues/6597 where some labelhashes
+    had their leading 0s truncated and lead to graph failures
+    """
+    tx_hex = deserialize_evm_tx_hash('0x8a809c2286342e04ce74494808c1dee5efd7aeb0af57b600780cb04eb3f83441')  # noqa: E501
+    evmhash = deserialize_evm_tx_hash(tx_hex)
+    user_address = ethereum_accounts[0]
+    events, decoder = get_decoded_events_of_transaction(
+        evm_inquirer=ethereum_inquirer,
+        database=database,
+        tx_hash=tx_hex,
+    )
+    timestamp = TimestampMS(1603662139000)
+    gas_str = '0.003424155'
+    register_fee_str = '0.122618417748598345'
+    expires_timestamp = Timestamp(1919231659)
+    erc721_asset = get_or_create_evm_token(  # TODO: Better way to test than this for ERC721 ...?
+        userdb=database,
+        evm_address=string_to_evm_address('0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85'),
+        chain_id=ChainID.ETHEREUM,
+        token_kind=EvmTokenKind.ERC721,
+        evm_inquirer=ethereum_inquirer,
+    )
+    expected_events = [
+        EvmEvent(
+            tx_hash=evmhash,
+            sequence_index=0,
+            timestamp=timestamp,
+            location=Location.ETHEREUM,
+            event_type=HistoryEventType.SPEND,
+            event_subtype=HistoryEventSubType.FEE,
+            asset=A_ETH,
+            balance=Balance(amount=FVal(gas_str)),
+            location_label=user_address,
+            notes=f'Burned {gas_str} ETH for gas',
+            counterparty=CPT_GAS,
+            address=None,
+        ), EvmEvent(
+            tx_hash=evmhash,
+            sequence_index=2,
+            timestamp=timestamp,
+            location=Location.ETHEREUM,
+            event_type=HistoryEventType.TRADE,
+            event_subtype=HistoryEventSubType.SPEND,
+            asset=A_ETH,
+            balance=Balance(amount=FVal(register_fee_str)),
+            location_label=user_address,
+            notes=f'Register ENS name cantillon.eth for {register_fee_str} ETH until {decoder.decoders["Ens"].timestamp_to_date(expires_timestamp)}',  # noqa: E501
+            counterparty=CPT_ENS,
+            address=ENS_REGISTRAR_CONTROLLER_1,
+        ), EvmEvent(
+            tx_hash=evmhash,
+            sequence_index=207,
+            timestamp=timestamp,
+            location=Location.ETHEREUM,
+            event_type=HistoryEventType.TRADE,
+            event_subtype=HistoryEventSubType.RECEIVE,
+            asset=erc721_asset,
+            balance=Balance(amount=FVal(1)),
+            location_label=user_address,
+            notes=f'Receive ENS name cantillon.eth from {ENS_REGISTRAR_CONTROLLER_1} to {user_address}',  # noqa: E501
+            counterparty=CPT_ENS,
+            address=ENS_REGISTRAR_CONTROLLER_1,
+            extra_data={
+                'token_id': 520289412805995815014030902380736904960994587318475958708983757899533811755,  # noqa: E501
+                'token_name': 'ERC721 token',
+            },
+        ),
+    ]
+    assert events == expected_events