From 6d40a10ae54eebd032ba7e1cbb59b4c53268f6b6 Mon Sep 17 00:00:00 2001 From: Mike Shultz Date: Tue, 9 Jan 2024 18:25:22 -0700 Subject: [PATCH] fix: encode/decode bytes/HexBytes recursively in messages --- silverback/middlewares.py | 16 ++++++++++------ silverback/utils.py | 6 +++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/silverback/middlewares.py b/silverback/middlewares.py index e6029b7f..4e713d73 100644 --- a/silverback/middlewares.py +++ b/silverback/middlewares.py @@ -1,8 +1,9 @@ -from typing import Optional, Tuple +from typing import Any, Optional, Tuple from ape.logging import logger from ape.types import ContractLog from ape.utils import ManagerAccessMixin +from eth_utils.conversions import to_hex from taskiq import TaskiqMessage, TaskiqMiddleware, TaskiqResult from silverback.persistence import HandlerResult @@ -45,13 +46,16 @@ def compute_block_time() -> int: self.persistence = settings.get_persistent_store() def pre_send(self, message: TaskiqMessage) -> TaskiqMessage: - # TODO: Necessary until https://github.com/ApeWorX/ape/issues/1465 is resolved - - def fix_dict(data: dict) -> dict: - fixed_data = {} + # TODO: Necessary because bytes/HexBytes doesn't encode/deocde well for some reason + def fix_dict(data: dict, recurse_count: int = 0) -> dict: + fixed_data: dict[str, Any] = {} for name, value in data.items(): if isinstance(value, bytes): - fixed_data[name] = value.hex() + fixed_data[name] = to_hex(value) + elif isinstance(value, dict): + if recurse_count > 3: + raise RecursionError("Event object is too deep") + fixed_data[name] = fix_dict(value, recurse_count + 1) else: fixed_data[name] = value diff --git a/silverback/utils.py b/silverback/utils.py index 2a6846e2..9e0fba02 100644 --- a/silverback/utils.py +++ b/silverback/utils.py @@ -38,13 +38,17 @@ def iter_to_queue(): return yield_queue_items() -def hexbytes_dict(data: dict) -> dict: +def hexbytes_dict(data: dict, recurse_count: int = 0) -> dict: """Converts any hex string values in a flat dictionary to HexBytes.""" fixed_data = {} for name, value in data.items(): if isinstance(value, str) and value.startswith("0x"): fixed_data[name] = HexBytes(value) + elif isinstance(value, dict): + if recurse_count > 3: + raise RecursionError("Event object is too deep") + hexbytes_dict(value, recurse_count + 1) else: fixed_data[name] = value