web3 7.3.0__py3-none-any.whl → 7.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ens/_normalization.py +3 -1
- ens/specs/nf.json +1 -1
- ens/specs/normalization_spec.json +1 -1
- web3/_utils/abi.py +3 -11
- web3/_utils/caching/caching_utils.py +125 -24
- web3/_utils/caching/request_caching_validation.py +204 -47
- web3/_utils/contract_sources/contract_data/offchain_lookup.py +2 -2
- web3/_utils/module_testing/eth_module.py +3 -3
- web3/_utils/module_testing/module_testing_utils.py +3 -3
- web3/_utils/module_testing/utils.py +11 -3
- web3/beacon/async_beacon.py +4 -1
- web3/contract/base_contract.py +1 -2
- web3/providers/async_base.py +7 -4
- web3/providers/base.py +7 -4
- web3/providers/ipc.py +4 -0
- web3/utils/async_exception_handling.py +2 -5
- web3/utils/exception_handling.py +2 -7
- {web3-7.3.0.dist-info → web3-7.4.0.dist-info}/METADATA +1 -1
- {web3-7.3.0.dist-info → web3-7.4.0.dist-info}/RECORD +22 -22
- {web3-7.3.0.dist-info → web3-7.4.0.dist-info}/WHEEL +1 -1
- {web3-7.3.0.dist-info → web3-7.4.0.dist-info}/LICENSE +0 -0
- {web3-7.3.0.dist-info → web3-7.4.0.dist-info}/top_level.txt +0 -0
web3/_utils/abi.py
CHANGED
|
@@ -110,19 +110,11 @@ def receive_func_abi_exists(contract_abi: ABI) -> Sequence[ABIReceive]:
|
|
|
110
110
|
|
|
111
111
|
|
|
112
112
|
def get_indexed_event_inputs(event_abi: ABIEvent) -> Sequence[ABIComponentIndexed]:
|
|
113
|
-
return [
|
|
114
|
-
cast(ABIComponentIndexed, arg)
|
|
115
|
-
for arg in event_abi["inputs"]
|
|
116
|
-
if cast(ABIComponentIndexed, arg)["indexed"] is True
|
|
117
|
-
]
|
|
113
|
+
return [arg for arg in event_abi["inputs"] if arg["indexed"] is True]
|
|
118
114
|
|
|
119
115
|
|
|
120
|
-
def exclude_indexed_event_inputs(event_abi: ABIEvent) -> Sequence[
|
|
121
|
-
return [
|
|
122
|
-
arg
|
|
123
|
-
for arg in event_abi["inputs"]
|
|
124
|
-
if cast(ABIComponentIndexed, arg)["indexed"] is False
|
|
125
|
-
]
|
|
116
|
+
def exclude_indexed_event_inputs(event_abi: ABIEvent) -> Sequence[ABIComponentIndexed]:
|
|
117
|
+
return [arg for arg in event_abi["inputs"] if arg["indexed"] is False]
|
|
126
118
|
|
|
127
119
|
|
|
128
120
|
def filter_by_argument_name(
|
|
@@ -16,6 +16,9 @@ from typing import (
|
|
|
16
16
|
Union,
|
|
17
17
|
)
|
|
18
18
|
|
|
19
|
+
from eth_typing import (
|
|
20
|
+
ChainId,
|
|
21
|
+
)
|
|
19
22
|
from eth_utils import (
|
|
20
23
|
is_boolean,
|
|
21
24
|
is_bytes,
|
|
@@ -34,12 +37,15 @@ from web3._utils.caching import (
|
|
|
34
37
|
from web3._utils.caching.request_caching_validation import (
|
|
35
38
|
UNCACHEABLE_BLOCK_IDS,
|
|
36
39
|
always_cache_request,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
async_validate_from_block_id_in_params,
|
|
41
|
+
async_validate_from_blockhash_in_params,
|
|
42
|
+
async_validate_from_blocknum_in_result,
|
|
43
|
+
validate_from_block_id_in_params,
|
|
44
|
+
validate_from_blockhash_in_params,
|
|
45
|
+
validate_from_blocknum_in_result,
|
|
46
|
+
)
|
|
47
|
+
from web3._utils.empty import (
|
|
48
|
+
empty,
|
|
43
49
|
)
|
|
44
50
|
from web3._utils.rpc_abi import (
|
|
45
51
|
RPC,
|
|
@@ -47,6 +53,12 @@ from web3._utils.rpc_abi import (
|
|
|
47
53
|
from web3.exceptions import (
|
|
48
54
|
Web3TypeError,
|
|
49
55
|
)
|
|
56
|
+
from web3.types import (
|
|
57
|
+
RPCEndpoint,
|
|
58
|
+
)
|
|
59
|
+
from web3.utils import (
|
|
60
|
+
RequestCacheValidationThreshold,
|
|
61
|
+
)
|
|
50
62
|
|
|
51
63
|
if TYPE_CHECKING:
|
|
52
64
|
from web3.providers import ( # noqa: F401
|
|
@@ -56,7 +68,6 @@ if TYPE_CHECKING:
|
|
|
56
68
|
from web3.types import ( # noqa: F401
|
|
57
69
|
AsyncMakeRequestFn,
|
|
58
70
|
MakeRequestFn,
|
|
59
|
-
RPCEndpoint,
|
|
60
71
|
RPCResponse,
|
|
61
72
|
)
|
|
62
73
|
|
|
@@ -84,7 +95,7 @@ def generate_cache_key(value: Any) -> str:
|
|
|
84
95
|
class RequestInformation:
|
|
85
96
|
def __init__(
|
|
86
97
|
self,
|
|
87
|
-
method:
|
|
98
|
+
method: RPCEndpoint,
|
|
88
99
|
params: Any,
|
|
89
100
|
response_formatters: Tuple[
|
|
90
101
|
Union[Dict[str, Callable[..., Any]], Callable[..., Any]],
|
|
@@ -100,9 +111,31 @@ class RequestInformation:
|
|
|
100
111
|
self.middleware_response_processors: List[Callable[..., Any]] = []
|
|
101
112
|
|
|
102
113
|
|
|
114
|
+
DEFAULT_VALIDATION_THRESHOLD = 60 * 60 # 1 hour
|
|
115
|
+
|
|
116
|
+
CHAIN_VALIDATION_THRESHOLD_DEFAULTS: Dict[
|
|
117
|
+
int, Union[RequestCacheValidationThreshold, int]
|
|
118
|
+
] = {
|
|
119
|
+
# Suggested safe values as defaults for each chain. Users can configure a different
|
|
120
|
+
# value if desired.
|
|
121
|
+
ChainId.ETH.value: RequestCacheValidationThreshold.FINALIZED,
|
|
122
|
+
ChainId.ARB1.value: 7 * 24 * 60 * 60, # 7 days
|
|
123
|
+
ChainId.ZKSYNC.value: 60 * 60, # 1 hour
|
|
124
|
+
ChainId.OETH.value: 3 * 60, # 3 minutes
|
|
125
|
+
ChainId.MATIC.value: 30 * 60, # 30 minutes
|
|
126
|
+
ChainId.ZKEVM.value: 60 * 60, # 1 hour
|
|
127
|
+
ChainId.BASE.value: 7 * 24 * 60 * 60, # 7 days
|
|
128
|
+
ChainId.SCR.value: 60 * 60, # 1 hour
|
|
129
|
+
ChainId.GNO.value: 5 * 60, # 5 minutes
|
|
130
|
+
ChainId.AVAX.value: 2 * 60, # 2 minutes
|
|
131
|
+
ChainId.BNB.value: 2 * 60, # 2 minutes
|
|
132
|
+
ChainId.FTM.value: 60, # 1 minute
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
103
136
|
def is_cacheable_request(
|
|
104
137
|
provider: Union[ASYNC_PROVIDER_TYPE, SYNC_PROVIDER_TYPE],
|
|
105
|
-
method:
|
|
138
|
+
method: RPCEndpoint,
|
|
106
139
|
params: Any,
|
|
107
140
|
) -> bool:
|
|
108
141
|
if not (provider.cache_allowed_requests and method in provider.cacheable_requests):
|
|
@@ -128,7 +161,7 @@ BLOCKNUM_IN_PARAMS = {
|
|
|
128
161
|
RPC.eth_getUncleByBlockNumberAndIndex,
|
|
129
162
|
RPC.eth_getUncleCountByBlockNumber,
|
|
130
163
|
}
|
|
131
|
-
|
|
164
|
+
BLOCK_IN_RESULT = {
|
|
132
165
|
RPC.eth_getBlockByHash,
|
|
133
166
|
RPC.eth_getTransactionByHash,
|
|
134
167
|
RPC.eth_getTransactionByBlockNumberAndIndex,
|
|
@@ -142,25 +175,58 @@ BLOCKHASH_IN_PARAMS = {
|
|
|
142
175
|
}
|
|
143
176
|
|
|
144
177
|
INTERNAL_VALIDATION_MAP: Dict[
|
|
145
|
-
|
|
178
|
+
RPCEndpoint,
|
|
179
|
+
Callable[
|
|
180
|
+
[SYNC_PROVIDER_TYPE, Sequence[Any], Dict[str, Any]],
|
|
181
|
+
bool,
|
|
182
|
+
],
|
|
146
183
|
] = {
|
|
147
184
|
**{endpoint: always_cache_request for endpoint in ALWAYS_CACHE},
|
|
148
|
-
**{endpoint:
|
|
149
|
-
**{endpoint:
|
|
150
|
-
**{endpoint:
|
|
185
|
+
**{endpoint: validate_from_block_id_in_params for endpoint in BLOCKNUM_IN_PARAMS},
|
|
186
|
+
**{endpoint: validate_from_blocknum_in_result for endpoint in BLOCK_IN_RESULT},
|
|
187
|
+
**{endpoint: validate_from_blockhash_in_params for endpoint in BLOCKHASH_IN_PARAMS},
|
|
151
188
|
}
|
|
152
189
|
CACHEABLE_REQUESTS = tuple(INTERNAL_VALIDATION_MAP.keys())
|
|
153
190
|
|
|
154
191
|
|
|
192
|
+
def set_threshold_if_empty(provider: SYNC_PROVIDER_TYPE) -> None:
|
|
193
|
+
current_threshold = provider.request_cache_validation_threshold
|
|
194
|
+
|
|
195
|
+
if current_threshold is empty or isinstance(
|
|
196
|
+
current_threshold, RequestCacheValidationThreshold
|
|
197
|
+
):
|
|
198
|
+
cache_allowed_requests = provider.cache_allowed_requests
|
|
199
|
+
try:
|
|
200
|
+
# turn off momentarily to avoid recursion
|
|
201
|
+
provider.cache_allowed_requests = False
|
|
202
|
+
chain_id_result = provider.make_request(RPCEndpoint("eth_chainId"), [])[
|
|
203
|
+
"result"
|
|
204
|
+
]
|
|
205
|
+
chain_id = int(chain_id_result, 16)
|
|
206
|
+
|
|
207
|
+
if current_threshold is empty:
|
|
208
|
+
provider.request_cache_validation_threshold = (
|
|
209
|
+
CHAIN_VALIDATION_THRESHOLD_DEFAULTS.get(
|
|
210
|
+
chain_id, DEFAULT_VALIDATION_THRESHOLD
|
|
211
|
+
)
|
|
212
|
+
)
|
|
213
|
+
except Exception:
|
|
214
|
+
provider.request_cache_validation_threshold = DEFAULT_VALIDATION_THRESHOLD
|
|
215
|
+
finally:
|
|
216
|
+
provider.cache_allowed_requests = cache_allowed_requests
|
|
217
|
+
|
|
218
|
+
|
|
155
219
|
def _should_cache_response(
|
|
156
220
|
provider: SYNC_PROVIDER_TYPE,
|
|
157
|
-
method:
|
|
221
|
+
method: RPCEndpoint,
|
|
158
222
|
params: Sequence[Any],
|
|
159
223
|
response: "RPCResponse",
|
|
160
224
|
) -> bool:
|
|
161
225
|
result = response.get("result", None)
|
|
162
226
|
if "error" in response or is_null(result):
|
|
163
227
|
return False
|
|
228
|
+
|
|
229
|
+
set_threshold_if_empty(provider)
|
|
164
230
|
if (
|
|
165
231
|
method in INTERNAL_VALIDATION_MAP
|
|
166
232
|
and provider.request_cache_validation_threshold is not None
|
|
@@ -170,10 +236,10 @@ def _should_cache_response(
|
|
|
170
236
|
|
|
171
237
|
|
|
172
238
|
def handle_request_caching(
|
|
173
|
-
func: Callable[[SYNC_PROVIDER_TYPE,
|
|
239
|
+
func: Callable[[SYNC_PROVIDER_TYPE, RPCEndpoint, Any], "RPCResponse"]
|
|
174
240
|
) -> Callable[..., "RPCResponse"]:
|
|
175
241
|
def wrapper(
|
|
176
|
-
provider: SYNC_PROVIDER_TYPE, method:
|
|
242
|
+
provider: SYNC_PROVIDER_TYPE, method: RPCEndpoint, params: Any
|
|
177
243
|
) -> "RPCResponse":
|
|
178
244
|
if is_cacheable_request(provider, method, params):
|
|
179
245
|
request_cache = provider._request_cache
|
|
@@ -204,25 +270,60 @@ ASYNC_VALIDATOR_TYPE = Callable[
|
|
|
204
270
|
Union[bool, Coroutine[Any, Any, bool]],
|
|
205
271
|
]
|
|
206
272
|
|
|
207
|
-
ASYNC_INTERNAL_VALIDATION_MAP: Dict[
|
|
273
|
+
ASYNC_INTERNAL_VALIDATION_MAP: Dict[RPCEndpoint, ASYNC_VALIDATOR_TYPE] = {
|
|
208
274
|
**{endpoint: always_cache_request for endpoint in ALWAYS_CACHE},
|
|
209
|
-
**{endpoint: async_validate_blocknum_in_params for endpoint in BLOCKNUM_IN_PARAMS},
|
|
210
|
-
**{endpoint: async_validate_blocknum_in_result for endpoint in BLOCKNUM_IN_RESULT},
|
|
211
275
|
**{
|
|
212
|
-
endpoint:
|
|
276
|
+
endpoint: async_validate_from_block_id_in_params
|
|
277
|
+
for endpoint in BLOCKNUM_IN_PARAMS
|
|
278
|
+
},
|
|
279
|
+
**{
|
|
280
|
+
endpoint: async_validate_from_blocknum_in_result for endpoint in BLOCK_IN_RESULT
|
|
281
|
+
},
|
|
282
|
+
**{
|
|
283
|
+
endpoint: async_validate_from_blockhash_in_params
|
|
284
|
+
for endpoint in BLOCKHASH_IN_PARAMS
|
|
213
285
|
},
|
|
214
286
|
}
|
|
215
287
|
|
|
216
288
|
|
|
289
|
+
async def async_set_threshold_if_empty(provider: ASYNC_PROVIDER_TYPE) -> None:
|
|
290
|
+
current_threshold = provider.request_cache_validation_threshold
|
|
291
|
+
|
|
292
|
+
if current_threshold is empty or isinstance(
|
|
293
|
+
current_threshold, RequestCacheValidationThreshold
|
|
294
|
+
):
|
|
295
|
+
cache_allowed_requests = provider.cache_allowed_requests
|
|
296
|
+
try:
|
|
297
|
+
# turn off momentarily to avoid recursion
|
|
298
|
+
provider.cache_allowed_requests = False
|
|
299
|
+
chain_id_result = await provider.make_request(
|
|
300
|
+
RPCEndpoint("eth_chainId"), []
|
|
301
|
+
)
|
|
302
|
+
chain_id = int(chain_id_result["result"], 16)
|
|
303
|
+
|
|
304
|
+
if current_threshold is empty:
|
|
305
|
+
provider.request_cache_validation_threshold = (
|
|
306
|
+
CHAIN_VALIDATION_THRESHOLD_DEFAULTS.get(
|
|
307
|
+
chain_id, DEFAULT_VALIDATION_THRESHOLD
|
|
308
|
+
)
|
|
309
|
+
)
|
|
310
|
+
except Exception:
|
|
311
|
+
provider.request_cache_validation_threshold = DEFAULT_VALIDATION_THRESHOLD
|
|
312
|
+
finally:
|
|
313
|
+
provider.cache_allowed_requests = cache_allowed_requests
|
|
314
|
+
|
|
315
|
+
|
|
217
316
|
async def _async_should_cache_response(
|
|
218
317
|
provider: ASYNC_PROVIDER_TYPE,
|
|
219
|
-
method:
|
|
318
|
+
method: RPCEndpoint,
|
|
220
319
|
params: Sequence[Any],
|
|
221
320
|
response: "RPCResponse",
|
|
222
321
|
) -> bool:
|
|
223
322
|
result = response.get("result", None)
|
|
224
323
|
if "error" in response or is_null(result):
|
|
225
324
|
return False
|
|
325
|
+
|
|
326
|
+
await async_set_threshold_if_empty(provider)
|
|
226
327
|
if (
|
|
227
328
|
method in ASYNC_INTERNAL_VALIDATION_MAP
|
|
228
329
|
and provider.request_cache_validation_threshold is not None
|
|
@@ -238,11 +339,11 @@ async def _async_should_cache_response(
|
|
|
238
339
|
|
|
239
340
|
def async_handle_request_caching(
|
|
240
341
|
func: Callable[
|
|
241
|
-
[ASYNC_PROVIDER_TYPE,
|
|
342
|
+
[ASYNC_PROVIDER_TYPE, RPCEndpoint, Any], Coroutine[Any, Any, "RPCResponse"]
|
|
242
343
|
],
|
|
243
344
|
) -> Callable[..., Coroutine[Any, Any, "RPCResponse"]]:
|
|
244
345
|
async def wrapper(
|
|
245
|
-
provider: ASYNC_PROVIDER_TYPE, method:
|
|
346
|
+
provider: ASYNC_PROVIDER_TYPE, method: RPCEndpoint, params: Any
|
|
246
347
|
) -> "RPCResponse":
|
|
247
348
|
if is_cacheable_request(provider, method, params):
|
|
248
349
|
request_cache = provider._request_cache
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import time
|
|
1
2
|
from typing import (
|
|
2
3
|
TYPE_CHECKING,
|
|
3
4
|
Any,
|
|
@@ -7,8 +8,11 @@ from typing import (
|
|
|
7
8
|
Union,
|
|
8
9
|
)
|
|
9
10
|
|
|
10
|
-
from
|
|
11
|
-
|
|
11
|
+
from web3.types import (
|
|
12
|
+
RPCEndpoint,
|
|
13
|
+
)
|
|
14
|
+
from web3.utils import (
|
|
15
|
+
RequestCacheValidationThreshold,
|
|
12
16
|
)
|
|
13
17
|
|
|
14
18
|
if TYPE_CHECKING:
|
|
@@ -31,99 +35,252 @@ def _error_log(
|
|
|
31
35
|
)
|
|
32
36
|
|
|
33
37
|
|
|
34
|
-
def
|
|
38
|
+
def always_cache_request(*_args: Any, **_kwargs: Any) -> bool:
|
|
39
|
+
return True
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def is_beyond_validation_threshold(
|
|
43
|
+
provider: SYNC_PROVIDER_TYPE,
|
|
44
|
+
blocknum: int = None,
|
|
45
|
+
block_timestamp: int = None,
|
|
46
|
+
) -> bool:
|
|
47
|
+
cache_allowed_requests = provider.cache_allowed_requests
|
|
35
48
|
try:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
49
|
+
threshold = provider.request_cache_validation_threshold
|
|
50
|
+
|
|
51
|
+
# turn off caching to prevent recursion
|
|
52
|
+
provider.cache_allowed_requests = False
|
|
53
|
+
if isinstance(threshold, RequestCacheValidationThreshold):
|
|
54
|
+
# if mainnet and threshold is "finalized" or "safe"
|
|
55
|
+
threshold_block = provider.make_request(
|
|
56
|
+
RPCEndpoint("eth_getBlockByNumber"), [threshold.value, False]
|
|
57
|
+
)["result"]
|
|
58
|
+
# we should have a `blocknum` to compare against
|
|
59
|
+
return blocknum <= int(threshold_block["number"], 16)
|
|
60
|
+
elif isinstance(threshold, int):
|
|
61
|
+
if not block_timestamp:
|
|
62
|
+
# if validating via `blocknum` from params, we need to get the timestamp
|
|
63
|
+
# for the block with `blocknum`.
|
|
64
|
+
block = provider.make_request(
|
|
65
|
+
RPCEndpoint("eth_getBlockByNumber"), [hex(blocknum), False]
|
|
66
|
+
)["result"]
|
|
67
|
+
block_timestamp = int(block["timestamp"], 16)
|
|
68
|
+
|
|
69
|
+
# if validating via `block_timestamp` from result, we should have a
|
|
70
|
+
# `block_timestamp` to compare against
|
|
71
|
+
return block_timestamp <= time.time() - threshold
|
|
72
|
+
else:
|
|
73
|
+
provider.logger.error(
|
|
74
|
+
"Invalid request_cache_validation_threshold value. This should not "
|
|
75
|
+
f"have happened. Request not cached.\n threshold: {threshold}"
|
|
76
|
+
)
|
|
77
|
+
return False
|
|
40
78
|
except Exception as e:
|
|
41
79
|
_error_log(provider, e)
|
|
42
80
|
return False
|
|
81
|
+
finally:
|
|
82
|
+
provider.cache_allowed_requests = cache_allowed_requests
|
|
43
83
|
|
|
44
84
|
|
|
45
|
-
def
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def validate_blocknum_in_params(
|
|
50
|
-
provider: SYNC_PROVIDER_TYPE, params: Sequence[Any], _result: Dict[str, Any]
|
|
85
|
+
def validate_from_block_id_in_params(
|
|
86
|
+
provider: SYNC_PROVIDER_TYPE,
|
|
87
|
+
params: Sequence[Any],
|
|
88
|
+
_result: Dict[str, Any],
|
|
51
89
|
) -> bool:
|
|
52
90
|
block_id = params[0]
|
|
53
91
|
if block_id == "earliest":
|
|
54
92
|
# `earliest` should always be cacheable
|
|
55
93
|
return True
|
|
56
|
-
|
|
57
|
-
|
|
94
|
+
|
|
95
|
+
blocknum = int(block_id, 16)
|
|
96
|
+
return is_beyond_validation_threshold(provider, blocknum=blocknum)
|
|
58
97
|
|
|
59
98
|
|
|
60
|
-
def
|
|
61
|
-
provider: SYNC_PROVIDER_TYPE,
|
|
99
|
+
def validate_from_blocknum_in_result(
|
|
100
|
+
provider: SYNC_PROVIDER_TYPE,
|
|
101
|
+
_params: Sequence[Any],
|
|
102
|
+
result: Dict[str, Any],
|
|
62
103
|
) -> bool:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
104
|
+
cache_allowed_requests = provider.cache_allowed_requests
|
|
105
|
+
try:
|
|
106
|
+
# turn off caching to prevent recursion
|
|
107
|
+
provider.cache_allowed_requests = False
|
|
66
108
|
|
|
109
|
+
# transaction results
|
|
110
|
+
if "blockNumber" in result:
|
|
111
|
+
blocknum = result.get("blockNumber")
|
|
112
|
+
# make an extra call to get the block values
|
|
113
|
+
block = provider.make_request(
|
|
114
|
+
RPCEndpoint("eth_getBlockByNumber"), [blocknum, False]
|
|
115
|
+
)["result"]
|
|
116
|
+
return is_beyond_validation_threshold(
|
|
117
|
+
provider,
|
|
118
|
+
blocknum=int(blocknum, 16),
|
|
119
|
+
block_timestamp=int(block["timestamp"], 16),
|
|
120
|
+
)
|
|
121
|
+
elif "number" in result:
|
|
122
|
+
return is_beyond_validation_threshold(
|
|
123
|
+
provider,
|
|
124
|
+
blocknum=int(result["number"], 16),
|
|
125
|
+
block_timestamp=int(result["timestamp"], 16),
|
|
126
|
+
)
|
|
127
|
+
else:
|
|
128
|
+
provider.logger.error(
|
|
129
|
+
"Could not find block number in result. This should not have happened. "
|
|
130
|
+
f"Request not cached.\n result: {result}",
|
|
131
|
+
)
|
|
132
|
+
return False
|
|
133
|
+
except Exception as e:
|
|
134
|
+
_error_log(provider, e)
|
|
135
|
+
return False
|
|
136
|
+
finally:
|
|
137
|
+
provider.cache_allowed_requests = cache_allowed_requests
|
|
67
138
|
|
|
68
|
-
|
|
69
|
-
|
|
139
|
+
|
|
140
|
+
def validate_from_blockhash_in_params(
|
|
141
|
+
provider: SYNC_PROVIDER_TYPE,
|
|
142
|
+
params: Sequence[Any],
|
|
143
|
+
_result: Dict[str, Any],
|
|
70
144
|
) -> bool:
|
|
145
|
+
cache_allowed_requests = provider.cache_allowed_requests
|
|
71
146
|
try:
|
|
147
|
+
# turn off caching to prevent recursion
|
|
148
|
+
provider.cache_allowed_requests = False
|
|
149
|
+
|
|
72
150
|
# make an extra call to get the block number from the hash
|
|
73
|
-
|
|
151
|
+
block = provider.make_request(
|
|
152
|
+
RPCEndpoint("eth_getBlockByHash"), [params[0], False]
|
|
153
|
+
)["result"]
|
|
154
|
+
return is_beyond_validation_threshold(
|
|
155
|
+
provider,
|
|
156
|
+
blocknum=int(block["number"], 16),
|
|
157
|
+
block_timestamp=int(block["timestamp"], 16),
|
|
158
|
+
)
|
|
74
159
|
except Exception as e:
|
|
75
160
|
_error_log(provider, e)
|
|
76
161
|
return False
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return is_beyond_validation_threshold(provider, blocknum)
|
|
162
|
+
finally:
|
|
163
|
+
provider.cache_allowed_requests = cache_allowed_requests
|
|
80
164
|
|
|
81
165
|
|
|
82
166
|
# -- async -- #
|
|
83
167
|
|
|
84
168
|
|
|
85
169
|
async def async_is_beyond_validation_threshold(
|
|
86
|
-
provider: ASYNC_PROVIDER_TYPE,
|
|
170
|
+
provider: ASYNC_PROVIDER_TYPE,
|
|
171
|
+
blocknum: int = None,
|
|
172
|
+
block_timestamp: int = None,
|
|
87
173
|
) -> bool:
|
|
174
|
+
cache_allowed_requests = provider.cache_allowed_requests
|
|
88
175
|
try:
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
)
|
|
94
|
-
|
|
176
|
+
threshold = provider.request_cache_validation_threshold
|
|
177
|
+
|
|
178
|
+
# turn off caching to prevent recursion
|
|
179
|
+
provider.cache_allowed_requests = False
|
|
180
|
+
if isinstance(threshold, RequestCacheValidationThreshold):
|
|
181
|
+
# if mainnet and threshold is "finalized" or "safe"
|
|
182
|
+
threshold_block = await provider.make_request(
|
|
183
|
+
RPCEndpoint("eth_getBlockByNumber"), [threshold.value, False]
|
|
184
|
+
)
|
|
185
|
+
# we should have a `blocknum` to compare against
|
|
186
|
+
return blocknum <= int(threshold_block["result"]["number"], 16)
|
|
187
|
+
elif isinstance(threshold, int):
|
|
188
|
+
if not block_timestamp:
|
|
189
|
+
block = await provider.make_request(
|
|
190
|
+
RPCEndpoint("eth_getBlockByNumber"), [hex(blocknum), False]
|
|
191
|
+
)
|
|
192
|
+
block_timestamp = int(block["result"]["timestamp"], 16)
|
|
193
|
+
|
|
194
|
+
# if validating via `block_timestamp` from result, we should have a
|
|
195
|
+
# `block_timestamp` to compare against
|
|
196
|
+
return block_timestamp <= time.time() - threshold
|
|
197
|
+
else:
|
|
198
|
+
provider.logger.error(
|
|
199
|
+
"Invalid request_cache_validation_threshold value. This should not "
|
|
200
|
+
f"have happened. Request not cached.\n threshold: {threshold}"
|
|
201
|
+
)
|
|
202
|
+
return False
|
|
95
203
|
except Exception as e:
|
|
96
204
|
_error_log(provider, e)
|
|
97
205
|
return False
|
|
206
|
+
finally:
|
|
207
|
+
provider.cache_allowed_requests = cache_allowed_requests
|
|
98
208
|
|
|
99
209
|
|
|
100
|
-
async def
|
|
101
|
-
provider: ASYNC_PROVIDER_TYPE,
|
|
210
|
+
async def async_validate_from_block_id_in_params(
|
|
211
|
+
provider: ASYNC_PROVIDER_TYPE,
|
|
212
|
+
params: Sequence[Any],
|
|
213
|
+
_result: Dict[str, Any],
|
|
102
214
|
) -> bool:
|
|
103
215
|
block_id = params[0]
|
|
104
216
|
if block_id == "earliest":
|
|
105
217
|
# `earliest` should always be cacheable
|
|
106
218
|
return True
|
|
107
|
-
|
|
108
|
-
|
|
219
|
+
|
|
220
|
+
blocknum = int(block_id, 16)
|
|
221
|
+
return await async_is_beyond_validation_threshold(provider, blocknum=blocknum)
|
|
109
222
|
|
|
110
223
|
|
|
111
|
-
async def
|
|
112
|
-
provider: ASYNC_PROVIDER_TYPE,
|
|
224
|
+
async def async_validate_from_blocknum_in_result(
|
|
225
|
+
provider: ASYNC_PROVIDER_TYPE,
|
|
226
|
+
_params: Sequence[Any],
|
|
227
|
+
result: Dict[str, Any],
|
|
113
228
|
) -> bool:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
229
|
+
cache_allowed_requests = provider.cache_allowed_requests
|
|
230
|
+
try:
|
|
231
|
+
# turn off caching to prevent recursion
|
|
232
|
+
provider.cache_allowed_requests = False
|
|
233
|
+
|
|
234
|
+
# transaction results
|
|
235
|
+
if "blockNumber" in result:
|
|
236
|
+
blocknum = result.get("blockNumber")
|
|
237
|
+
# make an extra call to get the block values
|
|
238
|
+
block = await provider.make_request(
|
|
239
|
+
RPCEndpoint("eth_getBlockByNumber"), [blocknum, False]
|
|
240
|
+
)
|
|
241
|
+
return await async_is_beyond_validation_threshold(
|
|
242
|
+
provider,
|
|
243
|
+
blocknum=int(blocknum, 16),
|
|
244
|
+
block_timestamp=int(block["result"]["timestamp"], 16),
|
|
245
|
+
)
|
|
246
|
+
elif "number" in result:
|
|
247
|
+
return await async_is_beyond_validation_threshold(
|
|
248
|
+
provider,
|
|
249
|
+
blocknum=int(result["number"], 16),
|
|
250
|
+
block_timestamp=int(result["timestamp"], 16),
|
|
251
|
+
)
|
|
252
|
+
else:
|
|
253
|
+
provider.logger.error(
|
|
254
|
+
"Could not find block number in result. This should not have happened. "
|
|
255
|
+
f"Request not cached.\n result: {result}",
|
|
256
|
+
)
|
|
257
|
+
return False
|
|
258
|
+
except Exception as e:
|
|
259
|
+
_error_log(provider, e)
|
|
260
|
+
return False
|
|
261
|
+
finally:
|
|
262
|
+
provider.cache_allowed_requests = cache_allowed_requests
|
|
117
263
|
|
|
118
264
|
|
|
119
|
-
async def
|
|
265
|
+
async def async_validate_from_blockhash_in_params(
|
|
120
266
|
provider: ASYNC_PROVIDER_TYPE, params: Sequence[Any], _result: Dict[str, Any]
|
|
121
267
|
) -> bool:
|
|
268
|
+
cache_allowed_requests = provider.cache_allowed_requests
|
|
122
269
|
try:
|
|
123
|
-
|
|
270
|
+
# turn off caching to prevent recursion
|
|
271
|
+
provider.cache_allowed_requests = False
|
|
272
|
+
|
|
273
|
+
# make an extra call to get the block number from the hash
|
|
274
|
+
response = await provider.make_request(
|
|
275
|
+
RPCEndpoint("eth_getBlockByHash"), [params[0], False]
|
|
276
|
+
)
|
|
277
|
+
return await async_is_beyond_validation_threshold(
|
|
278
|
+
provider,
|
|
279
|
+
blocknum=int(response["result"]["number"], 16),
|
|
280
|
+
block_timestamp=int(response["result"]["timestamp"], 16),
|
|
281
|
+
)
|
|
124
282
|
except Exception as e:
|
|
125
283
|
_error_log(provider, e)
|
|
126
284
|
return False
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return await async_is_beyond_validation_threshold(provider, blocknum)
|
|
285
|
+
finally:
|
|
286
|
+
provider.cache_allowed_requests = cache_allowed_requests
|
|
@@ -4,8 +4,8 @@ Compiled with Solidity v0.8.27.
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
# source: web3/_utils/contract_sources/OffchainLookup.sol:OffchainLookup
|
|
7
|
-
OFFCHAIN_LOOKUP_BYTECODE = "
|
|
8
|
-
OFFCHAIN_LOOKUP_RUNTIME = "
|
|
7
|
+
OFFCHAIN_LOOKUP_BYTECODE = "0x608060405260405180604001604052806040518060600160405280602c815260200161105e602c913981526020016040518060400160405280601781526020017f68747470733a2f2f776562332e70792f676174657761790000000000000000008152508152505f906002610075929190610087565b50348015610081575f5ffd5b50610465565b828054828255905f5260205f209081019282156100cd579160200282015b828111156100cc5782518290816100bc9190610396565b50916020019190600101906100a5565b5b5090506100da91906100de565b5090565b5b808211156100fd575f81816100f49190610101565b506001016100df565b5090565b50805461010d906101bd565b5f825580601f1061011e575061013b565b601f0160209004905f5260205f209081019061013a919061013e565b5b50565b5b80821115610155575f815f90555060010161013f565b5090565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806101d457607f821691505b6020821081036101e7576101e6610190565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026102497fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261020e565b610253868361020e565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61029761029261028d8461026b565b610274565b61026b565b9050919050565b5f819050919050565b6102b08361027d565b6102c46102bc8261029e565b84845461021a565b825550505050565b5f5f905090565b6102db6102cc565b6102e68184846102a7565b505050565b5b81811015610309576102fe5f826102d3565b6001810190506102ec565b5050565b601f82111561034e5761031f816101ed565b610328846101ff565b81016020851015610337578190505b61034b610343856101ff565b8301826102eb565b50505b505050565b5f82821c905092915050565b5f61036e5f1984600802610353565b1980831691505092915050565b5f610386838361035f565b9150826002028217905092915050565b61039f82610159565b67ffffffffffffffff8111156103b8576103b7610163565b5b6103c282546101bd565b6103cd82828561030d565b5f60209050601f8311600181146103fe575f84156103ec578287015190505b6103f6858261037b565b86555061045d565b601f19841661040c866101ed565b5f5b828110156104335784890151825560018201915060208501945060208101905061040e565b86831015610450578489015161044c601f89168261035f565b8355505b6001600288020188555050505b505050505050565b610bec806104725f395ff3fe608060405234801561000f575f5ffd5b506004361061003f575f3560e01c806309a3c01b146100435780636337ed5814610061578063da96d05a14610091575b5f5ffd5b61004b6100c1565b60405161005891906103f2565b60405180910390f35b61007b60048036038101906100769190610484565b610110565b60405161008891906103f2565b60405180910390f35b6100ab60048036038101906100a691906104cf565b6101fc565b6040516100b891906103f2565b60405180910390f35b606080305f826309a3c01b60e01b846040517f556f1830000000000000000000000000000000000000000000000000000000008152600401610107959493929190610783565b60405180910390fd5b60605f83838101906101229190610911565b90507fd9bdd1345ca2a00d0c1413137c1b2b1d0a35e5b0e11508f3b3eff856286af07581604051602001610156919061099c565b60405160208183030381529060405280519060200120146101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a390610a0c565b60405180910390fd5b305f858563da96d05a60e01b88886040517f556f18300000000000000000000000000000000000000000000000000000000081526004016101f39796959493929190610a56565b60405180910390fd5b60605f858581019061020e9190610911565b90507faed76f463930323372899e36460e078e5292aac45f645bbe567be6fca83ede1081604051602001610242919061099c565b6040516020818303038152906040528051906020012014610298576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161028f90610b30565b60405180910390fd5b5f84848101906102a89190610911565b90507fd9bdd1345ca2a00d0c1413137c1b2b1d0a35e5b0e11508f3b3eff856286af075816040516020016102dc919061099c565b6040516020818303038152906040528051906020012014610332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032990610b98565b60405180910390fd5b86868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505092505050949350505050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6103c482610382565b6103ce818561038c565b93506103de81856020860161039c565b6103e7816103aa565b840191505092915050565b5f6020820190508181035f83015261040a81846103ba565b905092915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f84011261044457610443610423565b5b8235905067ffffffffffffffff81111561046157610460610427565b5b60208301915083600182028301111561047d5761047c61042b565b5b9250929050565b5f5f6020838503121561049a5761049961041b565b5b5f83013567ffffffffffffffff8111156104b7576104b661041f565b5b6104c38582860161042f565b92509250509250929050565b5f5f5f5f604085870312156104e7576104e661041b565b5b5f85013567ffffffffffffffff8111156105045761050361041f565b5b6105108782880161042f565b9450945050602085013567ffffffffffffffff8111156105335761053261041f565b5b61053f8782880161042f565b925092505092959194509250565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6105768261054d565b9050919050565b6105868161056c565b82525050565b5f81549050919050565b5f82825260208201905092915050565b5f819050815f5260205f209050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806105fc57607f821691505b60208210810361060f5761060e6105b8565b5b50919050565b5f82825260208201905092915050565b5f819050815f5260205f209050919050565b5f8154610643816105e5565b61064d8186610615565b9450600182165f8114610667576001811461067d576106af565b60ff1983168652811515602002860193506106af565b61068685610625565b5f5b838110156106a757815481890152600182019150602081019050610688565b808801955050505b50505092915050565b5f6106c38383610637565b905092915050565b5f600182019050919050565b5f6106e18261058c565b6106eb8185610596565b9350836020820285016106fd856105a6565b805f5b858110156107375784840389528161071885826106b8565b9450610723836106cb565b925060208a01995050600181019050610700565b50829750879550505050505092915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61077d81610749565b82525050565b5f60a0820190506107965f83018861057d565b81810360208301526107a881876106d7565b905081810360408301526107bc81866103ba565b90506107cb6060830185610774565b81810360808301526107dd81846103ba565b90509695505050505050565b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610823826103aa565b810181811067ffffffffffffffff82111715610842576108416107ed565b5b80604052505050565b5f610854610412565b9050610860828261081a565b919050565b5f67ffffffffffffffff82111561087f5761087e6107ed565b5b610888826103aa565b9050602081019050919050565b828183375f83830152505050565b5f6108b56108b084610865565b61084b565b9050828152602081018484840111156108d1576108d06107e9565b5b6108dc848285610895565b509392505050565b5f82601f8301126108f8576108f7610423565b5b81356109088482602086016108a3565b91505092915050565b5f602082840312156109265761092561041b565b5b5f82013567ffffffffffffffff8111156109435761094261041f565b5b61094f848285016108e4565b91505092915050565b5f81519050919050565b5f81905092915050565b5f61097682610958565b6109808185610962565b935061099081856020860161039c565b80840191505092915050565b5f6109a7828461096c565b915081905092915050565b5f82825260208201905092915050565b7f7465737420646174612076616c69646174696f6e206661696c65642e000000005f82015250565b5f6109f6601c836109b2565b9150610a01826109c2565b602082019050919050565b5f6020820190508181035f830152610a23816109ea565b9050919050565b5f610a35838561038c565b9350610a42838584610895565b610a4b836103aa565b840190509392505050565b5f60a082019050610a695f83018a61057d565b8181036020830152610a7b81896106d7565b90508181036040830152610a90818789610a2a565b9050610a9f6060830186610774565b8181036080830152610ab2818486610a2a565b905098975050505050505050565b7f68747470207265717565737420726573756c742076616c69646174696f6e20665f8201527f61696c65642e0000000000000000000000000000000000000000000000000000602082015250565b5f610b1a6026836109b2565b9150610b2582610ac0565b604082019050919050565b5f6020820190508181035f830152610b4781610b0e565b9050919050565b7f6578747261446174612076616c69646174696f6e206661696c65642e000000005f82015250565b5f610b82601c836109b2565b9150610b8d82610b4e565b602082019050919050565b5f6020820190508181035f830152610baf81610b76565b905091905056fea264697066735822122057b6a2921a068efec1bdb94e9f03df697a3f59c9df2a9dad27bc3f325f5b629764736f6c634300081b003368747470733a2f2f776562332e70792f676174657761792f7b73656e6465727d2f7b646174617d2e6a736f6e" # noqa: E501
|
|
8
|
+
OFFCHAIN_LOOKUP_RUNTIME = "0x608060405234801561000f575f5ffd5b506004361061003f575f3560e01c806309a3c01b146100435780636337ed5814610061578063da96d05a14610091575b5f5ffd5b61004b6100c1565b60405161005891906103f2565b60405180910390f35b61007b60048036038101906100769190610484565b610110565b60405161008891906103f2565b60405180910390f35b6100ab60048036038101906100a691906104cf565b6101fc565b6040516100b891906103f2565b60405180910390f35b606080305f826309a3c01b60e01b846040517f556f1830000000000000000000000000000000000000000000000000000000008152600401610107959493929190610783565b60405180910390fd5b60605f83838101906101229190610911565b90507fd9bdd1345ca2a00d0c1413137c1b2b1d0a35e5b0e11508f3b3eff856286af07581604051602001610156919061099c565b60405160208183030381529060405280519060200120146101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a390610a0c565b60405180910390fd5b305f858563da96d05a60e01b88886040517f556f18300000000000000000000000000000000000000000000000000000000081526004016101f39796959493929190610a56565b60405180910390fd5b60605f858581019061020e9190610911565b90507faed76f463930323372899e36460e078e5292aac45f645bbe567be6fca83ede1081604051602001610242919061099c565b6040516020818303038152906040528051906020012014610298576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161028f90610b30565b60405180910390fd5b5f84848101906102a89190610911565b90507fd9bdd1345ca2a00d0c1413137c1b2b1d0a35e5b0e11508f3b3eff856286af075816040516020016102dc919061099c565b6040516020818303038152906040528051906020012014610332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032990610b98565b60405180910390fd5b86868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505092505050949350505050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6103c482610382565b6103ce818561038c565b93506103de81856020860161039c565b6103e7816103aa565b840191505092915050565b5f6020820190508181035f83015261040a81846103ba565b905092915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f84011261044457610443610423565b5b8235905067ffffffffffffffff81111561046157610460610427565b5b60208301915083600182028301111561047d5761047c61042b565b5b9250929050565b5f5f6020838503121561049a5761049961041b565b5b5f83013567ffffffffffffffff8111156104b7576104b661041f565b5b6104c38582860161042f565b92509250509250929050565b5f5f5f5f604085870312156104e7576104e661041b565b5b5f85013567ffffffffffffffff8111156105045761050361041f565b5b6105108782880161042f565b9450945050602085013567ffffffffffffffff8111156105335761053261041f565b5b61053f8782880161042f565b925092505092959194509250565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6105768261054d565b9050919050565b6105868161056c565b82525050565b5f81549050919050565b5f82825260208201905092915050565b5f819050815f5260205f209050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806105fc57607f821691505b60208210810361060f5761060e6105b8565b5b50919050565b5f82825260208201905092915050565b5f819050815f5260205f209050919050565b5f8154610643816105e5565b61064d8186610615565b9450600182165f8114610667576001811461067d576106af565b60ff1983168652811515602002860193506106af565b61068685610625565b5f5b838110156106a757815481890152600182019150602081019050610688565b808801955050505b50505092915050565b5f6106c38383610637565b905092915050565b5f600182019050919050565b5f6106e18261058c565b6106eb8185610596565b9350836020820285016106fd856105a6565b805f5b858110156107375784840389528161071885826106b8565b9450610723836106cb565b925060208a01995050600181019050610700565b50829750879550505050505092915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61077d81610749565b82525050565b5f60a0820190506107965f83018861057d565b81810360208301526107a881876106d7565b905081810360408301526107bc81866103ba565b90506107cb6060830185610774565b81810360808301526107dd81846103ba565b90509695505050505050565b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610823826103aa565b810181811067ffffffffffffffff82111715610842576108416107ed565b5b80604052505050565b5f610854610412565b9050610860828261081a565b919050565b5f67ffffffffffffffff82111561087f5761087e6107ed565b5b610888826103aa565b9050602081019050919050565b828183375f83830152505050565b5f6108b56108b084610865565b61084b565b9050828152602081018484840111156108d1576108d06107e9565b5b6108dc848285610895565b509392505050565b5f82601f8301126108f8576108f7610423565b5b81356109088482602086016108a3565b91505092915050565b5f602082840312156109265761092561041b565b5b5f82013567ffffffffffffffff8111156109435761094261041f565b5b61094f848285016108e4565b91505092915050565b5f81519050919050565b5f81905092915050565b5f61097682610958565b6109808185610962565b935061099081856020860161039c565b80840191505092915050565b5f6109a7828461096c565b915081905092915050565b5f82825260208201905092915050565b7f7465737420646174612076616c69646174696f6e206661696c65642e000000005f82015250565b5f6109f6601c836109b2565b9150610a01826109c2565b602082019050919050565b5f6020820190508181035f830152610a23816109ea565b9050919050565b5f610a35838561038c565b9350610a42838584610895565b610a4b836103aa565b840190509392505050565b5f60a082019050610a695f83018a61057d565b8181036020830152610a7b81896106d7565b90508181036040830152610a90818789610a2a565b9050610a9f6060830186610774565b8181036080830152610ab2818486610a2a565b905098975050505050505050565b7f68747470207265717565737420726573756c742076616c69646174696f6e20665f8201527f61696c65642e0000000000000000000000000000000000000000000000000000602082015250565b5f610b1a6026836109b2565b9150610b2582610ac0565b604082019050919050565b5f6020820190508181035f830152610b4781610b0e565b9050919050565b7f6578747261446174612076616c69646174696f6e206661696c65642e000000005f82015250565b5f610b82601c836109b2565b9150610b8d82610b4e565b602082019050919050565b5f6020820190508181035f830152610baf81610b76565b905091905056fea264697066735822122057b6a2921a068efec1bdb94e9f03df697a3f59c9df2a9dad27bc3f325f5b629764736f6c634300081b0033" # noqa: E501
|
|
9
9
|
OFFCHAIN_LOOKUP_ABI = [
|
|
10
10
|
{
|
|
11
11
|
"inputs": [
|