Skip to content

Commit a035bc5

Browse files
committed
Add tests for data decoder
1 parent 9473f16 commit a035bc5

File tree

3 files changed

+34
-21
lines changed

3 files changed

+34
-21
lines changed

app/services/data_decoder.py

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import logging
2-
from functools import cached_property, lru_cache
3-
from threading import Lock
4-
from typing import Any, NotRequired, Sequence, TypedDict, cast
2+
from functools import cache, cached_property, lru_cache
3+
from typing import (
4+
Any,
5+
AsyncGenerator,
6+
AsyncIterator,
7+
NotRequired,
8+
Sequence,
9+
TypedDict,
10+
cast,
11+
)
512

613
from eth_abi import decode as decode_abi
714
from eth_abi.exceptions import DecodingError
@@ -53,18 +60,28 @@ class MultisendDecoded(TypedDict):
5360
data_decoded: DataDecoded | None
5461

5562

56-
mutex = Lock()
63+
@cache
64+
def get_data_decoder_service() -> "DataDecoderService":
65+
d = DataDecoderService()
66+
d.init()
67+
return d
5768

5869

5970
class DataDecoderService:
6071
EXEC_TRANSACTION_SELECTOR = HexBytes("0x6a761202")
6172

6273
dummy_w3 = Web3()
6374

64-
def __init__(self):
75+
async def init(self):
76+
"""
77+
Initialize the data decoder service, loading the ABIs from the database and storing the 4byte selectors
78+
in memory
79+
"""
6580
logger.info("%s: Loading contract ABIs for decoding", self.__class__.__name__)
6681
self.fn_selectors_with_abis: dict[bytes, ABIFunction] = (
67-
self._generate_selectors_with_abis_from_abis(self.get_supported_abis())
82+
await self._generate_selectors_with_abis_from_abis(
83+
await self.get_supported_abis()
84+
)
6885
)
6986
logger.info(
7087
"%s: Contract ABIs for decoding were loaded", self.__class__.__name__
@@ -91,8 +108,8 @@ def _generate_selectors_with_abis_from_abi(
91108
if fn_abi["type"] == "function"
92109
}
93110

94-
def _generate_selectors_with_abis_from_abis(
95-
self, abis: Sequence[Sequence[ABIFunction]]
111+
async def _generate_selectors_with_abis_from_abis(
112+
self, abis: AsyncIterator[Sequence[ABIFunction]]
96113
) -> dict[bytes, ABIFunction]:
97114
"""
98115
:param abis: Contract ABIs. Last ABIs on the Sequence have preference if there's a collision on the
@@ -101,13 +118,13 @@ def _generate_selectors_with_abis_from_abis(
101118
"""
102119
return {
103120
fn_selector: fn_abi
104-
for supported_abi in abis
121+
async for supported_abi in abis
105122
for fn_selector, fn_abi in self._generate_selectors_with_abis_from_abi(
106123
supported_abi
107124
).items()
108125
}
109126

110-
async def get_supported_abis(self) -> Sequence[ABIFunction]:
127+
async def get_supported_abis(self) -> AsyncIterator[Sequence[ABIFunction]]:
111128
"""
112129
:return: Every ABI in the database
113130
"""
Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
import unittest
2-
31
from ...services.data_decoder import DataDecoderService
2+
from ..db.db_async_conn import DbAsyncConn
43

54

6-
class TestRouterAbout(unittest.TestCase):
7-
@classmethod
8-
def setUpClass(cls):
9-
cls.data_decoder = DataDecoderService()
10-
11-
def test_view_about(self):
12-
response = self.client.get("/api/v1/about")
13-
self.assertEqual(response.status_code, 200)
14-
self.assertEqual(response.json(), {"version": VERSION})
5+
class TestDataDecoderService(DbAsyncConn):
6+
async def test_init(self):
7+
d = DataDecoderService()
8+
await d.init()
9+
assert d.fn_selectors_with_abis == {}

requirements/dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ httpx
55
mypy
66
pre-commit
77
pytest
8+
pytest-asyncio

0 commit comments

Comments
 (0)