1
1
from time import sleep
2
- from typing import Optional
2
+ from typing import Optional , TypedDict , Sequence
3
3
4
- from eth_typing import BlockNumber
4
+ from eth_typing import BlockNumber , Address , ChecksumAddress
5
+ from hexbytes import HexBytes
5
6
from web3 .eth import Eth
6
7
from web3 .exceptions import ContractLogicError
7
- from web3 .types import FilterParams , LogReceipt , CallOverride , BlockIdentifier , TxParams , BlockData
8
+ from web3 .types import FilterParams , LogReceipt , CallOverride , BlockIdentifier , TxParams , BlockData , _Hash32
8
9
9
10
from IceCreamSwapWeb3 import Web3Advanced
10
11
from IceCreamSwapWeb3 .Subsquid import get_filter
11
12
12
13
14
+ class ForkedBlock (Exception ):
15
+ pass
16
+
17
+
18
+ class FilterParamsExtended (TypedDict , total = False ):
19
+ address : Address | ChecksumAddress | list [Address ] | list [ChecksumAddress ]
20
+ blockHash : HexBytes
21
+ fromBlock : BlockIdentifier | BlockData
22
+ toBlock : BlockIdentifier | BlockData
23
+ topics : Sequence [_Hash32 | Sequence [_Hash32 ] | None ]
24
+
25
+
13
26
def exponential_retry (func_name : str = None ):
14
27
def wrapper (func ):
15
28
def inner (* args , no_retry : bool = False , ** kwargs ):
@@ -121,7 +134,7 @@ def get_block(
121
134
122
135
def get_logs (
123
136
self ,
124
- filter_params : FilterParams ,
137
+ filter_params : FilterParamsExtended ,
125
138
show_progress_bar : bool = False ,
126
139
p_bar = None ,
127
140
no_retry : bool = False ,
@@ -143,6 +156,10 @@ def get_logs(
143
156
if isinstance (from_block_original , int ):
144
157
from_block_body = None
145
158
from_block = from_block_original
159
+ elif isinstance (from_block_original , BlockData ):
160
+ from_block_body = from_block_original
161
+ from_block = from_block_original ["number" ]
162
+ filter_params = {** filter_params , "fromBlock" : from_block }
146
163
else :
147
164
from_block_body = self .get_block (from_block_original )
148
165
from_block = from_block_body ["number" ]
@@ -151,6 +168,10 @@ def get_logs(
151
168
if isinstance (to_block_original , int ):
152
169
to_block_body = None
153
170
to_block = to_block_original
171
+ elif isinstance (to_block_original , BlockData ):
172
+ to_block_body = to_block_original
173
+ to_block = to_block_original ["number" ]
174
+ filter_params = {** filter_params , "toBlock" : to_block }
154
175
else :
155
176
to_block_body = self .get_block (to_block_original )
156
177
to_block = to_block_body ["number" ]
@@ -198,11 +219,13 @@ def get_logs(
198
219
block = self .get_block (block_number , no_retry = no_retry )
199
220
if block_hashes :
200
221
# make sure chain of blocks is consistent with each block building on the previous one
201
- assert block ["parentHash" ] == block_hashes [- 1 ], f"{ block_hashes [- 1 ]= } , { block ['parentHash' ]= } "
222
+ assert block ["parentHash" ] == block_hashes [- 1 ], f"{ block_hashes [- 1 ]. hex () = } , { block ['parentHash' ]. hex () = } "
202
223
if block_number == from_block and from_block_body is not None :
203
- assert block ["hash" ] == from_block_body ["hash" ], f"{ from_block_body ['hash' ]= } , { block ['hash' ]= } "
224
+ if block ["hash" ] != from_block_body ["hash" ]:
225
+ raise ForkedBlock (f"expected={ from_block_body ['hash' ].hex ()} , actual={ block ['hash' ].hex ()} " )
204
226
if block_number == to_block and to_block_body is not None :
205
- assert block ["hash" ] == to_block_body ["hash" ], f"{ to_block_body ['hash' ]= } , { block ['hash' ]= } "
227
+ if block ["hash" ] != to_block_body ["hash" ]:
228
+ raise ForkedBlock (f"expected={ to_block_body ['hash' ].hex ()} , actual={ block ['hash' ].hex ()} " )
206
229
block_hashes .append (block ["hash" ])
207
230
208
231
single_hash_filter = filter_params .copy ()
0 commit comments