web3 6.20.2__py3-none-any.whl → 7.0.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.
Files changed (270) hide show
  1. ens/__init__.py +13 -2
  2. ens/_normalization.py +2 -17
  3. ens/async_ens.py +33 -21
  4. ens/base_ens.py +3 -1
  5. ens/ens.py +16 -11
  6. ens/exceptions.py +16 -29
  7. ens/specs/nf.json +1 -1
  8. ens/specs/normalization_spec.json +1 -1
  9. ens/utils.py +52 -63
  10. web3/__init__.py +20 -24
  11. web3/_utils/abi.py +115 -271
  12. web3/_utils/async_transactions.py +7 -4
  13. web3/_utils/batching.py +217 -0
  14. web3/_utils/blocks.py +6 -2
  15. web3/_utils/caching.py +128 -5
  16. web3/_utils/compat/__init__.py +2 -3
  17. web3/_utils/contract_sources/compile_contracts.py +1 -1
  18. web3/_utils/contract_sources/contract_data/arrays_contract.py +3 -3
  19. web3/_utils/contract_sources/contract_data/bytes_contracts.py +5 -5
  20. web3/_utils/contract_sources/contract_data/constructor_contracts.py +7 -7
  21. web3/_utils/contract_sources/contract_data/contract_caller_tester.py +3 -3
  22. web3/_utils/contract_sources/contract_data/emitter_contract.py +3 -3
  23. web3/_utils/contract_sources/contract_data/event_contracts.py +5 -5
  24. web3/_utils/contract_sources/contract_data/extended_resolver.py +3 -3
  25. web3/_utils/contract_sources/contract_data/fallback_function_contract.py +3 -3
  26. web3/_utils/contract_sources/contract_data/function_name_tester_contract.py +3 -3
  27. web3/_utils/contract_sources/contract_data/math_contract.py +3 -3
  28. web3/_utils/contract_sources/contract_data/offchain_lookup.py +3 -3
  29. web3/_utils/contract_sources/contract_data/offchain_resolver.py +3 -3
  30. web3/_utils/contract_sources/contract_data/panic_errors_contract.py +3 -3
  31. web3/_utils/contract_sources/contract_data/payable_tester.py +3 -3
  32. web3/_utils/contract_sources/contract_data/receive_function_contracts.py +5 -5
  33. web3/_utils/contract_sources/contract_data/reflector_contracts.py +3 -3
  34. web3/_utils/contract_sources/contract_data/revert_contract.py +3 -3
  35. web3/_utils/contract_sources/contract_data/simple_resolver.py +3 -3
  36. web3/_utils/contract_sources/contract_data/storage_contract.py +3 -3
  37. web3/_utils/contract_sources/contract_data/string_contract.py +3 -3
  38. web3/_utils/contract_sources/contract_data/tuple_contracts.py +5 -5
  39. web3/_utils/contracts.py +130 -236
  40. web3/_utils/datatypes.py +5 -1
  41. web3/_utils/decorators.py +13 -23
  42. web3/_utils/empty.py +1 -1
  43. web3/_utils/encoding.py +16 -12
  44. web3/_utils/ens.py +2 -1
  45. web3/_utils/error_formatters_utils.py +5 -3
  46. web3/_utils/events.py +66 -69
  47. web3/_utils/fee_utils.py +1 -3
  48. web3/_utils/filters.py +24 -22
  49. web3/_utils/formatters.py +2 -2
  50. web3/_utils/http.py +5 -3
  51. web3/_utils/http_session_manager.py +303 -0
  52. web3/_utils/math.py +14 -15
  53. web3/_utils/method_formatters.py +34 -36
  54. web3/_utils/module.py +2 -1
  55. web3/_utils/module_testing/__init__.py +0 -3
  56. web3/_utils/module_testing/eth_module.py +695 -643
  57. web3/_utils/module_testing/module_testing_utils.py +61 -34
  58. web3/_utils/module_testing/persistent_connection_provider.py +56 -25
  59. web3/_utils/module_testing/utils.py +258 -0
  60. web3/_utils/module_testing/web3_module.py +438 -17
  61. web3/_utils/normalizers.py +13 -11
  62. web3/_utils/rpc_abi.py +5 -32
  63. web3/_utils/threads.py +8 -7
  64. web3/_utils/transactions.py +14 -12
  65. web3/_utils/type_conversion.py +5 -1
  66. web3/_utils/validation.py +17 -17
  67. web3/auto/gethdev.py +7 -2
  68. web3/beacon/__init__.py +6 -1
  69. web3/beacon/async_beacon.py +9 -5
  70. web3/beacon/{main.py → beacon.py} +7 -5
  71. web3/contract/__init__.py +7 -0
  72. web3/contract/async_contract.py +47 -46
  73. web3/contract/base_contract.py +183 -158
  74. web3/contract/contract.py +49 -43
  75. web3/contract/utils.py +203 -59
  76. web3/datastructures.py +79 -31
  77. web3/eth/__init__.py +7 -0
  78. web3/eth/async_eth.py +39 -51
  79. web3/eth/base_eth.py +17 -10
  80. web3/eth/eth.py +30 -68
  81. web3/exceptions.py +108 -82
  82. web3/gas_strategies/time_based.py +8 -6
  83. web3/geth.py +1 -254
  84. web3/main.py +75 -122
  85. web3/manager.py +316 -146
  86. web3/method.py +38 -31
  87. web3/middleware/__init__.py +67 -89
  88. web3/middleware/attrdict.py +36 -49
  89. web3/middleware/base.py +174 -0
  90. web3/middleware/buffered_gas_estimate.py +20 -21
  91. web3/middleware/filter.py +157 -117
  92. web3/middleware/formatting.py +124 -108
  93. web3/middleware/gas_price_strategy.py +20 -32
  94. web3/middleware/names.py +29 -26
  95. web3/middleware/proof_of_authority.py +68 -0
  96. web3/middleware/pythonic.py +2 -2
  97. web3/middleware/signing.py +74 -89
  98. web3/middleware/stalecheck.py +52 -79
  99. web3/middleware/validation.py +5 -13
  100. web3/module.py +54 -10
  101. web3/providers/__init__.py +10 -6
  102. web3/providers/async_base.py +117 -39
  103. web3/providers/auto.py +3 -3
  104. web3/providers/base.py +89 -33
  105. web3/providers/eth_tester/__init__.py +5 -0
  106. web3/providers/eth_tester/defaults.py +1 -64
  107. web3/providers/eth_tester/main.py +99 -31
  108. web3/providers/eth_tester/middleware.py +45 -73
  109. web3/providers/ipc.py +42 -46
  110. web3/providers/{websocket/websocket.py → legacy_websocket.py} +32 -7
  111. web3/providers/persistent/__init__.py +22 -0
  112. web3/providers/persistent/async_ipc.py +153 -0
  113. web3/providers/{persistent.py → persistent/persistent.py} +106 -25
  114. web3/providers/persistent/persistent_connection.py +84 -0
  115. web3/providers/{websocket → persistent}/request_processor.py +94 -32
  116. web3/providers/persistent/utils.py +43 -0
  117. web3/providers/{websocket/websocket_v2.py → persistent/websocket.py} +29 -28
  118. web3/providers/rpc/__init__.py +11 -0
  119. web3/providers/rpc/async_rpc.py +171 -0
  120. web3/providers/rpc/rpc.py +179 -0
  121. web3/providers/rpc/utils.py +92 -0
  122. web3/testing.py +4 -4
  123. web3/tools/benchmark/main.py +22 -22
  124. web3/tools/benchmark/node.py +2 -8
  125. web3/tools/benchmark/reporting.py +2 -2
  126. web3/tools/benchmark/utils.py +1 -1
  127. web3/tracing.py +9 -5
  128. web3/types.py +30 -107
  129. web3/utils/__init__.py +58 -5
  130. web3/utils/abi.py +575 -10
  131. web3/utils/async_exception_handling.py +19 -7
  132. web3/utils/caching.py +32 -13
  133. web3/utils/exception_handling.py +7 -5
  134. {web3-6.20.2.dist-info → web3-7.0.0.dist-info}/LICENSE +1 -1
  135. web3-7.0.0.dist-info/METADATA +112 -0
  136. web3-7.0.0.dist-info/RECORD +167 -0
  137. {web3-6.20.2.dist-info → web3-7.0.0.dist-info}/WHEEL +1 -1
  138. {web3-6.20.2.dist-info → web3-7.0.0.dist-info}/top_level.txt +0 -1
  139. ethpm/__init__.py +0 -20
  140. ethpm/_utils/__init__.py +0 -0
  141. ethpm/_utils/backend.py +0 -93
  142. ethpm/_utils/cache.py +0 -44
  143. ethpm/_utils/chains.py +0 -119
  144. ethpm/_utils/contract.py +0 -35
  145. ethpm/_utils/deployments.py +0 -145
  146. ethpm/_utils/ipfs.py +0 -116
  147. ethpm/_utils/protobuf/__init__.py +0 -0
  148. ethpm/_utils/protobuf/ipfs_file_pb2.py +0 -33
  149. ethpm/_utils/registry.py +0 -29
  150. ethpm/assets/__init__.py +0 -0
  151. ethpm/assets/ens/v3.json +0 -1
  152. ethpm/assets/escrow/with_bytecode_v3.json +0 -1
  153. ethpm/assets/ipfs_file.proto +0 -32
  154. ethpm/assets/owned/output_v3.json +0 -1
  155. ethpm/assets/owned/with_contract_type_v3.json +0 -1
  156. ethpm/assets/registry/contracts/Authority.sol +0 -156
  157. ethpm/assets/registry/contracts/IndexedOrderedSetLib.sol +0 -106
  158. ethpm/assets/registry/contracts/PackageDB.sol +0 -225
  159. ethpm/assets/registry/contracts/PackageRegistry.sol +0 -361
  160. ethpm/assets/registry/contracts/PackageRegistryInterface.sol +0 -97
  161. ethpm/assets/registry/contracts/ReleaseDB.sol +0 -309
  162. ethpm/assets/registry/contracts/ReleaseValidator.sol +0 -152
  163. ethpm/assets/registry/solc_input.json +0 -1
  164. ethpm/assets/registry/solc_output.json +0 -1
  165. ethpm/assets/registry/v3.json +0 -1
  166. ethpm/assets/safe-math-lib/v3-strict-no-deployments.json +0 -1
  167. ethpm/assets/simple-registry/contracts/Ownable.sol +0 -63
  168. ethpm/assets/simple-registry/contracts/PackageRegistry.sol +0 -373
  169. ethpm/assets/simple-registry/contracts/PackageRegistryInterface.sol +0 -96
  170. ethpm/assets/simple-registry/solc_input.json +0 -33
  171. ethpm/assets/simple-registry/solc_output.json +0 -1
  172. ethpm/assets/simple-registry/v3.json +0 -1
  173. ethpm/assets/standard-token/output_v3.json +0 -1
  174. ethpm/assets/standard-token/with_bytecode_v3.json +0 -1
  175. ethpm/assets/vyper_registry/0.1.0.json +0 -1
  176. ethpm/assets/vyper_registry/registry.vy +0 -216
  177. ethpm/assets/vyper_registry/registry_with_delete.vy +0 -244
  178. ethpm/backends/__init__.py +0 -0
  179. ethpm/backends/base.py +0 -43
  180. ethpm/backends/http.py +0 -108
  181. ethpm/backends/ipfs.py +0 -219
  182. ethpm/backends/registry.py +0 -154
  183. ethpm/constants.py +0 -17
  184. ethpm/contract.py +0 -187
  185. ethpm/dependencies.py +0 -58
  186. ethpm/deployments.py +0 -80
  187. ethpm/ethpm-spec/examples/escrow/1.0.0-pretty.json +0 -146
  188. ethpm/ethpm-spec/examples/escrow/1.0.0.json +0 -1
  189. ethpm/ethpm-spec/examples/escrow/contracts/Escrow.sol +0 -32
  190. ethpm/ethpm-spec/examples/escrow/contracts/SafeSendLib.sol +0 -20
  191. ethpm/ethpm-spec/examples/escrow/v3-pretty.json +0 -171
  192. ethpm/ethpm-spec/examples/escrow/v3.json +0 -1
  193. ethpm/ethpm-spec/examples/owned/1.0.0-pretty.json +0 -21
  194. ethpm/ethpm-spec/examples/owned/1.0.0.json +0 -1
  195. ethpm/ethpm-spec/examples/owned/contracts/Owned.sol +0 -12
  196. ethpm/ethpm-spec/examples/owned/v3-pretty.json +0 -27
  197. ethpm/ethpm-spec/examples/owned/v3.json +0 -1
  198. ethpm/ethpm-spec/examples/piper-coin/1.0.0-pretty.json +0 -31
  199. ethpm/ethpm-spec/examples/piper-coin/1.0.0.json +0 -1
  200. ethpm/ethpm-spec/examples/piper-coin/v3-pretty.json +0 -21
  201. ethpm/ethpm-spec/examples/piper-coin/v3.json +0 -1
  202. ethpm/ethpm-spec/examples/safe-math-lib/1.0.0-pretty.json +0 -85
  203. ethpm/ethpm-spec/examples/safe-math-lib/1.0.0.json +0 -1
  204. ethpm/ethpm-spec/examples/safe-math-lib/contracts/SafeMathLib.sol +0 -24
  205. ethpm/ethpm-spec/examples/safe-math-lib/v3-pretty.json +0 -117
  206. ethpm/ethpm-spec/examples/safe-math-lib/v3.json +0 -1
  207. ethpm/ethpm-spec/examples/standard-token/1.0.0-pretty.json +0 -55
  208. ethpm/ethpm-spec/examples/standard-token/1.0.0.json +0 -1
  209. ethpm/ethpm-spec/examples/standard-token/contracts/AbstractToken.sol +0 -20
  210. ethpm/ethpm-spec/examples/standard-token/contracts/StandardToken.sol +0 -84
  211. ethpm/ethpm-spec/examples/standard-token/v3-pretty.json +0 -460
  212. ethpm/ethpm-spec/examples/standard-token/v3.json +0 -1
  213. ethpm/ethpm-spec/examples/transferable/1.0.0-pretty.json +0 -21
  214. ethpm/ethpm-spec/examples/transferable/1.0.0.json +0 -1
  215. ethpm/ethpm-spec/examples/transferable/contracts/Transferable.sol +0 -14
  216. ethpm/ethpm-spec/examples/transferable/v3-pretty.json +0 -27
  217. ethpm/ethpm-spec/examples/transferable/v3.json +0 -1
  218. ethpm/ethpm-spec/examples/wallet/1.0.0-pretty.json +0 -120
  219. ethpm/ethpm-spec/examples/wallet/1.0.0.json +0 -1
  220. ethpm/ethpm-spec/examples/wallet/contracts/Wallet.sol +0 -41
  221. ethpm/ethpm-spec/examples/wallet/v3-pretty.json +0 -181
  222. ethpm/ethpm-spec/examples/wallet/v3.json +0 -1
  223. ethpm/ethpm-spec/examples/wallet-with-send/1.0.0-pretty.json +0 -135
  224. ethpm/ethpm-spec/examples/wallet-with-send/1.0.0.json +0 -1
  225. ethpm/ethpm-spec/examples/wallet-with-send/contracts/WalletWithSend.sol +0 -18
  226. ethpm/ethpm-spec/examples/wallet-with-send/v3-pretty.json +0 -207
  227. ethpm/ethpm-spec/examples/wallet-with-send/v3.json +0 -1
  228. ethpm/ethpm-spec/spec/package.spec.json +0 -379
  229. ethpm/ethpm-spec/spec/v3.spec.json +0 -483
  230. ethpm/exceptions.py +0 -68
  231. ethpm/package.py +0 -438
  232. ethpm/tools/__init__.py +0 -4
  233. ethpm/tools/builder.py +0 -930
  234. ethpm/tools/checker.py +0 -312
  235. ethpm/tools/get_manifest.py +0 -19
  236. ethpm/uri.py +0 -141
  237. ethpm/validation/__init__.py +0 -0
  238. ethpm/validation/manifest.py +0 -146
  239. ethpm/validation/misc.py +0 -39
  240. ethpm/validation/package.py +0 -80
  241. ethpm/validation/uri.py +0 -163
  242. web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
  243. web3/_utils/miner.py +0 -88
  244. web3/_utils/module_testing/go_ethereum_personal_module.py +0 -323
  245. web3/_utils/request.py +0 -265
  246. web3/middleware/abi.py +0 -11
  247. web3/middleware/async_cache.py +0 -99
  248. web3/middleware/cache.py +0 -374
  249. web3/middleware/exception_handling.py +0 -49
  250. web3/middleware/exception_retry_request.py +0 -188
  251. web3/middleware/fixture.py +0 -190
  252. web3/middleware/geth_poa.py +0 -81
  253. web3/middleware/normalize_request_parameters.py +0 -11
  254. web3/middleware/simulate_unmined_transaction.py +0 -43
  255. web3/pm.py +0 -602
  256. web3/providers/async_rpc.py +0 -99
  257. web3/providers/rpc.py +0 -98
  258. web3/providers/websocket/__init__.py +0 -11
  259. web3/providers/websocket/websocket_connection.py +0 -42
  260. web3/tools/__init__.py +0 -4
  261. web3/tools/pytest_ethereum/__init__.py +0 -0
  262. web3/tools/pytest_ethereum/_utils.py +0 -145
  263. web3/tools/pytest_ethereum/deployer.py +0 -48
  264. web3/tools/pytest_ethereum/exceptions.py +0 -22
  265. web3/tools/pytest_ethereum/linker.py +0 -128
  266. web3/tools/pytest_ethereum/plugins.py +0 -33
  267. web3-6.20.2.dist-info/METADATA +0 -103
  268. web3-6.20.2.dist-info/RECORD +0 -283
  269. web3-6.20.2.dist-info/entry_points.txt +0 -2
  270. /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
web3/middleware/cache.py DELETED
@@ -1,374 +0,0 @@
1
- import functools
2
- import threading
3
- import time
4
- from typing import (
5
- TYPE_CHECKING,
6
- Any,
7
- Callable,
8
- Collection,
9
- Dict,
10
- Set,
11
- cast,
12
- )
13
-
14
- from eth_utils import (
15
- is_list_like,
16
- )
17
- import lru
18
-
19
- from web3._utils.caching import (
20
- generate_cache_key,
21
- )
22
- from web3._utils.compat import (
23
- Literal,
24
- TypedDict,
25
- )
26
- from web3.types import (
27
- BlockData,
28
- BlockNumber,
29
- Middleware,
30
- RPCEndpoint,
31
- RPCResponse,
32
- )
33
- from web3.utils.caching import (
34
- SimpleCache,
35
- )
36
-
37
- if TYPE_CHECKING:
38
- from web3 import Web3 # noqa: F401
39
-
40
- SIMPLE_CACHE_RPC_WHITELIST = cast(
41
- Set[RPCEndpoint],
42
- (
43
- "web3_clientVersion",
44
- "net_version",
45
- "eth_getBlockTransactionCountByHash",
46
- "eth_getUncleCountByBlockHash",
47
- "eth_getBlockByHash",
48
- "eth_getTransactionByHash",
49
- "eth_getTransactionByBlockHashAndIndex",
50
- "eth_getRawTransactionByHash",
51
- "eth_getUncleByBlockHashAndIndex",
52
- "eth_chainId",
53
- ),
54
- )
55
-
56
-
57
- def _should_cache_response(
58
- _method: RPCEndpoint, _params: Any, response: RPCResponse
59
- ) -> bool:
60
- return (
61
- "error" not in response
62
- and "result" in response
63
- and response["result"] is not None
64
- )
65
-
66
-
67
- def construct_simple_cache_middleware(
68
- cache: SimpleCache = None,
69
- rpc_whitelist: Collection[RPCEndpoint] = None,
70
- should_cache_fn: Callable[
71
- [RPCEndpoint, Any, RPCResponse], bool
72
- ] = _should_cache_response,
73
- ) -> Middleware:
74
- """
75
- Constructs a middleware which caches responses based on the request
76
- ``method`` and ``params``
77
-
78
- :param cache: A ``SimpleCache`` class.
79
- :param rpc_whitelist: A set of RPC methods which may have their responses cached.
80
- :param should_cache_fn: A callable which accepts ``method`` ``params`` and
81
- ``response`` and returns a boolean as to whether the response should be
82
- cached.
83
- """
84
- if rpc_whitelist is None:
85
- rpc_whitelist = SIMPLE_CACHE_RPC_WHITELIST
86
-
87
- def simple_cache_middleware(
88
- make_request: Callable[[RPCEndpoint, Any], RPCResponse], _w3: "Web3"
89
- ) -> Callable[[RPCEndpoint, Any], RPCResponse]:
90
- lock = threading.Lock()
91
-
92
- # Setting the cache here, rather than in ``construct_simple_cache_middleware``,
93
- # ensures that each instance of the middleware has its own cache. This is
94
- # important for compatibility with multiple ``Web3`` instances.
95
- _cache = cache if cache else SimpleCache(256)
96
-
97
- def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
98
- if method in rpc_whitelist:
99
- cache_key = generate_cache_key(
100
- f"{threading.get_ident()}:{(method, params)}"
101
- )
102
- cached_request = _cache.get_cache_entry(cache_key)
103
- if cached_request is not None:
104
- return cached_request
105
-
106
- response = make_request(method, params)
107
- if should_cache_fn(method, params, response):
108
- if lock.acquire(blocking=False):
109
- try:
110
- _cache.cache(cache_key, response)
111
- finally:
112
- lock.release()
113
- return response
114
- else:
115
- return make_request(method, params)
116
-
117
- return middleware
118
-
119
- return simple_cache_middleware
120
-
121
-
122
- _simple_cache_middleware = construct_simple_cache_middleware()
123
-
124
-
125
- TIME_BASED_CACHE_RPC_WHITELIST = cast(
126
- Set[RPCEndpoint],
127
- {
128
- "eth_coinbase",
129
- "eth_accounts",
130
- },
131
- )
132
-
133
-
134
- def construct_time_based_cache_middleware(
135
- cache_class: Callable[..., Dict[Any, Any]],
136
- cache_expire_seconds: int = 15,
137
- rpc_whitelist: Collection[RPCEndpoint] = TIME_BASED_CACHE_RPC_WHITELIST,
138
- should_cache_fn: Callable[
139
- [RPCEndpoint, Any, RPCResponse], bool
140
- ] = _should_cache_response,
141
- ) -> Middleware:
142
- """
143
- Constructs a middleware which caches responses based on the request
144
- ``method`` and ``params`` for a maximum amount of time as specified
145
-
146
- :param cache_class: Any dictionary-like object
147
- :param cache_expire_seconds: The number of seconds an item may be cached
148
- before it should expire.
149
- :param rpc_whitelist: A set of RPC methods which may have their responses cached.
150
- :param should_cache_fn: A callable which accepts ``method`` ``params`` and
151
- ``response`` and returns a boolean as to whether the response should be
152
- cached.
153
- """
154
-
155
- def time_based_cache_middleware(
156
- make_request: Callable[[RPCEndpoint, Any], Any], w3: "Web3"
157
- ) -> Callable[[RPCEndpoint, Any], RPCResponse]:
158
- cache = cache_class()
159
- lock = threading.Lock()
160
-
161
- def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
162
- lock_acquired = (
163
- lock.acquire(blocking=False) if method in rpc_whitelist else False
164
- )
165
-
166
- try:
167
- if lock_acquired and method in rpc_whitelist:
168
- cache_key = generate_cache_key((method, params))
169
- if cache_key in cache:
170
- # check that the cached response is not expired.
171
- cached_at, cached_response = cache[cache_key]
172
- cached_for = time.time() - cached_at
173
-
174
- if cached_for <= cache_expire_seconds:
175
- return cached_response
176
- else:
177
- del cache[cache_key]
178
-
179
- # cache either missed or expired so make the request.
180
- response = make_request(method, params)
181
-
182
- if should_cache_fn(method, params, response):
183
- cache[cache_key] = (time.time(), response)
184
-
185
- return response
186
- else:
187
- return make_request(method, params)
188
- finally:
189
- if lock_acquired:
190
- lock.release()
191
-
192
- return middleware
193
-
194
- return time_based_cache_middleware
195
-
196
-
197
- _time_based_cache_middleware = construct_time_based_cache_middleware(
198
- cache_class=functools.partial(lru.LRU, 256),
199
- )
200
-
201
-
202
- BLOCK_NUMBER_RPC_WHITELIST = cast(
203
- Set[RPCEndpoint],
204
- {
205
- "eth_gasPrice",
206
- "eth_blockNumber",
207
- "eth_getBalance",
208
- "eth_getStorageAt",
209
- "eth_getTransactionCount",
210
- "eth_getBlockTransactionCountByNumber",
211
- "eth_getUncleCountByBlockNumber",
212
- "eth_getCode",
213
- "eth_call",
214
- "eth_createAccessList",
215
- "eth_estimateGas",
216
- "eth_getBlockByNumber",
217
- "eth_getTransactionByBlockNumberAndIndex",
218
- "eth_getTransactionReceipt",
219
- "eth_getUncleByBlockNumberAndIndex",
220
- "eth_getLogs",
221
- },
222
- )
223
-
224
- AVG_BLOCK_TIME_KEY: Literal["avg_block_time"] = "avg_block_time"
225
- AVG_BLOCK_SAMPLE_SIZE_KEY: Literal["avg_block_sample_size"] = "avg_block_sample_size"
226
- AVG_BLOCK_TIME_UPDATED_AT_KEY: Literal[
227
- "avg_block_time_updated_at"
228
- ] = "avg_block_time_updated_at"
229
-
230
-
231
- def _is_latest_block_number_request(method: RPCEndpoint, params: Any) -> bool:
232
- if method != "eth_getBlockByNumber":
233
- return False
234
- elif is_list_like(params) and tuple(params[:1]) == ("latest",):
235
- return True
236
- return False
237
-
238
-
239
- BlockInfoCache = TypedDict(
240
- "BlockInfoCache",
241
- {
242
- "avg_block_time": float,
243
- "avg_block_sample_size": int,
244
- "avg_block_time_updated_at": float,
245
- "latest_block": BlockData,
246
- },
247
- total=False,
248
- )
249
-
250
-
251
- def construct_latest_block_based_cache_middleware(
252
- cache_class: Callable[..., Dict[Any, Any]],
253
- rpc_whitelist: Collection[RPCEndpoint] = BLOCK_NUMBER_RPC_WHITELIST,
254
- average_block_time_sample_size: int = 240,
255
- default_average_block_time: int = 15,
256
- should_cache_fn: Callable[
257
- [RPCEndpoint, Any, RPCResponse], bool
258
- ] = _should_cache_response,
259
- ) -> Middleware:
260
- """
261
- Constructs a middleware which caches responses based on the request
262
- ``method``, ``params``, and the current latest block hash.
263
-
264
- :param cache_class: Any dictionary-like object
265
- :param rpc_whitelist: A set of RPC methods which may have their responses cached.
266
- :param average_block_time_sample_size: number of blocks to look back when computing
267
- average block time
268
- :param default_average_block_time: estimated number of seconds per block
269
- :param should_cache_fn: A callable which accepts ``method`` ``params`` and
270
- ``response`` and returns a boolean as to whether the response should be
271
- cached.
272
-
273
- .. note::
274
- This middleware avoids re-fetching the current latest block for each
275
- request by tracking the current average block time and only requesting
276
- a new block when the last seen latest block is older than the average
277
- block time.
278
- """
279
-
280
- def latest_block_based_cache_middleware(
281
- make_request: Callable[[RPCEndpoint, Any], Any], w3: "Web3"
282
- ) -> Callable[[RPCEndpoint, Any], RPCResponse]:
283
- cache = cache_class()
284
- block_info: BlockInfoCache = {}
285
-
286
- def _update_block_info_cache() -> None:
287
- avg_block_time = block_info.get(
288
- AVG_BLOCK_TIME_KEY, default_average_block_time
289
- )
290
- avg_block_sample_size = block_info.get(AVG_BLOCK_SAMPLE_SIZE_KEY, 0)
291
- avg_block_time_updated_at = block_info.get(AVG_BLOCK_TIME_UPDATED_AT_KEY, 0)
292
-
293
- # compute age as counted by number of blocks since the avg_block_time
294
- if avg_block_time == 0:
295
- avg_block_time_age_in_blocks: float = avg_block_sample_size
296
- else:
297
- avg_block_time_age_in_blocks = (
298
- time.time() - avg_block_time_updated_at
299
- ) / avg_block_time
300
-
301
- if avg_block_time_age_in_blocks >= avg_block_sample_size:
302
- # If the length of time since the average block time as
303
- # measured by blocks is greater than or equal to the number of
304
- # blocks sampled then we need to recompute the average block
305
- # time.
306
- latest_block = w3.eth.get_block("latest")
307
- ancestor_block_number = BlockNumber(
308
- max(
309
- 0,
310
- latest_block["number"] - average_block_time_sample_size,
311
- )
312
- )
313
- ancestor_block = w3.eth.get_block(ancestor_block_number)
314
- sample_size = latest_block["number"] - ancestor_block_number
315
-
316
- block_info[AVG_BLOCK_SAMPLE_SIZE_KEY] = sample_size
317
- if sample_size != 0:
318
- block_info[AVG_BLOCK_TIME_KEY] = (
319
- latest_block["timestamp"] - ancestor_block["timestamp"]
320
- ) / sample_size
321
- else:
322
- block_info[AVG_BLOCK_TIME_KEY] = avg_block_time
323
- block_info[AVG_BLOCK_TIME_UPDATED_AT_KEY] = time.time()
324
-
325
- if "latest_block" in block_info:
326
- latest_block = block_info["latest_block"]
327
- time_since_latest_block = time.time() - latest_block["timestamp"]
328
-
329
- # latest block is too old so update cache
330
- if time_since_latest_block > avg_block_time:
331
- block_info["latest_block"] = w3.eth.get_block("latest")
332
- else:
333
- # latest block has not been fetched so we fetch it.
334
- block_info["latest_block"] = w3.eth.get_block("latest")
335
-
336
- lock = threading.Lock()
337
-
338
- def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
339
- lock_acquired = (
340
- lock.acquire(blocking=False) if method in rpc_whitelist else False
341
- )
342
-
343
- try:
344
- should_try_cache = (
345
- lock_acquired
346
- and method in rpc_whitelist
347
- and not _is_latest_block_number_request(method, params)
348
- )
349
- if should_try_cache:
350
- _update_block_info_cache()
351
- latest_block_hash = block_info["latest_block"]["hash"]
352
- cache_key = generate_cache_key((latest_block_hash, method, params))
353
- if cache_key in cache:
354
- return cache[cache_key]
355
-
356
- response = make_request(method, params)
357
- if should_cache_fn(method, params, response):
358
- cache[cache_key] = response
359
- return response
360
- else:
361
- return make_request(method, params)
362
- finally:
363
- if lock_acquired:
364
- lock.release()
365
-
366
- return middleware
367
-
368
- return latest_block_based_cache_middleware
369
-
370
-
371
- _latest_block_based_cache_middleware = construct_latest_block_based_cache_middleware(
372
- cache_class=functools.partial(lru.LRU, 256),
373
- rpc_whitelist=BLOCK_NUMBER_RPC_WHITELIST,
374
- )
@@ -1,49 +0,0 @@
1
- from typing import (
2
- TYPE_CHECKING,
3
- Any,
4
- Callable,
5
- Dict,
6
- Optional,
7
- Tuple,
8
- Type,
9
- )
10
-
11
- from eth_utils.toolz import (
12
- excepts,
13
- )
14
-
15
- from web3.types import (
16
- Middleware,
17
- RPCEndpoint,
18
- RPCResponse,
19
- )
20
-
21
- if TYPE_CHECKING:
22
- from web3 import Web3 # noqa: F401
23
-
24
-
25
- def construct_exception_handler_middleware(
26
- method_handlers: Optional[
27
- Dict[RPCEndpoint, Tuple[Type[BaseException], Callable[..., None]]]
28
- ] = None
29
- ) -> Middleware:
30
- if method_handlers is None:
31
- method_handlers = {}
32
-
33
- def exception_handler_middleware(
34
- make_request: Callable[[RPCEndpoint, Any], Any], w3: "Web3"
35
- ) -> Callable[[RPCEndpoint, Any], RPCResponse]:
36
- def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
37
- if method in method_handlers:
38
- exc_type, handler = method_handlers[method]
39
- return excepts(
40
- exc_type,
41
- make_request,
42
- handler,
43
- )(method, params)
44
- else:
45
- return make_request(method, params)
46
-
47
- return middleware
48
-
49
- return exception_handler_middleware
@@ -1,188 +0,0 @@
1
- import asyncio
2
- import time
3
- from typing import (
4
- TYPE_CHECKING,
5
- Any,
6
- Callable,
7
- Collection,
8
- List,
9
- Optional,
10
- Type,
11
- )
12
-
13
- import aiohttp
14
- from requests.exceptions import (
15
- ConnectionError,
16
- HTTPError,
17
- Timeout,
18
- TooManyRedirects,
19
- )
20
-
21
- from web3.types import (
22
- AsyncMiddlewareCoroutine,
23
- RPCEndpoint,
24
- RPCResponse,
25
- )
26
-
27
- if TYPE_CHECKING:
28
- from web3 import ( # noqa: F401
29
- AsyncWeb3,
30
- Web3,
31
- )
32
-
33
- DEFAULT_ALLOWLIST = [
34
- "admin",
35
- "miner",
36
- "net",
37
- "txpool",
38
- "testing",
39
- "evm",
40
- "eth_protocolVersion",
41
- "eth_syncing",
42
- "eth_coinbase",
43
- "eth_mining",
44
- "eth_hashrate",
45
- "eth_chainId",
46
- "eth_gasPrice",
47
- "eth_accounts",
48
- "eth_blockNumber",
49
- "eth_getBalance",
50
- "eth_getStorageAt",
51
- "eth_getProof",
52
- "eth_getCode",
53
- "eth_getBlockByNumber",
54
- "eth_getBlockByHash",
55
- "eth_getBlockTransactionCountByNumber",
56
- "eth_getBlockTransactionCountByHash",
57
- "eth_getUncleCountByBlockNumber",
58
- "eth_getUncleCountByBlockHash",
59
- "eth_getTransactionByHash",
60
- "eth_getTransactionByBlockHashAndIndex",
61
- "eth_getTransactionByBlockNumberAndIndex",
62
- "eth_getTransactionReceipt",
63
- "eth_getTransactionCount",
64
- "eth_getRawTransactionByHash",
65
- "eth_call",
66
- "eth_createAccessList",
67
- "eth_estimateGas",
68
- "eth_maxPriorityFeePerGas",
69
- "eth_newBlockFilter",
70
- "eth_newPendingTransactionFilter",
71
- "eth_newFilter",
72
- "eth_getFilterChanges",
73
- "eth_getFilterLogs",
74
- "eth_getLogs",
75
- "eth_uninstallFilter",
76
- "eth_getCompilers",
77
- "eth_getWork",
78
- "eth_sign",
79
- "eth_signTypedData",
80
- "eth_sendRawTransaction",
81
- "personal_importRawKey",
82
- "personal_newAccount",
83
- "personal_listAccounts",
84
- "personal_listWallets",
85
- "personal_lockAccount",
86
- "personal_unlockAccount",
87
- "personal_ecRecover",
88
- "personal_sign",
89
- "personal_signTypedData",
90
- ]
91
-
92
-
93
- def check_if_retry_on_failure(
94
- method: str, allow_list: Optional[List[str]] = None
95
- ) -> bool:
96
- if allow_list is None:
97
- allow_list = DEFAULT_ALLOWLIST
98
-
99
- root = method.split("_")[0]
100
- if root in allow_list:
101
- return True
102
- elif method in allow_list:
103
- return True
104
- else:
105
- return False
106
-
107
-
108
- def exception_retry_middleware(
109
- make_request: Callable[[RPCEndpoint, Any], RPCResponse],
110
- _w3: "Web3",
111
- errors: Collection[Type[BaseException]],
112
- retries: int = 5,
113
- backoff_factor: float = 0.3,
114
- allow_list: Optional[List[str]] = None,
115
- ) -> Callable[[RPCEndpoint, Any], RPCResponse]:
116
- """
117
- Creates middleware that retries failed HTTP requests. Is a default
118
- middleware for HTTPProvider.
119
- """
120
-
121
- def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:
122
- if check_if_retry_on_failure(method, allow_list):
123
- for i in range(retries):
124
- try:
125
- return make_request(method, params)
126
- except tuple(errors):
127
- if i < retries - 1:
128
- time.sleep(backoff_factor)
129
- continue
130
- else:
131
- raise
132
- return None
133
- else:
134
- return make_request(method, params)
135
-
136
- return middleware
137
-
138
-
139
- def http_retry_request_middleware(
140
- make_request: Callable[[RPCEndpoint, Any], Any], w3: "Web3"
141
- ) -> Callable[[RPCEndpoint, Any], Any]:
142
- return exception_retry_middleware(
143
- make_request, w3, (ConnectionError, HTTPError, Timeout, TooManyRedirects)
144
- )
145
-
146
-
147
- # -- async -- #
148
-
149
-
150
- async def async_exception_retry_middleware(
151
- make_request: Callable[[RPCEndpoint, Any], Any],
152
- _async_w3: "AsyncWeb3",
153
- errors: Collection[Type[BaseException]],
154
- retries: int = 5,
155
- backoff_factor: float = 0.3,
156
- allow_list: Optional[List[str]] = None,
157
- ) -> AsyncMiddlewareCoroutine:
158
- """
159
- Creates middleware that retries failed HTTP requests.
160
- Is a default middleware for AsyncHTTPProvider.
161
- """
162
-
163
- async def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:
164
- if check_if_retry_on_failure(method, allow_list):
165
- for i in range(retries):
166
- try:
167
- return await make_request(method, params)
168
- except tuple(errors):
169
- if i < retries - 1:
170
- await asyncio.sleep(backoff_factor)
171
- continue
172
- else:
173
- raise
174
- return None
175
- else:
176
- return await make_request(method, params)
177
-
178
- return middleware
179
-
180
-
181
- async def async_http_retry_request_middleware(
182
- make_request: Callable[[RPCEndpoint, Any], Any], async_w3: "AsyncWeb3"
183
- ) -> Callable[[RPCEndpoint, Any], Any]:
184
- return await async_exception_retry_middleware(
185
- make_request,
186
- async_w3,
187
- (TimeoutError, aiohttp.ClientError),
188
- )