web3 7.0.0b1__py3-none-any.whl → 7.7.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 (261) hide show
  1. ens/__init__.py +13 -2
  2. ens/_normalization.py +4 -4
  3. ens/async_ens.py +31 -21
  4. ens/base_ens.py +3 -1
  5. ens/contract_data.py +2 -2
  6. ens/ens.py +14 -11
  7. ens/exceptions.py +16 -29
  8. ens/specs/nf.json +1 -1
  9. ens/specs/normalization_spec.json +1 -1
  10. ens/utils.py +33 -41
  11. web3/__init__.py +23 -12
  12. web3/_utils/abi.py +162 -274
  13. web3/_utils/async_transactions.py +34 -20
  14. web3/_utils/batching.py +217 -0
  15. web3/_utils/blocks.py +6 -2
  16. web3/_utils/caching/__init__.py +12 -0
  17. web3/_utils/caching/caching_utils.py +433 -0
  18. web3/_utils/caching/request_caching_validation.py +287 -0
  19. web3/_utils/compat/__init__.py +2 -3
  20. web3/_utils/contract_sources/compile_contracts.py +1 -1
  21. web3/_utils/contract_sources/contract_data/ambiguous_function_contract.py +42 -0
  22. web3/_utils/contract_sources/contract_data/arrays_contract.py +3 -3
  23. web3/_utils/contract_sources/contract_data/bytes_contracts.py +5 -5
  24. web3/_utils/contract_sources/contract_data/constructor_contracts.py +7 -7
  25. web3/_utils/contract_sources/contract_data/contract_caller_tester.py +3 -3
  26. web3/_utils/contract_sources/contract_data/emitter_contract.py +3 -3
  27. web3/_utils/contract_sources/contract_data/event_contracts.py +50 -5
  28. web3/_utils/contract_sources/contract_data/extended_resolver.py +3 -3
  29. web3/_utils/contract_sources/contract_data/fallback_function_contract.py +3 -3
  30. web3/_utils/contract_sources/contract_data/function_name_tester_contract.py +3 -3
  31. web3/_utils/contract_sources/contract_data/math_contract.py +3 -3
  32. web3/_utils/contract_sources/contract_data/offchain_lookup.py +3 -3
  33. web3/_utils/contract_sources/contract_data/offchain_resolver.py +3 -3
  34. web3/_utils/contract_sources/contract_data/panic_errors_contract.py +3 -3
  35. web3/_utils/contract_sources/contract_data/payable_tester.py +3 -3
  36. web3/_utils/contract_sources/contract_data/receive_function_contracts.py +5 -5
  37. web3/_utils/contract_sources/contract_data/reflector_contracts.py +3 -3
  38. web3/_utils/contract_sources/contract_data/revert_contract.py +3 -3
  39. web3/_utils/contract_sources/contract_data/simple_resolver.py +3 -3
  40. web3/_utils/contract_sources/contract_data/storage_contract.py +3 -3
  41. web3/_utils/contract_sources/contract_data/string_contract.py +3 -3
  42. web3/_utils/contract_sources/contract_data/tuple_contracts.py +5 -5
  43. web3/_utils/contracts.py +172 -220
  44. web3/_utils/datatypes.py +5 -1
  45. web3/_utils/decorators.py +6 -1
  46. web3/_utils/empty.py +1 -1
  47. web3/_utils/encoding.py +16 -12
  48. web3/_utils/error_formatters_utils.py +5 -3
  49. web3/_utils/events.py +78 -72
  50. web3/_utils/fee_utils.py +1 -3
  51. web3/_utils/filters.py +24 -22
  52. web3/_utils/formatters.py +2 -2
  53. web3/_utils/http.py +8 -2
  54. web3/_utils/http_session_manager.py +314 -0
  55. web3/_utils/math.py +14 -15
  56. web3/_utils/method_formatters.py +161 -34
  57. web3/_utils/module.py +2 -1
  58. web3/_utils/module_testing/__init__.py +3 -2
  59. web3/_utils/module_testing/eth_module.py +736 -583
  60. web3/_utils/module_testing/go_ethereum_debug_module.py +128 -0
  61. web3/_utils/module_testing/module_testing_utils.py +81 -24
  62. web3/_utils/module_testing/persistent_connection_provider.py +702 -220
  63. web3/_utils/module_testing/utils.py +114 -33
  64. web3/_utils/module_testing/web3_module.py +438 -17
  65. web3/_utils/normalizers.py +13 -11
  66. web3/_utils/rpc_abi.py +10 -22
  67. web3/_utils/threads.py +8 -7
  68. web3/_utils/transactions.py +32 -25
  69. web3/_utils/type_conversion.py +5 -1
  70. web3/_utils/validation.py +20 -17
  71. web3/beacon/__init__.py +5 -0
  72. web3/beacon/api_endpoints.py +3 -0
  73. web3/beacon/async_beacon.py +29 -6
  74. web3/beacon/beacon.py +24 -6
  75. web3/contract/__init__.py +7 -0
  76. web3/contract/async_contract.py +285 -82
  77. web3/contract/base_contract.py +556 -258
  78. web3/contract/contract.py +295 -84
  79. web3/contract/utils.py +251 -55
  80. web3/datastructures.py +56 -41
  81. web3/eth/__init__.py +7 -0
  82. web3/eth/async_eth.py +89 -69
  83. web3/eth/base_eth.py +7 -3
  84. web3/eth/eth.py +43 -66
  85. web3/exceptions.py +158 -83
  86. web3/gas_strategies/time_based.py +8 -6
  87. web3/geth.py +53 -184
  88. web3/main.py +77 -43
  89. web3/manager.py +368 -101
  90. web3/method.py +43 -15
  91. web3/middleware/__init__.py +26 -8
  92. web3/middleware/attrdict.py +12 -22
  93. web3/middleware/base.py +55 -2
  94. web3/middleware/filter.py +45 -23
  95. web3/middleware/formatting.py +6 -3
  96. web3/middleware/names.py +4 -1
  97. web3/middleware/signing.py +15 -6
  98. web3/middleware/stalecheck.py +2 -1
  99. web3/module.py +62 -26
  100. web3/providers/__init__.py +21 -0
  101. web3/providers/async_base.py +93 -38
  102. web3/providers/base.py +85 -40
  103. web3/providers/eth_tester/__init__.py +5 -0
  104. web3/providers/eth_tester/defaults.py +2 -55
  105. web3/providers/eth_tester/main.py +57 -35
  106. web3/providers/eth_tester/middleware.py +16 -17
  107. web3/providers/ipc.py +42 -18
  108. web3/providers/legacy_websocket.py +27 -2
  109. web3/providers/persistent/__init__.py +7 -0
  110. web3/providers/persistent/async_ipc.py +61 -121
  111. web3/providers/persistent/persistent.py +324 -17
  112. web3/providers/persistent/persistent_connection.py +54 -5
  113. web3/providers/persistent/request_processor.py +136 -56
  114. web3/providers/persistent/subscription_container.py +56 -0
  115. web3/providers/persistent/subscription_manager.py +233 -0
  116. web3/providers/persistent/websocket.py +29 -92
  117. web3/providers/rpc/__init__.py +5 -0
  118. web3/providers/rpc/async_rpc.py +73 -18
  119. web3/providers/rpc/rpc.py +73 -30
  120. web3/providers/rpc/utils.py +1 -13
  121. web3/scripts/install_pre_releases.py +33 -0
  122. web3/scripts/parse_pygeth_version.py +16 -0
  123. web3/testing.py +4 -4
  124. web3/tracing.py +9 -5
  125. web3/types.py +141 -74
  126. web3/utils/__init__.py +64 -5
  127. web3/utils/abi.py +790 -10
  128. web3/utils/address.py +8 -0
  129. web3/utils/async_exception_handling.py +20 -11
  130. web3/utils/caching.py +34 -4
  131. web3/utils/exception_handling.py +9 -12
  132. web3/utils/subscriptions.py +285 -0
  133. {web3-7.0.0b1.dist-info → web3-7.7.0.dist-info}/LICENSE +1 -1
  134. web3-7.7.0.dist-info/METADATA +130 -0
  135. web3-7.7.0.dist-info/RECORD +171 -0
  136. {web3-7.0.0b1.dist-info → web3-7.7.0.dist-info}/WHEEL +1 -1
  137. {web3-7.0.0b1.dist-info → web3-7.7.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/caching.py +0 -155
  242. web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
  243. web3/_utils/module_testing/go_ethereum_personal_module.py +0 -300
  244. web3/_utils/request.py +0 -265
  245. web3/pm.py +0 -602
  246. web3/tools/__init__.py +0 -4
  247. web3/tools/benchmark/__init__.py +0 -0
  248. web3/tools/benchmark/main.py +0 -185
  249. web3/tools/benchmark/node.py +0 -126
  250. web3/tools/benchmark/reporting.py +0 -39
  251. web3/tools/benchmark/utils.py +0 -69
  252. web3/tools/pytest_ethereum/__init__.py +0 -0
  253. web3/tools/pytest_ethereum/_utils.py +0 -145
  254. web3/tools/pytest_ethereum/deployer.py +0 -48
  255. web3/tools/pytest_ethereum/exceptions.py +0 -22
  256. web3/tools/pytest_ethereum/linker.py +0 -128
  257. web3/tools/pytest_ethereum/plugins.py +0 -33
  258. web3-7.0.0b1.dist-info/METADATA +0 -114
  259. web3-7.0.0b1.dist-info/RECORD +0 -280
  260. web3-7.0.0b1.dist-info/entry_points.txt +0 -2
  261. /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
web3/providers/base.py CHANGED
@@ -1,11 +1,15 @@
1
1
  import itertools
2
+ import logging
2
3
  import threading
3
4
  from typing import (
4
5
  TYPE_CHECKING,
5
6
  Any,
6
7
  Callable,
8
+ List,
9
+ Optional,
7
10
  Set,
8
11
  Tuple,
12
+ Union,
9
13
  cast,
10
14
  )
11
15
 
@@ -15,7 +19,11 @@ from eth_utils import (
15
19
  )
16
20
 
17
21
  from web3._utils.caching import (
18
- handle_request_caching,
22
+ CACHEABLE_REQUESTS,
23
+ )
24
+ from web3._utils.empty import (
25
+ Empty,
26
+ empty,
19
27
  )
20
28
  from web3._utils.encoding import (
21
29
  FriendlyJsonSerde,
@@ -25,7 +33,7 @@ from web3.exceptions import (
25
33
  ProviderConnectionError,
26
34
  )
27
35
  from web3.middleware import (
28
- combine_middlewares,
36
+ combine_middleware,
29
37
  )
30
38
  from web3.middleware.base import (
31
39
  Middleware,
@@ -36,6 +44,7 @@ from web3.types import (
36
44
  RPCResponse,
37
45
  )
38
46
  from web3.utils import (
47
+ RequestCacheValidationThreshold,
39
48
  SimpleCache,
40
49
  )
41
50
 
@@ -43,25 +52,10 @@ if TYPE_CHECKING:
43
52
  from web3 import Web3 # noqa: F401
44
53
 
45
54
 
46
- CACHEABLE_REQUESTS = cast(
47
- Set[RPCEndpoint],
48
- (
49
- "eth_chainId",
50
- "eth_getBlockByHash",
51
- "eth_getBlockTransactionCountByHash",
52
- "eth_getRawTransactionByHash",
53
- "eth_getTransactionByBlockHashAndIndex",
54
- "eth_getTransactionByHash",
55
- "eth_getUncleByBlockHashAndIndex",
56
- "eth_getUncleCountByBlockHash",
57
- "net_version",
58
- "web3_clientVersion",
59
- ),
60
- )
61
-
62
-
63
55
  class BaseProvider:
64
- # a tuple of (middlewares, request_func)
56
+ # Set generic logger for the provider. Override in subclasses for more specificity.
57
+ logger: logging.Logger = logging.getLogger("web3.providers.base.BaseProvider")
58
+ # a tuple of (middleware, request_func)
65
59
  _request_func_cache: Tuple[Tuple[Middleware, ...], Callable[..., RPCResponse]] = (
66
60
  None,
67
61
  None,
@@ -72,33 +66,39 @@ class BaseProvider:
72
66
  global_ccip_read_enabled: bool = True
73
67
  ccip_read_max_redirects: int = 4
74
68
 
75
- # request caching
76
- cache_allowed_requests: bool = False
77
- cacheable_requests: Set[RPCEndpoint] = CACHEABLE_REQUESTS
78
- _request_cache: SimpleCache
79
- _request_cache_lock: threading.Lock = threading.Lock()
80
-
81
- def __init__(self) -> None:
69
+ def __init__(
70
+ self,
71
+ cache_allowed_requests: bool = False,
72
+ cacheable_requests: Set[RPCEndpoint] = None,
73
+ request_cache_validation_threshold: Optional[
74
+ Union[RequestCacheValidationThreshold, int, Empty]
75
+ ] = empty,
76
+ ) -> None:
82
77
  self._request_cache = SimpleCache(1000)
78
+ self._request_cache_lock: threading.Lock = threading.Lock()
79
+
80
+ self.cache_allowed_requests = cache_allowed_requests
81
+ self.cacheable_requests = cacheable_requests or CACHEABLE_REQUESTS
82
+ self.request_cache_validation_threshold = request_cache_validation_threshold
83
83
 
84
84
  def request_func(
85
85
  self, w3: "Web3", middleware_onion: MiddlewareOnion
86
86
  ) -> Callable[..., RPCResponse]:
87
87
  """
88
88
  @param w3 is the web3 instance
89
- @param middleware_onion is an iterable of middlewares,
89
+ @param middleware_onion is an iterable of middleware,
90
90
  ordered by first to execute
91
91
  @returns a function that calls all the middleware and
92
92
  eventually self.make_request()
93
93
  """
94
- middlewares: Tuple[Middleware, ...] = middleware_onion.as_tuple_of_middlewares()
94
+ middleware: Tuple[Middleware, ...] = middleware_onion.as_tuple_of_middleware()
95
95
 
96
96
  cache_key = self._request_func_cache[0]
97
- if cache_key != middlewares:
97
+ if cache_key != middleware:
98
98
  self._request_func_cache = (
99
- middlewares,
100
- combine_middlewares(
101
- middlewares=middlewares,
99
+ middleware,
100
+ combine_middleware(
101
+ middleware=middleware,
102
102
  w3=w3,
103
103
  provider_request_fn=self.make_request,
104
104
  ),
@@ -106,7 +106,6 @@ class BaseProvider:
106
106
 
107
107
  return self._request_func_cache[-1]
108
108
 
109
- @handle_request_caching
110
109
  def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
111
110
  raise NotImplementedError("Providers must implement this method")
112
111
 
@@ -115,13 +114,16 @@ class BaseProvider:
115
114
 
116
115
 
117
116
  class JSONBaseProvider(BaseProvider):
118
- def __init__(self) -> None:
119
- self.request_counter = itertools.count()
120
- super().__init__()
117
+ logger = logging.getLogger("web3.providers.base.JSONBaseProvider")
121
118
 
122
- def decode_rpc_response(self, raw_response: bytes) -> RPCResponse:
123
- text_response = to_text(raw_response)
124
- return cast(RPCResponse, FriendlyJsonSerde().json_decode(text_response))
119
+ _is_batching: bool = False
120
+ _batch_request_func_cache: Tuple[
121
+ Tuple[Middleware, ...], Callable[..., List[RPCResponse]]
122
+ ] = (None, None)
123
+
124
+ def __init__(self, **kwargs: Any) -> None:
125
+ super().__init__(**kwargs)
126
+ self.request_counter = itertools.count()
125
127
 
126
128
  def encode_rpc_request(self, method: RPCEndpoint, params: Any) -> bytes:
127
129
  rpc_dict = {
@@ -133,6 +135,11 @@ class JSONBaseProvider(BaseProvider):
133
135
  encoded = FriendlyJsonSerde().json_encode(rpc_dict, Web3JsonEncoder)
134
136
  return to_bytes(text=encoded)
135
137
 
138
+ @staticmethod
139
+ def decode_rpc_response(raw_response: bytes) -> RPCResponse:
140
+ text_response = to_text(raw_response)
141
+ return cast(RPCResponse, FriendlyJsonSerde().json_decode(text_response))
142
+
136
143
  def is_connected(self, show_traceback: bool = False) -> bool:
137
144
  try:
138
145
  response = self.make_request(RPCEndpoint("web3_clientVersion"), [])
@@ -156,3 +163,41 @@ class JSONBaseProvider(BaseProvider):
156
163
  if show_traceback:
157
164
  raise ProviderConnectionError(f"Bad jsonrpc version: {response}")
158
165
  return False
166
+
167
+ # -- batch requests -- #
168
+
169
+ def batch_request_func(
170
+ self, w3: "Web3", middleware_onion: MiddlewareOnion
171
+ ) -> Callable[..., List[RPCResponse]]:
172
+ middleware: Tuple[Middleware, ...] = middleware_onion.as_tuple_of_middleware()
173
+
174
+ cache_key = self._batch_request_func_cache[0]
175
+ if cache_key != middleware:
176
+ accumulator_fn = self.make_batch_request
177
+ for mw in reversed(middleware):
178
+ initialized = mw(w3)
179
+ # type ignore bc in order to wrap the method, we have to call
180
+ # `wrap_make_batch_request` with the accumulator_fn as the argument
181
+ # which breaks the type hinting for this particular case.
182
+ accumulator_fn = initialized.wrap_make_batch_request(
183
+ accumulator_fn
184
+ ) # type: ignore # noqa: E501
185
+ self._batch_request_func_cache = (middleware, accumulator_fn)
186
+
187
+ return self._batch_request_func_cache[-1]
188
+
189
+ def encode_batch_rpc_request(
190
+ self, requests: List[Tuple[RPCEndpoint, Any]]
191
+ ) -> bytes:
192
+ return (
193
+ b"["
194
+ + b", ".join(
195
+ self.encode_rpc_request(method, params) for method, params in requests
196
+ )
197
+ + b"]"
198
+ )
199
+
200
+ def make_batch_request(
201
+ self, requests: List[Tuple[RPCEndpoint, Any]]
202
+ ) -> List[RPCResponse]:
203
+ raise NotImplementedError("Providers must implement this method")
@@ -2,3 +2,8 @@ from .main import (
2
2
  AsyncEthereumTesterProvider,
3
3
  EthereumTesterProvider,
4
4
  )
5
+
6
+ __all__ = [
7
+ "AsyncEthereumTesterProvider",
8
+ "EthereumTesterProvider",
9
+ ]
@@ -21,7 +21,6 @@ from eth_tester.exceptions import (
21
21
  FilterNotFound,
22
22
  TransactionFailed,
23
23
  TransactionNotFound,
24
- ValidationError,
25
24
  )
26
25
  from eth_typing import (
27
26
  HexAddress,
@@ -218,7 +217,7 @@ def _generate_random_private_key() -> HexStr:
218
217
  WARNING: This is not a secure way to generate private keys and should only
219
218
  be used for testing purposes.
220
219
  """
221
- return encode_hex(bytes(bytearray((random.randint(0, 255) for _ in range(32)))))
220
+ return encode_hex(bytes(bytearray(random.randint(0, 255) for _ in range(32))))
222
221
 
223
222
 
224
223
  @without_params
@@ -226,18 +225,6 @@ def create_new_account(eth_tester: "EthereumTester") -> HexAddress:
226
225
  return eth_tester.add_account(_generate_random_private_key())
227
226
 
228
227
 
229
- def personal_send_transaction(eth_tester: "EthereumTester", params: Any) -> HexStr:
230
- transaction, password = params
231
-
232
- try:
233
- eth_tester.unlock_account(transaction["from"], password)
234
- transaction_hash = eth_tester.send_transaction(transaction)
235
- finally:
236
- eth_tester.lock_account(transaction["from"])
237
-
238
- return transaction_hash
239
-
240
-
241
228
  API_ENDPOINTS = {
242
229
  "web3": {
243
230
  "clientVersion": client_version,
@@ -256,15 +243,10 @@ API_ENDPOINTS = {
256
243
  "eth": {
257
244
  "protocolVersion": static_return(63),
258
245
  "syncing": static_return(False),
259
- "coinbase": compose(
260
- operator.itemgetter(0),
261
- call_eth_tester("get_accounts"),
262
- ),
263
- "mining": static_return(False),
264
- "hashrate": static_return(0),
265
246
  "chainId": static_return(131277322940537), # from fixture generation file
266
247
  "feeHistory": call_eth_tester("get_fee_history"),
267
248
  "maxPriorityFeePerGas": static_return(10**9),
249
+ "blobBaseFee": static_return(10**9),
268
250
  "gasPrice": static_return(10**9), # must be >= base fee post-London
269
251
  "accounts": call_eth_tester("get_accounts"),
270
252
  "blockNumber": compose(
@@ -404,41 +386,6 @@ API_ENDPOINTS = {
404
386
  "writeBlockProfile": not_implemented,
405
387
  "writeMemProfile": not_implemented,
406
388
  },
407
- "personal": {
408
- "ec_recover": not_implemented,
409
- "import_raw_key": call_eth_tester("add_account"),
410
- "list_accounts": call_eth_tester("get_accounts"),
411
- "list_wallets": not_implemented,
412
- "lock_account": excepts(
413
- ValidationError,
414
- compose(static_return(True), call_eth_tester("lock_account")),
415
- static_return(False),
416
- ),
417
- "new_account": create_new_account,
418
- "unlock_account": excepts(
419
- ValidationError,
420
- compose(static_return(True), call_eth_tester("unlock_account")),
421
- static_return(False),
422
- ),
423
- "send_transaction": personal_send_transaction,
424
- "sign": not_implemented,
425
- # deprecated
426
- "ecRecover": not_implemented,
427
- "importRawKey": call_eth_tester("add_account"),
428
- "listAccounts": call_eth_tester("get_accounts"),
429
- "lockAccount": excepts(
430
- ValidationError,
431
- compose(static_return(True), call_eth_tester("lock_account")),
432
- static_return(False),
433
- ),
434
- "newAccount": create_new_account,
435
- "unlockAccount": excepts(
436
- ValidationError,
437
- compose(static_return(True), call_eth_tester("unlock_account")),
438
- static_return(False),
439
- ),
440
- "sendTransaction": personal_send_transaction,
441
- },
442
389
  "testing": {
443
390
  "timeTravel": call_eth_tester("time_travel"),
444
391
  },
@@ -4,23 +4,22 @@ from typing import (
4
4
  Callable,
5
5
  Coroutine,
6
6
  Dict,
7
+ Literal,
7
8
  Optional,
8
9
  Union,
10
+ cast,
9
11
  )
10
12
 
11
13
  from eth_abi import (
12
14
  abi,
13
15
  )
14
16
  from eth_abi.exceptions import (
15
- InsufficientDataBytes,
17
+ DecodingError,
16
18
  )
17
19
  from eth_utils import (
18
20
  is_bytes,
19
21
  )
20
22
 
21
- from web3._utils.compat import (
22
- Literal,
23
- )
24
23
  from web3.providers import (
25
24
  BaseProvider,
26
25
  )
@@ -33,9 +32,12 @@ from web3.types import (
33
32
  RPCResponse,
34
33
  )
35
34
 
35
+ from ...exceptions import (
36
+ Web3TypeError,
37
+ )
36
38
  from ...middleware import (
37
- async_combine_middlewares,
38
- combine_middlewares,
39
+ async_combine_middleware,
40
+ combine_middleware,
39
41
  )
40
42
  from .middleware import (
41
43
  default_transaction_fields_middleware,
@@ -58,7 +60,8 @@ if TYPE_CHECKING:
58
60
 
59
61
 
60
62
  class AsyncEthereumTesterProvider(AsyncBaseProvider):
61
- _middlewares = (
63
+ _current_request_id = 0
64
+ _middleware = (
62
65
  default_transaction_fields_middleware,
63
66
  ethereum_tester_middleware,
64
67
  )
@@ -83,16 +86,14 @@ class AsyncEthereumTesterProvider(AsyncBaseProvider):
83
86
  ) -> Callable[..., Coroutine[Any, Any, RPCResponse]]:
84
87
  # override the request_func to add the ethereum_tester_middleware
85
88
 
86
- middlewares = middleware_onion.as_tuple_of_middlewares() + tuple(
87
- self._middlewares
88
- )
89
+ middleware = middleware_onion.as_tuple_of_middleware() + tuple(self._middleware)
89
90
 
90
91
  cache_key = self._request_func_cache[0]
91
- if cache_key != middlewares:
92
+ if cache_key != middleware:
92
93
  self._request_func_cache = (
93
- middlewares,
94
- await async_combine_middlewares(
95
- middlewares=middlewares,
94
+ middleware,
95
+ await async_combine_middleware(
96
+ middleware=middleware,
96
97
  async_w3=async_w3,
97
98
  provider_request_fn=self.make_request,
98
99
  ),
@@ -100,14 +101,23 @@ class AsyncEthereumTesterProvider(AsyncBaseProvider):
100
101
  return self._request_func_cache[-1]
101
102
 
102
103
  async def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
103
- return _make_request(method, params, self.api_endpoints, self.ethereum_tester)
104
+ response = _make_request(
105
+ method,
106
+ params,
107
+ self.api_endpoints,
108
+ self.ethereum_tester,
109
+ repr(self._current_request_id),
110
+ )
111
+ self._current_request_id += 1
112
+ return response
104
113
 
105
114
  async def is_connected(self, show_traceback: bool = False) -> Literal[True]:
106
115
  return True
107
116
 
108
117
 
109
118
  class EthereumTesterProvider(BaseProvider):
110
- _middlewares = (
119
+ _current_request_id = 0
120
+ _middleware = (
111
121
  default_transaction_fields_middleware,
112
122
  ethereum_tester_middleware,
113
123
  )
@@ -135,7 +145,7 @@ class EthereumTesterProvider(BaseProvider):
135
145
  elif isinstance(ethereum_tester, BaseChainBackend):
136
146
  self.ethereum_tester = EthereumTester(ethereum_tester)
137
147
  else:
138
- raise TypeError(
148
+ raise Web3TypeError(
139
149
  "Expected ethereum_tester to be of type `eth_tester.EthereumTester` or "
140
150
  "a subclass of `eth_tester.backends.base.BaseChainBackend`, "
141
151
  f"instead received {type(ethereum_tester)}. "
@@ -159,16 +169,14 @@ class EthereumTesterProvider(BaseProvider):
159
169
  ) -> Callable[..., RPCResponse]:
160
170
  # override the request_func to add the ethereum_tester_middleware
161
171
 
162
- middlewares = middleware_onion.as_tuple_of_middlewares() + tuple(
163
- self._middlewares
164
- )
172
+ middleware = middleware_onion.as_tuple_of_middleware() + tuple(self._middleware)
165
173
 
166
174
  cache_key = self._request_func_cache[0]
167
- if cache_key != middlewares:
175
+ if cache_key != middleware:
168
176
  self._request_func_cache = (
169
- middlewares,
170
- combine_middlewares(
171
- middlewares=middlewares,
177
+ middleware,
178
+ combine_middleware(
179
+ middleware=middleware,
172
180
  w3=w3,
173
181
  provider_request_fn=self.make_request,
174
182
  ),
@@ -176,23 +184,32 @@ class EthereumTesterProvider(BaseProvider):
176
184
  return self._request_func_cache[-1]
177
185
 
178
186
  def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
179
- return _make_request(method, params, self.api_endpoints, self.ethereum_tester)
187
+ response = _make_request(
188
+ method,
189
+ params,
190
+ self.api_endpoints,
191
+ self.ethereum_tester,
192
+ repr(self._current_request_id),
193
+ )
194
+ self._current_request_id += 1
195
+ return response
180
196
 
181
197
  def is_connected(self, show_traceback: bool = False) -> Literal[True]:
182
198
  return True
183
199
 
184
200
 
185
- def _make_response(result: Any, message: str = "") -> RPCResponse:
201
+ def _make_response(result: Any, response_id: str, message: str = "") -> RPCResponse:
186
202
  if isinstance(result, Exception):
187
- return RPCResponse(
203
+ return cast(
204
+ RPCResponse,
188
205
  {
189
- "id": 1,
206
+ "id": response_id,
190
207
  "jsonrpc": "2.0",
191
- "error": RPCError({"code": -32601, "message": message}),
192
- }
208
+ "error": cast(RPCError, {"code": -32601, "message": message}),
209
+ },
193
210
  )
194
211
 
195
- return RPCResponse({"id": 1, "jsonrpc": "2.0", "result": result})
212
+ return cast(RPCResponse, {"id": response_id, "jsonrpc": "2.0", "result": result})
196
213
 
197
214
 
198
215
  def _make_request(
@@ -200,6 +217,7 @@ def _make_request(
200
217
  params: Any,
201
218
  api_endpoints: Dict[str, Dict[str, Any]],
202
219
  ethereum_tester_instance: "EthereumTester",
220
+ request_id: str,
203
221
  ) -> RPCResponse:
204
222
  # do not import eth_tester derivatives until runtime,
205
223
  # it is not a default dependency
@@ -212,11 +230,15 @@ def _make_request(
212
230
  try:
213
231
  delegator = api_endpoints[namespace][endpoint]
214
232
  except KeyError as e:
215
- return _make_response(e, f"Unknown RPC Endpoint: {method}")
233
+ return _make_response(e, request_id, message=f"Unknown RPC Endpoint: {method}")
216
234
  try:
217
235
  response = delegator(ethereum_tester_instance, params)
218
236
  except NotImplementedError as e:
219
- return _make_response(e, f"RPC Endpoint has not been implemented: {method}")
237
+ return _make_response(
238
+ e,
239
+ request_id,
240
+ message=f"RPC Endpoint has not been implemented: {method}",
241
+ )
220
242
  except TransactionFailed as e:
221
243
  first_arg = e.args[0]
222
244
  try:
@@ -229,8 +251,8 @@ def _make_request(
229
251
  if is_bytes(raw_error_msg)
230
252
  else raw_error_msg
231
253
  )
232
- except InsufficientDataBytes:
254
+ except DecodingError:
233
255
  reason = first_arg
234
256
  raise TransactionFailed(f"execution reverted: {reason}")
235
257
  else:
236
- return _make_response(response)
258
+ return _make_response(response, request_id)
@@ -59,7 +59,7 @@ if TYPE_CHECKING:
59
59
 
60
60
 
61
61
  def is_named_block(value: Any) -> bool:
62
- return value in {"latest", "earliest", "pending", "safe", "finalized"}
62
+ return value in {"latest", "earliest", "safe", "finalized"}
63
63
 
64
64
 
65
65
  def is_hexstr(value: Any) -> bool:
@@ -72,7 +72,9 @@ is_not_named_block = complement(is_named_block)
72
72
  # --- Request Mapping --- #
73
73
 
74
74
  TRANSACTION_REQUEST_KEY_MAPPING = {
75
+ "blobVersionedHashes": "blob_versioned_hashes",
75
76
  "gasPrice": "gas_price",
77
+ "maxFeePerBlobGas": "max_fee_per_blob_gas",
76
78
  "maxFeePerGas": "max_fee_per_gas",
77
79
  "maxPriorityFeePerGas": "max_priority_fee_per_gas",
78
80
  "accessList": "access_list",
@@ -90,7 +92,7 @@ TRANSACTION_REQUEST_FORMATTERS = {
90
92
  "maxFeePerGas": to_integer_if_hex,
91
93
  "maxPriorityFeePerGas": to_integer_if_hex,
92
94
  "accessList": apply_list_to_array_formatter(
93
- (apply_key_map({"storageKeys": "storage_keys"}))
95
+ apply_key_map({"storageKeys": "storage_keys"})
94
96
  ),
95
97
  }
96
98
  transaction_request_formatter = apply_formatters_to_dict(TRANSACTION_REQUEST_FORMATTERS)
@@ -108,14 +110,14 @@ filter_request_remapper = apply_key_map(FILTER_REQUEST_KEY_MAPPING)
108
110
 
109
111
 
110
112
  FILTER_REQUEST_FORMATTERS = {
111
- "fromBlock": to_integer_if_hex,
112
- "toBlock": to_integer_if_hex,
113
+ "from_block": to_integer_if_hex,
114
+ "to_block": to_integer_if_hex,
113
115
  }
114
116
  filter_request_formatter = apply_formatters_to_dict(FILTER_REQUEST_FORMATTERS)
115
117
 
116
118
  filter_request_transformer = compose(
117
- filter_request_remapper,
118
119
  filter_request_formatter,
120
+ filter_request_remapper,
119
121
  )
120
122
 
121
123
 
@@ -123,10 +125,12 @@ filter_request_transformer = compose(
123
125
 
124
126
  TRANSACTION_RESULT_KEY_MAPPING = {
125
127
  "access_list": "accessList",
128
+ "blob_versioned_hashes": "blobVersionedHashes",
126
129
  "block_hash": "blockHash",
127
130
  "block_number": "blockNumber",
128
131
  "chain_id": "chainId",
129
132
  "gas_price": "gasPrice",
133
+ "max_fee_per_blob_gas": "maxFeePerBlobGas",
130
134
  "max_fee_per_gas": "maxFeePerGas",
131
135
  "max_priority_fee_per_gas": "maxPriorityFeePerGas",
132
136
  "transaction_hash": "transactionHash",
@@ -164,6 +168,8 @@ RECEIPT_RESULT_KEY_MAPPING = {
164
168
  "effective_gas_price": "effectiveGasPrice",
165
169
  "transaction_hash": "transactionHash",
166
170
  "transaction_index": "transactionIndex",
171
+ "blob_gas_used": "blobGasUsed",
172
+ "blob_gas_price": "blobGasPrice",
167
173
  }
168
174
  receipt_result_remapper = apply_key_map(RECEIPT_RESULT_KEY_MAPPING)
169
175
 
@@ -186,6 +192,9 @@ BLOCK_RESULT_KEY_MAPPING = {
186
192
  # JSON-RPC spec still says miner
187
193
  "coinbase": "miner",
188
194
  "withdrawals_root": "withdrawalsRoot",
195
+ "parent_beacon_block_root": "parentBeaconBlockRoot",
196
+ "blob_gas_used": "blobGasUsed",
197
+ "excess_blob_gas": "excessBlobGas",
189
198
  }
190
199
  block_result_remapper = apply_key_map(BLOCK_RESULT_KEY_MAPPING)
191
200
 
@@ -276,11 +285,6 @@ request_formatters = {
276
285
  ),
277
286
  # EVM
278
287
  RPCEndpoint("evm_revert"): apply_formatters_to_args(hex_to_integer),
279
- # Personal
280
- RPCEndpoint("personal_sendTransaction"): apply_formatters_to_args(
281
- transaction_request_transformer,
282
- identity,
283
- ),
284
288
  }
285
289
 
286
290
  result_formatters: Optional[Dict[RPCEndpoint, Callable[..., Any]]] = {
@@ -330,9 +334,7 @@ result_formatters: Optional[Dict[RPCEndpoint, Callable[..., Any]]] = {
330
334
 
331
335
 
332
336
  def guess_from(w3: "Web3", _: TxParams) -> ChecksumAddress:
333
- if w3.eth.coinbase:
334
- return w3.eth.coinbase
335
- elif w3.eth.accounts and len(w3.eth.accounts) > 0:
337
+ if w3.eth.accounts and len(w3.eth.accounts) > 0:
336
338
  return w3.eth.accounts[0]
337
339
 
338
340
  return None
@@ -356,11 +358,8 @@ def fill_default(
356
358
  async def async_guess_from(
357
359
  async_w3: "AsyncWeb3", _: TxParams
358
360
  ) -> Optional[ChecksumAddress]:
359
- coinbase = await async_w3.eth.coinbase
360
361
  accounts = await async_w3.eth.accounts
361
- if coinbase is not None:
362
- return coinbase
363
- elif accounts is not None and len(accounts) > 0:
362
+ if accounts is not None and len(accounts) > 0:
364
363
  return accounts[0]
365
364
  return None
366
365