web3 7.0.0b5__py3-none-any.whl → 7.0.0b7__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
- web3/__init__.py +21 -5
- web3/_utils/batching.py +217 -0
- web3/_utils/caching.py +26 -2
- web3/_utils/compat/__init__.py +1 -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 +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/events.py +2 -2
- web3/_utils/http.py +3 -0
- web3/_utils/http_session_manager.py +280 -0
- web3/_utils/method_formatters.py +0 -2
- web3/_utils/module_testing/eth_module.py +92 -119
- web3/_utils/module_testing/module_testing_utils.py +27 -9
- web3/_utils/module_testing/persistent_connection_provider.py +1 -0
- web3/_utils/module_testing/web3_module.py +438 -17
- web3/_utils/rpc_abi.py +0 -3
- web3/beacon/__init__.py +5 -0
- web3/beacon/async_beacon.py +9 -5
- web3/beacon/beacon.py +7 -5
- web3/contract/__init__.py +7 -0
- web3/contract/base_contract.py +10 -1
- web3/contract/utils.py +112 -4
- web3/eth/__init__.py +7 -0
- web3/eth/async_eth.py +5 -37
- web3/eth/eth.py +7 -57
- web3/exceptions.py +20 -0
- web3/gas_strategies/time_based.py +2 -2
- web3/main.py +21 -9
- web3/manager.py +113 -8
- web3/method.py +29 -9
- web3/middleware/__init__.py +17 -0
- web3/middleware/base.py +43 -0
- web3/module.py +47 -7
- web3/providers/__init__.py +21 -0
- web3/providers/async_base.py +55 -23
- web3/providers/base.py +59 -26
- web3/providers/eth_tester/__init__.py +5 -0
- web3/providers/eth_tester/defaults.py +0 -6
- web3/providers/eth_tester/middleware.py +3 -8
- web3/providers/ipc.py +23 -8
- web3/providers/legacy_websocket.py +26 -1
- web3/providers/persistent/__init__.py +7 -0
- web3/providers/persistent/async_ipc.py +60 -76
- web3/providers/persistent/persistent.py +134 -10
- web3/providers/persistent/request_processor.py +98 -14
- web3/providers/persistent/websocket.py +43 -66
- web3/providers/rpc/__init__.py +5 -0
- web3/providers/rpc/async_rpc.py +34 -12
- web3/providers/rpc/rpc.py +34 -12
- web3/providers/rpc/utils.py +0 -3
- web3/tools/benchmark/main.py +7 -6
- web3/tools/benchmark/node.py +1 -1
- web3/types.py +7 -1
- web3/utils/__init__.py +14 -5
- web3/utils/async_exception_handling.py +19 -7
- web3/utils/exception_handling.py +7 -5
- {web3-7.0.0b5.dist-info → web3-7.0.0b7.dist-info}/LICENSE +1 -1
- {web3-7.0.0b5.dist-info → web3-7.0.0b7.dist-info}/METADATA +33 -20
- {web3-7.0.0b5.dist-info → web3-7.0.0b7.dist-info}/RECORD +80 -80
- {web3-7.0.0b5.dist-info → web3-7.0.0b7.dist-info}/WHEEL +1 -1
- web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
- web3/_utils/request.py +0 -265
- {web3-7.0.0b5.dist-info → web3-7.0.0b7.dist-info}/top_level.txt +0 -0
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
from typing import (
|
|
3
|
+
TYPE_CHECKING,
|
|
3
4
|
Any,
|
|
4
5
|
NoReturn,
|
|
5
6
|
Sequence,
|
|
6
|
-
|
|
7
|
+
cast,
|
|
7
8
|
)
|
|
8
9
|
|
|
9
10
|
from eth_typing import (
|
|
11
|
+
Address,
|
|
10
12
|
ChecksumAddress,
|
|
11
13
|
HexAddress,
|
|
12
14
|
HexStr,
|
|
@@ -23,10 +25,23 @@ from web3 import (
|
|
|
23
25
|
from web3._utils.ens import (
|
|
24
26
|
ens_addresses,
|
|
25
27
|
)
|
|
28
|
+
from web3.contract import (
|
|
29
|
+
Contract,
|
|
30
|
+
)
|
|
26
31
|
from web3.exceptions import (
|
|
27
32
|
InvalidAddress,
|
|
33
|
+
MethodNotSupported,
|
|
34
|
+
Web3ValueError,
|
|
35
|
+
)
|
|
36
|
+
from web3.types import (
|
|
37
|
+
BlockData,
|
|
28
38
|
)
|
|
29
39
|
|
|
40
|
+
if TYPE_CHECKING:
|
|
41
|
+
from web3.contract import ( # noqa: F401
|
|
42
|
+
AsyncContract,
|
|
43
|
+
)
|
|
44
|
+
|
|
30
45
|
|
|
31
46
|
class Web3ModuleTest:
|
|
32
47
|
def test_web3_client_version(self, w3: Web3) -> None:
|
|
@@ -223,16 +238,9 @@ class Web3ModuleTest:
|
|
|
223
238
|
),
|
|
224
239
|
),
|
|
225
240
|
)
|
|
226
|
-
@pytest.mark.parametrize(
|
|
227
|
-
"w3",
|
|
228
|
-
(
|
|
229
|
-
Web3,
|
|
230
|
-
AsyncWeb3,
|
|
231
|
-
),
|
|
232
|
-
)
|
|
233
241
|
def test_solidity_keccak(
|
|
234
242
|
self,
|
|
235
|
-
w3:
|
|
243
|
+
w3: "Web3",
|
|
236
244
|
types: Sequence[TypeStr],
|
|
237
245
|
values: Sequence[Any],
|
|
238
246
|
expected: HexBytes,
|
|
@@ -264,16 +272,9 @@ class Web3ModuleTest:
|
|
|
264
272
|
),
|
|
265
273
|
),
|
|
266
274
|
)
|
|
267
|
-
@pytest.mark.parametrize(
|
|
268
|
-
"w3",
|
|
269
|
-
(
|
|
270
|
-
Web3(),
|
|
271
|
-
AsyncWeb3(),
|
|
272
|
-
),
|
|
273
|
-
)
|
|
274
275
|
def test_solidity_keccak_ens(
|
|
275
276
|
self,
|
|
276
|
-
w3:
|
|
277
|
+
w3: "Web3",
|
|
277
278
|
types: Sequence[TypeStr],
|
|
278
279
|
values: Sequence[str],
|
|
279
280
|
expected: HexBytes,
|
|
@@ -313,3 +314,423 @@ class Web3ModuleTest:
|
|
|
313
314
|
|
|
314
315
|
def test_is_connected(self, w3: "Web3") -> None:
|
|
315
316
|
assert w3.is_connected()
|
|
317
|
+
|
|
318
|
+
def test_batch_requests(self, w3: "Web3", math_contract: Contract) -> None:
|
|
319
|
+
with w3.batch_requests() as batch:
|
|
320
|
+
batch.add(w3.eth.get_block(6))
|
|
321
|
+
batch.add(w3.eth.get_block(4))
|
|
322
|
+
batch.add(w3.eth.get_block(2))
|
|
323
|
+
batch.add(w3.eth.get_block(0))
|
|
324
|
+
batch.add(math_contract.functions.multiply7(0))
|
|
325
|
+
|
|
326
|
+
batch.add_mapping(
|
|
327
|
+
{
|
|
328
|
+
math_contract.functions.multiply7: [1, 2, 3],
|
|
329
|
+
w3.eth.get_block: [1, 3, 5],
|
|
330
|
+
}
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
assert len(batch._requests_info) == 11
|
|
334
|
+
responses = batch.execute()
|
|
335
|
+
assert len(responses) == 11
|
|
336
|
+
|
|
337
|
+
# assert proper batch cleanup after execution
|
|
338
|
+
assert batch._requests_info == []
|
|
339
|
+
assert not batch._provider._is_batching
|
|
340
|
+
|
|
341
|
+
# assert batch cannot be added to after execution
|
|
342
|
+
with pytest.raises(
|
|
343
|
+
Web3ValueError,
|
|
344
|
+
match="Batch has already been executed or cancelled",
|
|
345
|
+
):
|
|
346
|
+
batch.add(w3.eth.get_block(5))
|
|
347
|
+
|
|
348
|
+
# assert batch cannot be executed again
|
|
349
|
+
with pytest.raises(
|
|
350
|
+
Web3ValueError,
|
|
351
|
+
match="Batch has already been executed or cancelled",
|
|
352
|
+
):
|
|
353
|
+
batch.execute()
|
|
354
|
+
|
|
355
|
+
# assert can make a request after executing
|
|
356
|
+
block_num = w3.eth.block_number
|
|
357
|
+
assert isinstance(block_num, int)
|
|
358
|
+
|
|
359
|
+
first_four_responses: Sequence[BlockData] = cast(
|
|
360
|
+
Sequence[BlockData], responses[:4]
|
|
361
|
+
)
|
|
362
|
+
assert first_four_responses[0]["number"] == 6
|
|
363
|
+
assert first_four_responses[1]["number"] == 4
|
|
364
|
+
assert first_four_responses[2]["number"] == 2
|
|
365
|
+
assert first_four_responses[3]["number"] == 0
|
|
366
|
+
|
|
367
|
+
responses_five_through_eight: Sequence[int] = cast(
|
|
368
|
+
Sequence[int], responses[4:8]
|
|
369
|
+
)
|
|
370
|
+
assert responses_five_through_eight[0] == 0
|
|
371
|
+
assert responses_five_through_eight[1] == 7
|
|
372
|
+
assert responses_five_through_eight[2] == 14
|
|
373
|
+
assert responses_five_through_eight[3] == 21
|
|
374
|
+
|
|
375
|
+
last_three_responses: Sequence[BlockData] = cast(
|
|
376
|
+
Sequence[BlockData], responses[8:]
|
|
377
|
+
)
|
|
378
|
+
assert last_three_responses[0]["number"] == 1
|
|
379
|
+
assert last_three_responses[1]["number"] == 3
|
|
380
|
+
assert last_three_responses[2]["number"] == 5
|
|
381
|
+
|
|
382
|
+
def test_batch_requests_initialized_as_object(
|
|
383
|
+
self, w3: "Web3", math_contract: Contract
|
|
384
|
+
) -> None:
|
|
385
|
+
batch = w3.batch_requests()
|
|
386
|
+
batch.add(w3.eth.get_block(1))
|
|
387
|
+
batch.add(w3.eth.get_block(2))
|
|
388
|
+
batch.add(math_contract.functions.multiply7(0))
|
|
389
|
+
batch.add_mapping(
|
|
390
|
+
{math_contract.functions.multiply7: [1, 2], w3.eth.get_block: [3, 4]}
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
assert len(batch._requests_info) == 7
|
|
394
|
+
b1, b2, m0, m1, m2, b3, b4 = batch.execute()
|
|
395
|
+
|
|
396
|
+
# assert proper batch cleanup after execution
|
|
397
|
+
assert batch._requests_info == []
|
|
398
|
+
assert not batch._provider._is_batching
|
|
399
|
+
|
|
400
|
+
# assert batch cannot be added to after execution
|
|
401
|
+
with pytest.raises(
|
|
402
|
+
Web3ValueError,
|
|
403
|
+
match="Batch has already been executed or cancelled",
|
|
404
|
+
):
|
|
405
|
+
batch.add(w3.eth.get_block(5))
|
|
406
|
+
|
|
407
|
+
# assert batch cannot be executed again
|
|
408
|
+
with pytest.raises(
|
|
409
|
+
Web3ValueError,
|
|
410
|
+
match="Batch has already been executed or cancelled",
|
|
411
|
+
):
|
|
412
|
+
batch.execute()
|
|
413
|
+
|
|
414
|
+
# assert can make a request after executing
|
|
415
|
+
block_num = w3.eth.block_number
|
|
416
|
+
assert isinstance(block_num, int)
|
|
417
|
+
|
|
418
|
+
assert cast(BlockData, b1)["number"] == 1
|
|
419
|
+
assert cast(BlockData, b2)["number"] == 2
|
|
420
|
+
assert cast(int, m0) == 0
|
|
421
|
+
assert cast(int, m1) == 7
|
|
422
|
+
assert cast(int, m2) == 14
|
|
423
|
+
assert cast(BlockData, b3)["number"] == 3
|
|
424
|
+
assert cast(BlockData, b4)["number"] == 4
|
|
425
|
+
|
|
426
|
+
def test_batch_requests_clear(self, w3: "Web3") -> None:
|
|
427
|
+
with w3.batch_requests() as batch:
|
|
428
|
+
batch.add(w3.eth.get_block(1))
|
|
429
|
+
batch.add(w3.eth.get_block(2))
|
|
430
|
+
|
|
431
|
+
assert len(batch._requests_info) == 2
|
|
432
|
+
batch.clear()
|
|
433
|
+
assert batch._requests_info == []
|
|
434
|
+
|
|
435
|
+
batch.add(w3.eth.get_block(3))
|
|
436
|
+
batch.add(w3.eth.get_block(4))
|
|
437
|
+
|
|
438
|
+
r1, r2 = batch.execute()
|
|
439
|
+
|
|
440
|
+
assert cast(BlockData, r1)["number"] == 3
|
|
441
|
+
assert cast(BlockData, r2)["number"] == 4
|
|
442
|
+
|
|
443
|
+
new_batch = w3.batch_requests()
|
|
444
|
+
new_batch.add(w3.eth.get_block(5))
|
|
445
|
+
|
|
446
|
+
assert len(new_batch._requests_info) == 1
|
|
447
|
+
new_batch.clear()
|
|
448
|
+
assert new_batch._requests_info == []
|
|
449
|
+
|
|
450
|
+
new_batch.add(w3.eth.get_block(6))
|
|
451
|
+
(r3,) = new_batch.execute()
|
|
452
|
+
assert cast(BlockData, r3)["number"] == 6
|
|
453
|
+
|
|
454
|
+
def test_batch_requests_cancel(self, w3: "Web3") -> None:
|
|
455
|
+
# as context manager
|
|
456
|
+
with w3.batch_requests() as batch:
|
|
457
|
+
batch.add(w3.eth.get_block(1))
|
|
458
|
+
batch.cancel()
|
|
459
|
+
with pytest.raises(
|
|
460
|
+
Web3ValueError,
|
|
461
|
+
match="Batch has already been executed or cancelled",
|
|
462
|
+
):
|
|
463
|
+
batch.add(w3.eth.get_block(2))
|
|
464
|
+
with pytest.raises(
|
|
465
|
+
Web3ValueError,
|
|
466
|
+
match="Batch has already been executed or cancelled",
|
|
467
|
+
):
|
|
468
|
+
batch.execute()
|
|
469
|
+
|
|
470
|
+
# can make a request after cancelling
|
|
471
|
+
block_num = w3.eth.block_number
|
|
472
|
+
assert isinstance(block_num, int)
|
|
473
|
+
|
|
474
|
+
# as obj
|
|
475
|
+
new_batch = w3.batch_requests()
|
|
476
|
+
new_batch.add(w3.eth.get_block(1))
|
|
477
|
+
new_batch.cancel()
|
|
478
|
+
with pytest.raises(
|
|
479
|
+
Web3ValueError,
|
|
480
|
+
match="Batch has already been executed or cancelled",
|
|
481
|
+
):
|
|
482
|
+
new_batch.add(w3.eth.get_block(2))
|
|
483
|
+
with pytest.raises(
|
|
484
|
+
Web3ValueError,
|
|
485
|
+
match="Batch has already been executed or cancelled",
|
|
486
|
+
):
|
|
487
|
+
new_batch.execute()
|
|
488
|
+
|
|
489
|
+
# assert can make a request after cancelling
|
|
490
|
+
block_num = w3.eth.block_number
|
|
491
|
+
assert isinstance(block_num, int)
|
|
492
|
+
|
|
493
|
+
def test_batch_requests_raises_for_common_unsupported_methods(
|
|
494
|
+
self, w3: "Web3", math_contract: Contract
|
|
495
|
+
) -> None:
|
|
496
|
+
with w3.batch_requests() as batch:
|
|
497
|
+
with pytest.raises(MethodNotSupported, match="eth_sendTransaction"):
|
|
498
|
+
batch.add(w3.eth.send_transaction({}))
|
|
499
|
+
batch.execute()
|
|
500
|
+
|
|
501
|
+
with w3.batch_requests() as batch:
|
|
502
|
+
with pytest.raises(MethodNotSupported, match="eth_sendTransaction"):
|
|
503
|
+
batch.add(math_contract.functions.multiply7(1).transact({}))
|
|
504
|
+
batch.execute()
|
|
505
|
+
|
|
506
|
+
with w3.batch_requests() as batch:
|
|
507
|
+
with pytest.raises(MethodNotSupported, match="eth_sendRawTransaction"):
|
|
508
|
+
batch.add(w3.eth.send_raw_transaction(b""))
|
|
509
|
+
batch.execute()
|
|
510
|
+
|
|
511
|
+
with w3.batch_requests() as batch:
|
|
512
|
+
with pytest.raises(MethodNotSupported, match="eth_sign"):
|
|
513
|
+
batch.add(w3.eth.sign(Address(b"\x00" * 20)))
|
|
514
|
+
batch.execute()
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
# -- async -- #
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
class AsyncWeb3ModuleTest(Web3ModuleTest):
|
|
521
|
+
# Note: Any test that overrides the synchronous test from `Web3ModuleTest` with
|
|
522
|
+
# an asynchronous test should have the exact same name.
|
|
523
|
+
|
|
524
|
+
@pytest.mark.asyncio
|
|
525
|
+
async def test_web3_client_version(self, async_w3: AsyncWeb3) -> None:
|
|
526
|
+
client_version = await async_w3.client_version
|
|
527
|
+
self._check_web3_client_version(client_version)
|
|
528
|
+
|
|
529
|
+
@pytest.mark.asyncio
|
|
530
|
+
async def test_batch_requests(
|
|
531
|
+
self, async_w3: AsyncWeb3, async_math_contract: "AsyncContract"
|
|
532
|
+
) -> None:
|
|
533
|
+
async with async_w3.batch_requests() as batch:
|
|
534
|
+
batch.add(async_w3.eth.get_block(6))
|
|
535
|
+
batch.add(async_w3.eth.get_block(4))
|
|
536
|
+
batch.add(async_w3.eth.get_block(2))
|
|
537
|
+
batch.add(async_w3.eth.get_block(0))
|
|
538
|
+
|
|
539
|
+
batch.add(async_math_contract.functions.multiply7(0))
|
|
540
|
+
|
|
541
|
+
batch.add_mapping(
|
|
542
|
+
{
|
|
543
|
+
async_math_contract.functions.multiply7: [1, 2, 3],
|
|
544
|
+
async_w3.eth.get_block: [1, 3, 5],
|
|
545
|
+
}
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
assert len(batch._async_requests_info) == 11
|
|
549
|
+
responses = await batch.async_execute()
|
|
550
|
+
assert len(responses) == 11
|
|
551
|
+
|
|
552
|
+
# assert proper batch cleanup after execution
|
|
553
|
+
assert batch._async_requests_info == []
|
|
554
|
+
assert not batch._provider._is_batching
|
|
555
|
+
|
|
556
|
+
# assert batch cannot be added to after execution
|
|
557
|
+
with pytest.raises(
|
|
558
|
+
Web3ValueError,
|
|
559
|
+
match="Batch has already been executed or cancelled",
|
|
560
|
+
):
|
|
561
|
+
batch.add(async_w3.eth.get_block(5))
|
|
562
|
+
|
|
563
|
+
# assert batch cannot be executed again
|
|
564
|
+
with pytest.raises(
|
|
565
|
+
Web3ValueError,
|
|
566
|
+
match="Batch has already been executed or cancelled",
|
|
567
|
+
):
|
|
568
|
+
await batch.async_execute()
|
|
569
|
+
|
|
570
|
+
# assert can make a request after executing
|
|
571
|
+
block_num = await async_w3.eth.block_number
|
|
572
|
+
assert isinstance(block_num, int)
|
|
573
|
+
|
|
574
|
+
first_four_responses: Sequence[BlockData] = cast(
|
|
575
|
+
Sequence[BlockData], responses[:4]
|
|
576
|
+
)
|
|
577
|
+
assert first_four_responses[0]["number"] == 6
|
|
578
|
+
assert first_four_responses[1]["number"] == 4
|
|
579
|
+
assert first_four_responses[2]["number"] == 2
|
|
580
|
+
assert first_four_responses[3]["number"] == 0
|
|
581
|
+
|
|
582
|
+
responses_five_through_eight: Sequence[int] = cast(
|
|
583
|
+
Sequence[int], responses[4:8]
|
|
584
|
+
)
|
|
585
|
+
assert responses_five_through_eight[0] == 0
|
|
586
|
+
assert responses_five_through_eight[1] == 7
|
|
587
|
+
assert responses_five_through_eight[2] == 14
|
|
588
|
+
assert responses_five_through_eight[3] == 21
|
|
589
|
+
|
|
590
|
+
last_three_responses: Sequence[BlockData] = cast(
|
|
591
|
+
Sequence[BlockData], responses[8:]
|
|
592
|
+
)
|
|
593
|
+
assert last_three_responses[0]["number"] == 1
|
|
594
|
+
assert last_three_responses[1]["number"] == 3
|
|
595
|
+
assert last_three_responses[2]["number"] == 5
|
|
596
|
+
|
|
597
|
+
@pytest.mark.asyncio
|
|
598
|
+
async def test_batch_requests_initialized_as_object(
|
|
599
|
+
self, async_w3: AsyncWeb3, async_math_contract: "AsyncContract"
|
|
600
|
+
) -> None:
|
|
601
|
+
batch = async_w3.batch_requests()
|
|
602
|
+
batch.add(async_w3.eth.get_block(1))
|
|
603
|
+
batch.add(async_w3.eth.get_block(2))
|
|
604
|
+
batch.add(async_math_contract.functions.multiply7(0))
|
|
605
|
+
batch.add_mapping(
|
|
606
|
+
{
|
|
607
|
+
async_math_contract.functions.multiply7: [1, 2],
|
|
608
|
+
async_w3.eth.get_block: [3, 4],
|
|
609
|
+
}
|
|
610
|
+
)
|
|
611
|
+
|
|
612
|
+
assert len(batch._async_requests_info) == 7
|
|
613
|
+
b1, b2, m0, m1, m2, b3, b4 = await batch.async_execute()
|
|
614
|
+
|
|
615
|
+
# assert proper batch cleanup after execution
|
|
616
|
+
assert batch._async_requests_info == []
|
|
617
|
+
assert not batch._provider._is_batching
|
|
618
|
+
|
|
619
|
+
# assert batch cannot be added to after execution
|
|
620
|
+
with pytest.raises(
|
|
621
|
+
Web3ValueError,
|
|
622
|
+
match="Batch has already been executed or cancelled",
|
|
623
|
+
):
|
|
624
|
+
batch.add(async_w3.eth.get_block(5))
|
|
625
|
+
|
|
626
|
+
# assert batch cannot be executed again
|
|
627
|
+
with pytest.raises(
|
|
628
|
+
Web3ValueError,
|
|
629
|
+
match="Batch has already been executed or cancelled",
|
|
630
|
+
):
|
|
631
|
+
await batch.async_execute()
|
|
632
|
+
|
|
633
|
+
# assert can make a request after executing
|
|
634
|
+
block_num = await async_w3.eth.block_number
|
|
635
|
+
assert isinstance(block_num, int)
|
|
636
|
+
|
|
637
|
+
assert cast(BlockData, b1)["number"] == 1
|
|
638
|
+
assert cast(BlockData, b2)["number"] == 2
|
|
639
|
+
assert cast(int, m0) == 0
|
|
640
|
+
assert cast(int, m1) == 7
|
|
641
|
+
assert cast(int, m2) == 14
|
|
642
|
+
assert cast(BlockData, b3)["number"] == 3
|
|
643
|
+
assert cast(BlockData, b4)["number"] == 4
|
|
644
|
+
|
|
645
|
+
@pytest.mark.asyncio
|
|
646
|
+
async def test_batch_requests_clear(self, async_w3: AsyncWeb3) -> None:
|
|
647
|
+
async with async_w3.batch_requests() as batch:
|
|
648
|
+
batch.add(async_w3.eth.get_block(1))
|
|
649
|
+
batch.add(async_w3.eth.get_block(2))
|
|
650
|
+
|
|
651
|
+
assert len(batch._async_requests_info) == 2
|
|
652
|
+
batch.clear()
|
|
653
|
+
assert batch._async_requests_info == []
|
|
654
|
+
|
|
655
|
+
batch.add(async_w3.eth.get_block(3))
|
|
656
|
+
batch.add(async_w3.eth.get_block(4))
|
|
657
|
+
|
|
658
|
+
r1, r2 = await batch.async_execute()
|
|
659
|
+
|
|
660
|
+
assert cast(BlockData, r1)["number"] == 3
|
|
661
|
+
assert cast(BlockData, r2)["number"] == 4
|
|
662
|
+
|
|
663
|
+
new_batch = async_w3.batch_requests()
|
|
664
|
+
new_batch.add(async_w3.eth.get_block(5))
|
|
665
|
+
|
|
666
|
+
assert len(new_batch._async_requests_info) == 1
|
|
667
|
+
new_batch.clear()
|
|
668
|
+
assert new_batch._async_requests_info == []
|
|
669
|
+
|
|
670
|
+
new_batch.add(async_w3.eth.get_block(6))
|
|
671
|
+
(r3,) = await new_batch.async_execute()
|
|
672
|
+
assert cast(BlockData, r3)["number"] == 6
|
|
673
|
+
|
|
674
|
+
@pytest.mark.asyncio
|
|
675
|
+
async def test_batch_requests_cancel(self, async_w3: AsyncWeb3) -> None:
|
|
676
|
+
# as context manager
|
|
677
|
+
async with async_w3.batch_requests() as batch:
|
|
678
|
+
batch.add(async_w3.eth.get_block(1))
|
|
679
|
+
batch.cancel()
|
|
680
|
+
with pytest.raises(
|
|
681
|
+
Web3ValueError,
|
|
682
|
+
match="Batch has already been executed or cancelled",
|
|
683
|
+
):
|
|
684
|
+
batch.add(async_w3.eth.get_block(2))
|
|
685
|
+
with pytest.raises(
|
|
686
|
+
Web3ValueError,
|
|
687
|
+
match="Batch has already been executed or cancelled",
|
|
688
|
+
):
|
|
689
|
+
await batch.async_execute()
|
|
690
|
+
|
|
691
|
+
# can make a request after cancelling
|
|
692
|
+
block_num = await async_w3.eth.block_number
|
|
693
|
+
assert isinstance(block_num, int)
|
|
694
|
+
|
|
695
|
+
# as obj
|
|
696
|
+
new_batch = async_w3.batch_requests()
|
|
697
|
+
new_batch.add(async_w3.eth.get_block(1))
|
|
698
|
+
new_batch.cancel()
|
|
699
|
+
with pytest.raises(
|
|
700
|
+
Web3ValueError,
|
|
701
|
+
match="Batch has already been executed or cancelled",
|
|
702
|
+
):
|
|
703
|
+
new_batch.add(async_w3.eth.get_block(2))
|
|
704
|
+
with pytest.raises(
|
|
705
|
+
Web3ValueError,
|
|
706
|
+
match="Batch has already been executed or cancelled",
|
|
707
|
+
):
|
|
708
|
+
await new_batch.async_execute()
|
|
709
|
+
|
|
710
|
+
# can make a request after cancelling
|
|
711
|
+
block_num = await async_w3.eth.block_number
|
|
712
|
+
assert isinstance(block_num, int)
|
|
713
|
+
|
|
714
|
+
@pytest.mark.asyncio
|
|
715
|
+
async def test_batch_requests_raises_for_common_unsupported_methods(
|
|
716
|
+
self, async_w3: AsyncWeb3, async_math_contract: "AsyncContract"
|
|
717
|
+
) -> None:
|
|
718
|
+
async with async_w3.batch_requests() as batch:
|
|
719
|
+
with pytest.raises(MethodNotSupported, match="eth_sendTransaction"):
|
|
720
|
+
batch.add(async_w3.eth.send_transaction({}))
|
|
721
|
+
await batch.async_execute()
|
|
722
|
+
|
|
723
|
+
async with async_w3.batch_requests() as batch:
|
|
724
|
+
with pytest.raises(MethodNotSupported, match="eth_sendTransaction"):
|
|
725
|
+
batch.add(async_math_contract.functions.multiply7(1).transact({}))
|
|
726
|
+
await batch.async_execute()
|
|
727
|
+
|
|
728
|
+
async with async_w3.batch_requests() as batch:
|
|
729
|
+
with pytest.raises(MethodNotSupported, match="eth_sendRawTransaction"):
|
|
730
|
+
batch.add(async_w3.eth.send_raw_transaction(b""))
|
|
731
|
+
await batch.async_execute()
|
|
732
|
+
|
|
733
|
+
async with async_w3.batch_requests() as batch:
|
|
734
|
+
with pytest.raises(MethodNotSupported, match="eth_sign"):
|
|
735
|
+
batch.add(async_w3.eth.sign(Address(b"\x00" * 20)))
|
|
736
|
+
await batch.async_execute()
|
web3/_utils/rpc_abi.py
CHANGED
|
@@ -52,7 +52,6 @@ class RPC:
|
|
|
52
52
|
eth_call = RPCEndpoint("eth_call")
|
|
53
53
|
eth_createAccessList = RPCEndpoint("eth_createAccessList")
|
|
54
54
|
eth_chainId = RPCEndpoint("eth_chainId")
|
|
55
|
-
eth_coinbase = RPCEndpoint("eth_coinbase")
|
|
56
55
|
eth_estimateGas = RPCEndpoint("eth_estimateGas")
|
|
57
56
|
eth_feeHistory = RPCEndpoint("eth_feeHistory")
|
|
58
57
|
eth_maxPriorityFeePerGas = RPCEndpoint("eth_maxPriorityFeePerGas")
|
|
@@ -94,8 +93,6 @@ class RPC:
|
|
|
94
93
|
eth_getUncleCountByBlockHash = RPCEndpoint("eth_getUncleCountByBlockHash")
|
|
95
94
|
eth_getUncleCountByBlockNumber = RPCEndpoint("eth_getUncleCountByBlockNumber")
|
|
96
95
|
eth_getWork = RPCEndpoint("eth_getWork")
|
|
97
|
-
eth_hashrate = RPCEndpoint("eth_hashrate")
|
|
98
|
-
eth_mining = RPCEndpoint("eth_mining")
|
|
99
96
|
eth_newBlockFilter = RPCEndpoint("eth_newBlockFilter")
|
|
100
97
|
eth_newFilter = RPCEndpoint("eth_newFilter")
|
|
101
98
|
eth_newPendingTransactionFilter = RPCEndpoint("eth_newPendingTransactionFilter")
|
web3/beacon/__init__.py
CHANGED
web3/beacon/async_beacon.py
CHANGED
|
@@ -8,9 +8,8 @@ from eth_typing import (
|
|
|
8
8
|
HexStr,
|
|
9
9
|
)
|
|
10
10
|
|
|
11
|
-
from web3._utils.
|
|
12
|
-
|
|
13
|
-
async_json_make_get_request,
|
|
11
|
+
from web3._utils.http_session_manager import (
|
|
12
|
+
HTTPSessionManager,
|
|
14
13
|
)
|
|
15
14
|
from web3.beacon.api_endpoints import (
|
|
16
15
|
GET_ATTESTATIONS,
|
|
@@ -63,10 +62,13 @@ class AsyncBeacon:
|
|
|
63
62
|
) -> None:
|
|
64
63
|
self.base_url = base_url
|
|
65
64
|
self.request_timeout = request_timeout
|
|
65
|
+
self._request_session_manager = HTTPSessionManager()
|
|
66
66
|
|
|
67
67
|
async def _async_make_get_request(self, endpoint_uri: str) -> Dict[str, Any]:
|
|
68
68
|
uri = URI(self.base_url + endpoint_uri)
|
|
69
|
-
return await async_json_make_get_request(
|
|
69
|
+
return await self._request_session_manager.async_json_make_get_request(
|
|
70
|
+
uri, timeout=self.request_timeout
|
|
71
|
+
)
|
|
70
72
|
|
|
71
73
|
# [ BEACON endpoints ]
|
|
72
74
|
|
|
@@ -208,7 +210,9 @@ class AsyncBeacon:
|
|
|
208
210
|
|
|
209
211
|
async def get_health(self) -> int:
|
|
210
212
|
url = URI(self.base_url + GET_HEALTH)
|
|
211
|
-
response =
|
|
213
|
+
response = (
|
|
214
|
+
await self._request_session_manager.async_get_response_from_get_request(url)
|
|
215
|
+
)
|
|
212
216
|
return response.status
|
|
213
217
|
|
|
214
218
|
async def get_version(self) -> Dict[str, Any]:
|
web3/beacon/beacon.py
CHANGED
|
@@ -8,9 +8,8 @@ from eth_typing import (
|
|
|
8
8
|
HexStr,
|
|
9
9
|
)
|
|
10
10
|
|
|
11
|
-
from web3._utils.
|
|
12
|
-
|
|
13
|
-
json_make_get_request,
|
|
11
|
+
from web3._utils.http_session_manager import (
|
|
12
|
+
HTTPSessionManager,
|
|
14
13
|
)
|
|
15
14
|
from web3.beacon.api_endpoints import (
|
|
16
15
|
GET_ATTESTATIONS,
|
|
@@ -61,10 +60,13 @@ class Beacon:
|
|
|
61
60
|
) -> None:
|
|
62
61
|
self.base_url = base_url
|
|
63
62
|
self.request_timeout = request_timeout
|
|
63
|
+
self._request_session_manager = HTTPSessionManager()
|
|
64
64
|
|
|
65
65
|
def _make_get_request(self, endpoint_url: str) -> Dict[str, Any]:
|
|
66
66
|
uri = URI(self.base_url + endpoint_url)
|
|
67
|
-
return json_make_get_request(
|
|
67
|
+
return self._request_session_manager.json_make_get_request(
|
|
68
|
+
uri, timeout=self.request_timeout
|
|
69
|
+
)
|
|
68
70
|
|
|
69
71
|
# [ BEACON endpoints ]
|
|
70
72
|
|
|
@@ -196,7 +198,7 @@ class Beacon:
|
|
|
196
198
|
|
|
197
199
|
def get_health(self) -> int:
|
|
198
200
|
url = URI(self.base_url + GET_HEALTH)
|
|
199
|
-
response = get_response_from_get_request(url)
|
|
201
|
+
response = self._request_session_manager.get_response_from_get_request(url)
|
|
200
202
|
return response.status_code
|
|
201
203
|
|
|
202
204
|
def get_version(self) -> Dict[str, Any]:
|
web3/contract/__init__.py
CHANGED
web3/contract/base_contract.py
CHANGED
|
@@ -16,6 +16,9 @@ from typing import (
|
|
|
16
16
|
)
|
|
17
17
|
import warnings
|
|
18
18
|
|
|
19
|
+
from eth_abi.exceptions import (
|
|
20
|
+
InsufficientDataBytes,
|
|
21
|
+
)
|
|
19
22
|
from eth_typing import (
|
|
20
23
|
Address,
|
|
21
24
|
ChecksumAddress,
|
|
@@ -174,7 +177,13 @@ class BaseContractEvent:
|
|
|
174
177
|
for log in txn_receipt["logs"]:
|
|
175
178
|
try:
|
|
176
179
|
rich_log = get_event_data(self.w3.codec, self.abi, log)
|
|
177
|
-
except (
|
|
180
|
+
except (
|
|
181
|
+
MismatchedABI,
|
|
182
|
+
LogTopicError,
|
|
183
|
+
InvalidEventABI,
|
|
184
|
+
TypeError,
|
|
185
|
+
InsufficientDataBytes,
|
|
186
|
+
) as e:
|
|
178
187
|
if errors == DISCARD:
|
|
179
188
|
continue
|
|
180
189
|
elif errors == IGNORE:
|