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.
- ens/__init__.py +13 -2
- ens/_normalization.py +4 -4
- ens/async_ens.py +31 -21
- ens/base_ens.py +3 -1
- ens/contract_data.py +2 -2
- ens/ens.py +14 -11
- ens/exceptions.py +16 -29
- ens/specs/nf.json +1 -1
- ens/specs/normalization_spec.json +1 -1
- ens/utils.py +33 -41
- web3/__init__.py +23 -12
- web3/_utils/abi.py +162 -274
- web3/_utils/async_transactions.py +34 -20
- web3/_utils/batching.py +217 -0
- web3/_utils/blocks.py +6 -2
- web3/_utils/caching/__init__.py +12 -0
- web3/_utils/caching/caching_utils.py +433 -0
- web3/_utils/caching/request_caching_validation.py +287 -0
- web3/_utils/compat/__init__.py +2 -3
- web3/_utils/contract_sources/compile_contracts.py +1 -1
- web3/_utils/contract_sources/contract_data/ambiguous_function_contract.py +42 -0
- web3/_utils/contract_sources/contract_data/arrays_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/bytes_contracts.py +5 -5
- web3/_utils/contract_sources/contract_data/constructor_contracts.py +7 -7
- web3/_utils/contract_sources/contract_data/contract_caller_tester.py +3 -3
- web3/_utils/contract_sources/contract_data/emitter_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/event_contracts.py +50 -5
- web3/_utils/contract_sources/contract_data/extended_resolver.py +3 -3
- web3/_utils/contract_sources/contract_data/fallback_function_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/function_name_tester_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/math_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/offchain_lookup.py +3 -3
- web3/_utils/contract_sources/contract_data/offchain_resolver.py +3 -3
- web3/_utils/contract_sources/contract_data/panic_errors_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/payable_tester.py +3 -3
- web3/_utils/contract_sources/contract_data/receive_function_contracts.py +5 -5
- web3/_utils/contract_sources/contract_data/reflector_contracts.py +3 -3
- web3/_utils/contract_sources/contract_data/revert_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/simple_resolver.py +3 -3
- web3/_utils/contract_sources/contract_data/storage_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/string_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/tuple_contracts.py +5 -5
- web3/_utils/contracts.py +172 -220
- web3/_utils/datatypes.py +5 -1
- web3/_utils/decorators.py +6 -1
- web3/_utils/empty.py +1 -1
- web3/_utils/encoding.py +16 -12
- web3/_utils/error_formatters_utils.py +5 -3
- web3/_utils/events.py +78 -72
- web3/_utils/fee_utils.py +1 -3
- web3/_utils/filters.py +24 -22
- web3/_utils/formatters.py +2 -2
- web3/_utils/http.py +8 -2
- web3/_utils/http_session_manager.py +314 -0
- web3/_utils/math.py +14 -15
- web3/_utils/method_formatters.py +161 -34
- web3/_utils/module.py +2 -1
- web3/_utils/module_testing/__init__.py +3 -2
- web3/_utils/module_testing/eth_module.py +736 -583
- web3/_utils/module_testing/go_ethereum_debug_module.py +128 -0
- web3/_utils/module_testing/module_testing_utils.py +81 -24
- web3/_utils/module_testing/persistent_connection_provider.py +702 -220
- web3/_utils/module_testing/utils.py +114 -33
- web3/_utils/module_testing/web3_module.py +438 -17
- web3/_utils/normalizers.py +13 -11
- web3/_utils/rpc_abi.py +10 -22
- web3/_utils/threads.py +8 -7
- web3/_utils/transactions.py +32 -25
- web3/_utils/type_conversion.py +5 -1
- web3/_utils/validation.py +20 -17
- web3/beacon/__init__.py +5 -0
- web3/beacon/api_endpoints.py +3 -0
- web3/beacon/async_beacon.py +29 -6
- web3/beacon/beacon.py +24 -6
- web3/contract/__init__.py +7 -0
- web3/contract/async_contract.py +285 -82
- web3/contract/base_contract.py +556 -258
- web3/contract/contract.py +295 -84
- web3/contract/utils.py +251 -55
- web3/datastructures.py +56 -41
- web3/eth/__init__.py +7 -0
- web3/eth/async_eth.py +89 -69
- web3/eth/base_eth.py +7 -3
- web3/eth/eth.py +43 -66
- web3/exceptions.py +158 -83
- web3/gas_strategies/time_based.py +8 -6
- web3/geth.py +53 -184
- web3/main.py +77 -43
- web3/manager.py +368 -101
- web3/method.py +43 -15
- web3/middleware/__init__.py +26 -8
- web3/middleware/attrdict.py +12 -22
- web3/middleware/base.py +55 -2
- web3/middleware/filter.py +45 -23
- web3/middleware/formatting.py +6 -3
- web3/middleware/names.py +4 -1
- web3/middleware/signing.py +15 -6
- web3/middleware/stalecheck.py +2 -1
- web3/module.py +62 -26
- web3/providers/__init__.py +21 -0
- web3/providers/async_base.py +93 -38
- web3/providers/base.py +85 -40
- web3/providers/eth_tester/__init__.py +5 -0
- web3/providers/eth_tester/defaults.py +2 -55
- web3/providers/eth_tester/main.py +57 -35
- web3/providers/eth_tester/middleware.py +16 -17
- web3/providers/ipc.py +42 -18
- web3/providers/legacy_websocket.py +27 -2
- web3/providers/persistent/__init__.py +7 -0
- web3/providers/persistent/async_ipc.py +61 -121
- web3/providers/persistent/persistent.py +324 -17
- web3/providers/persistent/persistent_connection.py +54 -5
- web3/providers/persistent/request_processor.py +136 -56
- web3/providers/persistent/subscription_container.py +56 -0
- web3/providers/persistent/subscription_manager.py +233 -0
- web3/providers/persistent/websocket.py +29 -92
- web3/providers/rpc/__init__.py +5 -0
- web3/providers/rpc/async_rpc.py +73 -18
- web3/providers/rpc/rpc.py +73 -30
- web3/providers/rpc/utils.py +1 -13
- web3/scripts/install_pre_releases.py +33 -0
- web3/scripts/parse_pygeth_version.py +16 -0
- web3/testing.py +4 -4
- web3/tracing.py +9 -5
- web3/types.py +141 -74
- web3/utils/__init__.py +64 -5
- web3/utils/abi.py +790 -10
- web3/utils/address.py +8 -0
- web3/utils/async_exception_handling.py +20 -11
- web3/utils/caching.py +34 -4
- web3/utils/exception_handling.py +9 -12
- web3/utils/subscriptions.py +285 -0
- {web3-7.0.0b1.dist-info → web3-7.7.0.dist-info}/LICENSE +1 -1
- web3-7.7.0.dist-info/METADATA +130 -0
- web3-7.7.0.dist-info/RECORD +171 -0
- {web3-7.0.0b1.dist-info → web3-7.7.0.dist-info}/WHEEL +1 -1
- {web3-7.0.0b1.dist-info → web3-7.7.0.dist-info}/top_level.txt +0 -1
- ethpm/__init__.py +0 -20
- ethpm/_utils/__init__.py +0 -0
- ethpm/_utils/backend.py +0 -93
- ethpm/_utils/cache.py +0 -44
- ethpm/_utils/chains.py +0 -119
- ethpm/_utils/contract.py +0 -35
- ethpm/_utils/deployments.py +0 -145
- ethpm/_utils/ipfs.py +0 -116
- ethpm/_utils/protobuf/__init__.py +0 -0
- ethpm/_utils/protobuf/ipfs_file_pb2.py +0 -33
- ethpm/_utils/registry.py +0 -29
- ethpm/assets/__init__.py +0 -0
- ethpm/assets/ens/v3.json +0 -1
- ethpm/assets/escrow/with_bytecode_v3.json +0 -1
- ethpm/assets/ipfs_file.proto +0 -32
- ethpm/assets/owned/output_v3.json +0 -1
- ethpm/assets/owned/with_contract_type_v3.json +0 -1
- ethpm/assets/registry/contracts/Authority.sol +0 -156
- ethpm/assets/registry/contracts/IndexedOrderedSetLib.sol +0 -106
- ethpm/assets/registry/contracts/PackageDB.sol +0 -225
- ethpm/assets/registry/contracts/PackageRegistry.sol +0 -361
- ethpm/assets/registry/contracts/PackageRegistryInterface.sol +0 -97
- ethpm/assets/registry/contracts/ReleaseDB.sol +0 -309
- ethpm/assets/registry/contracts/ReleaseValidator.sol +0 -152
- ethpm/assets/registry/solc_input.json +0 -1
- ethpm/assets/registry/solc_output.json +0 -1
- ethpm/assets/registry/v3.json +0 -1
- ethpm/assets/safe-math-lib/v3-strict-no-deployments.json +0 -1
- ethpm/assets/simple-registry/contracts/Ownable.sol +0 -63
- ethpm/assets/simple-registry/contracts/PackageRegistry.sol +0 -373
- ethpm/assets/simple-registry/contracts/PackageRegistryInterface.sol +0 -96
- ethpm/assets/simple-registry/solc_input.json +0 -33
- ethpm/assets/simple-registry/solc_output.json +0 -1
- ethpm/assets/simple-registry/v3.json +0 -1
- ethpm/assets/standard-token/output_v3.json +0 -1
- ethpm/assets/standard-token/with_bytecode_v3.json +0 -1
- ethpm/assets/vyper_registry/0.1.0.json +0 -1
- ethpm/assets/vyper_registry/registry.vy +0 -216
- ethpm/assets/vyper_registry/registry_with_delete.vy +0 -244
- ethpm/backends/__init__.py +0 -0
- ethpm/backends/base.py +0 -43
- ethpm/backends/http.py +0 -108
- ethpm/backends/ipfs.py +0 -219
- ethpm/backends/registry.py +0 -154
- ethpm/constants.py +0 -17
- ethpm/contract.py +0 -187
- ethpm/dependencies.py +0 -58
- ethpm/deployments.py +0 -80
- ethpm/ethpm-spec/examples/escrow/1.0.0-pretty.json +0 -146
- ethpm/ethpm-spec/examples/escrow/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/escrow/contracts/Escrow.sol +0 -32
- ethpm/ethpm-spec/examples/escrow/contracts/SafeSendLib.sol +0 -20
- ethpm/ethpm-spec/examples/escrow/v3-pretty.json +0 -171
- ethpm/ethpm-spec/examples/escrow/v3.json +0 -1
- ethpm/ethpm-spec/examples/owned/1.0.0-pretty.json +0 -21
- ethpm/ethpm-spec/examples/owned/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/owned/contracts/Owned.sol +0 -12
- ethpm/ethpm-spec/examples/owned/v3-pretty.json +0 -27
- ethpm/ethpm-spec/examples/owned/v3.json +0 -1
- ethpm/ethpm-spec/examples/piper-coin/1.0.0-pretty.json +0 -31
- ethpm/ethpm-spec/examples/piper-coin/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/piper-coin/v3-pretty.json +0 -21
- ethpm/ethpm-spec/examples/piper-coin/v3.json +0 -1
- ethpm/ethpm-spec/examples/safe-math-lib/1.0.0-pretty.json +0 -85
- ethpm/ethpm-spec/examples/safe-math-lib/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/safe-math-lib/contracts/SafeMathLib.sol +0 -24
- ethpm/ethpm-spec/examples/safe-math-lib/v3-pretty.json +0 -117
- ethpm/ethpm-spec/examples/safe-math-lib/v3.json +0 -1
- ethpm/ethpm-spec/examples/standard-token/1.0.0-pretty.json +0 -55
- ethpm/ethpm-spec/examples/standard-token/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/standard-token/contracts/AbstractToken.sol +0 -20
- ethpm/ethpm-spec/examples/standard-token/contracts/StandardToken.sol +0 -84
- ethpm/ethpm-spec/examples/standard-token/v3-pretty.json +0 -460
- ethpm/ethpm-spec/examples/standard-token/v3.json +0 -1
- ethpm/ethpm-spec/examples/transferable/1.0.0-pretty.json +0 -21
- ethpm/ethpm-spec/examples/transferable/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/transferable/contracts/Transferable.sol +0 -14
- ethpm/ethpm-spec/examples/transferable/v3-pretty.json +0 -27
- ethpm/ethpm-spec/examples/transferable/v3.json +0 -1
- ethpm/ethpm-spec/examples/wallet/1.0.0-pretty.json +0 -120
- ethpm/ethpm-spec/examples/wallet/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/wallet/contracts/Wallet.sol +0 -41
- ethpm/ethpm-spec/examples/wallet/v3-pretty.json +0 -181
- ethpm/ethpm-spec/examples/wallet/v3.json +0 -1
- ethpm/ethpm-spec/examples/wallet-with-send/1.0.0-pretty.json +0 -135
- ethpm/ethpm-spec/examples/wallet-with-send/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/wallet-with-send/contracts/WalletWithSend.sol +0 -18
- ethpm/ethpm-spec/examples/wallet-with-send/v3-pretty.json +0 -207
- ethpm/ethpm-spec/examples/wallet-with-send/v3.json +0 -1
- ethpm/ethpm-spec/spec/package.spec.json +0 -379
- ethpm/ethpm-spec/spec/v3.spec.json +0 -483
- ethpm/exceptions.py +0 -68
- ethpm/package.py +0 -438
- ethpm/tools/__init__.py +0 -4
- ethpm/tools/builder.py +0 -930
- ethpm/tools/checker.py +0 -312
- ethpm/tools/get_manifest.py +0 -19
- ethpm/uri.py +0 -141
- ethpm/validation/__init__.py +0 -0
- ethpm/validation/manifest.py +0 -146
- ethpm/validation/misc.py +0 -39
- ethpm/validation/package.py +0 -80
- ethpm/validation/uri.py +0 -163
- web3/_utils/caching.py +0 -155
- web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
- web3/_utils/module_testing/go_ethereum_personal_module.py +0 -300
- web3/_utils/request.py +0 -265
- web3/pm.py +0 -602
- web3/tools/__init__.py +0 -4
- web3/tools/benchmark/__init__.py +0 -0
- web3/tools/benchmark/main.py +0 -185
- web3/tools/benchmark/node.py +0 -126
- web3/tools/benchmark/reporting.py +0 -39
- web3/tools/benchmark/utils.py +0 -69
- web3/tools/pytest_ethereum/__init__.py +0 -0
- web3/tools/pytest_ethereum/_utils.py +0 -145
- web3/tools/pytest_ethereum/deployer.py +0 -48
- web3/tools/pytest_ethereum/exceptions.py +0 -22
- web3/tools/pytest_ethereum/linker.py +0 -128
- web3/tools/pytest_ethereum/plugins.py +0 -33
- web3-7.0.0b1.dist-info/METADATA +0 -114
- web3-7.0.0b1.dist-info/RECORD +0 -280
- web3-7.0.0b1.dist-info/entry_points.txt +0 -2
- /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
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
|
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
|
-
|
|
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 !=
|
|
97
|
+
if cache_key != middleware:
|
|
98
98
|
self._request_func_cache = (
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
119
|
-
self.request_counter = itertools.count()
|
|
120
|
-
super().__init__()
|
|
117
|
+
logger = logging.getLogger("web3.providers.base.JSONBaseProvider")
|
|
121
118
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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")
|
|
@@ -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(
|
|
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
|
-
|
|
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
|
-
|
|
38
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 !=
|
|
92
|
+
if cache_key != middleware:
|
|
92
93
|
self._request_func_cache = (
|
|
93
|
-
|
|
94
|
-
await
|
|
95
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 !=
|
|
175
|
+
if cache_key != middleware:
|
|
168
176
|
self._request_func_cache = (
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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
|
-
|
|
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
|
|
203
|
+
return cast(
|
|
204
|
+
RPCResponse,
|
|
188
205
|
{
|
|
189
|
-
"id":
|
|
206
|
+
"id": response_id,
|
|
190
207
|
"jsonrpc": "2.0",
|
|
191
|
-
"error": RPCError
|
|
192
|
-
}
|
|
208
|
+
"error": cast(RPCError, {"code": -32601, "message": message}),
|
|
209
|
+
},
|
|
193
210
|
)
|
|
194
211
|
|
|
195
|
-
return RPCResponse
|
|
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(
|
|
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
|
|
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", "
|
|
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
|
-
|
|
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
|
-
"
|
|
112
|
-
"
|
|
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.
|
|
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
|
|
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
|
|