From ef951b7beb4f5e5c2cbf076ebca80b4f3d968e5a Mon Sep 17 00:00:00 2001 From: Igor Sereda Date: Sat, 1 Feb 2025 14:40:21 +0300 Subject: [PATCH] Fixed data parsing for `__kind` junctions with multiple keys --- CHANGELOG.md | 2 +- src/dipdup/runtimes.py | 14 +---- tests/test_datasources/test_substrate.py | 77 ++++++++++++++++++++++-- 3 files changed, 76 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e44caf158..d0f411eea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ Releases prior to 7.0 has been removed from this file to declutter search result - cli: Fixed help message on `CallbackError` reporting `batch` handler instead of actual one. - substrate.subsquid: Fixed parsing nested structures in response. -- substrate.subsquid: Fixed data parsing for `__kind=GeneralKey`. +- substrate.subsquid: Fixed parsing for `__kind` junctions with multiple keys. ### Changed diff --git a/src/dipdup/runtimes.py b/src/dipdup/runtimes.py index b300febcf..feca6ce6a 100644 --- a/src/dipdup/runtimes.py +++ b/src/dipdup/runtimes.py @@ -274,10 +274,12 @@ def extract_subsquid_payload(data: Any) -> Any: return tuple(extract_subsquid_payload(item) for item in data) if isinstance(data, dict): - if (kind := data.get('__kind')) is None: return {key: extract_subsquid_payload(value) for key, value in data.items()} + if len(data) > 2: + return {kind: {key: value for key, value in data.items() if key != '__kind'}} + if 'value' in data: value = data['value'] if isinstance(value, list | tuple): @@ -289,16 +291,6 @@ def extract_subsquid_payload(data: Any) -> Any: if 'key' in data: return {kind: data['key']} - # See: https://github.com/galacticcouncil/hydration-node/blob/master/precompiles/utils/src/solidity/codec/xcm.rs#L294 - if ( - 'data' in data and - 'length' in data and - isinstance(data['data'], str) and - data['data'].startswith('0x') and - isinstance(data['length'], int) - ): - return {kind: data['data'][:2+data['length']*2]} - return kind return data diff --git a/tests/test_datasources/test_substrate.py b/tests/test_datasources/test_substrate.py index 1d6438540..af1fe32d5 100644 --- a/tests/test_datasources/test_substrate.py +++ b/tests/test_datasources/test_substrate.py @@ -1,3 +1,5 @@ +import pytest + from dipdup.runtimes import extract_subsquid_payload path_1 = [ @@ -58,6 +60,35 @@ } ] +subsquid_general_key_with_value_payload_example = { + 'parents': 1, + 'interior': { + '__kind': 'X2', + 'value': [ + {'__kind': 'Parachain', 'value': 2030}, + { + '__kind': 'GeneralKey', + 'value': '0x02c80084af223c8b598536178d9361dc55bfda6818', + }, + ], + }, +} +subsquid_general_key_with_data_and_length_payload_example = { + 'parents': 1, + 'interior': { + '__kind': 'X2', + 'value': [ + {'__kind': 'Parachain', 'value': 2030}, + { + '__kind': 'GeneralKey', + 'data': '0x0809000000000000000000000000000000000000000000000000000000000000', + 'length': 2, + }, + ], + }, +} + + processed_path_1 = ( ( { @@ -105,10 +136,46 @@ }, }, ) +node_general_key_with_value_payload_example = { + 'parents': 1, + 'interior': { + 'X2': ( + {'Parachain': 2030}, + {'GeneralKey': '0x02c80084af223c8b598536178d9361dc55bfda6818'}, + ), + }, +} +node_general_key_with_data_and_length_payload_example = { + 'parents': 1, + 'interior': { + 'X2': ( + {'Parachain': 2030}, + { + 'GeneralKey': { + 'data': '0x0809000000000000000000000000000000000000000000000000000000000000', + 'length': 2, + } + }, + ), + }, +} -def test_extract_subsquid_payload() -> None: - - assert extract_subsquid_payload(path_1) == processed_path_1 - assert extract_subsquid_payload(path_2) == processed_path_2 - assert extract_subsquid_payload(path_3) == processed_path_3 +@pytest.mark.parametrize( + 'subsquid_payload, expected_node_payload', + ( + (path_1, processed_path_1), + (path_2, processed_path_2), + (path_3, processed_path_3), + ( + subsquid_general_key_with_value_payload_example, + node_general_key_with_value_payload_example, + ), + ( + subsquid_general_key_with_data_and_length_payload_example, + node_general_key_with_data_and_length_payload_example, + ), + ), +) +def test_extract_subsquid_payload(subsquid_payload, expected_node_payload) -> None: + assert extract_subsquid_payload(subsquid_payload) == expected_node_payload