web3 7.0.0b2__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 +27 -15
- ens/base_ens.py +3 -1
- ens/contract_data.py +2 -2
- ens/ens.py +10 -7
- ens/exceptions.py +16 -29
- ens/specs/nf.json +1 -1
- ens/specs/normalization_spec.json +1 -1
- ens/utils.py +24 -32
- web3/__init__.py +23 -12
- web3/_utils/abi.py +157 -263
- 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 +49 -34
- 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 -17
- web3/manager.py +362 -95
- web3/method.py +43 -15
- web3/middleware/__init__.py +17 -0
- 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 +61 -25
- web3/providers/__init__.py +21 -0
- web3/providers/async_base.py +87 -32
- web3/providers/base.py +77 -32
- web3/providers/eth_tester/__init__.py +5 -0
- web3/providers/eth_tester/defaults.py +2 -55
- web3/providers/eth_tester/main.py +41 -15
- web3/providers/eth_tester/middleware.py +16 -17
- web3/providers/ipc.py +41 -17
- web3/providers/legacy_websocket.py +26 -1
- web3/providers/persistent/__init__.py +7 -0
- web3/providers/persistent/async_ipc.py +61 -121
- web3/providers/persistent/persistent.py +323 -16
- 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.0b2.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.0b2.dist-info → web3-7.7.0.dist-info}/WHEEL +1 -1
- 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-7.0.0b2.dist-info/METADATA +0 -106
- web3-7.0.0b2.dist-info/RECORD +0 -163
- /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
- {web3-7.0.0b2.dist-info → web3-7.7.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from typing import (
|
|
2
2
|
TYPE_CHECKING,
|
|
3
|
+
Dict,
|
|
3
4
|
Optional,
|
|
5
|
+
Union,
|
|
4
6
|
cast,
|
|
5
7
|
)
|
|
6
8
|
|
|
@@ -24,6 +26,9 @@ from web3._utils.utility_methods import (
|
|
|
24
26
|
from web3.constants import (
|
|
25
27
|
DYNAMIC_FEE_TXN_PARAMS,
|
|
26
28
|
)
|
|
29
|
+
from web3.exceptions import (
|
|
30
|
+
Web3ValueError,
|
|
31
|
+
)
|
|
27
32
|
from web3.types import (
|
|
28
33
|
BlockIdentifier,
|
|
29
34
|
TxData,
|
|
@@ -39,21 +44,32 @@ if TYPE_CHECKING:
|
|
|
39
44
|
)
|
|
40
45
|
|
|
41
46
|
|
|
42
|
-
|
|
47
|
+
# unused vars present in these funcs because they all need to have the same signature
|
|
48
|
+
async def _estimate_gas(
|
|
49
|
+
async_w3: "AsyncWeb3", tx: TxParams, _defaults: Dict[str, Union[bytes, int]]
|
|
50
|
+
) -> int:
|
|
43
51
|
return await async_w3.eth.estimate_gas(tx)
|
|
44
52
|
|
|
45
53
|
|
|
46
|
-
async def _max_fee_per_gas(
|
|
54
|
+
async def _max_fee_per_gas(
|
|
55
|
+
async_w3: "AsyncWeb3", tx: TxParams, defaults: Dict[str, Union[bytes, int]]
|
|
56
|
+
) -> Wei:
|
|
47
57
|
block = await async_w3.eth.get_block("latest")
|
|
48
|
-
max_priority_fee =
|
|
49
|
-
|
|
58
|
+
max_priority_fee = tx.get(
|
|
59
|
+
"maxPriorityFeePerGas", defaults.get("maxPriorityFeePerGas")
|
|
60
|
+
)
|
|
61
|
+
return Wei(int(max_priority_fee) + (2 * int(block["baseFeePerGas"])))
|
|
50
62
|
|
|
51
63
|
|
|
52
|
-
async def _max_priority_fee_gas(
|
|
64
|
+
async def _max_priority_fee_gas(
|
|
65
|
+
async_w3: "AsyncWeb3", _tx: TxParams, _defaults: Dict[str, Union[bytes, int]]
|
|
66
|
+
) -> Wei:
|
|
53
67
|
return await async_w3.eth.max_priority_fee
|
|
54
68
|
|
|
55
69
|
|
|
56
|
-
async def _chain_id(
|
|
70
|
+
async def _chain_id(
|
|
71
|
+
async_w3: "AsyncWeb3", _tx: TxParams, _defaults: Dict[str, Union[bytes, int]]
|
|
72
|
+
) -> int:
|
|
57
73
|
return await async_w3.eth.chain_id
|
|
58
74
|
|
|
59
75
|
|
|
@@ -61,9 +77,9 @@ TRANSACTION_DEFAULTS = {
|
|
|
61
77
|
"value": 0,
|
|
62
78
|
"data": b"",
|
|
63
79
|
"gas": _estimate_gas,
|
|
64
|
-
"gasPrice": lambda async_w3, tx: async_w3.eth.generate_gas_price(tx),
|
|
65
|
-
"maxFeePerGas": _max_fee_per_gas,
|
|
80
|
+
"gasPrice": lambda async_w3, tx, _defaults: async_w3.eth.generate_gas_price(tx),
|
|
66
81
|
"maxPriorityFeePerGas": _max_priority_fee_gas,
|
|
82
|
+
"maxFeePerGas": _max_fee_per_gas,
|
|
67
83
|
"chainId": _chain_id,
|
|
68
84
|
}
|
|
69
85
|
|
|
@@ -71,9 +87,7 @@ TRANSACTION_DEFAULTS = {
|
|
|
71
87
|
async def get_block_gas_limit(
|
|
72
88
|
web3_eth: "AsyncEth", block_identifier: Optional[BlockIdentifier] = None
|
|
73
89
|
) -> int:
|
|
74
|
-
|
|
75
|
-
block_identifier = await web3_eth.block_number
|
|
76
|
-
block = await web3_eth.get_block(block_identifier)
|
|
90
|
+
block = await web3_eth.get_block(block_identifier or "latest")
|
|
77
91
|
return block["gasLimit"]
|
|
78
92
|
|
|
79
93
|
|
|
@@ -87,9 +101,9 @@ async def get_buffered_gas_estimate(
|
|
|
87
101
|
gas_limit = await get_block_gas_limit(async_w3.eth)
|
|
88
102
|
|
|
89
103
|
if gas_estimate > gas_limit:
|
|
90
|
-
raise
|
|
91
|
-
"
|
|
92
|
-
f"
|
|
104
|
+
raise Web3ValueError(
|
|
105
|
+
"Gas estimate for transaction is higher than current network gas limits. "
|
|
106
|
+
f"Transaction could not be sent. Estimated: {gas_estimate}. "
|
|
93
107
|
f"Current gas limit: {gas_limit}"
|
|
94
108
|
)
|
|
95
109
|
|
|
@@ -110,7 +124,7 @@ async def async_fill_transaction_defaults(
|
|
|
110
124
|
async_w3: "AsyncWeb3", transaction: TxParams
|
|
111
125
|
) -> TxParams:
|
|
112
126
|
"""
|
|
113
|
-
|
|
127
|
+
If async_w3 is None, fill as much as possible while offline
|
|
114
128
|
"""
|
|
115
129
|
strategy_based_gas_price = async_w3.eth.generate_gas_price(transaction)
|
|
116
130
|
|
|
@@ -119,7 +133,7 @@ async def async_fill_transaction_defaults(
|
|
|
119
133
|
or any_in_dict(DYNAMIC_FEE_TXN_PARAMS, transaction)
|
|
120
134
|
)
|
|
121
135
|
|
|
122
|
-
defaults = {}
|
|
136
|
+
defaults: Dict[str, Union[bytes, int]] = {}
|
|
123
137
|
for key, default_getter in TRANSACTION_DEFAULTS.items():
|
|
124
138
|
if key not in transaction:
|
|
125
139
|
if (
|
|
@@ -134,15 +148,15 @@ async def async_fill_transaction_defaults(
|
|
|
134
148
|
|
|
135
149
|
if callable(default_getter):
|
|
136
150
|
if async_w3 is None:
|
|
137
|
-
raise
|
|
151
|
+
raise Web3ValueError(
|
|
138
152
|
f"You must specify a '{key}' value in the transaction"
|
|
139
153
|
)
|
|
140
154
|
if key == "gasPrice":
|
|
141
155
|
# `generate_gas_price()` is on the `BaseEth` class and does not
|
|
142
156
|
# need to be awaited
|
|
143
|
-
default_val = default_getter(async_w3, transaction)
|
|
157
|
+
default_val = default_getter(async_w3, transaction, defaults)
|
|
144
158
|
else:
|
|
145
|
-
default_val = await default_getter(async_w3, transaction)
|
|
159
|
+
default_val = await default_getter(async_w3, transaction, defaults)
|
|
146
160
|
else:
|
|
147
161
|
default_val = default_getter
|
|
148
162
|
|
|
@@ -155,7 +169,7 @@ async def async_get_required_transaction(
|
|
|
155
169
|
) -> TxData:
|
|
156
170
|
current_transaction = await async_w3.eth.get_transaction(transaction_hash)
|
|
157
171
|
if not current_transaction:
|
|
158
|
-
raise
|
|
172
|
+
raise Web3ValueError(
|
|
159
173
|
f"Supplied transaction with hash {transaction_hash!r} does not exist"
|
|
160
174
|
)
|
|
161
175
|
return current_transaction
|
web3/_utils/batching.py
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
from copy import (
|
|
2
|
+
copy,
|
|
3
|
+
)
|
|
4
|
+
from types import (
|
|
5
|
+
TracebackType,
|
|
6
|
+
)
|
|
7
|
+
from typing import (
|
|
8
|
+
TYPE_CHECKING,
|
|
9
|
+
Any,
|
|
10
|
+
Callable,
|
|
11
|
+
Coroutine,
|
|
12
|
+
Dict,
|
|
13
|
+
Generic,
|
|
14
|
+
List,
|
|
15
|
+
Sequence,
|
|
16
|
+
Tuple,
|
|
17
|
+
Type,
|
|
18
|
+
Union,
|
|
19
|
+
cast,
|
|
20
|
+
)
|
|
21
|
+
import warnings
|
|
22
|
+
|
|
23
|
+
from web3._utils.compat import (
|
|
24
|
+
Self,
|
|
25
|
+
)
|
|
26
|
+
from web3.contract.async_contract import (
|
|
27
|
+
AsyncContractFunction,
|
|
28
|
+
)
|
|
29
|
+
from web3.contract.contract import (
|
|
30
|
+
ContractFunction,
|
|
31
|
+
)
|
|
32
|
+
from web3.exceptions import (
|
|
33
|
+
Web3ValueError,
|
|
34
|
+
)
|
|
35
|
+
from web3.types import (
|
|
36
|
+
TFunc,
|
|
37
|
+
TReturn,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
if TYPE_CHECKING:
|
|
41
|
+
from web3 import ( # noqa: F401
|
|
42
|
+
AsyncWeb3,
|
|
43
|
+
Web3,
|
|
44
|
+
)
|
|
45
|
+
from web3.method import ( # noqa: F401
|
|
46
|
+
Method,
|
|
47
|
+
)
|
|
48
|
+
from web3.providers import ( # noqa: F401
|
|
49
|
+
PersistentConnectionProvider,
|
|
50
|
+
)
|
|
51
|
+
from web3.providers.async_base import ( # noqa: F401
|
|
52
|
+
AsyncJSONBaseProvider,
|
|
53
|
+
)
|
|
54
|
+
from web3.providers.base import ( # noqa: F401
|
|
55
|
+
JSONBaseProvider,
|
|
56
|
+
)
|
|
57
|
+
from web3.types import ( # noqa: F401
|
|
58
|
+
RPCEndpoint,
|
|
59
|
+
RPCResponse,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
BATCH_REQUEST_ID = "batch_request" # for use as the cache key for batch requests
|
|
64
|
+
|
|
65
|
+
BatchRequestInformation = Tuple[Tuple["RPCEndpoint", Any], Sequence[Any]]
|
|
66
|
+
RPC_METHODS_UNSUPPORTED_DURING_BATCH = {
|
|
67
|
+
"eth_subscribe",
|
|
68
|
+
"eth_unsubscribe",
|
|
69
|
+
"eth_sendRawTransaction",
|
|
70
|
+
"eth_sendTransaction",
|
|
71
|
+
"eth_signTransaction",
|
|
72
|
+
"eth_sign",
|
|
73
|
+
"eth_signTypedData",
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class RequestBatcher(Generic[TFunc]):
|
|
78
|
+
def __init__(self, web3: Union["AsyncWeb3", "Web3"]) -> None:
|
|
79
|
+
self.web3 = web3
|
|
80
|
+
self._requests_info: List[BatchRequestInformation] = []
|
|
81
|
+
self._async_requests_info: List[
|
|
82
|
+
Coroutine[Any, Any, BatchRequestInformation]
|
|
83
|
+
] = []
|
|
84
|
+
self._initialize_batching()
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def _provider(self) -> Union["JSONBaseProvider", "AsyncJSONBaseProvider"]:
|
|
88
|
+
return (
|
|
89
|
+
cast("AsyncJSONBaseProvider", self.web3.provider)
|
|
90
|
+
if self.web3.provider.is_async
|
|
91
|
+
else cast("JSONBaseProvider", self.web3.provider)
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
def _validate_is_batching(self) -> None:
|
|
95
|
+
if not self._provider._is_batching:
|
|
96
|
+
raise Web3ValueError(
|
|
97
|
+
"Batch has already been executed or cancelled. Create a new batch to "
|
|
98
|
+
"issue batched requests."
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
def _initialize_batching(self) -> None:
|
|
102
|
+
self._provider._is_batching = True
|
|
103
|
+
self.clear()
|
|
104
|
+
|
|
105
|
+
def _end_batching(self) -> None:
|
|
106
|
+
self.clear()
|
|
107
|
+
self._provider._is_batching = False
|
|
108
|
+
if self._provider.has_persistent_connection:
|
|
109
|
+
provider = cast("PersistentConnectionProvider", self._provider)
|
|
110
|
+
provider._batch_request_counter = None
|
|
111
|
+
|
|
112
|
+
def add(self, batch_payload: TReturn) -> None:
|
|
113
|
+
self._validate_is_batching()
|
|
114
|
+
|
|
115
|
+
if isinstance(batch_payload, (ContractFunction, AsyncContractFunction)):
|
|
116
|
+
batch_payload = batch_payload.call() # type: ignore
|
|
117
|
+
|
|
118
|
+
# When batching, we don't make a request. Instead, we will get the request
|
|
119
|
+
# information and store it in the `_requests_info` list. So we have to cast the
|
|
120
|
+
# apparent "request" into the BatchRequestInformation type.
|
|
121
|
+
if self._provider.is_async:
|
|
122
|
+
self._async_requests_info.append(
|
|
123
|
+
cast(Coroutine[Any, Any, BatchRequestInformation], batch_payload)
|
|
124
|
+
)
|
|
125
|
+
else:
|
|
126
|
+
self._requests_info.append(cast(BatchRequestInformation, batch_payload))
|
|
127
|
+
|
|
128
|
+
def add_mapping(
|
|
129
|
+
self,
|
|
130
|
+
batch_payload: Dict[
|
|
131
|
+
Union[
|
|
132
|
+
"Method[Callable[..., Any]]",
|
|
133
|
+
Callable[..., Any],
|
|
134
|
+
ContractFunction,
|
|
135
|
+
AsyncContractFunction,
|
|
136
|
+
],
|
|
137
|
+
List[Any],
|
|
138
|
+
],
|
|
139
|
+
) -> None:
|
|
140
|
+
self._validate_is_batching()
|
|
141
|
+
for method, params in batch_payload.items():
|
|
142
|
+
for param in params:
|
|
143
|
+
self.add(method(param))
|
|
144
|
+
|
|
145
|
+
def execute(self) -> List["RPCResponse"]:
|
|
146
|
+
self._validate_is_batching()
|
|
147
|
+
responses = self.web3.manager._make_batch_request(self._requests_info)
|
|
148
|
+
self._end_batching()
|
|
149
|
+
return responses
|
|
150
|
+
|
|
151
|
+
def clear(self) -> None:
|
|
152
|
+
self._requests_info = []
|
|
153
|
+
self._async_requests_info = []
|
|
154
|
+
if self._provider.has_persistent_connection:
|
|
155
|
+
provider = cast("PersistentConnectionProvider", self._provider)
|
|
156
|
+
provider._batch_request_counter = next(copy(provider.request_counter))
|
|
157
|
+
|
|
158
|
+
def cancel(self) -> None:
|
|
159
|
+
self._end_batching()
|
|
160
|
+
|
|
161
|
+
# -- context manager -- #
|
|
162
|
+
|
|
163
|
+
def __enter__(self) -> Self:
|
|
164
|
+
self._initialize_batching()
|
|
165
|
+
return self
|
|
166
|
+
|
|
167
|
+
def __exit__(
|
|
168
|
+
self,
|
|
169
|
+
exc_type: Type[BaseException],
|
|
170
|
+
exc_val: BaseException,
|
|
171
|
+
exc_tb: TracebackType,
|
|
172
|
+
) -> None:
|
|
173
|
+
self._end_batching()
|
|
174
|
+
|
|
175
|
+
# -- async -- #
|
|
176
|
+
|
|
177
|
+
async def async_execute(self) -> List["RPCResponse"]:
|
|
178
|
+
self._validate_is_batching()
|
|
179
|
+
responses = await self.web3.manager._async_make_batch_request(
|
|
180
|
+
self._async_requests_info
|
|
181
|
+
)
|
|
182
|
+
self._end_batching()
|
|
183
|
+
return responses
|
|
184
|
+
|
|
185
|
+
# -- async context manager -- #
|
|
186
|
+
|
|
187
|
+
async def __aenter__(self) -> Self:
|
|
188
|
+
self._initialize_batching()
|
|
189
|
+
return self
|
|
190
|
+
|
|
191
|
+
async def __aexit__(
|
|
192
|
+
self,
|
|
193
|
+
exc_type: Type[BaseException],
|
|
194
|
+
exc_val: BaseException,
|
|
195
|
+
exc_tb: TracebackType,
|
|
196
|
+
) -> None:
|
|
197
|
+
self._end_batching()
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def sort_batch_response_by_response_ids(
|
|
201
|
+
responses: List["RPCResponse"],
|
|
202
|
+
) -> List["RPCResponse"]:
|
|
203
|
+
if all(response.get("id") is not None for response in responses):
|
|
204
|
+
# If all responses have an `id`, sort them by `id, since the JSON-RPC 2.0 spec
|
|
205
|
+
# doesn't guarantee order.
|
|
206
|
+
return sorted(responses, key=lambda response: response["id"])
|
|
207
|
+
else:
|
|
208
|
+
# If any response is missing an `id`, which should only happen on particular
|
|
209
|
+
# errors, return them in the order they were received and hope that the
|
|
210
|
+
# provider is returning them in order. Issue a warning.
|
|
211
|
+
warnings.warn(
|
|
212
|
+
"Received batch response with missing `id` for one or more responses. "
|
|
213
|
+
"Relying on provider to return these responses in order.",
|
|
214
|
+
RuntimeWarning,
|
|
215
|
+
stacklevel=2,
|
|
216
|
+
)
|
|
217
|
+
return responses
|
web3/_utils/blocks.py
CHANGED
|
@@ -15,6 +15,10 @@ from eth_utils.toolz import (
|
|
|
15
15
|
curry,
|
|
16
16
|
)
|
|
17
17
|
|
|
18
|
+
from web3.exceptions import (
|
|
19
|
+
Web3TypeError,
|
|
20
|
+
Web3ValueError,
|
|
21
|
+
)
|
|
18
22
|
from web3.types import (
|
|
19
23
|
RPCEndpoint,
|
|
20
24
|
)
|
|
@@ -32,7 +36,7 @@ def is_predefined_block_number(value: Any) -> bool:
|
|
|
32
36
|
elif is_integer(value):
|
|
33
37
|
return False
|
|
34
38
|
else:
|
|
35
|
-
raise
|
|
39
|
+
raise Web3TypeError(f"unrecognized block reference: {value!r}")
|
|
36
40
|
|
|
37
41
|
return value_text in {"latest", "pending", "earliest", "safe", "finalized"}
|
|
38
42
|
|
|
@@ -70,6 +74,6 @@ def select_method_for_block_identifier(
|
|
|
70
74
|
elif is_hex_encoded_block_number(value):
|
|
71
75
|
return if_number
|
|
72
76
|
else:
|
|
73
|
-
raise
|
|
77
|
+
raise Web3ValueError(
|
|
74
78
|
f"Value did not match any of the recognized block identifiers: {value}"
|
|
75
79
|
)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from .request_caching_validation import (
|
|
2
|
+
ASYNC_PROVIDER_TYPE,
|
|
3
|
+
SYNC_PROVIDER_TYPE,
|
|
4
|
+
)
|
|
5
|
+
from .caching_utils import (
|
|
6
|
+
CACHEABLE_REQUESTS,
|
|
7
|
+
async_handle_request_caching,
|
|
8
|
+
generate_cache_key,
|
|
9
|
+
handle_request_caching,
|
|
10
|
+
is_cacheable_request,
|
|
11
|
+
RequestInformation,
|
|
12
|
+
)
|