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
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from typing import (
|
|
3
|
+
cast,
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
from eth_typing import (
|
|
7
|
+
HexStr,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
from web3 import (
|
|
11
|
+
AsyncWeb3,
|
|
12
|
+
Web3,
|
|
13
|
+
)
|
|
14
|
+
from web3.types import (
|
|
15
|
+
BlockData,
|
|
16
|
+
CallTrace,
|
|
17
|
+
ChecksumAddress,
|
|
18
|
+
DiffModeTrace,
|
|
19
|
+
OpcodeTrace,
|
|
20
|
+
PrestateTrace,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class GoEthereumAsyncDebugModuleTest:
|
|
25
|
+
@pytest.mark.asyncio
|
|
26
|
+
async def test_async_geth_debug_trace_transaction_opcode_logger(
|
|
27
|
+
self, async_w3: "AsyncWeb3", txn_hash_with_log: HexStr
|
|
28
|
+
) -> None:
|
|
29
|
+
result = await async_w3.geth.debug.trace_transaction(txn_hash_with_log)
|
|
30
|
+
assert "structLogs" in dict(result).keys()
|
|
31
|
+
assert "gas" in dict(result).keys()
|
|
32
|
+
assert "failed" in dict(result).keys()
|
|
33
|
+
|
|
34
|
+
@pytest.mark.asyncio
|
|
35
|
+
async def test_async_geth_debug_trace_transaction_call_tracer(
|
|
36
|
+
self, async_w3: "AsyncWeb3", txn_hash_with_log: HexStr
|
|
37
|
+
) -> None:
|
|
38
|
+
result = cast(
|
|
39
|
+
CallTrace,
|
|
40
|
+
await async_w3.geth.debug.trace_transaction(
|
|
41
|
+
txn_hash_with_log, {"tracer": "callTracer"}
|
|
42
|
+
),
|
|
43
|
+
)
|
|
44
|
+
assert result.get("type") == "CALL"
|
|
45
|
+
|
|
46
|
+
@pytest.mark.asyncio
|
|
47
|
+
async def test_async_geth_debug_trace_transaction_prestate_tracer_diffMode(
|
|
48
|
+
self, async_w3: "AsyncWeb3", txn_hash_with_log: HexStr
|
|
49
|
+
) -> None:
|
|
50
|
+
result = cast(
|
|
51
|
+
DiffModeTrace,
|
|
52
|
+
await async_w3.geth.debug.trace_transaction(
|
|
53
|
+
txn_hash_with_log,
|
|
54
|
+
{"tracer": "prestateTracer", "tracerConfig": {"diffMode": True}},
|
|
55
|
+
),
|
|
56
|
+
)
|
|
57
|
+
assert "post" in dict(result).keys()
|
|
58
|
+
assert "pre" in dict(result).keys()
|
|
59
|
+
|
|
60
|
+
@pytest.mark.asyncio
|
|
61
|
+
async def test_async_geth_debug_trace_transaction_prestate_tracer(
|
|
62
|
+
self,
|
|
63
|
+
async_w3: "AsyncWeb3",
|
|
64
|
+
txn_hash_with_log: HexStr,
|
|
65
|
+
async_block_with_txn_with_log: BlockData,
|
|
66
|
+
) -> None:
|
|
67
|
+
result = cast(
|
|
68
|
+
PrestateTrace,
|
|
69
|
+
await async_w3.geth.debug.trace_transaction(
|
|
70
|
+
txn_hash_with_log,
|
|
71
|
+
{"tracer": "prestateTracer"},
|
|
72
|
+
),
|
|
73
|
+
)
|
|
74
|
+
tx = await async_w3.eth.get_transaction(txn_hash_with_log)
|
|
75
|
+
from_addr: ChecksumAddress = tx["from"]
|
|
76
|
+
assert isinstance(result[from_addr].get("balance"), int)
|
|
77
|
+
assert "post" not in dict(result).keys()
|
|
78
|
+
assert "pre" not in dict(result).keys()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class GoEthereumDebugModuleTest:
|
|
82
|
+
def test_geth_debug_trace_transaction_opcode_logger(
|
|
83
|
+
self, w3: "Web3", txn_hash_with_log: HexStr
|
|
84
|
+
) -> None:
|
|
85
|
+
result = cast(OpcodeTrace, w3.geth.debug.trace_transaction(txn_hash_with_log))
|
|
86
|
+
assert "structLogs" in dict(result).keys()
|
|
87
|
+
assert "gas" in dict(result).keys()
|
|
88
|
+
assert "failed" in dict(result).keys()
|
|
89
|
+
|
|
90
|
+
def test_geth_debug_trace_transaction_call_tracer(
|
|
91
|
+
self, w3: "Web3", txn_hash_with_log: HexStr
|
|
92
|
+
) -> None:
|
|
93
|
+
result = cast(
|
|
94
|
+
CallTrace,
|
|
95
|
+
w3.geth.debug.trace_transaction(
|
|
96
|
+
txn_hash_with_log, {"tracer": "callTracer"}
|
|
97
|
+
),
|
|
98
|
+
)
|
|
99
|
+
assert result.get("type") == "CALL"
|
|
100
|
+
|
|
101
|
+
def test_geth_debug_trace_transaction_prestate_tracer_diffmode(
|
|
102
|
+
self, w3: "Web3", txn_hash_with_log: HexStr
|
|
103
|
+
) -> None:
|
|
104
|
+
result = cast(
|
|
105
|
+
DiffModeTrace,
|
|
106
|
+
w3.geth.debug.trace_transaction(
|
|
107
|
+
txn_hash_with_log,
|
|
108
|
+
{"tracer": "prestateTracer", "tracerConfig": {"diffMode": True}},
|
|
109
|
+
),
|
|
110
|
+
)
|
|
111
|
+
assert "post" in dict(result).keys()
|
|
112
|
+
assert "pre" in dict(result).keys()
|
|
113
|
+
|
|
114
|
+
def test_geth_debug_trace_transaction_prestate_tracer(
|
|
115
|
+
self, w3: "Web3", txn_hash_with_log: HexStr
|
|
116
|
+
) -> None:
|
|
117
|
+
result = cast(
|
|
118
|
+
PrestateTrace,
|
|
119
|
+
w3.geth.debug.trace_transaction(
|
|
120
|
+
txn_hash_with_log,
|
|
121
|
+
{"tracer": "prestateTracer"},
|
|
122
|
+
),
|
|
123
|
+
)
|
|
124
|
+
tx = w3.eth.get_transaction(txn_hash_with_log)
|
|
125
|
+
from_addr: ChecksumAddress = tx["from"]
|
|
126
|
+
assert isinstance(result[from_addr].get("balance"), int)
|
|
127
|
+
assert "post" not in dict(result).keys()
|
|
128
|
+
assert "pre" not in dict(result).keys()
|
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import asyncio
|
|
2
|
+
import functools
|
|
3
|
+
import pytest
|
|
4
4
|
from typing import (
|
|
5
5
|
TYPE_CHECKING,
|
|
6
6
|
Any,
|
|
7
|
+
Callable,
|
|
7
8
|
Collection,
|
|
8
9
|
Dict,
|
|
9
10
|
Generator,
|
|
11
|
+
Literal,
|
|
10
12
|
Sequence,
|
|
13
|
+
Tuple,
|
|
14
|
+
Type,
|
|
11
15
|
Union,
|
|
12
16
|
)
|
|
13
17
|
|
|
14
18
|
from aiohttp import (
|
|
19
|
+
ClientSession,
|
|
15
20
|
ClientTimeout,
|
|
16
21
|
)
|
|
17
22
|
from eth_typing import (
|
|
@@ -27,13 +32,10 @@ from flaky import (
|
|
|
27
32
|
from hexbytes import (
|
|
28
33
|
HexBytes,
|
|
29
34
|
)
|
|
35
|
+
import requests
|
|
30
36
|
|
|
31
|
-
from web3._utils.
|
|
32
|
-
|
|
33
|
-
)
|
|
34
|
-
from web3._utils.request import (
|
|
35
|
-
async_cache_and_return_session,
|
|
36
|
-
cache_and_return_session,
|
|
37
|
+
from web3._utils.http import (
|
|
38
|
+
DEFAULT_HTTP_TIMEOUT,
|
|
37
39
|
)
|
|
38
40
|
from web3.types import (
|
|
39
41
|
BlockData,
|
|
@@ -42,7 +44,9 @@ from web3.types import (
|
|
|
42
44
|
|
|
43
45
|
if TYPE_CHECKING:
|
|
44
46
|
from _pytest.monkeypatch import MonkeyPatch # noqa: F401
|
|
45
|
-
from aiohttp import
|
|
47
|
+
from aiohttp import ( # noqa: F401
|
|
48
|
+
ClientResponse,
|
|
49
|
+
)
|
|
46
50
|
from requests import Response # noqa: F401
|
|
47
51
|
|
|
48
52
|
from web3 import Web3 # noqa: F401
|
|
@@ -56,7 +60,44 @@ flaky_geth_dev_mining decorator for tests requiring a pending block
|
|
|
56
60
|
for the duration of the test. This behavior can be flaky
|
|
57
61
|
due to timing of the test running as a block is mined.
|
|
58
62
|
"""
|
|
59
|
-
flaky_geth_dev_mining = flaky(max_runs=3)
|
|
63
|
+
flaky_geth_dev_mining = flaky(max_runs=3, min_passes=1)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def flaky_with_xfail_on_exception(
|
|
67
|
+
reason: str,
|
|
68
|
+
exception: Union[Type[Exception], Tuple[Type[Exception], ...]],
|
|
69
|
+
max_runs: int = 3,
|
|
70
|
+
min_passes: int = 1,
|
|
71
|
+
) -> Callable[[Any], Any]:
|
|
72
|
+
"""
|
|
73
|
+
Some tests inconsistently fail hard with a particular exception and retrying
|
|
74
|
+
these tests often times does not get them "unstuck". If we've exhausted all flaky
|
|
75
|
+
retries and this expected exception is raised, `xfail` the test with the given
|
|
76
|
+
reason.
|
|
77
|
+
"""
|
|
78
|
+
runs = max_runs
|
|
79
|
+
|
|
80
|
+
def decorator(func: Any) -> Any:
|
|
81
|
+
@flaky(max_runs=max_runs, min_passes=min_passes)
|
|
82
|
+
@functools.wraps(func)
|
|
83
|
+
async def wrapper(self: Any, *args: Any, **kwargs: Any) -> Any:
|
|
84
|
+
nonlocal runs
|
|
85
|
+
try:
|
|
86
|
+
return await func(self, *args, **kwargs)
|
|
87
|
+
except exception:
|
|
88
|
+
# xfail the test only if the exception is raised and we have exhausted
|
|
89
|
+
# all flaky retries
|
|
90
|
+
if runs == 1:
|
|
91
|
+
pytest.xfail(reason)
|
|
92
|
+
runs -= 1
|
|
93
|
+
pytest.fail(f"xfailed but {runs} run(s) remaining with flaky...")
|
|
94
|
+
except Exception as e:
|
|
95
|
+
# let flaky handle it
|
|
96
|
+
raise e
|
|
97
|
+
|
|
98
|
+
return wrapper
|
|
99
|
+
|
|
100
|
+
return decorator
|
|
60
101
|
|
|
61
102
|
|
|
62
103
|
def assert_contains_log(
|
|
@@ -65,7 +106,7 @@ def assert_contains_log(
|
|
|
65
106
|
emitter_contract_address: ChecksumAddress,
|
|
66
107
|
txn_hash_with_log: HexStr,
|
|
67
108
|
) -> None:
|
|
68
|
-
assert len(result)
|
|
109
|
+
assert len(result) > 0
|
|
69
110
|
log_entry = result[0]
|
|
70
111
|
assert log_entry["blockNumber"] == block_with_txn_with_log["number"]
|
|
71
112
|
assert log_entry["blockHash"] == block_with_txn_with_log["hash"]
|
|
@@ -104,13 +145,13 @@ def mock_offchain_lookup_request_response(
|
|
|
104
145
|
|
|
105
146
|
# mock response only to specified url while validating appropriate fields
|
|
106
147
|
if url_from_args == mocked_request_url:
|
|
107
|
-
assert kwargs["timeout"] ==
|
|
148
|
+
assert kwargs["timeout"] == DEFAULT_HTTP_TIMEOUT
|
|
108
149
|
if http_method.upper() == "POST":
|
|
109
|
-
assert kwargs["
|
|
150
|
+
assert kwargs["json"] == {"data": calldata, "sender": sender}
|
|
110
151
|
return MockedResponse()
|
|
111
152
|
|
|
112
153
|
# else, make a normal request (no mocking)
|
|
113
|
-
session =
|
|
154
|
+
session = requests.Session()
|
|
114
155
|
return session.request(method=http_method.upper(), url=url_from_args, **kwargs)
|
|
115
156
|
|
|
116
157
|
monkeypatch.setattr(
|
|
@@ -154,16 +195,18 @@ def async_mock_offchain_lookup_request_response(
|
|
|
154
195
|
|
|
155
196
|
# mock response only to specified url while validating appropriate fields
|
|
156
197
|
if url_from_args == mocked_request_url:
|
|
157
|
-
assert kwargs["timeout"] == ClientTimeout(
|
|
158
|
-
if http_method.upper() == "
|
|
159
|
-
assert kwargs["
|
|
198
|
+
assert kwargs["timeout"] == ClientTimeout(DEFAULT_HTTP_TIMEOUT)
|
|
199
|
+
if http_method.upper() == "POST":
|
|
200
|
+
assert kwargs["json"] == {"data": calldata, "sender": sender}
|
|
160
201
|
return AsyncMockedResponse()
|
|
161
202
|
|
|
162
203
|
# else, make a normal request (no mocking)
|
|
163
|
-
session =
|
|
164
|
-
|
|
204
|
+
session = ClientSession()
|
|
205
|
+
response = await session.request(
|
|
165
206
|
method=http_method.upper(), url=url_from_args, **kwargs
|
|
166
207
|
)
|
|
208
|
+
await session.close()
|
|
209
|
+
return response
|
|
167
210
|
|
|
168
211
|
monkeypatch.setattr(
|
|
169
212
|
f"aiohttp.ClientSession.{http_method.lower()}", _mock_specific_request
|
|
@@ -176,20 +219,34 @@ class WebSocketMessageStreamMock:
|
|
|
176
219
|
def __init__(
|
|
177
220
|
self, messages: Collection[bytes] = None, raise_exception: Exception = None
|
|
178
221
|
) -> None:
|
|
179
|
-
self.
|
|
222
|
+
self.queue = asyncio.Queue() # type: ignore # py38 issue
|
|
223
|
+
for msg in messages or []:
|
|
224
|
+
self.queue.put_nowait(msg)
|
|
180
225
|
self.raise_exception = raise_exception
|
|
181
226
|
|
|
227
|
+
def __await__(self) -> Generator[Any, Any, "Self"]:
|
|
228
|
+
async def __async_init__() -> "Self":
|
|
229
|
+
return self
|
|
230
|
+
|
|
231
|
+
return __async_init__().__await__()
|
|
232
|
+
|
|
182
233
|
def __aiter__(self) -> "Self":
|
|
183
234
|
return self
|
|
184
235
|
|
|
185
236
|
async def __anext__(self) -> bytes:
|
|
237
|
+
return await self.queue.get()
|
|
238
|
+
|
|
239
|
+
async def recv(self) -> bytes:
|
|
186
240
|
if self.raise_exception:
|
|
187
241
|
raise self.raise_exception
|
|
242
|
+
return await self.queue.get()
|
|
188
243
|
|
|
189
|
-
|
|
190
|
-
|
|
244
|
+
@staticmethod
|
|
245
|
+
async def pong() -> Literal[False]:
|
|
246
|
+
return False
|
|
191
247
|
|
|
192
|
-
|
|
248
|
+
async def connect(self) -> None:
|
|
249
|
+
pass
|
|
193
250
|
|
|
194
251
|
async def send(self, data: bytes) -> None:
|
|
195
252
|
pass
|