web3 7.0.0b2__py3-none-any.whl → 7.0.0b4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ens/_normalization.py +1 -3
- ens/async_ens.py +14 -11
- ens/contract_data.py +2 -2
- ens/ens.py +10 -7
- ens/exceptions.py +19 -27
- ens/specs/nf.json +1 -1
- ens/specs/normalization_spec.json +1 -1
- ens/utils.py +24 -15
- web3/__init__.py +2 -7
- web3/_utils/abi.py +30 -29
- web3/_utils/async_transactions.py +7 -4
- web3/_utils/blocks.py +6 -2
- web3/_utils/caching.py +7 -3
- web3/_utils/compat/__init__.py +0 -3
- web3/_utils/contract_sources/compile_contracts.py +1 -1
- web3/_utils/contracts.py +12 -12
- web3/_utils/datatypes.py +5 -1
- web3/_utils/decorators.py +6 -1
- web3/_utils/empty.py +1 -1
- web3/_utils/encoding.py +15 -10
- web3/_utils/error_formatters_utils.py +5 -3
- web3/_utils/events.py +35 -24
- web3/_utils/fee_utils.py +2 -4
- web3/_utils/filters.py +17 -12
- web3/_utils/formatters.py +2 -2
- web3/_utils/math.py +14 -15
- web3/_utils/method_formatters.py +31 -5
- web3/_utils/module.py +2 -1
- web3/_utils/module_testing/eth_module.py +129 -75
- web3/_utils/module_testing/go_ethereum_personal_module.py +1 -1
- web3/_utils/module_testing/module_testing_utils.py +1 -3
- web3/_utils/module_testing/utils.py +14 -7
- web3/_utils/normalizers.py +3 -3
- web3/_utils/request.py +4 -4
- web3/_utils/rpc_abi.py +6 -1
- web3/_utils/threads.py +8 -7
- web3/_utils/transactions.py +18 -12
- web3/_utils/type_conversion.py +5 -1
- web3/_utils/validation.py +12 -10
- web3/contract/async_contract.py +12 -7
- web3/contract/base_contract.py +51 -57
- web3/contract/contract.py +12 -6
- web3/contract/utils.py +11 -6
- web3/datastructures.py +22 -12
- web3/eth/async_eth.py +53 -30
- web3/eth/base_eth.py +7 -3
- web3/eth/eth.py +31 -14
- web3/exceptions.py +41 -59
- web3/gas_strategies/time_based.py +2 -4
- web3/geth.py +1 -3
- web3/main.py +6 -2
- web3/manager.py +13 -12
- web3/method.py +13 -5
- web3/middleware/base.py +4 -2
- web3/middleware/filter.py +27 -17
- web3/middleware/formatting.py +6 -3
- web3/middleware/names.py +4 -1
- web3/middleware/signing.py +6 -2
- web3/middleware/stalecheck.py +2 -1
- web3/providers/eth_tester/defaults.py +1 -1
- web3/providers/eth_tester/main.py +5 -4
- web3/providers/eth_tester/middleware.py +10 -1
- web3/providers/ipc.py +7 -3
- web3/providers/persistent/async_ipc.py +6 -7
- web3/providers/persistent/persistent.py +12 -2
- web3/providers/persistent/request_processor.py +10 -12
- web3/providers/persistent/websocket.py +3 -3
- web3/providers/rpc/async_rpc.py +23 -6
- web3/providers/rpc/rpc.py +27 -16
- web3/testing.py +4 -4
- web3/tools/benchmark/__init__.py +0 -0
- web3/tools/benchmark/main.py +189 -0
- web3/tools/benchmark/node.py +126 -0
- web3/tools/benchmark/reporting.py +39 -0
- web3/tools/benchmark/utils.py +69 -0
- web3/tracing.py +9 -5
- web3/types.py +23 -22
- web3/utils/caching.py +2 -4
- {web3-7.0.0b2.dist-info → web3-7.0.0b4.dist-info}/METADATA +13 -26
- {web3-7.0.0b2.dist-info → web3-7.0.0b4.dist-info}/RECORD +83 -78
- {web3-7.0.0b2.dist-info → web3-7.0.0b4.dist-info}/LICENSE +0 -0
- {web3-7.0.0b2.dist-info → web3-7.0.0b4.dist-info}/WHEEL +0 -0
- {web3-7.0.0b2.dist-info → web3-7.0.0b4.dist-info}/top_level.txt +0 -0
web3/middleware/formatting.py
CHANGED
|
@@ -3,6 +3,7 @@ from typing import (
|
|
|
3
3
|
Any,
|
|
4
4
|
Callable,
|
|
5
5
|
Coroutine,
|
|
6
|
+
Literal,
|
|
6
7
|
Optional,
|
|
7
8
|
Union,
|
|
8
9
|
cast,
|
|
@@ -14,6 +15,9 @@ from eth_utils.toolz import (
|
|
|
14
15
|
merge,
|
|
15
16
|
)
|
|
16
17
|
|
|
18
|
+
from web3.exceptions import (
|
|
19
|
+
Web3ValueError,
|
|
20
|
+
)
|
|
17
21
|
from web3.middleware.base import (
|
|
18
22
|
Web3MiddlewareBuilder,
|
|
19
23
|
)
|
|
@@ -21,7 +25,6 @@ from web3.types import (
|
|
|
21
25
|
EthSubscriptionParams,
|
|
22
26
|
Formatters,
|
|
23
27
|
FormattersDict,
|
|
24
|
-
Literal,
|
|
25
28
|
RPCEndpoint,
|
|
26
29
|
RPCResponse,
|
|
27
30
|
)
|
|
@@ -118,7 +121,7 @@ class FormattingMiddlewareBuilder(Web3MiddlewareBuilder):
|
|
|
118
121
|
if (
|
|
119
122
|
sync_formatters_builder is None and async_formatters_builder is not None
|
|
120
123
|
) or (sync_formatters_builder is not None and async_formatters_builder is None):
|
|
121
|
-
raise
|
|
124
|
+
raise Web3ValueError(
|
|
122
125
|
"Must specify both sync_formatters_builder and async_formatters_builder"
|
|
123
126
|
)
|
|
124
127
|
|
|
@@ -128,7 +131,7 @@ class FormattingMiddlewareBuilder(Web3MiddlewareBuilder):
|
|
|
128
131
|
or result_formatters is not None
|
|
129
132
|
or error_formatters is not None
|
|
130
133
|
):
|
|
131
|
-
raise
|
|
134
|
+
raise Web3ValueError(
|
|
132
135
|
"Cannot specify formatters_builder and formatters at the same time"
|
|
133
136
|
)
|
|
134
137
|
|
web3/middleware/names.py
CHANGED
|
@@ -31,6 +31,9 @@ from .._utils.abi import (
|
|
|
31
31
|
from .._utils.formatters import (
|
|
32
32
|
recursive_map,
|
|
33
33
|
)
|
|
34
|
+
from ..exceptions import (
|
|
35
|
+
Web3TypeError,
|
|
36
|
+
)
|
|
34
37
|
from .base import (
|
|
35
38
|
Web3Middleware,
|
|
36
39
|
)
|
|
@@ -92,7 +95,7 @@ async def async_apply_ens_to_address_conversion(
|
|
|
92
95
|
return (formatted_params_dict, *params[1:])
|
|
93
96
|
|
|
94
97
|
else:
|
|
95
|
-
raise
|
|
98
|
+
raise Web3TypeError(
|
|
96
99
|
f"ABI definitions must be a list or dictionary, "
|
|
97
100
|
f"got {abi_types_for_method!r}"
|
|
98
101
|
)
|
web3/middleware/signing.py
CHANGED
|
@@ -55,6 +55,9 @@ from web3._utils.transactions import (
|
|
|
55
55
|
fill_nonce,
|
|
56
56
|
fill_transaction_defaults,
|
|
57
57
|
)
|
|
58
|
+
from web3.exceptions import (
|
|
59
|
+
Web3TypeError,
|
|
60
|
+
)
|
|
58
61
|
from web3.middleware.base import (
|
|
59
62
|
Web3MiddlewareBuilder,
|
|
60
63
|
)
|
|
@@ -108,7 +111,7 @@ def gen_normalized_accounts(
|
|
|
108
111
|
|
|
109
112
|
@singledispatch
|
|
110
113
|
def to_account(val: Any) -> LocalAccount:
|
|
111
|
-
raise
|
|
114
|
+
raise Web3TypeError(
|
|
112
115
|
"key must be one of the types: "
|
|
113
116
|
"eth_keys.datatype.PrivateKey, eth_account.signers.local.LocalAccount, "
|
|
114
117
|
"or raw private key as a hex string or byte string. "
|
|
@@ -132,7 +135,8 @@ to_account.register(bytes, private_key_to_account)
|
|
|
132
135
|
|
|
133
136
|
|
|
134
137
|
def format_transaction(transaction: TxParams) -> TxParams:
|
|
135
|
-
"""
|
|
138
|
+
"""
|
|
139
|
+
Format transaction so that it can be used correctly in the signing middleware.
|
|
136
140
|
|
|
137
141
|
Converts bytes to hex strings and other types that can be passed to
|
|
138
142
|
the underlying layers. Also has the effect of normalizing 'from' for
|
web3/middleware/stalecheck.py
CHANGED
|
@@ -16,6 +16,7 @@ from toolz import (
|
|
|
16
16
|
|
|
17
17
|
from web3.exceptions import (
|
|
18
18
|
StaleBlockchain,
|
|
19
|
+
Web3ValueError,
|
|
19
20
|
)
|
|
20
21
|
from web3.middleware.base import (
|
|
21
22
|
Web3Middleware,
|
|
@@ -54,7 +55,7 @@ class StalecheckMiddlewareBuilder(Web3MiddlewareBuilder):
|
|
|
54
55
|
skip_stalecheck_for_methods: Collection[str] = SKIP_STALECHECK_FOR_METHODS,
|
|
55
56
|
) -> Web3Middleware:
|
|
56
57
|
if allowable_delay <= 0:
|
|
57
|
-
raise
|
|
58
|
+
raise Web3ValueError(
|
|
58
59
|
"You must set a positive allowable_delay in seconds for this middleware"
|
|
59
60
|
)
|
|
60
61
|
middleware = StalecheckMiddlewareBuilder(w3)
|
|
@@ -218,7 +218,7 @@ def _generate_random_private_key() -> HexStr:
|
|
|
218
218
|
WARNING: This is not a secure way to generate private keys and should only
|
|
219
219
|
be used for testing purposes.
|
|
220
220
|
"""
|
|
221
|
-
return encode_hex(bytes(bytearray(
|
|
221
|
+
return encode_hex(bytes(bytearray(random.randint(0, 255) for _ in range(32))))
|
|
222
222
|
|
|
223
223
|
|
|
224
224
|
@without_params
|
|
@@ -4,6 +4,7 @@ from typing import (
|
|
|
4
4
|
Callable,
|
|
5
5
|
Coroutine,
|
|
6
6
|
Dict,
|
|
7
|
+
Literal,
|
|
7
8
|
Optional,
|
|
8
9
|
Union,
|
|
9
10
|
)
|
|
@@ -18,9 +19,6 @@ from eth_utils import (
|
|
|
18
19
|
is_bytes,
|
|
19
20
|
)
|
|
20
21
|
|
|
21
|
-
from web3._utils.compat import (
|
|
22
|
-
Literal,
|
|
23
|
-
)
|
|
24
22
|
from web3.providers import (
|
|
25
23
|
BaseProvider,
|
|
26
24
|
)
|
|
@@ -33,6 +31,9 @@ from web3.types import (
|
|
|
33
31
|
RPCResponse,
|
|
34
32
|
)
|
|
35
33
|
|
|
34
|
+
from ...exceptions import (
|
|
35
|
+
Web3TypeError,
|
|
36
|
+
)
|
|
36
37
|
from ...middleware import (
|
|
37
38
|
async_combine_middleware,
|
|
38
39
|
combine_middleware,
|
|
@@ -133,7 +134,7 @@ class EthereumTesterProvider(BaseProvider):
|
|
|
133
134
|
elif isinstance(ethereum_tester, BaseChainBackend):
|
|
134
135
|
self.ethereum_tester = EthereumTester(ethereum_tester)
|
|
135
136
|
else:
|
|
136
|
-
raise
|
|
137
|
+
raise Web3TypeError(
|
|
137
138
|
"Expected ethereum_tester to be of type `eth_tester.EthereumTester` or "
|
|
138
139
|
"a subclass of `eth_tester.backends.base.BaseChainBackend`, "
|
|
139
140
|
f"instead received {type(ethereum_tester)}. "
|
|
@@ -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)
|
|
@@ -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
|
|
web3/providers/ipc.py
CHANGED
|
@@ -26,6 +26,10 @@ from web3.types import (
|
|
|
26
26
|
RPCResponse,
|
|
27
27
|
)
|
|
28
28
|
|
|
29
|
+
from ..exceptions import (
|
|
30
|
+
Web3TypeError,
|
|
31
|
+
Web3ValueError,
|
|
32
|
+
)
|
|
29
33
|
from .base import (
|
|
30
34
|
JSONBaseProvider,
|
|
31
35
|
)
|
|
@@ -96,7 +100,7 @@ def get_default_ipc_path() -> str:
|
|
|
96
100
|
return r"\\.\pipe\geth.ipc"
|
|
97
101
|
|
|
98
102
|
else:
|
|
99
|
-
raise
|
|
103
|
+
raise Web3ValueError(
|
|
100
104
|
f"Unsupported platform '{sys.platform}'. Only darwin/linux/win32/"
|
|
101
105
|
"freebsd are supported. You must specify the ipc_path"
|
|
102
106
|
)
|
|
@@ -117,7 +121,7 @@ def get_dev_ipc_path() -> str:
|
|
|
117
121
|
return r"\\.\pipe\geth.ipc"
|
|
118
122
|
|
|
119
123
|
else:
|
|
120
|
-
raise
|
|
124
|
+
raise Web3ValueError(
|
|
121
125
|
f"Unsupported platform '{sys.platform}'. Only darwin/linux/win32/"
|
|
122
126
|
"freebsd are supported. You must specify the ipc_path"
|
|
123
127
|
)
|
|
@@ -139,7 +143,7 @@ class IPCProvider(JSONBaseProvider):
|
|
|
139
143
|
elif isinstance(ipc_path, str) or isinstance(ipc_path, Path):
|
|
140
144
|
self.ipc_path = str(Path(ipc_path).expanduser().resolve())
|
|
141
145
|
else:
|
|
142
|
-
raise
|
|
146
|
+
raise Web3TypeError("ipc_path must be of type string or pathlib.Path")
|
|
143
147
|
|
|
144
148
|
self.timeout = timeout
|
|
145
149
|
self._lock = threading.Lock()
|
|
@@ -33,6 +33,7 @@ from ..._utils.caching import (
|
|
|
33
33
|
)
|
|
34
34
|
from ...exceptions import (
|
|
35
35
|
ProviderConnectionError,
|
|
36
|
+
Web3TypeError,
|
|
36
37
|
)
|
|
37
38
|
from ..ipc import (
|
|
38
39
|
get_default_ipc_path,
|
|
@@ -71,7 +72,7 @@ class AsyncIPCProvider(PersistentConnectionProvider):
|
|
|
71
72
|
elif isinstance(ipc_path, str) or isinstance(ipc_path, Path):
|
|
72
73
|
self.ipc_path = str(Path(ipc_path).expanduser().resolve())
|
|
73
74
|
else:
|
|
74
|
-
raise
|
|
75
|
+
raise Web3TypeError("ipc_path must be of type string or pathlib.Path")
|
|
75
76
|
|
|
76
77
|
self._max_connection_retries = max_connection_retries
|
|
77
78
|
super().__init__(**kwargs)
|
|
@@ -91,7 +92,7 @@ class AsyncIPCProvider(PersistentConnectionProvider):
|
|
|
91
92
|
current_request_id = json.loads(request_data)["id"]
|
|
92
93
|
await self._get_response_for_request_id(current_request_id, timeout=2)
|
|
93
94
|
return True
|
|
94
|
-
except (OSError,
|
|
95
|
+
except (OSError, ProviderConnectionError) as e:
|
|
95
96
|
if show_traceback:
|
|
96
97
|
raise ProviderConnectionError(
|
|
97
98
|
f"Problem connecting to provider with error: {type(e)}: {e}"
|
|
@@ -114,11 +115,11 @@ class AsyncIPCProvider(PersistentConnectionProvider):
|
|
|
114
115
|
except OSError as e:
|
|
115
116
|
if _connection_attempts == self._max_connection_retries:
|
|
116
117
|
raise ProviderConnectionError(
|
|
117
|
-
f"Could not connect to
|
|
118
|
+
f"Could not connect to: {self.ipc_path}. "
|
|
118
119
|
f"Retries exceeded max of {self._max_connection_retries}."
|
|
119
120
|
) from e
|
|
120
121
|
self.logger.info(
|
|
121
|
-
f"Could not connect to
|
|
122
|
+
f"Could not connect to: {self.ipc_path}. Retrying in "
|
|
122
123
|
f"{round(_backoff_time, 1)} seconds.",
|
|
123
124
|
exc_info=True,
|
|
124
125
|
)
|
|
@@ -130,9 +131,7 @@ class AsyncIPCProvider(PersistentConnectionProvider):
|
|
|
130
131
|
self._writer.close()
|
|
131
132
|
await self._writer.wait_closed()
|
|
132
133
|
self._writer = None
|
|
133
|
-
self.logger.debug(
|
|
134
|
-
f'Successfully disconnected from endpoint: "{self.endpoint_uri}'
|
|
135
|
-
)
|
|
134
|
+
self.logger.debug(f'Successfully disconnected from : "{self.ipc_path}')
|
|
136
135
|
|
|
137
136
|
try:
|
|
138
137
|
self._message_listener_task.cancel()
|
|
@@ -30,7 +30,6 @@ DEFAULT_PERSISTENT_CONNECTION_TIMEOUT = 30.0
|
|
|
30
30
|
class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
31
31
|
logger = logging.getLogger("web3.providers.PersistentConnectionProvider")
|
|
32
32
|
has_persistent_connection = True
|
|
33
|
-
endpoint_uri: Optional[str] = None
|
|
34
33
|
|
|
35
34
|
_request_processor: RequestProcessor
|
|
36
35
|
_message_listener_task: Optional["asyncio.Task[None]"] = None
|
|
@@ -50,6 +49,17 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
50
49
|
self.request_timeout = request_timeout
|
|
51
50
|
self.silence_listener_task_exceptions = silence_listener_task_exceptions
|
|
52
51
|
|
|
52
|
+
def get_endpoint_uri_or_ipc_path(self) -> str:
|
|
53
|
+
if hasattr(self, "endpoint_uri"):
|
|
54
|
+
return str(self.endpoint_uri)
|
|
55
|
+
elif hasattr(self, "ipc_path"):
|
|
56
|
+
return str(self.ipc_path)
|
|
57
|
+
else:
|
|
58
|
+
raise AttributeError(
|
|
59
|
+
"`PersistentConnectionProvider` must have either `endpoint_uri` or "
|
|
60
|
+
"`ipc_path` attribute."
|
|
61
|
+
)
|
|
62
|
+
|
|
53
63
|
async def connect(self) -> None:
|
|
54
64
|
raise NotImplementedError("Must be implemented by subclasses")
|
|
55
65
|
|
|
@@ -78,7 +88,7 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
78
88
|
self.logger.debug(
|
|
79
89
|
f"Popping response for id {request_id} from cache."
|
|
80
90
|
)
|
|
81
|
-
popped_response = self._request_processor.pop_raw_response(
|
|
91
|
+
popped_response = await self._request_processor.pop_raw_response(
|
|
82
92
|
cache_key=request_cache_key,
|
|
83
93
|
)
|
|
84
94
|
return popped_response
|
|
@@ -15,6 +15,9 @@ from web3._utils.caching import (
|
|
|
15
15
|
RequestInformation,
|
|
16
16
|
generate_cache_key,
|
|
17
17
|
)
|
|
18
|
+
from web3.exceptions import (
|
|
19
|
+
Web3ValueError,
|
|
20
|
+
)
|
|
18
21
|
from web3.types import (
|
|
19
22
|
RPCEndpoint,
|
|
20
23
|
RPCResponse,
|
|
@@ -136,9 +139,9 @@ class RequestProcessor:
|
|
|
136
139
|
) -> RequestInformation:
|
|
137
140
|
if "method" in response and response["method"] == "eth_subscription":
|
|
138
141
|
if "params" not in response:
|
|
139
|
-
raise
|
|
142
|
+
raise Web3ValueError("Subscription response must have params field")
|
|
140
143
|
if "subscription" not in response["params"]:
|
|
141
|
-
raise
|
|
144
|
+
raise Web3ValueError(
|
|
142
145
|
"Subscription response params must have subscription field"
|
|
143
146
|
)
|
|
144
147
|
|
|
@@ -235,19 +238,17 @@ class RequestProcessor:
|
|
|
235
238
|
)
|
|
236
239
|
self._request_response_cache.cache(cache_key, raw_response)
|
|
237
240
|
|
|
238
|
-
def pop_raw_response(
|
|
241
|
+
async def pop_raw_response(
|
|
239
242
|
self, cache_key: str = None, subscription: bool = False
|
|
240
243
|
) -> Any:
|
|
241
244
|
if subscription:
|
|
242
245
|
qsize = self._subscription_response_queue.qsize()
|
|
243
|
-
|
|
244
|
-
return None
|
|
246
|
+
raw_response = await self._subscription_response_queue.get()
|
|
245
247
|
|
|
246
248
|
if not self._provider._listen_event.is_set():
|
|
247
249
|
self._provider._listen_event.set()
|
|
248
250
|
|
|
249
|
-
|
|
250
|
-
if qsize == 1:
|
|
251
|
+
if qsize == 0:
|
|
251
252
|
if not self._subscription_queue_synced_with_ws_stream:
|
|
252
253
|
self._subscription_queue_synced_with_ws_stream = True
|
|
253
254
|
self._provider.logger.info(
|
|
@@ -268,7 +269,7 @@ class RequestProcessor:
|
|
|
268
269
|
)
|
|
269
270
|
else:
|
|
270
271
|
if not cache_key:
|
|
271
|
-
raise
|
|
272
|
+
raise Web3ValueError(
|
|
272
273
|
"Must provide cache key when popping a non-subscription response."
|
|
273
274
|
)
|
|
274
275
|
|
|
@@ -285,10 +286,7 @@ class RequestProcessor:
|
|
|
285
286
|
# request processor class methods
|
|
286
287
|
|
|
287
288
|
def clear_caches(self) -> None:
|
|
288
|
-
"""
|
|
289
|
-
Clear the request processor caches.
|
|
290
|
-
"""
|
|
291
|
-
|
|
289
|
+
"""Clear the request processor caches."""
|
|
292
290
|
self._request_information_cache.clear()
|
|
293
291
|
self._request_response_cache.clear()
|
|
294
292
|
self._subscription_response_queue = asyncio.Queue(
|
|
@@ -71,9 +71,9 @@ class WebSocketProvider(PersistentConnectionProvider):
|
|
|
71
71
|
# `PersistentConnectionProvider` kwargs can be passed through
|
|
72
72
|
**kwargs: Any,
|
|
73
73
|
) -> None:
|
|
74
|
-
self.endpoint_uri =
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
self.endpoint_uri = (
|
|
75
|
+
URI(endpoint_uri) if endpoint_uri is not None else get_default_endpoint()
|
|
76
|
+
)
|
|
77
77
|
|
|
78
78
|
if not any(
|
|
79
79
|
self.endpoint_uri.startswith(prefix)
|
web3/providers/rpc/async_rpc.py
CHANGED
|
@@ -20,6 +20,10 @@ from eth_utils import (
|
|
|
20
20
|
to_dict,
|
|
21
21
|
)
|
|
22
22
|
|
|
23
|
+
from web3._utils.empty import (
|
|
24
|
+
Empty,
|
|
25
|
+
empty,
|
|
26
|
+
)
|
|
23
27
|
from web3._utils.http import (
|
|
24
28
|
construct_user_agent,
|
|
25
29
|
)
|
|
@@ -54,9 +58,9 @@ class AsyncHTTPProvider(AsyncJSONBaseProvider):
|
|
|
54
58
|
self,
|
|
55
59
|
endpoint_uri: Optional[Union[URI, str]] = None,
|
|
56
60
|
request_kwargs: Optional[Any] = None,
|
|
57
|
-
exception_retry_configuration:
|
|
58
|
-
ExceptionRetryConfiguration
|
|
59
|
-
] =
|
|
61
|
+
exception_retry_configuration: Union[
|
|
62
|
+
ExceptionRetryConfiguration, Empty
|
|
63
|
+
] = empty,
|
|
60
64
|
) -> None:
|
|
61
65
|
if endpoint_uri is None:
|
|
62
66
|
self.endpoint_uri = get_default_http_endpoint()
|
|
@@ -64,7 +68,7 @@ class AsyncHTTPProvider(AsyncJSONBaseProvider):
|
|
|
64
68
|
self.endpoint_uri = URI(endpoint_uri)
|
|
65
69
|
|
|
66
70
|
self._request_kwargs = request_kwargs or {}
|
|
67
|
-
self.
|
|
71
|
+
self._exception_retry_configuration = exception_retry_configuration
|
|
68
72
|
|
|
69
73
|
super().__init__()
|
|
70
74
|
|
|
@@ -74,12 +78,25 @@ class AsyncHTTPProvider(AsyncJSONBaseProvider):
|
|
|
74
78
|
def __str__(self) -> str:
|
|
75
79
|
return f"RPC connection {self.endpoint_uri}"
|
|
76
80
|
|
|
81
|
+
@property
|
|
82
|
+
def exception_retry_configuration(self) -> ExceptionRetryConfiguration:
|
|
83
|
+
if isinstance(self._exception_retry_configuration, Empty):
|
|
84
|
+
self._exception_retry_configuration = ExceptionRetryConfiguration(
|
|
85
|
+
errors=(ClientError, TimeoutError)
|
|
86
|
+
)
|
|
87
|
+
return self._exception_retry_configuration
|
|
88
|
+
|
|
89
|
+
@exception_retry_configuration.setter
|
|
90
|
+
def exception_retry_configuration(
|
|
91
|
+
self, value: Union[ExceptionRetryConfiguration, Empty]
|
|
92
|
+
) -> None:
|
|
93
|
+
self._exception_retry_configuration = value
|
|
94
|
+
|
|
77
95
|
@to_dict
|
|
78
96
|
def get_request_kwargs(self) -> Iterable[Tuple[str, Any]]:
|
|
79
97
|
if "headers" not in self._request_kwargs:
|
|
80
98
|
yield "headers", self.get_request_headers()
|
|
81
|
-
|
|
82
|
-
yield key, value
|
|
99
|
+
yield from self._request_kwargs.items()
|
|
83
100
|
|
|
84
101
|
def get_request_headers(self) -> Dict[str, str]:
|
|
85
102
|
return {
|
web3/providers/rpc/rpc.py
CHANGED
|
@@ -18,6 +18,10 @@ from eth_utils import (
|
|
|
18
18
|
)
|
|
19
19
|
import requests
|
|
20
20
|
|
|
21
|
+
from web3._utils.empty import (
|
|
22
|
+
Empty,
|
|
23
|
+
empty,
|
|
24
|
+
)
|
|
21
25
|
from web3._utils.http import (
|
|
22
26
|
construct_user_agent,
|
|
23
27
|
)
|
|
@@ -51,26 +55,16 @@ if TYPE_CHECKING:
|
|
|
51
55
|
class HTTPProvider(JSONBaseProvider):
|
|
52
56
|
logger = logging.getLogger("web3.providers.HTTPProvider")
|
|
53
57
|
endpoint_uri = None
|
|
54
|
-
|
|
55
|
-
_request_args = None
|
|
56
58
|
_request_kwargs = None
|
|
57
59
|
|
|
58
|
-
exception_retry_configuration: Optional[ExceptionRetryConfiguration] = None
|
|
59
|
-
|
|
60
60
|
def __init__(
|
|
61
61
|
self,
|
|
62
62
|
endpoint_uri: Optional[Union[URI, str]] = None,
|
|
63
63
|
request_kwargs: Optional[Any] = None,
|
|
64
64
|
session: Optional[Any] = None,
|
|
65
|
-
exception_retry_configuration:
|
|
66
|
-
ExceptionRetryConfiguration
|
|
67
|
-
|
|
68
|
-
ConnectionError,
|
|
69
|
-
requests.HTTPError,
|
|
70
|
-
requests.Timeout,
|
|
71
|
-
)
|
|
72
|
-
)
|
|
73
|
-
),
|
|
65
|
+
exception_retry_configuration: Union[
|
|
66
|
+
ExceptionRetryConfiguration, Empty
|
|
67
|
+
] = empty,
|
|
74
68
|
) -> None:
|
|
75
69
|
if endpoint_uri is None:
|
|
76
70
|
self.endpoint_uri = get_default_http_endpoint()
|
|
@@ -78,7 +72,7 @@ class HTTPProvider(JSONBaseProvider):
|
|
|
78
72
|
self.endpoint_uri = URI(endpoint_uri)
|
|
79
73
|
|
|
80
74
|
self._request_kwargs = request_kwargs or {}
|
|
81
|
-
self.
|
|
75
|
+
self._exception_retry_configuration = exception_retry_configuration
|
|
82
76
|
|
|
83
77
|
if session:
|
|
84
78
|
cache_and_return_session(self.endpoint_uri, session)
|
|
@@ -88,12 +82,29 @@ class HTTPProvider(JSONBaseProvider):
|
|
|
88
82
|
def __str__(self) -> str:
|
|
89
83
|
return f"RPC connection {self.endpoint_uri}"
|
|
90
84
|
|
|
85
|
+
@property
|
|
86
|
+
def exception_retry_configuration(self) -> ExceptionRetryConfiguration:
|
|
87
|
+
if isinstance(self._exception_retry_configuration, Empty):
|
|
88
|
+
self._exception_retry_configuration = ExceptionRetryConfiguration(
|
|
89
|
+
errors=(
|
|
90
|
+
ConnectionError,
|
|
91
|
+
requests.HTTPError,
|
|
92
|
+
requests.Timeout,
|
|
93
|
+
)
|
|
94
|
+
)
|
|
95
|
+
return self._exception_retry_configuration
|
|
96
|
+
|
|
97
|
+
@exception_retry_configuration.setter
|
|
98
|
+
def exception_retry_configuration(
|
|
99
|
+
self, value: Union[ExceptionRetryConfiguration, Empty]
|
|
100
|
+
) -> None:
|
|
101
|
+
self._exception_retry_configuration = value
|
|
102
|
+
|
|
91
103
|
@to_dict
|
|
92
104
|
def get_request_kwargs(self) -> Iterable[Tuple[str, Any]]:
|
|
93
105
|
if "headers" not in self._request_kwargs:
|
|
94
106
|
yield "headers", self.get_request_headers()
|
|
95
|
-
|
|
96
|
-
yield key, value
|
|
107
|
+
yield from self._request_kwargs.items()
|
|
97
108
|
|
|
98
109
|
def get_request_headers(self) -> Dict[str, str]:
|
|
99
110
|
return {
|
web3/testing.py
CHANGED
|
@@ -12,21 +12,21 @@ from web3.module import (
|
|
|
12
12
|
|
|
13
13
|
class Testing(Module):
|
|
14
14
|
def timeTravel(self, timestamp: int) -> None:
|
|
15
|
-
|
|
15
|
+
self.w3.manager.request_blocking(RPC.testing_timeTravel, [timestamp])
|
|
16
16
|
|
|
17
17
|
def mine(self, num_blocks: int = 1) -> None:
|
|
18
|
-
|
|
18
|
+
self.w3.manager.request_blocking(RPC.evm_mine, [num_blocks])
|
|
19
19
|
|
|
20
20
|
def snapshot(self) -> int:
|
|
21
21
|
self.last_snapshot_idx = self.w3.manager.request_blocking(RPC.evm_snapshot, [])
|
|
22
22
|
return self.last_snapshot_idx
|
|
23
23
|
|
|
24
24
|
def reset(self) -> None:
|
|
25
|
-
|
|
25
|
+
self.w3.manager.request_blocking(RPC.evm_reset, [])
|
|
26
26
|
|
|
27
27
|
def revert(self, snapshot_idx: Optional[int] = None) -> None:
|
|
28
28
|
if snapshot_idx is None:
|
|
29
29
|
revert_target = self.last_snapshot_idx
|
|
30
30
|
else:
|
|
31
31
|
revert_target = snapshot_idx
|
|
32
|
-
|
|
32
|
+
self.w3.manager.request_blocking(RPC.evm_revert, [revert_target])
|
|
File without changes
|