web3 7.11.0__py3-none-any.whl → 7.12.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/async_ens.py +2 -2
- ens/ens.py +2 -2
- ens/utils.py +14 -3
- web3/_utils/abi.py +24 -20
- web3/_utils/batching.py +22 -68
- web3/_utils/caching/request_caching_validation.py +8 -4
- 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 +14 -11
- web3/_utils/error_formatters_utils.py +17 -0
- web3/_utils/filters.py +39 -28
- web3/_utils/http_session_manager.py +18 -15
- web3/_utils/method_formatters.py +19 -24
- web3/_utils/module_testing/eth_module.py +107 -47
- web3/_utils/module_testing/web3_module.py +78 -4
- web3/_utils/validation.py +1 -1
- web3/contract/utils.py +20 -35
- web3/eth/async_eth.py +4 -0
- web3/eth/eth.py +15 -2
- web3/manager.py +105 -23
- web3/method.py +17 -9
- web3/providers/async_base.py +15 -1
- web3/providers/base.py +18 -5
- web3/providers/ipc.py +2 -4
- web3/providers/legacy_websocket.py +4 -5
- web3/providers/persistent/async_ipc.py +3 -1
- web3/providers/persistent/persistent.py +110 -40
- web3/providers/persistent/request_processor.py +34 -51
- web3/providers/persistent/subscription_manager.py +13 -7
- web3/providers/rpc/async_rpc.py +7 -7
- web3/providers/rpc/rpc.py +6 -6
- web3/utils/abi.py +1 -1
- web3/utils/subscriptions.py +7 -4
- {web3-7.11.0.dist-info → web3-7.12.0.dist-info}/METADATA +1 -1
- {web3-7.11.0.dist-info → web3-7.12.0.dist-info}/RECORD +58 -58
- {web3-7.11.0.dist-info → web3-7.12.0.dist-info}/WHEEL +1 -1
- {web3-7.11.0.dist-info → web3-7.12.0.dist-info}/licenses/LICENSE +0 -0
- {web3-7.11.0.dist-info → web3-7.12.0.dist-info}/top_level.txt +0 -0
|
@@ -37,6 +37,7 @@ from eth_utils import (
|
|
|
37
37
|
)
|
|
38
38
|
from eth_utils.toolz import (
|
|
39
39
|
assoc,
|
|
40
|
+
merge,
|
|
40
41
|
)
|
|
41
42
|
from hexbytes import (
|
|
42
43
|
HexBytes,
|
|
@@ -717,12 +718,14 @@ class AsyncEthModuleTest:
|
|
|
717
718
|
async_w3.middleware_onion.remove("signing")
|
|
718
719
|
|
|
719
720
|
@pytest.mark.asyncio
|
|
720
|
-
async def
|
|
721
|
+
async def test_async_sign_authorization_send_raw_and_send_set_code_transactions(
|
|
721
722
|
self,
|
|
722
723
|
async_w3: "AsyncWeb3",
|
|
723
724
|
keyfile_account_pkey: HexStr,
|
|
724
725
|
async_math_contract: "AsyncContract",
|
|
725
726
|
) -> None:
|
|
727
|
+
# TODO: remove blockNumber block_id from eth_call and eth_getCode calls once
|
|
728
|
+
# geth behavior for "latest" seems stable again.
|
|
726
729
|
keyfile_account = async_w3.eth.account.from_key(keyfile_account_pkey)
|
|
727
730
|
|
|
728
731
|
chain_id = await async_w3.eth.chain_id
|
|
@@ -737,9 +740,7 @@ class AsyncEthModuleTest:
|
|
|
737
740
|
|
|
738
741
|
# get current math counter and increase it only in the delegation by n
|
|
739
742
|
math_counter = await async_math_contract.functions.counter().call()
|
|
740
|
-
|
|
741
|
-
math_counter + 1337
|
|
742
|
-
).build_transaction({})
|
|
743
|
+
data = async_math_contract.encode_abi("incrementCounter", [math_counter + 1337])
|
|
743
744
|
txn: TxParams = {
|
|
744
745
|
"chainId": chain_id,
|
|
745
746
|
"to": keyfile_account.address,
|
|
@@ -748,23 +749,31 @@ class AsyncEthModuleTest:
|
|
|
748
749
|
"nonce": nonce,
|
|
749
750
|
"maxPriorityFeePerGas": Wei(10**9),
|
|
750
751
|
"maxFeePerGas": Wei(10**9),
|
|
751
|
-
"data":
|
|
752
|
+
"data": data,
|
|
752
753
|
"authorizationList": [signed_auth],
|
|
753
754
|
}
|
|
754
755
|
|
|
756
|
+
# test eth_sendRawTransaction
|
|
755
757
|
signed = keyfile_account.sign_transaction(txn)
|
|
756
758
|
tx_hash = await async_w3.eth.send_raw_transaction(signed.raw_transaction)
|
|
757
759
|
get_tx = await async_w3.eth.get_transaction(tx_hash)
|
|
758
|
-
await async_w3.eth.wait_for_transaction_receipt(
|
|
760
|
+
tx_receipt = await async_w3.eth.wait_for_transaction_receipt(
|
|
761
|
+
tx_hash, timeout=10
|
|
762
|
+
)
|
|
759
763
|
|
|
760
|
-
code = await async_w3.eth.get_code(
|
|
764
|
+
code = await async_w3.eth.get_code(
|
|
765
|
+
keyfile_account.address, block_identifier=tx_receipt["blockNumber"]
|
|
766
|
+
)
|
|
761
767
|
assert code.to_0x_hex() == f"0xef0100{async_math_contract.address[2:].lower()}"
|
|
762
768
|
delegated = async_w3.eth.contract(
|
|
763
769
|
address=keyfile_account.address, abi=async_math_contract.abi
|
|
764
770
|
)
|
|
771
|
+
|
|
765
772
|
# assert the math counter is increased by 1337 only in delegated acct
|
|
766
773
|
assert await async_math_contract.functions.counter().call() == math_counter
|
|
767
|
-
delegated_call = await delegated.functions.counter().call(
|
|
774
|
+
delegated_call = await delegated.functions.counter().call(
|
|
775
|
+
block_identifier=tx_receipt["blockNumber"]
|
|
776
|
+
)
|
|
768
777
|
assert delegated_call == math_counter + 1337
|
|
769
778
|
|
|
770
779
|
assert len(get_tx["authorizationList"]) == 1
|
|
@@ -783,17 +792,24 @@ class AsyncEthModuleTest:
|
|
|
783
792
|
"nonce": nonce + 3,
|
|
784
793
|
}
|
|
785
794
|
signed_reset_auth = keyfile_account.sign_authorization(reset_auth)
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
795
|
+
reset_code_txn = merge(
|
|
796
|
+
txn,
|
|
797
|
+
{
|
|
798
|
+
"from": keyfile_account.address,
|
|
799
|
+
"authorizationList": [signed_reset_auth],
|
|
800
|
+
"nonce": nonce + 2,
|
|
801
|
+
},
|
|
802
|
+
)
|
|
789
803
|
|
|
790
|
-
|
|
791
|
-
reset_tx_hash = await async_w3.eth.
|
|
792
|
-
|
|
804
|
+
# test eth_sendTransaction
|
|
805
|
+
reset_tx_hash = await async_w3.eth.send_transaction(reset_code_txn)
|
|
806
|
+
reset_tx_receipt = await async_w3.eth.wait_for_transaction_receipt(
|
|
807
|
+
reset_tx_hash, timeout=10
|
|
793
808
|
)
|
|
794
|
-
await async_w3.eth.wait_for_transaction_receipt(reset_tx_hash, timeout=10)
|
|
795
809
|
|
|
796
|
-
reset_code = await async_w3.eth.get_code(
|
|
810
|
+
reset_code = await async_w3.eth.get_code(
|
|
811
|
+
keyfile_account.address, reset_tx_receipt["blockNumber"]
|
|
812
|
+
)
|
|
797
813
|
assert reset_code == HexBytes("0x")
|
|
798
814
|
|
|
799
815
|
@pytest.mark.asyncio
|
|
@@ -1881,6 +1897,10 @@ class AsyncEthModuleTest:
|
|
|
1881
1897
|
assert effective_gas_price > 0
|
|
1882
1898
|
|
|
1883
1899
|
@pytest.mark.asyncio
|
|
1900
|
+
# TODO: Remove xfail when issue has been identified
|
|
1901
|
+
@pytest.mark.xfail(
|
|
1902
|
+
reason="latest geth seems to cause this to be flaky", strict=False
|
|
1903
|
+
)
|
|
1884
1904
|
async def test_async_eth_wait_for_transaction_receipt_unmined(
|
|
1885
1905
|
self,
|
|
1886
1906
|
async_w3: "AsyncWeb3",
|
|
@@ -2221,19 +2241,31 @@ class AsyncEthModuleTest:
|
|
|
2221
2241
|
async def test_eth_getUncleCountByBlockHash(
|
|
2222
2242
|
self, async_w3: "AsyncWeb3", async_empty_block: BlockData
|
|
2223
2243
|
) -> None:
|
|
2224
|
-
|
|
2244
|
+
with pytest.warns(
|
|
2245
|
+
DeprecationWarning,
|
|
2246
|
+
match=r"get_uncle_count is deprecated: all get_uncle\* "
|
|
2247
|
+
r"methods will be removed in v8",
|
|
2248
|
+
):
|
|
2249
|
+
uncle_count = await async_w3.eth.get_uncle_count(async_empty_block["hash"])
|
|
2225
2250
|
|
|
2226
|
-
|
|
2227
|
-
|
|
2251
|
+
assert is_integer(uncle_count)
|
|
2252
|
+
assert uncle_count == 0
|
|
2228
2253
|
|
|
2229
2254
|
@pytest.mark.asyncio
|
|
2230
2255
|
async def test_eth_getUncleCountByBlockNumber(
|
|
2231
2256
|
self, async_w3: "AsyncWeb3", async_empty_block: BlockData
|
|
2232
2257
|
) -> None:
|
|
2233
|
-
|
|
2258
|
+
with pytest.warns(
|
|
2259
|
+
DeprecationWarning,
|
|
2260
|
+
match=r"get_uncle_count is deprecated: all get_uncle\* "
|
|
2261
|
+
r"methods will be removed in v8",
|
|
2262
|
+
):
|
|
2263
|
+
uncle_count = await async_w3.eth.get_uncle_count(
|
|
2264
|
+
async_empty_block["number"]
|
|
2265
|
+
)
|
|
2234
2266
|
|
|
2235
|
-
|
|
2236
|
-
|
|
2267
|
+
assert is_integer(uncle_count)
|
|
2268
|
+
assert uncle_count == 0
|
|
2237
2269
|
|
|
2238
2270
|
@pytest.mark.asyncio
|
|
2239
2271
|
async def test_eth_getBlockTransactionCountByNumber_block_with_txn(
|
|
@@ -2718,13 +2750,15 @@ class EthModuleTest:
|
|
|
2718
2750
|
assert balance >= 0
|
|
2719
2751
|
|
|
2720
2752
|
def test_eth_get_balance_with_block_identifier(self, w3: "Web3") -> None:
|
|
2721
|
-
|
|
2722
|
-
|
|
2753
|
+
genesis_block = w3.eth.get_block(0)
|
|
2754
|
+
miner_address = genesis_block["miner"]
|
|
2755
|
+
|
|
2756
|
+
balance_genesis = w3.eth.get_balance(miner_address, 0)
|
|
2723
2757
|
later_balance = w3.eth.get_balance(miner_address, "latest")
|
|
2724
2758
|
|
|
2725
|
-
assert is_integer(
|
|
2759
|
+
assert is_integer(balance_genesis)
|
|
2726
2760
|
assert is_integer(later_balance)
|
|
2727
|
-
assert later_balance
|
|
2761
|
+
assert later_balance != balance_genesis
|
|
2728
2762
|
|
|
2729
2763
|
@pytest.mark.parametrize(
|
|
2730
2764
|
"address, expect_success",
|
|
@@ -2843,18 +2877,24 @@ class EthModuleTest:
|
|
|
2843
2877
|
def test_eth_getUncleCountByBlockHash(
|
|
2844
2878
|
self, w3: "Web3", empty_block: BlockData
|
|
2845
2879
|
) -> None:
|
|
2846
|
-
|
|
2880
|
+
with pytest.warns(
|
|
2881
|
+
DeprecationWarning, match=r"All get_uncle\* methods have been deprecated"
|
|
2882
|
+
):
|
|
2883
|
+
uncle_count = w3.eth.get_uncle_count(empty_block["hash"])
|
|
2847
2884
|
|
|
2848
|
-
|
|
2849
|
-
|
|
2885
|
+
assert is_integer(uncle_count)
|
|
2886
|
+
assert uncle_count == 0
|
|
2850
2887
|
|
|
2851
2888
|
def test_eth_getUncleCountByBlockNumber(
|
|
2852
2889
|
self, w3: "Web3", empty_block: BlockData
|
|
2853
2890
|
) -> None:
|
|
2854
|
-
|
|
2891
|
+
with pytest.warns(
|
|
2892
|
+
DeprecationWarning, match=r"All get_uncle\* methods have been deprecated"
|
|
2893
|
+
):
|
|
2894
|
+
uncle_count = w3.eth.get_uncle_count(empty_block["number"])
|
|
2855
2895
|
|
|
2856
|
-
|
|
2857
|
-
|
|
2896
|
+
assert is_integer(uncle_count)
|
|
2897
|
+
assert uncle_count == 0
|
|
2858
2898
|
|
|
2859
2899
|
def test_eth_get_code(
|
|
2860
2900
|
self, w3: "Web3", math_contract_address: ChecksumAddress
|
|
@@ -3832,9 +3872,11 @@ class EthModuleTest:
|
|
|
3832
3872
|
# cleanup
|
|
3833
3873
|
w3.middleware_onion.remove("signing")
|
|
3834
3874
|
|
|
3835
|
-
def
|
|
3875
|
+
def test_sign_authorization_send_raw_and_send_set_code_transactions(
|
|
3836
3876
|
self, w3: "Web3", keyfile_account_pkey: HexStr, math_contract: "Contract"
|
|
3837
3877
|
) -> None:
|
|
3878
|
+
# TODO: remove blockNumber block_id from eth_call and eth_getCode calls once
|
|
3879
|
+
# geth behavior for "latest" seems stable again.
|
|
3838
3880
|
keyfile_account = w3.eth.account.from_key(keyfile_account_pkey)
|
|
3839
3881
|
|
|
3840
3882
|
chain_id = w3.eth.chain_id
|
|
@@ -3849,9 +3891,7 @@ class EthModuleTest:
|
|
|
3849
3891
|
|
|
3850
3892
|
# get current math counter and increase it only in the delegation by n
|
|
3851
3893
|
math_counter = math_contract.functions.counter().call()
|
|
3852
|
-
data = math_contract.
|
|
3853
|
-
math_counter + 1337
|
|
3854
|
-
).build_transaction({})["data"]
|
|
3894
|
+
data = math_contract.encode_abi("incrementCounter", [math_counter + 1337])
|
|
3855
3895
|
txn: TxParams = {
|
|
3856
3896
|
"chainId": chain_id,
|
|
3857
3897
|
"to": keyfile_account.address,
|
|
@@ -3864,19 +3904,30 @@ class EthModuleTest:
|
|
|
3864
3904
|
"authorizationList": [signed_auth],
|
|
3865
3905
|
}
|
|
3866
3906
|
|
|
3907
|
+
# test eth_sendRawTransaction
|
|
3867
3908
|
signed = keyfile_account.sign_transaction(txn)
|
|
3868
3909
|
tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)
|
|
3869
3910
|
get_tx = w3.eth.get_transaction(tx_hash)
|
|
3870
|
-
w3.eth.wait_for_transaction_receipt(tx_hash, timeout=10)
|
|
3911
|
+
receipt = w3.eth.wait_for_transaction_receipt(tx_hash, timeout=10)
|
|
3871
3912
|
|
|
3872
|
-
code = w3.eth.get_code(
|
|
3913
|
+
code = w3.eth.get_code(
|
|
3914
|
+
keyfile_account.address, block_identifier=receipt["blockNumber"]
|
|
3915
|
+
)
|
|
3873
3916
|
assert code.to_0x_hex() == f"0xef0100{math_contract.address[2:].lower()}"
|
|
3874
3917
|
delegated = w3.eth.contract(
|
|
3875
3918
|
address=keyfile_account.address, abi=math_contract.abi
|
|
3876
3919
|
)
|
|
3877
3920
|
# assert the math counter is increased by 1337 only in delegated acct
|
|
3878
|
-
assert
|
|
3879
|
-
|
|
3921
|
+
assert (
|
|
3922
|
+
math_contract.functions.counter().call(
|
|
3923
|
+
block_identifier=receipt["blockNumber"]
|
|
3924
|
+
)
|
|
3925
|
+
== math_counter
|
|
3926
|
+
)
|
|
3927
|
+
assert (
|
|
3928
|
+
delegated.functions.counter().call(block_identifier=receipt["blockNumber"])
|
|
3929
|
+
== math_counter + 1337
|
|
3930
|
+
)
|
|
3880
3931
|
|
|
3881
3932
|
assert len(get_tx["authorizationList"]) == 1
|
|
3882
3933
|
get_auth = get_tx["authorizationList"][0]
|
|
@@ -3894,15 +3945,24 @@ class EthModuleTest:
|
|
|
3894
3945
|
"nonce": nonce + 3,
|
|
3895
3946
|
}
|
|
3896
3947
|
signed_reset_auth = keyfile_account.sign_authorization(reset_auth)
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3948
|
+
reset_code_txn = merge(
|
|
3949
|
+
txn,
|
|
3950
|
+
{
|
|
3951
|
+
"from": keyfile_account.address,
|
|
3952
|
+
"authorizationList": [signed_reset_auth],
|
|
3953
|
+
"nonce": nonce + 2,
|
|
3954
|
+
},
|
|
3955
|
+
)
|
|
3900
3956
|
|
|
3901
|
-
|
|
3902
|
-
reset_tx_hash = w3.eth.
|
|
3903
|
-
w3.eth.wait_for_transaction_receipt(
|
|
3957
|
+
# test eth_sendTransaction
|
|
3958
|
+
reset_tx_hash = w3.eth.send_transaction(reset_code_txn)
|
|
3959
|
+
reset_tx_receipt = w3.eth.wait_for_transaction_receipt(
|
|
3960
|
+
reset_tx_hash, timeout=10
|
|
3961
|
+
)
|
|
3904
3962
|
|
|
3905
|
-
reset_code = w3.eth.get_code(
|
|
3963
|
+
reset_code = w3.eth.get_code(
|
|
3964
|
+
keyfile_account.address, block_identifier=reset_tx_receipt["blockNumber"]
|
|
3965
|
+
)
|
|
3906
3966
|
assert reset_code == HexBytes("0x")
|
|
3907
3967
|
|
|
3908
3968
|
def test_eth_call(self, w3: "Web3", math_contract: "Contract") -> None:
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import pytest
|
|
2
|
+
import asyncio
|
|
3
|
+
import threading
|
|
4
|
+
import time
|
|
2
5
|
from typing import (
|
|
3
6
|
TYPE_CHECKING,
|
|
4
7
|
Any,
|
|
@@ -43,6 +46,9 @@ if TYPE_CHECKING:
|
|
|
43
46
|
)
|
|
44
47
|
|
|
45
48
|
|
|
49
|
+
SOME_BLOCK_KEYS = {"number", "hash", "parentHash", "stateRoot", "transactions"}
|
|
50
|
+
|
|
51
|
+
|
|
46
52
|
class Web3ModuleTest:
|
|
47
53
|
def test_web3_client_version(self, w3: Web3) -> None:
|
|
48
54
|
client_version = w3.client_version
|
|
@@ -336,7 +342,7 @@ class Web3ModuleTest:
|
|
|
336
342
|
|
|
337
343
|
# assert proper batch cleanup after execution
|
|
338
344
|
assert batch._requests_info == []
|
|
339
|
-
assert not
|
|
345
|
+
assert not w3.provider._is_batching
|
|
340
346
|
|
|
341
347
|
# assert batch cannot be added to after execution
|
|
342
348
|
with pytest.raises(
|
|
@@ -395,7 +401,7 @@ class Web3ModuleTest:
|
|
|
395
401
|
|
|
396
402
|
# assert proper batch cleanup after execution
|
|
397
403
|
assert batch._requests_info == []
|
|
398
|
-
assert not
|
|
404
|
+
assert not w3.provider._is_batching
|
|
399
405
|
|
|
400
406
|
# assert batch cannot be added to after execution
|
|
401
407
|
with pytest.raises(
|
|
@@ -513,6 +519,43 @@ class Web3ModuleTest:
|
|
|
513
519
|
batch.add(w3.eth.sign(Address(b"\x00" * 20)))
|
|
514
520
|
batch.execute()
|
|
515
521
|
|
|
522
|
+
def test_batch_requests_concurrently_with_regular_requests(
|
|
523
|
+
self, w3: "Web3"
|
|
524
|
+
) -> None:
|
|
525
|
+
num_requests = 40
|
|
526
|
+
responses = []
|
|
527
|
+
batch_response = []
|
|
528
|
+
|
|
529
|
+
def make_regular_requests() -> None:
|
|
530
|
+
for _ in range(num_requests):
|
|
531
|
+
responses.append(w3.eth.get_block(0))
|
|
532
|
+
time.sleep(0.01)
|
|
533
|
+
|
|
534
|
+
def make_batch_request() -> None:
|
|
535
|
+
with w3.batch_requests() as batch:
|
|
536
|
+
for _ in range(num_requests):
|
|
537
|
+
batch.add(w3.eth.get_block(0))
|
|
538
|
+
time.sleep(0.01)
|
|
539
|
+
batch_response.extend(batch.execute())
|
|
540
|
+
|
|
541
|
+
# split into threads
|
|
542
|
+
regular_thread = threading.Thread(target=make_regular_requests)
|
|
543
|
+
batch_thread = threading.Thread(target=make_batch_request)
|
|
544
|
+
|
|
545
|
+
regular_thread.start()
|
|
546
|
+
batch_thread.start()
|
|
547
|
+
|
|
548
|
+
# wait for threads to finish
|
|
549
|
+
regular_thread.join()
|
|
550
|
+
batch_thread.join()
|
|
551
|
+
assert not regular_thread.is_alive()
|
|
552
|
+
assert not batch_thread.is_alive()
|
|
553
|
+
|
|
554
|
+
assert len(responses) == num_requests
|
|
555
|
+
assert len(batch_response) == num_requests
|
|
556
|
+
assert all(SOME_BLOCK_KEYS.issubset(response.keys()) for response in responses)
|
|
557
|
+
assert set(responses) == set(batch_response)
|
|
558
|
+
|
|
516
559
|
|
|
517
560
|
# -- async -- #
|
|
518
561
|
|
|
@@ -551,7 +594,7 @@ class AsyncWeb3ModuleTest(Web3ModuleTest):
|
|
|
551
594
|
|
|
552
595
|
# assert proper batch cleanup after execution
|
|
553
596
|
assert batch._async_requests_info == []
|
|
554
|
-
assert not
|
|
597
|
+
assert not async_w3.provider._is_batching
|
|
555
598
|
|
|
556
599
|
# assert batch cannot be added to after execution
|
|
557
600
|
with pytest.raises(
|
|
@@ -614,7 +657,7 @@ class AsyncWeb3ModuleTest(Web3ModuleTest):
|
|
|
614
657
|
|
|
615
658
|
# assert proper batch cleanup after execution
|
|
616
659
|
assert batch._async_requests_info == []
|
|
617
|
-
assert not
|
|
660
|
+
assert not async_w3.provider._is_batching
|
|
618
661
|
|
|
619
662
|
# assert batch cannot be added to after execution
|
|
620
663
|
with pytest.raises(
|
|
@@ -734,3 +777,34 @@ class AsyncWeb3ModuleTest(Web3ModuleTest):
|
|
|
734
777
|
with pytest.raises(MethodNotSupported, match="eth_sign"):
|
|
735
778
|
batch.add(async_w3.eth.sign(Address(b"\x00" * 20)))
|
|
736
779
|
await batch.async_execute()
|
|
780
|
+
|
|
781
|
+
@pytest.mark.asyncio
|
|
782
|
+
async def test_batch_requests_concurrently_with_regular_requests( # type: ignore[override] # noqa: E501
|
|
783
|
+
self, async_w3: AsyncWeb3 # type: ignore[override]
|
|
784
|
+
) -> None:
|
|
785
|
+
responses = []
|
|
786
|
+
batch_response = []
|
|
787
|
+
|
|
788
|
+
num_blocks = await async_w3.eth.block_number
|
|
789
|
+
|
|
790
|
+
async def make_regular_requests() -> None:
|
|
791
|
+
for i in range(num_blocks):
|
|
792
|
+
responses.append(await async_w3.eth.get_block(i))
|
|
793
|
+
await asyncio.sleep(0.01)
|
|
794
|
+
|
|
795
|
+
async def make_batch_request() -> None:
|
|
796
|
+
async with async_w3.batch_requests() as batch:
|
|
797
|
+
for i in range(num_blocks):
|
|
798
|
+
batch.add(async_w3.eth.get_block(i))
|
|
799
|
+
await asyncio.sleep(0.01)
|
|
800
|
+
batch_response.extend(await batch.async_execute())
|
|
801
|
+
|
|
802
|
+
await asyncio.gather(
|
|
803
|
+
make_regular_requests(),
|
|
804
|
+
make_batch_request(),
|
|
805
|
+
)
|
|
806
|
+
|
|
807
|
+
assert len(responses) == num_blocks
|
|
808
|
+
assert len(batch_response) == num_blocks
|
|
809
|
+
assert all(SOME_BLOCK_KEYS.issubset(response.keys()) for response in responses)
|
|
810
|
+
assert set(responses) == set(batch_response)
|
web3/_utils/validation.py
CHANGED
|
@@ -396,7 +396,7 @@ def validate_rpc_response_and_raise_if_error(
|
|
|
396
396
|
|
|
397
397
|
response = apply_error_formatters(error_formatters, response)
|
|
398
398
|
if logger is not None:
|
|
399
|
-
logger.debug(
|
|
399
|
+
logger.debug("RPC error response: %s", response)
|
|
400
400
|
|
|
401
401
|
raise web3_rpc_error
|
|
402
402
|
|
web3/contract/utils.py
CHANGED
|
@@ -43,8 +43,8 @@ from web3._utils.abi import (
|
|
|
43
43
|
from web3._utils.async_transactions import (
|
|
44
44
|
async_fill_transaction_defaults,
|
|
45
45
|
)
|
|
46
|
-
from web3._utils.
|
|
47
|
-
|
|
46
|
+
from web3._utils.batching import (
|
|
47
|
+
BatchRequestInformation,
|
|
48
48
|
)
|
|
49
49
|
from web3._utils.contracts import (
|
|
50
50
|
prepare_transaction,
|
|
@@ -62,7 +62,6 @@ from web3.exceptions import (
|
|
|
62
62
|
from web3.types import (
|
|
63
63
|
ABIElementIdentifier,
|
|
64
64
|
BlockIdentifier,
|
|
65
|
-
RPCEndpoint,
|
|
66
65
|
StateOverride,
|
|
67
66
|
TContractEvent,
|
|
68
67
|
TContractFn,
|
|
@@ -175,10 +174,8 @@ def call_contract_function(
|
|
|
175
174
|
if abi_callable["type"] == "function":
|
|
176
175
|
output_types = get_abi_output_types(abi_callable)
|
|
177
176
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
BatchingReturnData: TypeAlias = Tuple[Tuple[RPCEndpoint, Any], Tuple[Any, ...]]
|
|
181
|
-
request_information = tuple(cast(BatchingReturnData, return_data))
|
|
177
|
+
if w3.provider._is_batching:
|
|
178
|
+
request_information = tuple(cast(BatchRequestInformation, return_data))
|
|
182
179
|
method_and_params = request_information[0]
|
|
183
180
|
|
|
184
181
|
# append return data formatting to result formatters
|
|
@@ -483,35 +480,23 @@ async def async_call_contract_function(
|
|
|
483
480
|
normalizers,
|
|
484
481
|
output_types,
|
|
485
482
|
)
|
|
486
|
-
if async_w3.provider.has_persistent_connection:
|
|
487
|
-
# get the current request id
|
|
488
|
-
provider = cast("PersistentConnectionProvider", async_w3.provider)
|
|
489
|
-
current_request_id = provider._batch_request_counter - 1
|
|
490
|
-
provider._request_processor.append_result_formatter_for_request(
|
|
491
|
-
current_request_id, contract_call_return_data_formatter
|
|
492
|
-
)
|
|
493
|
-
else:
|
|
494
|
-
BatchingReturnData: TypeAlias = Tuple[
|
|
495
|
-
Tuple[RPCEndpoint, Any], Tuple[Any, ...]
|
|
496
|
-
]
|
|
497
|
-
request_information = tuple(cast(BatchingReturnData, return_data))
|
|
498
|
-
method_and_params = request_information[0]
|
|
499
|
-
|
|
500
|
-
# append return data formatter to result formatters
|
|
501
|
-
current_response_formatters = request_information[1]
|
|
502
|
-
current_result_formatters = current_response_formatters[0]
|
|
503
|
-
updated_result_formatters = compose(
|
|
504
|
-
contract_call_return_data_formatter,
|
|
505
|
-
current_result_formatters,
|
|
506
|
-
)
|
|
507
|
-
response_formatters = (
|
|
508
|
-
updated_result_formatters, # result formatters
|
|
509
|
-
current_response_formatters[1], # error formatters
|
|
510
|
-
current_response_formatters[2], # null result formatters
|
|
511
|
-
)
|
|
512
|
-
return (method_and_params, response_formatters)
|
|
513
483
|
|
|
514
|
-
|
|
484
|
+
request_information = tuple(cast(BatchRequestInformation, return_data))
|
|
485
|
+
method_and_params = request_information[0]
|
|
486
|
+
|
|
487
|
+
# append return data formatter to result formatters
|
|
488
|
+
current_response_formatters = request_information[1]
|
|
489
|
+
current_result_formatters = current_response_formatters[0]
|
|
490
|
+
updated_result_formatters = compose(
|
|
491
|
+
contract_call_return_data_formatter,
|
|
492
|
+
current_result_formatters,
|
|
493
|
+
)
|
|
494
|
+
response_formatters = (
|
|
495
|
+
updated_result_formatters, # result formatters
|
|
496
|
+
current_response_formatters[1], # error formatters
|
|
497
|
+
current_response_formatters[2], # null result formatters
|
|
498
|
+
)
|
|
499
|
+
return (method_and_params, response_formatters)
|
|
515
500
|
|
|
516
501
|
try:
|
|
517
502
|
output_data = async_w3.codec.decode(output_types, return_data)
|
web3/eth/async_eth.py
CHANGED
|
@@ -39,6 +39,9 @@ from web3._utils.blocks import (
|
|
|
39
39
|
from web3._utils.compat import (
|
|
40
40
|
Unpack,
|
|
41
41
|
)
|
|
42
|
+
from web3._utils.decorators import (
|
|
43
|
+
deprecated_for,
|
|
44
|
+
)
|
|
42
45
|
from web3._utils.fee_utils import (
|
|
43
46
|
async_fee_history_priority_fee,
|
|
44
47
|
)
|
|
@@ -669,6 +672,7 @@ class AsyncEth(BaseEth):
|
|
|
669
672
|
mungers=[default_root_munger],
|
|
670
673
|
)
|
|
671
674
|
|
|
675
|
+
@deprecated_for("all get_uncle* methods will be removed in v8")
|
|
672
676
|
async def get_uncle_count(self, block_identifier: BlockIdentifier) -> int:
|
|
673
677
|
return await self._get_uncle_count(block_identifier)
|
|
674
678
|
|
web3/eth/eth.py
CHANGED
|
@@ -69,6 +69,7 @@ from web3.exceptions import (
|
|
|
69
69
|
Web3ValueError,
|
|
70
70
|
)
|
|
71
71
|
from web3.method import (
|
|
72
|
+
DeprecatedMethod,
|
|
72
73
|
Method,
|
|
73
74
|
default_root_munger,
|
|
74
75
|
)
|
|
@@ -566,7 +567,7 @@ class Eth(BaseEth):
|
|
|
566
567
|
# eth_getUncleCountByBlockHash
|
|
567
568
|
# eth_getUncleCountByBlockNumber
|
|
568
569
|
|
|
569
|
-
|
|
570
|
+
_get_uncle_count: Method[Callable[[BlockIdentifier], int]] = Method(
|
|
570
571
|
method_choice_depends_on_args=select_method_for_block_identifier(
|
|
571
572
|
if_predefined=RPC.eth_getUncleCountByBlockNumber,
|
|
572
573
|
if_hash=RPC.eth_getUncleCountByBlockHash,
|
|
@@ -574,11 +575,17 @@ class Eth(BaseEth):
|
|
|
574
575
|
),
|
|
575
576
|
mungers=[default_root_munger],
|
|
576
577
|
)
|
|
578
|
+
get_uncle_count = DeprecatedMethod(
|
|
579
|
+
_get_uncle_count,
|
|
580
|
+
old_name="_get_uncle_count",
|
|
581
|
+
new_name="get_uncle_count",
|
|
582
|
+
msg="All get_uncle* methods have been deprecated",
|
|
583
|
+
)
|
|
577
584
|
|
|
578
585
|
# eth_getUncleByBlockHashAndIndex
|
|
579
586
|
# eth_getUncleByBlockNumberAndIndex
|
|
580
587
|
|
|
581
|
-
|
|
588
|
+
_get_uncle_by_block: Method[Callable[[BlockIdentifier, int], Uncle]] = Method(
|
|
582
589
|
method_choice_depends_on_args=select_method_for_block_identifier(
|
|
583
590
|
if_predefined=RPC.eth_getUncleByBlockNumberAndIndex,
|
|
584
591
|
if_hash=RPC.eth_getUncleByBlockHashAndIndex,
|
|
@@ -586,6 +593,12 @@ class Eth(BaseEth):
|
|
|
586
593
|
),
|
|
587
594
|
mungers=[default_root_munger],
|
|
588
595
|
)
|
|
596
|
+
get_uncle_by_block = DeprecatedMethod(
|
|
597
|
+
_get_uncle_by_block,
|
|
598
|
+
old_name="_get_uncle_by_block",
|
|
599
|
+
new_name="get_uncle_by_block",
|
|
600
|
+
msg="All get_uncle* methods have been deprecated",
|
|
601
|
+
)
|
|
589
602
|
|
|
590
603
|
def replace_transaction(
|
|
591
604
|
self, transaction_hash: _Hash32, new_transaction: TxParams
|