web3 6.20.3__py3-none-any.whl → 7.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ens/__init__.py +13 -2
- ens/_normalization.py +2 -17
- ens/async_ens.py +33 -21
- ens/base_ens.py +3 -1
- ens/ens.py +16 -11
- ens/exceptions.py +16 -29
- ens/specs/nf.json +1 -1
- ens/specs/normalization_spec.json +1 -1
- ens/utils.py +52 -63
- web3/__init__.py +20 -24
- web3/_utils/abi.py +115 -271
- web3/_utils/async_transactions.py +7 -4
- web3/_utils/batching.py +217 -0
- web3/_utils/blocks.py +6 -2
- web3/_utils/caching.py +128 -5
- web3/_utils/compat/__init__.py +2 -3
- web3/_utils/contract_sources/compile_contracts.py +1 -1
- 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 +5 -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 +130 -236
- web3/_utils/datatypes.py +5 -1
- web3/_utils/decorators.py +13 -23
- web3/_utils/empty.py +1 -1
- web3/_utils/encoding.py +16 -12
- web3/_utils/ens.py +2 -1
- web3/_utils/error_formatters_utils.py +5 -3
- web3/_utils/events.py +66 -69
- web3/_utils/fee_utils.py +1 -3
- web3/_utils/filters.py +24 -22
- web3/_utils/formatters.py +2 -2
- web3/_utils/http.py +5 -3
- web3/_utils/http_session_manager.py +303 -0
- web3/_utils/math.py +14 -15
- web3/_utils/method_formatters.py +34 -36
- web3/_utils/module.py +2 -1
- web3/_utils/module_testing/__init__.py +0 -3
- web3/_utils/module_testing/eth_module.py +695 -643
- web3/_utils/module_testing/module_testing_utils.py +61 -34
- web3/_utils/module_testing/persistent_connection_provider.py +56 -25
- web3/_utils/module_testing/utils.py +258 -0
- web3/_utils/module_testing/web3_module.py +438 -17
- web3/_utils/normalizers.py +13 -11
- web3/_utils/rpc_abi.py +5 -32
- web3/_utils/threads.py +8 -7
- web3/_utils/transactions.py +14 -12
- web3/_utils/type_conversion.py +5 -1
- web3/_utils/validation.py +17 -17
- web3/auto/gethdev.py +7 -2
- web3/beacon/__init__.py +6 -1
- web3/beacon/async_beacon.py +9 -5
- web3/beacon/{main.py → beacon.py} +7 -5
- web3/contract/__init__.py +7 -0
- web3/contract/async_contract.py +47 -46
- web3/contract/base_contract.py +183 -158
- web3/contract/contract.py +49 -43
- web3/contract/utils.py +203 -59
- web3/datastructures.py +79 -31
- web3/eth/__init__.py +7 -0
- web3/eth/async_eth.py +39 -51
- web3/eth/base_eth.py +17 -10
- web3/eth/eth.py +30 -68
- web3/exceptions.py +108 -82
- web3/gas_strategies/time_based.py +8 -6
- web3/geth.py +1 -254
- web3/main.py +75 -122
- web3/manager.py +316 -146
- web3/method.py +38 -31
- web3/middleware/__init__.py +67 -89
- web3/middleware/attrdict.py +36 -49
- web3/middleware/base.py +174 -0
- web3/middleware/buffered_gas_estimate.py +20 -21
- web3/middleware/filter.py +157 -117
- web3/middleware/formatting.py +124 -108
- web3/middleware/gas_price_strategy.py +20 -32
- web3/middleware/names.py +29 -26
- web3/middleware/proof_of_authority.py +68 -0
- web3/middleware/pythonic.py +2 -2
- web3/middleware/signing.py +74 -89
- web3/middleware/stalecheck.py +52 -79
- web3/middleware/validation.py +5 -13
- web3/module.py +54 -10
- web3/providers/__init__.py +10 -6
- web3/providers/async_base.py +117 -39
- web3/providers/auto.py +3 -3
- web3/providers/base.py +89 -33
- web3/providers/eth_tester/__init__.py +5 -0
- web3/providers/eth_tester/defaults.py +1 -64
- web3/providers/eth_tester/main.py +99 -31
- web3/providers/eth_tester/middleware.py +45 -73
- web3/providers/ipc.py +42 -46
- web3/providers/{websocket/websocket.py → legacy_websocket.py} +32 -7
- web3/providers/persistent/__init__.py +22 -0
- web3/providers/persistent/async_ipc.py +153 -0
- web3/providers/{persistent.py → persistent/persistent.py} +106 -25
- web3/providers/persistent/persistent_connection.py +84 -0
- web3/providers/{websocket → persistent}/request_processor.py +94 -32
- web3/providers/persistent/utils.py +43 -0
- web3/providers/{websocket/websocket_v2.py → persistent/websocket.py} +29 -28
- web3/providers/rpc/__init__.py +11 -0
- web3/providers/rpc/async_rpc.py +171 -0
- web3/providers/rpc/rpc.py +179 -0
- web3/providers/rpc/utils.py +92 -0
- web3/testing.py +4 -4
- web3/tools/benchmark/main.py +22 -22
- web3/tools/benchmark/node.py +2 -8
- web3/tools/benchmark/reporting.py +2 -2
- web3/tools/benchmark/utils.py +1 -1
- web3/tracing.py +9 -5
- web3/types.py +30 -107
- web3/utils/__init__.py +58 -5
- web3/utils/abi.py +575 -10
- web3/utils/async_exception_handling.py +19 -7
- web3/utils/caching.py +32 -13
- web3/utils/exception_handling.py +7 -5
- {web3-6.20.3.dist-info → web3-7.0.0.dist-info}/LICENSE +1 -1
- web3-7.0.0.dist-info/METADATA +112 -0
- web3-7.0.0.dist-info/RECORD +167 -0
- {web3-6.20.3.dist-info → web3-7.0.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/contract_sources/contract_data/address_reflector.py +0 -29
- web3/_utils/miner.py +0 -88
- web3/_utils/module_testing/go_ethereum_personal_module.py +0 -323
- web3/_utils/request.py +0 -265
- web3/middleware/abi.py +0 -11
- web3/middleware/async_cache.py +0 -99
- web3/middleware/cache.py +0 -374
- web3/middleware/exception_handling.py +0 -49
- web3/middleware/exception_retry_request.py +0 -188
- web3/middleware/fixture.py +0 -190
- web3/middleware/geth_poa.py +0 -81
- web3/middleware/normalize_request_parameters.py +0 -11
- web3/middleware/simulate_unmined_transaction.py +0 -43
- web3/pm.py +0 -602
- web3/providers/async_rpc.py +0 -99
- web3/providers/rpc.py +0 -98
- web3/providers/websocket/__init__.py +0 -11
- web3/providers/websocket/websocket_connection.py +0 -42
- web3/tools/__init__.py +0 -4
- 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-6.20.3.dist-info/METADATA +0 -104
- web3-6.20.3.dist-info/RECORD +0 -283
- web3-6.20.3.dist-info/entry_points.txt +0 -2
- /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
- {web3-6.20.3.dist-info → web3-7.0.0.dist-info}/WHEEL +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import (
|
|
2
2
|
TYPE_CHECKING,
|
|
3
3
|
Any,
|
|
4
|
-
|
|
4
|
+
cast,
|
|
5
5
|
)
|
|
6
6
|
|
|
7
7
|
from eth_utils.toolz import (
|
|
@@ -14,10 +14,11 @@ from web3._utils.async_transactions import (
|
|
|
14
14
|
from web3._utils.transactions import (
|
|
15
15
|
get_buffered_gas_estimate,
|
|
16
16
|
)
|
|
17
|
+
from web3.middleware.base import (
|
|
18
|
+
Web3Middleware,
|
|
19
|
+
)
|
|
17
20
|
from web3.types import (
|
|
18
|
-
AsyncMiddlewareCoroutine,
|
|
19
21
|
RPCEndpoint,
|
|
20
|
-
RPCResponse,
|
|
21
22
|
)
|
|
22
23
|
|
|
23
24
|
if TYPE_CHECKING:
|
|
@@ -27,34 +28,32 @@ if TYPE_CHECKING:
|
|
|
27
28
|
)
|
|
28
29
|
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
class BufferedGasEstimateMiddleware(Web3Middleware):
|
|
32
|
+
"""
|
|
33
|
+
Includes a gas estimate for all transactions that do not already have a gas value.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def request_processor(self, method: "RPCEndpoint", params: Any) -> Any:
|
|
34
37
|
if method == "eth_sendTransaction":
|
|
35
38
|
transaction = params[0]
|
|
36
39
|
if "gas" not in transaction:
|
|
37
40
|
transaction = assoc(
|
|
38
41
|
transaction,
|
|
39
42
|
"gas",
|
|
40
|
-
hex(get_buffered_gas_estimate(
|
|
43
|
+
hex(get_buffered_gas_estimate(cast("Web3", self._w3), transaction)),
|
|
41
44
|
)
|
|
42
|
-
|
|
43
|
-
return
|
|
44
|
-
|
|
45
|
-
return middleware
|
|
45
|
+
params = (transaction,)
|
|
46
|
+
return method, params
|
|
46
47
|
|
|
48
|
+
# -- async -- #
|
|
47
49
|
|
|
48
|
-
async def
|
|
49
|
-
make_request: Callable[[RPCEndpoint, Any], Any], w3: "AsyncWeb3"
|
|
50
|
-
) -> AsyncMiddlewareCoroutine:
|
|
51
|
-
async def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
|
|
50
|
+
async def async_request_processor(self, method: "RPCEndpoint", params: Any) -> Any:
|
|
52
51
|
if method == "eth_sendTransaction":
|
|
53
52
|
transaction = params[0]
|
|
54
53
|
if "gas" not in transaction:
|
|
55
|
-
gas_estimate = await async_get_buffered_gas_estimate(
|
|
54
|
+
gas_estimate = await async_get_buffered_gas_estimate(
|
|
55
|
+
cast("AsyncWeb3", self._w3), transaction
|
|
56
|
+
)
|
|
56
57
|
transaction = assoc(transaction, "gas", hex(gas_estimate))
|
|
57
|
-
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
return middleware
|
|
58
|
+
params = (transaction,)
|
|
59
|
+
return method, params
|
web3/middleware/filter.py
CHANGED
|
@@ -5,7 +5,6 @@ from typing import (
|
|
|
5
5
|
Any,
|
|
6
6
|
AsyncIterable,
|
|
7
7
|
AsyncIterator,
|
|
8
|
-
Callable,
|
|
9
8
|
Dict,
|
|
10
9
|
Generator,
|
|
11
10
|
Iterable,
|
|
@@ -43,18 +42,30 @@ from web3._utils.formatters import (
|
|
|
43
42
|
from web3._utils.rpc_abi import (
|
|
44
43
|
RPC,
|
|
45
44
|
)
|
|
45
|
+
from web3.exceptions import (
|
|
46
|
+
Web3TypeError,
|
|
47
|
+
)
|
|
48
|
+
from web3.middleware.base import (
|
|
49
|
+
Web3Middleware,
|
|
50
|
+
)
|
|
46
51
|
from web3.types import (
|
|
47
|
-
|
|
52
|
+
AsyncMakeRequestFn,
|
|
48
53
|
FilterParams,
|
|
49
54
|
LatestBlockParam,
|
|
50
55
|
LogReceipt,
|
|
51
|
-
|
|
52
|
-
RPCResponse,
|
|
56
|
+
MakeRequestFn,
|
|
53
57
|
_Hash32,
|
|
54
58
|
)
|
|
55
59
|
|
|
56
60
|
if TYPE_CHECKING:
|
|
57
|
-
from web3 import
|
|
61
|
+
from web3 import ( # noqa: F401
|
|
62
|
+
AsyncWeb3,
|
|
63
|
+
Web3,
|
|
64
|
+
)
|
|
65
|
+
from web3.types import ( # noqa: F401
|
|
66
|
+
RPCEndpoint,
|
|
67
|
+
RPCResponse,
|
|
68
|
+
)
|
|
58
69
|
|
|
59
70
|
if "WEB3_MAX_BLOCK_REQUEST" in os.environ:
|
|
60
71
|
MAX_BLOCK_REQUEST = to_int(text=os.environ["WEB3_MAX_BLOCK_REQUEST"])
|
|
@@ -63,7 +74,8 @@ else:
|
|
|
63
74
|
|
|
64
75
|
|
|
65
76
|
def segment_count(start: int, stop: int, step: int = 5) -> Iterable[Tuple[int, int]]:
|
|
66
|
-
"""
|
|
77
|
+
"""
|
|
78
|
+
Creates a segment counting generator
|
|
67
79
|
|
|
68
80
|
The generator returns tuple pairs of integers
|
|
69
81
|
that correspond to segments in the provided range.
|
|
@@ -76,6 +88,7 @@ def segment_count(start: int, stop: int, step: int = 5) -> Iterable[Tuple[int, i
|
|
|
76
88
|
|
|
77
89
|
|
|
78
90
|
Example:
|
|
91
|
+
-------
|
|
79
92
|
|
|
80
93
|
>>> segment_counter = segment_count(start=0, stop=10, step=3)
|
|
81
94
|
>>> next(segment_counter)
|
|
@@ -86,6 +99,7 @@ def segment_count(start: int, stop: int, step: int = 5) -> Iterable[Tuple[int, i
|
|
|
86
99
|
(6, 9)
|
|
87
100
|
>>> next(segment_counter) # Remainder is also returned
|
|
88
101
|
(9, 10)
|
|
102
|
+
|
|
89
103
|
"""
|
|
90
104
|
return gen_bounded_segments(start, stop, step)
|
|
91
105
|
|
|
@@ -96,10 +110,9 @@ def gen_bounded_segments(start: int, stop: int, step: int) -> Iterable[Tuple[int
|
|
|
96
110
|
if start + step >= stop:
|
|
97
111
|
yield (start, stop)
|
|
98
112
|
return
|
|
99
|
-
|
|
113
|
+
yield from zip(
|
|
100
114
|
range(start, stop - step + 1, step), range(start + step, stop + 1, step)
|
|
101
|
-
)
|
|
102
|
-
yield segment
|
|
115
|
+
)
|
|
103
116
|
|
|
104
117
|
remainder = (stop - start) % step
|
|
105
118
|
# Handle the remainder
|
|
@@ -110,13 +123,14 @@ def gen_bounded_segments(start: int, stop: int, step: int) -> Iterable[Tuple[int
|
|
|
110
123
|
def block_ranges(
|
|
111
124
|
start_block: BlockNumber, last_block: Optional[BlockNumber], step: int = 5
|
|
112
125
|
) -> Iterable[Tuple[BlockNumber, BlockNumber]]:
|
|
113
|
-
"""
|
|
126
|
+
"""
|
|
127
|
+
Returns 2-tuple ranges describing ranges of block from start_block to last_block
|
|
114
128
|
|
|
115
129
|
Ranges do not overlap to facilitate use as ``toBlock``, ``fromBlock``
|
|
116
130
|
json-rpc arguments, which are both inclusive.
|
|
117
131
|
"""
|
|
118
132
|
if last_block is not None and start_block > last_block:
|
|
119
|
-
raise
|
|
133
|
+
raise Web3TypeError(
|
|
120
134
|
"Incompatible start and stop arguments.",
|
|
121
135
|
"Start must be less than or equal to stop.",
|
|
122
136
|
)
|
|
@@ -130,7 +144,8 @@ def block_ranges(
|
|
|
130
144
|
def iter_latest_block(
|
|
131
145
|
w3: "Web3", to_block: Optional[Union[BlockNumber, LatestBlockParam]] = None
|
|
132
146
|
) -> Iterable[BlockNumber]:
|
|
133
|
-
"""
|
|
147
|
+
"""
|
|
148
|
+
Returns a generator that dispenses the latest block, if
|
|
134
149
|
any new blocks have been mined since last iteration.
|
|
135
150
|
|
|
136
151
|
If there are no new blocks or the latest block is greater than
|
|
@@ -152,8 +167,7 @@ def iter_latest_block(
|
|
|
152
167
|
|
|
153
168
|
while True:
|
|
154
169
|
latest_block = w3.eth.block_number
|
|
155
|
-
|
|
156
|
-
if is_bounded_range and latest_block > to_block: # type: ignore
|
|
170
|
+
if is_bounded_range and latest_block > cast(BlockNumber, to_block):
|
|
157
171
|
yield None
|
|
158
172
|
# No new blocks since last iteration.
|
|
159
173
|
if _last is not None and _last == latest_block:
|
|
@@ -168,7 +182,8 @@ def iter_latest_block_ranges(
|
|
|
168
182
|
from_block: BlockNumber,
|
|
169
183
|
to_block: Optional[Union[BlockNumber, LatestBlockParam]] = None,
|
|
170
184
|
) -> Iterable[Tuple[Optional[BlockNumber], Optional[BlockNumber]]]:
|
|
171
|
-
"""
|
|
185
|
+
"""
|
|
186
|
+
Returns an iterator unloading ranges of available blocks
|
|
172
187
|
|
|
173
188
|
starting from `fromBlock` to the latest mined block,
|
|
174
189
|
until reaching toBlock. e.g.:
|
|
@@ -204,7 +219,8 @@ def get_logs_multipart(
|
|
|
204
219
|
topics: List[Optional[Union[_Hash32, List[_Hash32]]]],
|
|
205
220
|
max_blocks: int,
|
|
206
221
|
) -> Iterable[List[LogReceipt]]:
|
|
207
|
-
"""
|
|
222
|
+
"""
|
|
223
|
+
Used to break up requests to ``eth_getLogs``
|
|
208
224
|
|
|
209
225
|
The getLog request is partitioned into multiple calls of the max number of blocks
|
|
210
226
|
``max_blocks``.
|
|
@@ -239,9 +255,8 @@ class RequestLogs:
|
|
|
239
255
|
if from_block is None or from_block == "latest":
|
|
240
256
|
self._from_block = BlockNumber(w3.eth.block_number + 1)
|
|
241
257
|
elif is_string(from_block) and is_hex(from_block):
|
|
242
|
-
self._from_block = BlockNumber(hex_to_integer(from_block))
|
|
258
|
+
self._from_block = BlockNumber(hex_to_integer(cast(HexStr, from_block)))
|
|
243
259
|
else:
|
|
244
|
-
# cast b/c LatestBlockParam is handled above
|
|
245
260
|
self._from_block = from_block
|
|
246
261
|
self._to_block = to_block
|
|
247
262
|
self.filter_changes = self._get_filter_changes()
|
|
@@ -257,7 +272,7 @@ class RequestLogs:
|
|
|
257
272
|
elif self._to_block == "latest":
|
|
258
273
|
to_block = self.w3.eth.block_number
|
|
259
274
|
elif is_string(self._to_block) and is_hex(self._to_block):
|
|
260
|
-
to_block = BlockNumber(hex_to_integer(self._to_block))
|
|
275
|
+
to_block = BlockNumber(hex_to_integer(cast(HexStr, self._to_block)))
|
|
261
276
|
else:
|
|
262
277
|
to_block = self._to_block
|
|
263
278
|
|
|
@@ -338,59 +353,14 @@ def block_hashes_in_range(
|
|
|
338
353
|
yield getattr(w3.eth.get_block(BlockNumber(block_number)), "hash", None)
|
|
339
354
|
|
|
340
355
|
|
|
341
|
-
def local_filter_middleware(
|
|
342
|
-
make_request: Callable[[RPCEndpoint, Any], Any], w3: "Web3"
|
|
343
|
-
) -> Callable[[RPCEndpoint, Any], RPCResponse]:
|
|
344
|
-
filters = {}
|
|
345
|
-
filter_id_counter = map(to_hex, itertools.count())
|
|
346
|
-
|
|
347
|
-
def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
|
|
348
|
-
if method in NEW_FILTER_METHODS:
|
|
349
|
-
filter_id = next(filter_id_counter)
|
|
350
|
-
|
|
351
|
-
_filter: Union[RequestLogs, RequestBlocks]
|
|
352
|
-
if method == RPC.eth_newFilter:
|
|
353
|
-
_filter = RequestLogs(
|
|
354
|
-
w3, **apply_key_map(FILTER_PARAMS_KEY_MAP, params[0])
|
|
355
|
-
)
|
|
356
|
-
|
|
357
|
-
elif method == RPC.eth_newBlockFilter:
|
|
358
|
-
_filter = RequestBlocks(w3)
|
|
359
|
-
|
|
360
|
-
else:
|
|
361
|
-
raise NotImplementedError(method)
|
|
362
|
-
|
|
363
|
-
filters[filter_id] = _filter
|
|
364
|
-
return {"result": filter_id}
|
|
365
|
-
|
|
366
|
-
elif method in FILTER_CHANGES_METHODS:
|
|
367
|
-
filter_id = params[0]
|
|
368
|
-
# Pass through to filters not created by middleware
|
|
369
|
-
if filter_id not in filters:
|
|
370
|
-
return make_request(method, params)
|
|
371
|
-
_filter = filters[filter_id]
|
|
372
|
-
if method == RPC.eth_getFilterChanges:
|
|
373
|
-
return {"result": next(_filter.filter_changes)}
|
|
374
|
-
|
|
375
|
-
elif method == RPC.eth_getFilterLogs:
|
|
376
|
-
# type ignored b/c logic prevents RequestBlocks which
|
|
377
|
-
# doesn't implement get_logs
|
|
378
|
-
return {"result": _filter.get_logs()} # type: ignore
|
|
379
|
-
else:
|
|
380
|
-
raise NotImplementedError(method)
|
|
381
|
-
else:
|
|
382
|
-
return make_request(method, params)
|
|
383
|
-
|
|
384
|
-
return middleware
|
|
385
|
-
|
|
386
|
-
|
|
387
356
|
# --- async --- #
|
|
388
357
|
|
|
389
358
|
|
|
390
359
|
async def async_iter_latest_block(
|
|
391
|
-
w3: "
|
|
360
|
+
w3: "AsyncWeb3", to_block: Optional[Union[BlockNumber, LatestBlockParam]] = None
|
|
392
361
|
) -> AsyncIterable[BlockNumber]:
|
|
393
|
-
"""
|
|
362
|
+
"""
|
|
363
|
+
Returns a generator that dispenses the latest block, if
|
|
394
364
|
any new blocks have been mined since last iteration.
|
|
395
365
|
|
|
396
366
|
If there are no new blocks or the latest block is greater than
|
|
@@ -411,9 +381,9 @@ async def async_iter_latest_block(
|
|
|
411
381
|
is_bounded_range = to_block is not None and to_block != "latest"
|
|
412
382
|
|
|
413
383
|
while True:
|
|
414
|
-
latest_block = await w3.eth.block_number
|
|
384
|
+
latest_block = await w3.eth.block_number
|
|
415
385
|
# type ignored b/c is_bounded_range prevents unsupported comparison
|
|
416
|
-
if is_bounded_range and latest_block > to_block:
|
|
386
|
+
if is_bounded_range and latest_block > cast(int, to_block):
|
|
417
387
|
yield None
|
|
418
388
|
# No new blocks since last iteration.
|
|
419
389
|
if _last is not None and _last == latest_block:
|
|
@@ -424,11 +394,12 @@ async def async_iter_latest_block(
|
|
|
424
394
|
|
|
425
395
|
|
|
426
396
|
async def async_iter_latest_block_ranges(
|
|
427
|
-
w3: "
|
|
397
|
+
w3: "AsyncWeb3",
|
|
428
398
|
from_block: BlockNumber,
|
|
429
399
|
to_block: Optional[Union[BlockNumber, LatestBlockParam]] = None,
|
|
430
400
|
) -> AsyncIterable[Tuple[Optional[BlockNumber], Optional[BlockNumber]]]:
|
|
431
|
-
"""
|
|
401
|
+
"""
|
|
402
|
+
Returns an iterator unloading ranges of available blocks
|
|
432
403
|
|
|
433
404
|
starting from `from_block` to the latest mined block,
|
|
434
405
|
until reaching to_block. e.g.:
|
|
@@ -454,14 +425,15 @@ async def async_iter_latest_block_ranges(
|
|
|
454
425
|
|
|
455
426
|
|
|
456
427
|
async def async_get_logs_multipart(
|
|
457
|
-
w3: "
|
|
428
|
+
w3: "AsyncWeb3",
|
|
458
429
|
start_block: BlockNumber,
|
|
459
430
|
stop_block: BlockNumber,
|
|
460
431
|
address: Union[Address, ChecksumAddress, List[Union[Address, ChecksumAddress]]],
|
|
461
432
|
topics: List[Optional[Union[_Hash32, List[_Hash32]]]],
|
|
462
433
|
max_blocks: int,
|
|
463
434
|
) -> AsyncIterable[List[LogReceipt]]:
|
|
464
|
-
"""
|
|
435
|
+
"""
|
|
436
|
+
Used to break up requests to ``eth_getLogs``
|
|
465
437
|
|
|
466
438
|
The getLog request is partitioned into multiple calls of the max number of blocks
|
|
467
439
|
``max_blocks``.
|
|
@@ -477,7 +449,7 @@ async def async_get_logs_multipart(
|
|
|
477
449
|
params_with_none_dropped = cast(
|
|
478
450
|
FilterParams, drop_items_with_none_value(params)
|
|
479
451
|
)
|
|
480
|
-
next_logs = await w3.eth.get_logs(params_with_none_dropped)
|
|
452
|
+
next_logs = await w3.eth.get_logs(params_with_none_dropped)
|
|
481
453
|
yield next_logs
|
|
482
454
|
|
|
483
455
|
|
|
@@ -486,7 +458,7 @@ class AsyncRequestLogs:
|
|
|
486
458
|
|
|
487
459
|
def __init__(
|
|
488
460
|
self,
|
|
489
|
-
w3: "
|
|
461
|
+
w3: "AsyncWeb3",
|
|
490
462
|
from_block: Optional[Union[BlockNumber, LatestBlockParam]] = None,
|
|
491
463
|
to_block: Optional[Union[BlockNumber, LatestBlockParam]] = None,
|
|
492
464
|
address: Optional[
|
|
@@ -504,7 +476,7 @@ class AsyncRequestLogs:
|
|
|
504
476
|
def __await__(self) -> Generator[Any, None, "AsyncRequestLogs"]:
|
|
505
477
|
async def closure() -> "AsyncRequestLogs":
|
|
506
478
|
if self._from_block_arg is None or self._from_block_arg == "latest":
|
|
507
|
-
self.block_number = await self.w3.eth.block_number
|
|
479
|
+
self.block_number = await self.w3.eth.block_number
|
|
508
480
|
self._from_block = BlockNumber(self.block_number + 1)
|
|
509
481
|
elif is_string(self._from_block_arg) and is_hex(self._from_block_arg):
|
|
510
482
|
self._from_block = BlockNumber(
|
|
@@ -524,7 +496,7 @@ class AsyncRequestLogs:
|
|
|
524
496
|
@property
|
|
525
497
|
async def to_block(self) -> BlockNumber:
|
|
526
498
|
if self._to_block is None or self._to_block == "latest":
|
|
527
|
-
to_block = await self.w3.eth.block_number
|
|
499
|
+
to_block = await self.w3.eth.block_number
|
|
528
500
|
elif is_string(self._to_block) and is_hex(self._to_block):
|
|
529
501
|
to_block = BlockNumber(hex_to_integer(cast(HexStr, self._to_block)))
|
|
530
502
|
else:
|
|
@@ -572,12 +544,12 @@ class AsyncRequestLogs:
|
|
|
572
544
|
|
|
573
545
|
|
|
574
546
|
class AsyncRequestBlocks:
|
|
575
|
-
def __init__(self, w3: "
|
|
547
|
+
def __init__(self, w3: "AsyncWeb3") -> None:
|
|
576
548
|
self.w3 = w3
|
|
577
549
|
|
|
578
550
|
def __await__(self) -> Generator[Any, None, "AsyncRequestBlocks"]:
|
|
579
551
|
async def closure() -> "AsyncRequestBlocks":
|
|
580
|
-
self.block_number = await self.w3.eth.block_number
|
|
552
|
+
self.block_number = await self.w3.eth.block_number
|
|
581
553
|
self.start_block = BlockNumber(self.block_number + 1)
|
|
582
554
|
return self
|
|
583
555
|
|
|
@@ -597,7 +569,7 @@ class AsyncRequestBlocks:
|
|
|
597
569
|
|
|
598
570
|
|
|
599
571
|
async def async_block_hashes_in_range(
|
|
600
|
-
w3: "
|
|
572
|
+
w3: "AsyncWeb3", block_range: Tuple[BlockNumber, BlockNumber]
|
|
601
573
|
) -> List[Union[None, Hash32]]:
|
|
602
574
|
from_block, to_block = block_range
|
|
603
575
|
if from_block is None or to_block is None:
|
|
@@ -605,56 +577,124 @@ async def async_block_hashes_in_range(
|
|
|
605
577
|
|
|
606
578
|
block_hashes = []
|
|
607
579
|
for block_number in range(from_block, to_block + 1):
|
|
608
|
-
w3_get_block = await w3.eth.get_block(BlockNumber(block_number))
|
|
580
|
+
w3_get_block = await w3.eth.get_block(BlockNumber(block_number))
|
|
609
581
|
block_hashes.append(getattr(w3_get_block, "hash", None))
|
|
610
582
|
|
|
611
583
|
return block_hashes
|
|
612
584
|
|
|
613
585
|
|
|
614
|
-
|
|
615
|
-
make_request: Callable[[RPCEndpoint, Any], Any], w3: "Web3"
|
|
616
|
-
) -> Callable[[RPCEndpoint, Any], Coroutine[Any, Any, RPCResponse]]:
|
|
617
|
-
filters = {}
|
|
618
|
-
filter_id_counter = map(to_hex, itertools.count())
|
|
586
|
+
# -- middleware -- #
|
|
619
587
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
filter_id = next(filter_id_counter)
|
|
588
|
+
SyncFilter = Union[RequestLogs, RequestBlocks]
|
|
589
|
+
AsyncFilter = Union[AsyncRequestLogs, AsyncRequestBlocks]
|
|
623
590
|
|
|
624
|
-
_filter: Union[AsyncRequestLogs, AsyncRequestBlocks]
|
|
625
|
-
if method == RPC.eth_newFilter:
|
|
626
|
-
_filter = await AsyncRequestLogs(
|
|
627
|
-
w3, **apply_key_map(FILTER_PARAMS_KEY_MAP, params[0])
|
|
628
|
-
)
|
|
629
591
|
|
|
630
|
-
|
|
631
|
-
|
|
592
|
+
def _simulate_rpc_response_with_result(filter_id: str) -> "RPCResponse":
|
|
593
|
+
return {"jsonrpc": "2.0", "id": -1, "result": filter_id}
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
class LocalFilterMiddleware(Web3Middleware):
|
|
597
|
+
def __init__(self, w3: Union["Web3", "AsyncWeb3"]):
|
|
598
|
+
self.filters: Dict[str, SyncFilter] = {}
|
|
599
|
+
self.async_filters: Dict[str, AsyncFilter] = {}
|
|
600
|
+
self.filter_id_counter = itertools.count()
|
|
601
|
+
super().__init__(w3)
|
|
602
|
+
|
|
603
|
+
def wrap_make_request(self, make_request: MakeRequestFn) -> MakeRequestFn:
|
|
604
|
+
def middleware(method: "RPCEndpoint", params: Any) -> "RPCResponse":
|
|
605
|
+
if method in NEW_FILTER_METHODS:
|
|
606
|
+
_filter: SyncFilter
|
|
607
|
+
filter_id = to_hex(next(self.filter_id_counter))
|
|
608
|
+
|
|
609
|
+
if method == RPC.eth_newFilter:
|
|
610
|
+
_filter = RequestLogs(
|
|
611
|
+
cast("Web3", self._w3),
|
|
612
|
+
**apply_key_map(FILTER_PARAMS_KEY_MAP, params[0])
|
|
613
|
+
)
|
|
614
|
+
|
|
615
|
+
elif method == RPC.eth_newBlockFilter:
|
|
616
|
+
_filter = RequestBlocks(cast("Web3", self._w3))
|
|
617
|
+
|
|
618
|
+
else:
|
|
619
|
+
raise NotImplementedError(method)
|
|
620
|
+
|
|
621
|
+
self.filters[filter_id] = _filter
|
|
622
|
+
return _simulate_rpc_response_with_result(filter_id)
|
|
623
|
+
|
|
624
|
+
elif method in FILTER_CHANGES_METHODS:
|
|
625
|
+
_filter_id = params[0]
|
|
626
|
+
|
|
627
|
+
# Pass through to filters not created by middleware
|
|
628
|
+
if _filter_id not in self.filters:
|
|
629
|
+
return make_request(method, params)
|
|
630
|
+
|
|
631
|
+
_filter = self.filters[_filter_id]
|
|
632
|
+
if method == RPC.eth_getFilterChanges:
|
|
633
|
+
return _simulate_rpc_response_with_result(
|
|
634
|
+
next(_filter.filter_changes) # type: ignore
|
|
635
|
+
)
|
|
632
636
|
|
|
637
|
+
elif method == RPC.eth_getFilterLogs:
|
|
638
|
+
# type ignored b/c logic prevents RequestBlocks which
|
|
639
|
+
# doesn't implement get_logs
|
|
640
|
+
return _simulate_rpc_response_with_result(
|
|
641
|
+
_filter.get_logs() # type: ignore
|
|
642
|
+
)
|
|
643
|
+
else:
|
|
644
|
+
raise NotImplementedError(method)
|
|
633
645
|
else:
|
|
634
|
-
|
|
646
|
+
return make_request(method, params)
|
|
635
647
|
|
|
636
|
-
|
|
637
|
-
return {"result": filter_id}
|
|
648
|
+
return middleware
|
|
638
649
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
650
|
+
# -- async -- #
|
|
651
|
+
|
|
652
|
+
async def async_wrap_make_request(
|
|
653
|
+
self,
|
|
654
|
+
make_request: AsyncMakeRequestFn,
|
|
655
|
+
) -> AsyncMakeRequestFn:
|
|
656
|
+
async def middleware(method: "RPCEndpoint", params: Any) -> "RPCResponse":
|
|
657
|
+
if method in NEW_FILTER_METHODS:
|
|
658
|
+
_filter: AsyncFilter
|
|
659
|
+
filter_id = to_hex(next(self.filter_id_counter))
|
|
660
|
+
|
|
661
|
+
if method == RPC.eth_newFilter:
|
|
662
|
+
_filter = await AsyncRequestLogs(
|
|
663
|
+
cast("AsyncWeb3", self._w3),
|
|
664
|
+
**apply_key_map(FILTER_PARAMS_KEY_MAP, params[0])
|
|
665
|
+
)
|
|
666
|
+
|
|
667
|
+
elif method == RPC.eth_newBlockFilter:
|
|
668
|
+
_filter = await AsyncRequestBlocks(cast("AsyncWeb3", self._w3))
|
|
645
669
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
return {"result": changes}
|
|
670
|
+
else:
|
|
671
|
+
raise NotImplementedError(method)
|
|
649
672
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
673
|
+
self.async_filters[filter_id] = _filter
|
|
674
|
+
return _simulate_rpc_response_with_result(filter_id)
|
|
675
|
+
|
|
676
|
+
elif method in FILTER_CHANGES_METHODS:
|
|
677
|
+
_filter_id = params[0]
|
|
678
|
+
|
|
679
|
+
# Pass through to filters not created by middleware
|
|
680
|
+
if _filter_id not in self.async_filters:
|
|
681
|
+
return await make_request(method, params)
|
|
682
|
+
|
|
683
|
+
_filter = self.async_filters[_filter_id]
|
|
684
|
+
if method == RPC.eth_getFilterChanges:
|
|
685
|
+
return _simulate_rpc_response_with_result(
|
|
686
|
+
await _filter.filter_changes.__anext__() # type: ignore
|
|
687
|
+
)
|
|
688
|
+
|
|
689
|
+
elif method == RPC.eth_getFilterLogs:
|
|
690
|
+
# type ignored b/c logic prevents RequestBlocks which
|
|
691
|
+
# doesn't implement get_logs
|
|
692
|
+
return _simulate_rpc_response_with_result(
|
|
693
|
+
await _filter.get_logs() # type: ignore
|
|
694
|
+
)
|
|
695
|
+
else:
|
|
696
|
+
raise NotImplementedError(method)
|
|
655
697
|
else:
|
|
656
|
-
|
|
657
|
-
else:
|
|
658
|
-
return await make_request(method, params)
|
|
698
|
+
return await make_request(method, params)
|
|
659
699
|
|
|
660
|
-
|
|
700
|
+
return middleware
|