1
1
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
+ )
5
12
6
13
from eth_abi import decode as decode_abi
7
14
from eth_abi .exceptions import DecodingError
@@ -53,18 +60,28 @@ class MultisendDecoded(TypedDict):
53
60
data_decoded : DataDecoded | None
54
61
55
62
56
- mutex = Lock ()
63
+ @cache
64
+ def get_data_decoder_service () -> "DataDecoderService" :
65
+ d = DataDecoderService ()
66
+ d .init ()
67
+ return d
57
68
58
69
59
70
class DataDecoderService :
60
71
EXEC_TRANSACTION_SELECTOR = HexBytes ("0x6a761202" )
61
72
62
73
dummy_w3 = Web3 ()
63
74
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
+ """
65
80
logger .info ("%s: Loading contract ABIs for decoding" , self .__class__ .__name__ )
66
81
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
+ )
68
85
)
69
86
logger .info (
70
87
"%s: Contract ABIs for decoding were loaded" , self .__class__ .__name__
@@ -91,8 +108,8 @@ def _generate_selectors_with_abis_from_abi(
91
108
if fn_abi ["type" ] == "function"
92
109
}
93
110
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 ]]
96
113
) -> dict [bytes , ABIFunction ]:
97
114
"""
98
115
: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(
101
118
"""
102
119
return {
103
120
fn_selector : fn_abi
104
- for supported_abi in abis
121
+ async for supported_abi in abis
105
122
for fn_selector , fn_abi in self ._generate_selectors_with_abis_from_abi (
106
123
supported_abi
107
124
).items ()
108
125
}
109
126
110
- async def get_supported_abis (self ) -> Sequence [ABIFunction ]:
127
+ async def get_supported_abis (self ) -> AsyncIterator [ Sequence [ABIFunction ] ]:
111
128
"""
112
129
:return: Every ABI in the database
113
130
"""
0 commit comments