web3 6.20.3__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.3.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.3.dist-info → web3-7.0.0.dist-info}/top_level.txt +0 -1
  138. ethpm/__init__.py +0 -20
  139. ethpm/_utils/__init__.py +0 -0
  140. ethpm/_utils/backend.py +0 -93
  141. ethpm/_utils/cache.py +0 -44
  142. ethpm/_utils/chains.py +0 -119
  143. ethpm/_utils/contract.py +0 -35
  144. ethpm/_utils/deployments.py +0 -145
  145. ethpm/_utils/ipfs.py +0 -116
  146. ethpm/_utils/protobuf/__init__.py +0 -0
  147. ethpm/_utils/protobuf/ipfs_file_pb2.py +0 -33
  148. ethpm/_utils/registry.py +0 -29
  149. ethpm/assets/__init__.py +0 -0
  150. ethpm/assets/ens/v3.json +0 -1
  151. ethpm/assets/escrow/with_bytecode_v3.json +0 -1
  152. ethpm/assets/ipfs_file.proto +0 -32
  153. ethpm/assets/owned/output_v3.json +0 -1
  154. ethpm/assets/owned/with_contract_type_v3.json +0 -1
  155. ethpm/assets/registry/contracts/Authority.sol +0 -156
  156. ethpm/assets/registry/contracts/IndexedOrderedSetLib.sol +0 -106
  157. ethpm/assets/registry/contracts/PackageDB.sol +0 -225
  158. ethpm/assets/registry/contracts/PackageRegistry.sol +0 -361
  159. ethpm/assets/registry/contracts/PackageRegistryInterface.sol +0 -97
  160. ethpm/assets/registry/contracts/ReleaseDB.sol +0 -309
  161. ethpm/assets/registry/contracts/ReleaseValidator.sol +0 -152
  162. ethpm/assets/registry/solc_input.json +0 -1
  163. ethpm/assets/registry/solc_output.json +0 -1
  164. ethpm/assets/registry/v3.json +0 -1
  165. ethpm/assets/safe-math-lib/v3-strict-no-deployments.json +0 -1
  166. ethpm/assets/simple-registry/contracts/Ownable.sol +0 -63
  167. ethpm/assets/simple-registry/contracts/PackageRegistry.sol +0 -373
  168. ethpm/assets/simple-registry/contracts/PackageRegistryInterface.sol +0 -96
  169. ethpm/assets/simple-registry/solc_input.json +0 -33
  170. ethpm/assets/simple-registry/solc_output.json +0 -1
  171. ethpm/assets/simple-registry/v3.json +0 -1
  172. ethpm/assets/standard-token/output_v3.json +0 -1
  173. ethpm/assets/standard-token/with_bytecode_v3.json +0 -1
  174. ethpm/assets/vyper_registry/0.1.0.json +0 -1
  175. ethpm/assets/vyper_registry/registry.vy +0 -216
  176. ethpm/assets/vyper_registry/registry_with_delete.vy +0 -244
  177. ethpm/backends/__init__.py +0 -0
  178. ethpm/backends/base.py +0 -43
  179. ethpm/backends/http.py +0 -108
  180. ethpm/backends/ipfs.py +0 -219
  181. ethpm/backends/registry.py +0 -154
  182. ethpm/constants.py +0 -17
  183. ethpm/contract.py +0 -187
  184. ethpm/dependencies.py +0 -58
  185. ethpm/deployments.py +0 -80
  186. ethpm/ethpm-spec/examples/escrow/1.0.0-pretty.json +0 -146
  187. ethpm/ethpm-spec/examples/escrow/1.0.0.json +0 -1
  188. ethpm/ethpm-spec/examples/escrow/contracts/Escrow.sol +0 -32
  189. ethpm/ethpm-spec/examples/escrow/contracts/SafeSendLib.sol +0 -20
  190. ethpm/ethpm-spec/examples/escrow/v3-pretty.json +0 -171
  191. ethpm/ethpm-spec/examples/escrow/v3.json +0 -1
  192. ethpm/ethpm-spec/examples/owned/1.0.0-pretty.json +0 -21
  193. ethpm/ethpm-spec/examples/owned/1.0.0.json +0 -1
  194. ethpm/ethpm-spec/examples/owned/contracts/Owned.sol +0 -12
  195. ethpm/ethpm-spec/examples/owned/v3-pretty.json +0 -27
  196. ethpm/ethpm-spec/examples/owned/v3.json +0 -1
  197. ethpm/ethpm-spec/examples/piper-coin/1.0.0-pretty.json +0 -31
  198. ethpm/ethpm-spec/examples/piper-coin/1.0.0.json +0 -1
  199. ethpm/ethpm-spec/examples/piper-coin/v3-pretty.json +0 -21
  200. ethpm/ethpm-spec/examples/piper-coin/v3.json +0 -1
  201. ethpm/ethpm-spec/examples/safe-math-lib/1.0.0-pretty.json +0 -85
  202. ethpm/ethpm-spec/examples/safe-math-lib/1.0.0.json +0 -1
  203. ethpm/ethpm-spec/examples/safe-math-lib/contracts/SafeMathLib.sol +0 -24
  204. ethpm/ethpm-spec/examples/safe-math-lib/v3-pretty.json +0 -117
  205. ethpm/ethpm-spec/examples/safe-math-lib/v3.json +0 -1
  206. ethpm/ethpm-spec/examples/standard-token/1.0.0-pretty.json +0 -55
  207. ethpm/ethpm-spec/examples/standard-token/1.0.0.json +0 -1
  208. ethpm/ethpm-spec/examples/standard-token/contracts/AbstractToken.sol +0 -20
  209. ethpm/ethpm-spec/examples/standard-token/contracts/StandardToken.sol +0 -84
  210. ethpm/ethpm-spec/examples/standard-token/v3-pretty.json +0 -460
  211. ethpm/ethpm-spec/examples/standard-token/v3.json +0 -1
  212. ethpm/ethpm-spec/examples/transferable/1.0.0-pretty.json +0 -21
  213. ethpm/ethpm-spec/examples/transferable/1.0.0.json +0 -1
  214. ethpm/ethpm-spec/examples/transferable/contracts/Transferable.sol +0 -14
  215. ethpm/ethpm-spec/examples/transferable/v3-pretty.json +0 -27
  216. ethpm/ethpm-spec/examples/transferable/v3.json +0 -1
  217. ethpm/ethpm-spec/examples/wallet/1.0.0-pretty.json +0 -120
  218. ethpm/ethpm-spec/examples/wallet/1.0.0.json +0 -1
  219. ethpm/ethpm-spec/examples/wallet/contracts/Wallet.sol +0 -41
  220. ethpm/ethpm-spec/examples/wallet/v3-pretty.json +0 -181
  221. ethpm/ethpm-spec/examples/wallet/v3.json +0 -1
  222. ethpm/ethpm-spec/examples/wallet-with-send/1.0.0-pretty.json +0 -135
  223. ethpm/ethpm-spec/examples/wallet-with-send/1.0.0.json +0 -1
  224. ethpm/ethpm-spec/examples/wallet-with-send/contracts/WalletWithSend.sol +0 -18
  225. ethpm/ethpm-spec/examples/wallet-with-send/v3-pretty.json +0 -207
  226. ethpm/ethpm-spec/examples/wallet-with-send/v3.json +0 -1
  227. ethpm/ethpm-spec/spec/package.spec.json +0 -379
  228. ethpm/ethpm-spec/spec/v3.spec.json +0 -483
  229. ethpm/exceptions.py +0 -68
  230. ethpm/package.py +0 -438
  231. ethpm/tools/__init__.py +0 -4
  232. ethpm/tools/builder.py +0 -930
  233. ethpm/tools/checker.py +0 -312
  234. ethpm/tools/get_manifest.py +0 -19
  235. ethpm/uri.py +0 -141
  236. ethpm/validation/__init__.py +0 -0
  237. ethpm/validation/manifest.py +0 -146
  238. ethpm/validation/misc.py +0 -39
  239. ethpm/validation/package.py +0 -80
  240. ethpm/validation/uri.py +0 -163
  241. web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
  242. web3/_utils/miner.py +0 -88
  243. web3/_utils/module_testing/go_ethereum_personal_module.py +0 -323
  244. web3/_utils/request.py +0 -265
  245. web3/middleware/abi.py +0 -11
  246. web3/middleware/async_cache.py +0 -99
  247. web3/middleware/cache.py +0 -374
  248. web3/middleware/exception_handling.py +0 -49
  249. web3/middleware/exception_retry_request.py +0 -188
  250. web3/middleware/fixture.py +0 -190
  251. web3/middleware/geth_poa.py +0 -81
  252. web3/middleware/normalize_request_parameters.py +0 -11
  253. web3/middleware/simulate_unmined_transaction.py +0 -43
  254. web3/pm.py +0 -602
  255. web3/providers/async_rpc.py +0 -99
  256. web3/providers/rpc.py +0 -98
  257. web3/providers/websocket/__init__.py +0 -11
  258. web3/providers/websocket/websocket_connection.py +0 -42
  259. web3/tools/__init__.py +0 -4
  260. web3/tools/pytest_ethereum/__init__.py +0 -0
  261. web3/tools/pytest_ethereum/_utils.py +0 -145
  262. web3/tools/pytest_ethereum/deployer.py +0 -48
  263. web3/tools/pytest_ethereum/exceptions.py +0 -22
  264. web3/tools/pytest_ethereum/linker.py +0 -128
  265. web3/tools/pytest_ethereum/plugins.py +0 -33
  266. web3-6.20.3.dist-info/METADATA +0 -104
  267. web3-6.20.3.dist-info/RECORD +0 -283
  268. web3-6.20.3.dist-info/entry_points.txt +0 -2
  269. /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
  270. {web3-6.20.3.dist-info → web3-7.0.0.dist-info}/WHEEL +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
- )