web3 7.10.0__py3-none-any.whl → 7.11.1__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/exceptions.py +1 -1
- web3/_utils/batching.py +42 -1
- web3/_utils/contract_sources/contract_data/ambiguous_function_contract.py +3 -3
- 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 +7 -7
- 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/decorators.py +2 -2
- web3/_utils/encoding.py +8 -0
- web3/_utils/ens.py +9 -1
- web3/_utils/error_formatters_utils.py +17 -0
- web3/_utils/filters.py +39 -28
- web3/_utils/method_formatters.py +58 -7
- web3/_utils/module_testing/eth_module.py +218 -80
- web3/_utils/module_testing/module_testing_utils.py +0 -12
- web3/_utils/module_testing/persistent_connection_provider.py +3 -3
- web3/_utils/normalizers.py +1 -1
- web3/_utils/rpc_abi.py +5 -4
- web3/_utils/utility_methods.py +8 -6
- web3/eth/async_eth.py +4 -0
- web3/eth/eth.py +15 -2
- web3/method.py +10 -2
- web3/providers/async_base.py +5 -6
- web3/providers/base.py +5 -5
- web3/providers/eth_tester/middleware.py +20 -0
- web3/providers/ipc.py +2 -0
- web3/providers/legacy_websocket.py +2 -0
- web3/providers/persistent/async_ipc.py +3 -1
- web3/providers/persistent/persistent.py +15 -10
- web3/providers/persistent/request_processor.py +10 -1
- web3/providers/persistent/subscription_manager.py +1 -0
- web3/providers/rpc/async_rpc.py +2 -0
- web3/providers/rpc/rpc.py +2 -0
- web3/types.py +27 -0
- web3/utils/abi.py +1 -1
- web3/utils/caching.py +8 -5
- {web3-7.10.0.dist-info → web3-7.11.1.dist-info}/METADATA +56 -69
- {web3-7.10.0.dist-info → web3-7.11.1.dist-info}/RECORD +58 -58
- {web3-7.10.0.dist-info → web3-7.11.1.dist-info}/WHEEL +1 -1
- {web3-7.10.0.dist-info/licenses → web3-7.11.1.dist-info}/LICENSE +0 -0
- {web3-7.10.0.dist-info → web3-7.11.1.dist-info}/top_level.txt +0 -0
|
@@ -57,7 +57,6 @@ from web3._utils.method_formatters import (
|
|
|
57
57
|
from web3._utils.module_testing.module_testing_utils import (
|
|
58
58
|
assert_contains_log,
|
|
59
59
|
async_mock_offchain_lookup_request_response,
|
|
60
|
-
flaky_geth_dev_mining,
|
|
61
60
|
mock_offchain_lookup_request_response,
|
|
62
61
|
)
|
|
63
62
|
from web3._utils.module_testing.utils import (
|
|
@@ -115,27 +114,6 @@ OFFCHAIN_LOOKUP_RETURN_DATA = "0000000000000000000000000000000000000000000000000
|
|
|
115
114
|
# "web3py" as an abi-encoded string
|
|
116
115
|
WEB3PY_AS_HEXBYTES = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000067765623370790000000000000000000000000000000000000000000000000000" # noqa: E501
|
|
117
116
|
|
|
118
|
-
RLP_ACCESS_LIST = [
|
|
119
|
-
(
|
|
120
|
-
"0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae",
|
|
121
|
-
(
|
|
122
|
-
"0x0000000000000000000000000000000000000000000000000000000000000003",
|
|
123
|
-
"0x0000000000000000000000000000000000000000000000000000000000000007",
|
|
124
|
-
),
|
|
125
|
-
),
|
|
126
|
-
("0xbb9bc244d798123fde783fcc1c72d3bb8c189413", ()),
|
|
127
|
-
]
|
|
128
|
-
|
|
129
|
-
RPC_ACCESS_LIST = [
|
|
130
|
-
{
|
|
131
|
-
"address": "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae",
|
|
132
|
-
"storageKeys": (
|
|
133
|
-
"0x0000000000000000000000000000000000000000000000000000000000000003",
|
|
134
|
-
"0x0000000000000000000000000000000000000000000000000000000000000007",
|
|
135
|
-
),
|
|
136
|
-
},
|
|
137
|
-
{"address": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413", "storageKeys": ()},
|
|
138
|
-
]
|
|
139
117
|
|
|
140
118
|
if TYPE_CHECKING:
|
|
141
119
|
from _pytest.monkeypatch import MonkeyPatch # noqa: F401
|
|
@@ -454,9 +432,6 @@ class AsyncEthModuleTest:
|
|
|
454
432
|
assert result["tx"]["nonce"] == txn_params["nonce"]
|
|
455
433
|
|
|
456
434
|
@pytest.mark.asyncio
|
|
457
|
-
@pytest.mark.xfail(
|
|
458
|
-
reason="async name_to_address_middleware has not been implemented yet"
|
|
459
|
-
)
|
|
460
435
|
async def test_async_eth_sign_transaction_ens_names(
|
|
461
436
|
self, async_w3: "AsyncWeb3", async_keyfile_account_address: ChecksumAddress
|
|
462
437
|
) -> None:
|
|
@@ -638,9 +613,6 @@ class AsyncEthModuleTest:
|
|
|
638
613
|
assert txn["value"] == 1
|
|
639
614
|
assert txn["gas"] == 21000
|
|
640
615
|
|
|
641
|
-
block = await async_w3.eth.get_block("latest")
|
|
642
|
-
assert txn["maxFeePerGas"] == maxPriorityFeePerGas + 2 * block["baseFeePerGas"]
|
|
643
|
-
|
|
644
616
|
@pytest.mark.asyncio
|
|
645
617
|
async def test_eth_send_transaction_max_fee_less_than_tip(
|
|
646
618
|
self,
|
|
@@ -744,6 +716,97 @@ class AsyncEthModuleTest:
|
|
|
744
716
|
# clean up
|
|
745
717
|
async_w3.middleware_onion.remove("signing")
|
|
746
718
|
|
|
719
|
+
@pytest.mark.asyncio
|
|
720
|
+
async def test_async_sign_authorization_and_send_raw_set_code_transaction(
|
|
721
|
+
self,
|
|
722
|
+
async_w3: "AsyncWeb3",
|
|
723
|
+
keyfile_account_pkey: HexStr,
|
|
724
|
+
async_math_contract: "AsyncContract",
|
|
725
|
+
) -> None:
|
|
726
|
+
# TODO: remove blockNumber block_id from eth_call and eth_getCode calls once
|
|
727
|
+
# geth behavior for "latest" seems stable again.
|
|
728
|
+
keyfile_account = async_w3.eth.account.from_key(keyfile_account_pkey)
|
|
729
|
+
|
|
730
|
+
chain_id = await async_w3.eth.chain_id
|
|
731
|
+
nonce = await async_w3.eth.get_transaction_count(keyfile_account.address)
|
|
732
|
+
|
|
733
|
+
auth = {
|
|
734
|
+
"chainId": chain_id,
|
|
735
|
+
"address": async_math_contract.address,
|
|
736
|
+
"nonce": nonce + 1,
|
|
737
|
+
}
|
|
738
|
+
signed_auth = keyfile_account.sign_authorization(auth)
|
|
739
|
+
|
|
740
|
+
# get current math counter and increase it only in the delegation by n
|
|
741
|
+
math_counter = await async_math_contract.functions.counter().call()
|
|
742
|
+
data = async_math_contract.encode_abi("incrementCounter", [math_counter + 1337])
|
|
743
|
+
txn: TxParams = {
|
|
744
|
+
"chainId": chain_id,
|
|
745
|
+
"to": keyfile_account.address,
|
|
746
|
+
"value": Wei(0),
|
|
747
|
+
"gas": 200_000,
|
|
748
|
+
"nonce": nonce,
|
|
749
|
+
"maxPriorityFeePerGas": Wei(10**9),
|
|
750
|
+
"maxFeePerGas": Wei(10**9),
|
|
751
|
+
"data": data,
|
|
752
|
+
"authorizationList": [signed_auth],
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
signed = keyfile_account.sign_transaction(txn)
|
|
756
|
+
tx_hash = await async_w3.eth.send_raw_transaction(signed.raw_transaction)
|
|
757
|
+
get_tx = await async_w3.eth.get_transaction(tx_hash)
|
|
758
|
+
tx_receipt = await async_w3.eth.wait_for_transaction_receipt(
|
|
759
|
+
tx_hash, timeout=10
|
|
760
|
+
)
|
|
761
|
+
|
|
762
|
+
code = await async_w3.eth.get_code(
|
|
763
|
+
keyfile_account.address, block_identifier=tx_receipt["blockNumber"]
|
|
764
|
+
)
|
|
765
|
+
assert code.to_0x_hex() == f"0xef0100{async_math_contract.address[2:].lower()}"
|
|
766
|
+
delegated = async_w3.eth.contract(
|
|
767
|
+
address=keyfile_account.address, abi=async_math_contract.abi
|
|
768
|
+
)
|
|
769
|
+
|
|
770
|
+
# assert the math counter is increased by 1337 only in delegated acct
|
|
771
|
+
assert await async_math_contract.functions.counter().call() == math_counter
|
|
772
|
+
delegated_call = await delegated.functions.counter().call(
|
|
773
|
+
block_identifier=tx_receipt["blockNumber"]
|
|
774
|
+
)
|
|
775
|
+
assert delegated_call == math_counter + 1337
|
|
776
|
+
|
|
777
|
+
assert len(get_tx["authorizationList"]) == 1
|
|
778
|
+
get_auth = get_tx["authorizationList"][0]
|
|
779
|
+
assert get_auth["chainId"] == chain_id
|
|
780
|
+
assert get_auth["address"] == async_math_contract.address
|
|
781
|
+
assert get_auth["nonce"] == nonce + 1
|
|
782
|
+
assert isinstance(get_auth["yParity"], int)
|
|
783
|
+
assert isinstance(get_auth["r"], HexBytes)
|
|
784
|
+
assert isinstance(get_auth["s"], HexBytes)
|
|
785
|
+
|
|
786
|
+
# reset code
|
|
787
|
+
reset_auth = {
|
|
788
|
+
"chainId": chain_id,
|
|
789
|
+
"address": "0x" + ("00" * 20),
|
|
790
|
+
"nonce": nonce + 3,
|
|
791
|
+
}
|
|
792
|
+
signed_reset_auth = keyfile_account.sign_authorization(reset_auth)
|
|
793
|
+
new_txn = dict(txn)
|
|
794
|
+
new_txn["authorizationList"] = [signed_reset_auth]
|
|
795
|
+
new_txn["nonce"] = nonce + 2
|
|
796
|
+
|
|
797
|
+
signed_reset = keyfile_account.sign_transaction(new_txn)
|
|
798
|
+
reset_tx_hash = await async_w3.eth.send_raw_transaction(
|
|
799
|
+
signed_reset.raw_transaction
|
|
800
|
+
)
|
|
801
|
+
reset_tx_receipt = await async_w3.eth.wait_for_transaction_receipt(
|
|
802
|
+
reset_tx_hash, timeout=10
|
|
803
|
+
)
|
|
804
|
+
|
|
805
|
+
reset_code = await async_w3.eth.get_code(
|
|
806
|
+
keyfile_account.address, reset_tx_receipt["blockNumber"]
|
|
807
|
+
)
|
|
808
|
+
assert reset_code == HexBytes("0x")
|
|
809
|
+
|
|
747
810
|
@pytest.mark.asyncio
|
|
748
811
|
async def test_GasPriceStrategyMiddleware(
|
|
749
812
|
self,
|
|
@@ -1763,7 +1826,6 @@ class AsyncEthModuleTest:
|
|
|
1763
1826
|
assert isinstance(effective_gas_price, int)
|
|
1764
1827
|
assert effective_gas_price > 0
|
|
1765
1828
|
|
|
1766
|
-
@flaky_geth_dev_mining
|
|
1767
1829
|
@pytest.mark.asyncio
|
|
1768
1830
|
async def test_async_eth_get_transaction_receipt_unmined(
|
|
1769
1831
|
self,
|
|
@@ -1829,8 +1891,11 @@ class AsyncEthModuleTest:
|
|
|
1829
1891
|
assert isinstance(effective_gas_price, int)
|
|
1830
1892
|
assert effective_gas_price > 0
|
|
1831
1893
|
|
|
1832
|
-
@flaky_geth_dev_mining
|
|
1833
1894
|
@pytest.mark.asyncio
|
|
1895
|
+
# TODO: Remove xfail when issue has been identified
|
|
1896
|
+
@pytest.mark.xfail(
|
|
1897
|
+
reason="latest geth seems to cause this to be flaky", strict=False
|
|
1898
|
+
)
|
|
1834
1899
|
async def test_async_eth_wait_for_transaction_receipt_unmined(
|
|
1835
1900
|
self,
|
|
1836
1901
|
async_w3: "AsyncWeb3",
|
|
@@ -2086,7 +2151,6 @@ class AsyncEthModuleTest:
|
|
|
2086
2151
|
assert bytes(slot_4[:4]) == b"four"
|
|
2087
2152
|
|
|
2088
2153
|
@pytest.mark.asyncio
|
|
2089
|
-
@pytest.mark.xfail
|
|
2090
2154
|
async def test_async_eth_get_storage_at_ens_name(
|
|
2091
2155
|
self, async_w3: "AsyncWeb3", async_storage_contract: "AsyncContract"
|
|
2092
2156
|
) -> None:
|
|
@@ -2172,19 +2236,31 @@ class AsyncEthModuleTest:
|
|
|
2172
2236
|
async def test_eth_getUncleCountByBlockHash(
|
|
2173
2237
|
self, async_w3: "AsyncWeb3", async_empty_block: BlockData
|
|
2174
2238
|
) -> None:
|
|
2175
|
-
|
|
2239
|
+
with pytest.warns(
|
|
2240
|
+
DeprecationWarning,
|
|
2241
|
+
match=r"get_uncle_count is deprecated: all get_uncle\* "
|
|
2242
|
+
r"methods will be removed in v8",
|
|
2243
|
+
):
|
|
2244
|
+
uncle_count = await async_w3.eth.get_uncle_count(async_empty_block["hash"])
|
|
2176
2245
|
|
|
2177
|
-
|
|
2178
|
-
|
|
2246
|
+
assert is_integer(uncle_count)
|
|
2247
|
+
assert uncle_count == 0
|
|
2179
2248
|
|
|
2180
2249
|
@pytest.mark.asyncio
|
|
2181
2250
|
async def test_eth_getUncleCountByBlockNumber(
|
|
2182
2251
|
self, async_w3: "AsyncWeb3", async_empty_block: BlockData
|
|
2183
2252
|
) -> None:
|
|
2184
|
-
|
|
2253
|
+
with pytest.warns(
|
|
2254
|
+
DeprecationWarning,
|
|
2255
|
+
match=r"get_uncle_count is deprecated: all get_uncle\* "
|
|
2256
|
+
r"methods will be removed in v8",
|
|
2257
|
+
):
|
|
2258
|
+
uncle_count = await async_w3.eth.get_uncle_count(
|
|
2259
|
+
async_empty_block["number"]
|
|
2260
|
+
)
|
|
2185
2261
|
|
|
2186
|
-
|
|
2187
|
-
|
|
2262
|
+
assert is_integer(uncle_count)
|
|
2263
|
+
assert uncle_count == 0
|
|
2188
2264
|
|
|
2189
2265
|
@pytest.mark.asyncio
|
|
2190
2266
|
async def test_eth_getBlockTransactionCountByNumber_block_with_txn(
|
|
@@ -2238,9 +2314,6 @@ class AsyncEthModuleTest:
|
|
|
2238
2314
|
assert new_signature != signature
|
|
2239
2315
|
|
|
2240
2316
|
@pytest.mark.asyncio
|
|
2241
|
-
@pytest.mark.xfail(
|
|
2242
|
-
reason="Async middleware to convert ENS names to addresses is missing"
|
|
2243
|
-
)
|
|
2244
2317
|
async def test_async_eth_sign_ens_names(
|
|
2245
2318
|
self,
|
|
2246
2319
|
async_w3: "AsyncWeb3",
|
|
@@ -2255,7 +2328,6 @@ class AsyncEthModuleTest:
|
|
|
2255
2328
|
assert is_bytes(signature)
|
|
2256
2329
|
assert len(signature) == 32 + 32 + 1
|
|
2257
2330
|
|
|
2258
|
-
@flaky_geth_dev_mining
|
|
2259
2331
|
@pytest.mark.asyncio
|
|
2260
2332
|
async def test_async_eth_replace_transaction_legacy(
|
|
2261
2333
|
self,
|
|
@@ -2285,7 +2357,6 @@ class AsyncEthModuleTest:
|
|
|
2285
2357
|
assert replace_txn["gas"] == 21000
|
|
2286
2358
|
assert replace_txn["gasPrice"] == txn_params["gasPrice"]
|
|
2287
2359
|
|
|
2288
|
-
@flaky_geth_dev_mining
|
|
2289
2360
|
@pytest.mark.asyncio
|
|
2290
2361
|
async def test_async_eth_replace_transaction(
|
|
2291
2362
|
self,
|
|
@@ -2322,7 +2393,6 @@ class AsyncEthModuleTest:
|
|
|
2322
2393
|
assert replace_txn["maxFeePerGas"] == three_gwei_in_wei
|
|
2323
2394
|
assert replace_txn["maxPriorityFeePerGas"] == two_gwei_in_wei
|
|
2324
2395
|
|
|
2325
|
-
@flaky_geth_dev_mining
|
|
2326
2396
|
@pytest.mark.asyncio
|
|
2327
2397
|
async def test_async_eth_replace_transaction_underpriced(
|
|
2328
2398
|
self,
|
|
@@ -2349,7 +2419,6 @@ class AsyncEthModuleTest:
|
|
|
2349
2419
|
with pytest.raises(Web3RPCError, match="replacement transaction underpriced"):
|
|
2350
2420
|
await async_w3.eth.replace_transaction(txn_hash, txn_params)
|
|
2351
2421
|
|
|
2352
|
-
@flaky_geth_dev_mining
|
|
2353
2422
|
@pytest.mark.asyncio
|
|
2354
2423
|
async def test_async_eth_replace_transaction_non_existing_transaction(
|
|
2355
2424
|
self,
|
|
@@ -2372,7 +2441,6 @@ class AsyncEthModuleTest:
|
|
|
2372
2441
|
txn_params,
|
|
2373
2442
|
)
|
|
2374
2443
|
|
|
2375
|
-
@flaky_geth_dev_mining
|
|
2376
2444
|
@pytest.mark.asyncio
|
|
2377
2445
|
async def test_async_eth_replace_transaction_already_mined(
|
|
2378
2446
|
self,
|
|
@@ -2395,7 +2463,6 @@ class AsyncEthModuleTest:
|
|
|
2395
2463
|
with pytest.raises(Web3ValueError, match="Supplied transaction with hash"):
|
|
2396
2464
|
await async_w3.eth.replace_transaction(txn_hash, txn_params)
|
|
2397
2465
|
|
|
2398
|
-
@flaky_geth_dev_mining
|
|
2399
2466
|
@pytest.mark.asyncio
|
|
2400
2467
|
async def test_async_eth_replace_transaction_incorrect_nonce(
|
|
2401
2468
|
self, async_w3: "AsyncWeb3", async_keyfile_account_address: ChecksumAddress
|
|
@@ -2417,7 +2484,6 @@ class AsyncEthModuleTest:
|
|
|
2417
2484
|
with pytest.raises(Web3ValueError):
|
|
2418
2485
|
await async_w3.eth.replace_transaction(txn_hash, txn_params)
|
|
2419
2486
|
|
|
2420
|
-
@flaky_geth_dev_mining
|
|
2421
2487
|
@pytest.mark.asyncio
|
|
2422
2488
|
async def test_async_eth_replace_transaction_gas_price_too_low(
|
|
2423
2489
|
self,
|
|
@@ -2437,7 +2503,6 @@ class AsyncEthModuleTest:
|
|
|
2437
2503
|
with pytest.raises(Web3ValueError):
|
|
2438
2504
|
await async_w3.eth.replace_transaction(txn_hash, txn_params)
|
|
2439
2505
|
|
|
2440
|
-
@flaky_geth_dev_mining
|
|
2441
2506
|
@pytest.mark.asyncio
|
|
2442
2507
|
async def test_async_eth_replace_transaction_gas_price_defaulting_minimum(
|
|
2443
2508
|
self, async_w3: "AsyncWeb3", async_keyfile_account_address: ChecksumAddress
|
|
@@ -2461,7 +2526,6 @@ class AsyncEthModuleTest:
|
|
|
2461
2526
|
gas_price * 1.125
|
|
2462
2527
|
) # minimum gas price
|
|
2463
2528
|
|
|
2464
|
-
@flaky_geth_dev_mining
|
|
2465
2529
|
@pytest.mark.asyncio
|
|
2466
2530
|
async def test_async_eth_replace_transaction_gas_price_defaulting_strategy_higher(
|
|
2467
2531
|
self, async_w3: "AsyncWeb3", async_keyfile_account_address: ChecksumAddress
|
|
@@ -2490,7 +2554,6 @@ class AsyncEthModuleTest:
|
|
|
2490
2554
|
) # Strategy provides higher gas price
|
|
2491
2555
|
async_w3.eth.set_gas_price_strategy(None) # reset strategy
|
|
2492
2556
|
|
|
2493
|
-
@flaky_geth_dev_mining
|
|
2494
2557
|
@pytest.mark.asyncio
|
|
2495
2558
|
async def test_async_eth_replace_transaction_gas_price_defaulting_strategy_lower(
|
|
2496
2559
|
self, async_w3: "AsyncWeb3", async_keyfile_account_address: ChecksumAddress
|
|
@@ -2682,13 +2745,15 @@ class EthModuleTest:
|
|
|
2682
2745
|
assert balance >= 0
|
|
2683
2746
|
|
|
2684
2747
|
def test_eth_get_balance_with_block_identifier(self, w3: "Web3") -> None:
|
|
2685
|
-
|
|
2686
|
-
|
|
2748
|
+
genesis_block = w3.eth.get_block(0)
|
|
2749
|
+
miner_address = genesis_block["miner"]
|
|
2750
|
+
|
|
2751
|
+
balance_genesis = w3.eth.get_balance(miner_address, 0)
|
|
2687
2752
|
later_balance = w3.eth.get_balance(miner_address, "latest")
|
|
2688
2753
|
|
|
2689
|
-
assert is_integer(
|
|
2754
|
+
assert is_integer(balance_genesis)
|
|
2690
2755
|
assert is_integer(later_balance)
|
|
2691
|
-
assert later_balance
|
|
2756
|
+
assert later_balance != balance_genesis
|
|
2692
2757
|
|
|
2693
2758
|
@pytest.mark.parametrize(
|
|
2694
2759
|
"address, expect_success",
|
|
@@ -2807,18 +2872,24 @@ class EthModuleTest:
|
|
|
2807
2872
|
def test_eth_getUncleCountByBlockHash(
|
|
2808
2873
|
self, w3: "Web3", empty_block: BlockData
|
|
2809
2874
|
) -> None:
|
|
2810
|
-
|
|
2875
|
+
with pytest.warns(
|
|
2876
|
+
DeprecationWarning, match=r"All get_uncle\* methods have been deprecated"
|
|
2877
|
+
):
|
|
2878
|
+
uncle_count = w3.eth.get_uncle_count(empty_block["hash"])
|
|
2811
2879
|
|
|
2812
|
-
|
|
2813
|
-
|
|
2880
|
+
assert is_integer(uncle_count)
|
|
2881
|
+
assert uncle_count == 0
|
|
2814
2882
|
|
|
2815
2883
|
def test_eth_getUncleCountByBlockNumber(
|
|
2816
2884
|
self, w3: "Web3", empty_block: BlockData
|
|
2817
2885
|
) -> None:
|
|
2818
|
-
|
|
2886
|
+
with pytest.warns(
|
|
2887
|
+
DeprecationWarning, match=r"All get_uncle\* methods have been deprecated"
|
|
2888
|
+
):
|
|
2889
|
+
uncle_count = w3.eth.get_uncle_count(empty_block["number"])
|
|
2819
2890
|
|
|
2820
|
-
|
|
2821
|
-
|
|
2891
|
+
assert is_integer(uncle_count)
|
|
2892
|
+
assert uncle_count == 0
|
|
2822
2893
|
|
|
2823
2894
|
def test_eth_get_code(
|
|
2824
2895
|
self, w3: "Web3", math_contract_address: ChecksumAddress
|
|
@@ -3464,7 +3535,6 @@ class EthModuleTest:
|
|
|
3464
3535
|
assert txn["gasPrice"] == two_gwei_in_wei
|
|
3465
3536
|
w3.eth.set_gas_price_strategy(None) # reset strategy
|
|
3466
3537
|
|
|
3467
|
-
@flaky_geth_dev_mining
|
|
3468
3538
|
def test_eth_replace_transaction_legacy(
|
|
3469
3539
|
self, w3: "Web3", keyfile_account_address_dual_type: ChecksumAddress
|
|
3470
3540
|
) -> None:
|
|
@@ -3493,7 +3563,6 @@ class EthModuleTest:
|
|
|
3493
3563
|
assert replace_txn["gas"] == 21000
|
|
3494
3564
|
assert replace_txn["gasPrice"] == txn_params["gasPrice"]
|
|
3495
3565
|
|
|
3496
|
-
@flaky_geth_dev_mining
|
|
3497
3566
|
def test_eth_replace_transaction(
|
|
3498
3567
|
self, w3: "Web3", keyfile_account_address_dual_type: ChecksumAddress
|
|
3499
3568
|
) -> None:
|
|
@@ -3527,7 +3596,6 @@ class EthModuleTest:
|
|
|
3527
3596
|
assert replace_txn["maxFeePerGas"] == three_gwei_in_wei
|
|
3528
3597
|
assert replace_txn["maxPriorityFeePerGas"] == two_gwei_in_wei
|
|
3529
3598
|
|
|
3530
|
-
@flaky_geth_dev_mining
|
|
3531
3599
|
def test_eth_replace_transaction_underpriced(
|
|
3532
3600
|
self, w3: "Web3", keyfile_account_address_dual_type: ChecksumAddress
|
|
3533
3601
|
) -> None:
|
|
@@ -3551,7 +3619,6 @@ class EthModuleTest:
|
|
|
3551
3619
|
with pytest.raises(Web3RPCError, match="replacement transaction underpriced"):
|
|
3552
3620
|
w3.eth.replace_transaction(txn_hash, txn_params)
|
|
3553
3621
|
|
|
3554
|
-
@flaky_geth_dev_mining
|
|
3555
3622
|
def test_eth_replace_transaction_non_existing_transaction(
|
|
3556
3623
|
self, w3: "Web3", keyfile_account_address_dual_type: ChecksumAddress
|
|
3557
3624
|
) -> None:
|
|
@@ -3571,7 +3638,6 @@ class EthModuleTest:
|
|
|
3571
3638
|
txn_params,
|
|
3572
3639
|
)
|
|
3573
3640
|
|
|
3574
|
-
@flaky_geth_dev_mining
|
|
3575
3641
|
def test_eth_replace_transaction_already_mined(
|
|
3576
3642
|
self, w3: "Web3", keyfile_account_address_dual_type: ChecksumAddress
|
|
3577
3643
|
) -> None:
|
|
@@ -3591,7 +3657,6 @@ class EthModuleTest:
|
|
|
3591
3657
|
with pytest.raises(Web3ValueError, match="Supplied transaction with hash"):
|
|
3592
3658
|
w3.eth.replace_transaction(txn_hash, txn_params)
|
|
3593
3659
|
|
|
3594
|
-
@flaky_geth_dev_mining
|
|
3595
3660
|
def test_eth_replace_transaction_incorrect_nonce(
|
|
3596
3661
|
self, w3: "Web3", keyfile_account_address: ChecksumAddress
|
|
3597
3662
|
) -> None:
|
|
@@ -3612,7 +3677,6 @@ class EthModuleTest:
|
|
|
3612
3677
|
with pytest.raises(Web3ValueError):
|
|
3613
3678
|
w3.eth.replace_transaction(txn_hash, txn_params)
|
|
3614
3679
|
|
|
3615
|
-
@flaky_geth_dev_mining
|
|
3616
3680
|
def test_eth_replace_transaction_gas_price_too_low(
|
|
3617
3681
|
self, w3: "Web3", keyfile_account_address_dual_type: ChecksumAddress
|
|
3618
3682
|
) -> None:
|
|
@@ -3629,7 +3693,6 @@ class EthModuleTest:
|
|
|
3629
3693
|
with pytest.raises(Web3ValueError):
|
|
3630
3694
|
w3.eth.replace_transaction(txn_hash, txn_params)
|
|
3631
3695
|
|
|
3632
|
-
@flaky_geth_dev_mining
|
|
3633
3696
|
def test_eth_replace_transaction_gas_price_defaulting_minimum(
|
|
3634
3697
|
self, w3: "Web3", keyfile_account_address: ChecksumAddress
|
|
3635
3698
|
) -> None:
|
|
@@ -3652,7 +3715,6 @@ class EthModuleTest:
|
|
|
3652
3715
|
gas_price * 1.125
|
|
3653
3716
|
) # minimum gas price
|
|
3654
3717
|
|
|
3655
|
-
@flaky_geth_dev_mining
|
|
3656
3718
|
def test_eth_replace_transaction_gas_price_defaulting_strategy_higher(
|
|
3657
3719
|
self, w3: "Web3", keyfile_account_address: ChecksumAddress
|
|
3658
3720
|
) -> None:
|
|
@@ -3680,7 +3742,6 @@ class EthModuleTest:
|
|
|
3680
3742
|
) # Strategy provides higher gas price
|
|
3681
3743
|
w3.eth.set_gas_price_strategy(None) # reset strategy
|
|
3682
3744
|
|
|
3683
|
-
@flaky_geth_dev_mining
|
|
3684
3745
|
def test_eth_replace_transaction_gas_price_defaulting_strategy_lower(
|
|
3685
3746
|
self, w3: "Web3", keyfile_account_address: ChecksumAddress
|
|
3686
3747
|
) -> None:
|
|
@@ -3806,6 +3867,93 @@ class EthModuleTest:
|
|
|
3806
3867
|
# cleanup
|
|
3807
3868
|
w3.middleware_onion.remove("signing")
|
|
3808
3869
|
|
|
3870
|
+
def test_sign_authorization_and_send_raw_set_code_transaction(
|
|
3871
|
+
self, w3: "Web3", keyfile_account_pkey: HexStr, math_contract: "Contract"
|
|
3872
|
+
) -> None:
|
|
3873
|
+
# TODO: remove blockNumber block_id from eth_call and eth_getCode calls once
|
|
3874
|
+
# geth behavior for "latest" seems stable again.
|
|
3875
|
+
keyfile_account = w3.eth.account.from_key(keyfile_account_pkey)
|
|
3876
|
+
|
|
3877
|
+
chain_id = w3.eth.chain_id
|
|
3878
|
+
nonce = w3.eth.get_transaction_count(keyfile_account.address)
|
|
3879
|
+
|
|
3880
|
+
auth = {
|
|
3881
|
+
"chainId": chain_id,
|
|
3882
|
+
"address": math_contract.address,
|
|
3883
|
+
"nonce": nonce + 1,
|
|
3884
|
+
}
|
|
3885
|
+
signed_auth = keyfile_account.sign_authorization(auth)
|
|
3886
|
+
|
|
3887
|
+
# get current math counter and increase it only in the delegation by n
|
|
3888
|
+
math_counter = math_contract.functions.counter().call()
|
|
3889
|
+
data = math_contract.encode_abi("incrementCounter", [math_counter + 1337])
|
|
3890
|
+
txn: TxParams = {
|
|
3891
|
+
"chainId": chain_id,
|
|
3892
|
+
"to": keyfile_account.address,
|
|
3893
|
+
"value": Wei(0),
|
|
3894
|
+
"gas": 200_000,
|
|
3895
|
+
"nonce": nonce,
|
|
3896
|
+
"maxPriorityFeePerGas": Wei(10**9),
|
|
3897
|
+
"maxFeePerGas": Wei(10**9),
|
|
3898
|
+
"data": data,
|
|
3899
|
+
"authorizationList": [signed_auth],
|
|
3900
|
+
}
|
|
3901
|
+
|
|
3902
|
+
signed = keyfile_account.sign_transaction(txn)
|
|
3903
|
+
tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)
|
|
3904
|
+
get_tx = w3.eth.get_transaction(tx_hash)
|
|
3905
|
+
receipt = w3.eth.wait_for_transaction_receipt(tx_hash, timeout=10)
|
|
3906
|
+
|
|
3907
|
+
code = w3.eth.get_code(
|
|
3908
|
+
keyfile_account.address, block_identifier=receipt["blockNumber"]
|
|
3909
|
+
)
|
|
3910
|
+
assert code.to_0x_hex() == f"0xef0100{math_contract.address[2:].lower()}"
|
|
3911
|
+
delegated = w3.eth.contract(
|
|
3912
|
+
address=keyfile_account.address, abi=math_contract.abi
|
|
3913
|
+
)
|
|
3914
|
+
# assert the math counter is increased by 1337 only in delegated acct
|
|
3915
|
+
assert (
|
|
3916
|
+
math_contract.functions.counter().call(
|
|
3917
|
+
block_identifier=receipt["blockNumber"]
|
|
3918
|
+
)
|
|
3919
|
+
== math_counter
|
|
3920
|
+
)
|
|
3921
|
+
assert (
|
|
3922
|
+
delegated.functions.counter().call(block_identifier=receipt["blockNumber"])
|
|
3923
|
+
== math_counter + 1337
|
|
3924
|
+
)
|
|
3925
|
+
|
|
3926
|
+
assert len(get_tx["authorizationList"]) == 1
|
|
3927
|
+
get_auth = get_tx["authorizationList"][0]
|
|
3928
|
+
assert get_auth["chainId"] == chain_id
|
|
3929
|
+
assert get_auth["address"] == math_contract.address
|
|
3930
|
+
assert get_auth["nonce"] == nonce + 1
|
|
3931
|
+
assert isinstance(get_auth["yParity"], int)
|
|
3932
|
+
assert isinstance(get_auth["r"], HexBytes)
|
|
3933
|
+
assert isinstance(get_auth["s"], HexBytes)
|
|
3934
|
+
|
|
3935
|
+
# reset storage value and code
|
|
3936
|
+
reset_auth = {
|
|
3937
|
+
"chainId": chain_id,
|
|
3938
|
+
"address": "0x" + ("00" * 20),
|
|
3939
|
+
"nonce": nonce + 3,
|
|
3940
|
+
}
|
|
3941
|
+
signed_reset_auth = keyfile_account.sign_authorization(reset_auth)
|
|
3942
|
+
new_txn = dict(txn)
|
|
3943
|
+
new_txn["authorizationList"] = [signed_reset_auth]
|
|
3944
|
+
new_txn["nonce"] = nonce + 2
|
|
3945
|
+
|
|
3946
|
+
signed_reset = keyfile_account.sign_transaction(new_txn)
|
|
3947
|
+
reset_tx_hash = w3.eth.send_raw_transaction(signed_reset.raw_transaction)
|
|
3948
|
+
reset_tx_receipt = w3.eth.wait_for_transaction_receipt(
|
|
3949
|
+
reset_tx_hash, timeout=10
|
|
3950
|
+
)
|
|
3951
|
+
|
|
3952
|
+
reset_code = w3.eth.get_code(
|
|
3953
|
+
keyfile_account.address, block_identifier=reset_tx_receipt["blockNumber"]
|
|
3954
|
+
)
|
|
3955
|
+
assert reset_code == HexBytes("0x")
|
|
3956
|
+
|
|
3809
3957
|
def test_eth_call(self, w3: "Web3", math_contract: "Contract") -> None:
|
|
3810
3958
|
txn_params = math_contract._prepare_transaction(
|
|
3811
3959
|
abi_element_identifier="add",
|
|
@@ -4514,7 +4662,6 @@ class EthModuleTest:
|
|
|
4514
4662
|
assert isinstance(effective_gas_price, int)
|
|
4515
4663
|
assert effective_gas_price > 0
|
|
4516
4664
|
|
|
4517
|
-
@flaky_geth_dev_mining
|
|
4518
4665
|
def test_eth_get_transaction_receipt_unmined(
|
|
4519
4666
|
self, w3: "Web3", keyfile_account_address_dual_type: ChecksumAddress
|
|
4520
4667
|
) -> None:
|
|
@@ -4572,7 +4719,6 @@ class EthModuleTest:
|
|
|
4572
4719
|
assert isinstance(effective_gas_price, int)
|
|
4573
4720
|
assert effective_gas_price > 0
|
|
4574
4721
|
|
|
4575
|
-
@flaky_geth_dev_mining
|
|
4576
4722
|
def test_eth_wait_for_transaction_receipt_unmined(
|
|
4577
4723
|
self, w3: "Web3", keyfile_account_address_dual_type: ChecksumAddress
|
|
4578
4724
|
) -> None:
|
|
@@ -4617,14 +4763,6 @@ class EthModuleTest:
|
|
|
4617
4763
|
assert log_entry["transactionIndex"] == 0
|
|
4618
4764
|
assert log_entry["transactionHash"] == HexBytes(txn_hash_with_log)
|
|
4619
4765
|
|
|
4620
|
-
def test_eth_getUncleByBlockHashAndIndex(self, w3: "Web3") -> None:
|
|
4621
|
-
# TODO: how do we make uncles....
|
|
4622
|
-
pass
|
|
4623
|
-
|
|
4624
|
-
def test_eth_getUncleByBlockNumberAndIndex(self, w3: "Web3") -> None:
|
|
4625
|
-
# TODO: how do we make uncles....
|
|
4626
|
-
pass
|
|
4627
|
-
|
|
4628
4766
|
def test_eth_new_filter(self, w3: "Web3") -> None:
|
|
4629
4767
|
filter = w3.eth.filter({})
|
|
4630
4768
|
|
|
@@ -21,9 +21,6 @@ from eth_typing import (
|
|
|
21
21
|
from eth_utils import (
|
|
22
22
|
is_same_address,
|
|
23
23
|
)
|
|
24
|
-
from flaky import (
|
|
25
|
-
flaky,
|
|
26
|
-
)
|
|
27
24
|
from hexbytes import (
|
|
28
25
|
HexBytes,
|
|
29
26
|
)
|
|
@@ -44,20 +41,11 @@ if TYPE_CHECKING:
|
|
|
44
41
|
)
|
|
45
42
|
from requests import Response # noqa: F401
|
|
46
43
|
|
|
47
|
-
from web3 import Web3 # noqa: F401
|
|
48
44
|
from web3._utils.compat import ( # noqa: F401
|
|
49
45
|
Self,
|
|
50
46
|
)
|
|
51
47
|
|
|
52
48
|
|
|
53
|
-
"""
|
|
54
|
-
flaky_geth_dev_mining decorator for tests requiring a pending block
|
|
55
|
-
for the duration of the test. This behavior can be flaky
|
|
56
|
-
due to timing of the test running as a block is mined.
|
|
57
|
-
"""
|
|
58
|
-
flaky_geth_dev_mining = flaky(max_runs=3, min_passes=1)
|
|
59
|
-
|
|
60
|
-
|
|
61
49
|
def assert_contains_log(
|
|
62
50
|
result: Sequence[LogReceipt],
|
|
63
51
|
block_with_txn_with_log: BlockData,
|
|
@@ -655,11 +655,11 @@ class PersistentConnectionProviderTest:
|
|
|
655
655
|
assert all(k in pending.keys() for k in SOME_BLOCK_KEYS)
|
|
656
656
|
|
|
657
657
|
assert isinstance(block_num, int)
|
|
658
|
-
assert latest["number"] == block_num
|
|
659
|
-
|
|
660
658
|
assert isinstance(chain_id, int)
|
|
661
659
|
assert isinstance(chain_id2, int)
|
|
662
660
|
assert isinstance(chain_id3, int)
|
|
661
|
+
# chain id is set in fixture file
|
|
662
|
+
assert chain_id == chain_id2 == chain_id3 == 131277322940537
|
|
663
663
|
|
|
664
664
|
@pytest.mark.asyncio
|
|
665
665
|
async def test_async_public_socket_api(self, async_w3: AsyncWeb3) -> None:
|
|
@@ -854,7 +854,7 @@ class PersistentConnectionProviderTest:
|
|
|
854
854
|
async_w3: AsyncWeb3,
|
|
855
855
|
) -> None:
|
|
856
856
|
async def unsubscribe_subs(
|
|
857
|
-
subs: List[Union[NewHeadsSubscription, LogsSubscription]]
|
|
857
|
+
subs: List[Union[NewHeadsSubscription, LogsSubscription]],
|
|
858
858
|
) -> None:
|
|
859
859
|
for sub in subs:
|
|
860
860
|
await sub.unsubscribe()
|
web3/_utils/normalizers.py
CHANGED
|
@@ -228,7 +228,7 @@ def abi_ens_resolver(
|
|
|
228
228
|
return type_str, validate_name_has_address(_ens, val)
|
|
229
229
|
except NameNotFound as e:
|
|
230
230
|
# TODO: This try/except is to keep backwards compatibility when we
|
|
231
|
-
# removed the mainnet requirement. Remove this in web3.py
|
|
231
|
+
# removed the mainnet requirement. Remove this in web3.py v8 and allow
|
|
232
232
|
# NameNotFound to raise.
|
|
233
233
|
if not isinstance(_ens, StaticENS):
|
|
234
234
|
raise InvalidAddress(f"{e}")
|
web3/_utils/rpc_abi.py
CHANGED
|
@@ -215,11 +215,12 @@ def apply_abi_formatters_to_dict(
|
|
|
215
215
|
fields = list(abi_dict.keys() & data.keys())
|
|
216
216
|
formatted_values = map_abi_data(
|
|
217
217
|
normalizers,
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
(abi_dict[field] for field in fields),
|
|
219
|
+
(data[field] for field in fields),
|
|
220
220
|
)
|
|
221
|
-
formatted_dict =
|
|
222
|
-
|
|
221
|
+
formatted_dict = data.copy()
|
|
222
|
+
formatted_dict.update(zip(fields, formatted_values))
|
|
223
|
+
return formatted_dict
|
|
223
224
|
|
|
224
225
|
|
|
225
226
|
@to_dict
|
web3/_utils/utility_methods.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import (
|
|
2
2
|
Any,
|
|
3
|
-
Dict,
|
|
4
3
|
Iterable,
|
|
4
|
+
Mapping,
|
|
5
5
|
Set,
|
|
6
6
|
Union,
|
|
7
7
|
)
|
|
@@ -13,7 +13,7 @@ from web3.types import (
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def all_in_dict(
|
|
16
|
-
values: Iterable[Any], d: Union[
|
|
16
|
+
values: Iterable[Any], d: Union[Mapping[Any, Any], TxData, TxParams]
|
|
17
17
|
) -> bool:
|
|
18
18
|
"""
|
|
19
19
|
Returns a bool based on whether ALL of the provided values exist
|
|
@@ -24,11 +24,12 @@ def all_in_dict(
|
|
|
24
24
|
:return: True if ALL values exist in keys;
|
|
25
25
|
False if NOT ALL values exist in keys
|
|
26
26
|
"""
|
|
27
|
-
|
|
27
|
+
d = dict(d)
|
|
28
|
+
return all(_ in d for _ in values)
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
def any_in_dict(
|
|
31
|
-
values: Iterable[Any], d: Union[
|
|
32
|
+
values: Iterable[Any], d: Union[Mapping[Any, Any], TxData, TxParams]
|
|
32
33
|
) -> bool:
|
|
33
34
|
"""
|
|
34
35
|
Returns a bool based on whether ANY of the provided values exist
|
|
@@ -39,11 +40,12 @@ def any_in_dict(
|
|
|
39
40
|
:return: True if ANY value exists in keys;
|
|
40
41
|
False if NONE of the values exist in keys
|
|
41
42
|
"""
|
|
42
|
-
|
|
43
|
+
d = dict(d)
|
|
44
|
+
return any(_ in d for _ in values)
|
|
43
45
|
|
|
44
46
|
|
|
45
47
|
def none_in_dict(
|
|
46
|
-
values: Iterable[Any], d: Union[
|
|
48
|
+
values: Iterable[Any], d: Union[Mapping[Any, Any], TxData, TxParams]
|
|
47
49
|
) -> bool:
|
|
48
50
|
"""
|
|
49
51
|
Returns a bool based on whether NONE of the provided values exist
|