web3 7.0.0b4__py3-none-any.whl → 7.0.0b6__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.
- web3/_utils/batching.py +217 -0
- web3/_utils/caching.py +26 -2
- web3/_utils/compat/__init__.py +1 -0
- web3/_utils/contracts.py +5 -5
- web3/_utils/events.py +20 -20
- web3/_utils/filters.py +6 -6
- web3/_utils/method_formatters.py +0 -23
- web3/_utils/module_testing/__init__.py +0 -3
- web3/_utils/module_testing/eth_module.py +442 -373
- web3/_utils/module_testing/module_testing_utils.py +13 -0
- web3/_utils/module_testing/web3_module.py +438 -17
- web3/_utils/rpc_abi.py +0 -18
- web3/contract/async_contract.py +11 -11
- web3/contract/base_contract.py +19 -18
- web3/contract/contract.py +13 -13
- web3/contract/utils.py +112 -4
- web3/eth/async_eth.py +10 -8
- web3/eth/eth.py +7 -6
- web3/exceptions.py +75 -21
- web3/gas_strategies/time_based.py +2 -2
- web3/geth.py +0 -188
- web3/main.py +21 -13
- web3/manager.py +237 -74
- web3/method.py +29 -9
- web3/middleware/base.py +43 -0
- web3/middleware/filter.py +18 -6
- web3/middleware/signing.py +2 -2
- web3/module.py +47 -7
- web3/providers/async_base.py +55 -23
- web3/providers/base.py +59 -26
- web3/providers/eth_tester/defaults.py +0 -48
- web3/providers/eth_tester/main.py +36 -11
- web3/providers/eth_tester/middleware.py +3 -8
- web3/providers/ipc.py +23 -8
- web3/providers/legacy_websocket.py +26 -1
- 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/async_rpc.py +20 -2
- web3/providers/rpc/rpc.py +22 -2
- web3/providers/rpc/utils.py +1 -10
- web3/tools/benchmark/node.py +2 -8
- web3/types.py +8 -2
- {web3-7.0.0b4.dist-info → web3-7.0.0b6.dist-info}/LICENSE +1 -1
- {web3-7.0.0b4.dist-info → web3-7.0.0b6.dist-info}/METADATA +32 -21
- {web3-7.0.0b4.dist-info → web3-7.0.0b6.dist-info}/RECORD +49 -49
- web3/_utils/module_testing/go_ethereum_personal_module.py +0 -300
- {web3-7.0.0b4.dist-info → web3-7.0.0b6.dist-info}/WHEEL +0 -0
- {web3-7.0.0b4.dist-info → web3-7.0.0b6.dist-info}/top_level.txt +0 -0
|
@@ -177,6 +177,12 @@ class WebSocketMessageStreamMock:
|
|
|
177
177
|
self.messages = deque(messages) if messages else deque()
|
|
178
178
|
self.raise_exception = raise_exception
|
|
179
179
|
|
|
180
|
+
def __await__(self) -> Generator[Any, Any, "Self"]:
|
|
181
|
+
async def __async_init__() -> "Self":
|
|
182
|
+
return self
|
|
183
|
+
|
|
184
|
+
return __async_init__().__await__()
|
|
185
|
+
|
|
180
186
|
def __aiter__(self) -> "Self":
|
|
181
187
|
return self
|
|
182
188
|
|
|
@@ -189,6 +195,13 @@ class WebSocketMessageStreamMock:
|
|
|
189
195
|
|
|
190
196
|
return self.messages.popleft()
|
|
191
197
|
|
|
198
|
+
@staticmethod
|
|
199
|
+
async def pong() -> Literal[False]:
|
|
200
|
+
return False
|
|
201
|
+
|
|
202
|
+
async def connect(self) -> None:
|
|
203
|
+
pass
|
|
204
|
+
|
|
192
205
|
async def send(self, data: bytes) -> None:
|
|
193
206
|
pass
|
|
194
207
|
|
|
@@ -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
|
@@ -123,18 +123,6 @@ class RPC:
|
|
|
123
123
|
net_peerCount = RPCEndpoint("net_peerCount")
|
|
124
124
|
net_version = RPCEndpoint("net_version")
|
|
125
125
|
|
|
126
|
-
# personal
|
|
127
|
-
personal_ecRecover = RPCEndpoint("personal_ecRecover")
|
|
128
|
-
personal_importRawKey = RPCEndpoint("personal_importRawKey")
|
|
129
|
-
personal_listAccounts = RPCEndpoint("personal_listAccounts")
|
|
130
|
-
personal_listWallets = RPCEndpoint("personal_listWallets")
|
|
131
|
-
personal_lockAccount = RPCEndpoint("personal_lockAccount")
|
|
132
|
-
personal_newAccount = RPCEndpoint("personal_newAccount")
|
|
133
|
-
personal_sendTransaction = RPCEndpoint("personal_sendTransaction")
|
|
134
|
-
personal_sign = RPCEndpoint("personal_sign")
|
|
135
|
-
personal_signTypedData = RPCEndpoint("personal_signTypedData")
|
|
136
|
-
personal_unlockAccount = RPCEndpoint("personal_unlockAccount")
|
|
137
|
-
|
|
138
126
|
# testing
|
|
139
127
|
testing_timeTravel = RPCEndpoint("testing_timeTravel")
|
|
140
128
|
|
|
@@ -211,12 +199,6 @@ RPC_ABIS: Dict[str, Union[Sequence[Any], Dict[str, str]]] = {
|
|
|
211
199
|
"eth_signTypedData": ["address", None],
|
|
212
200
|
"eth_submitHashrate": ["uint", "bytes32"],
|
|
213
201
|
"eth_submitWork": ["bytes8", "bytes32", "bytes32"],
|
|
214
|
-
# personal
|
|
215
|
-
"personal_sendTransaction": TRANSACTION_PARAMS_ABIS,
|
|
216
|
-
"personal_lockAccount": ["address"],
|
|
217
|
-
"personal_unlockAccount": ["address", None, None],
|
|
218
|
-
"personal_sign": [None, "address", None],
|
|
219
|
-
"personal_signTypedData": [None, "address", None],
|
|
220
202
|
"trace_call": TRANSACTION_PARAMS_ABIS,
|
|
221
203
|
"trace_filter": TRACE_FILTER_PARAM_ABIS,
|
|
222
204
|
}
|
web3/contract/async_contract.py
CHANGED
|
@@ -111,8 +111,8 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
111
111
|
async def get_logs(
|
|
112
112
|
self,
|
|
113
113
|
argument_filters: Optional[Dict[str, Any]] = None,
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
from_block: Optional[BlockIdentifier] = None,
|
|
115
|
+
to_block: Optional[BlockIdentifier] = None,
|
|
116
116
|
block_hash: Optional[HexBytes] = None,
|
|
117
117
|
) -> Awaitable[Iterable[EventData]]:
|
|
118
118
|
"""
|
|
@@ -135,7 +135,7 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
135
135
|
from = max(mycontract.web3.eth.block_number - 10, 1)
|
|
136
136
|
to = mycontract.web3.eth.block_number
|
|
137
137
|
|
|
138
|
-
events = mycontract.events.Transfer.getLogs(
|
|
138
|
+
events = mycontract.events.Transfer.getLogs(from_block=from, to_block=to)
|
|
139
139
|
|
|
140
140
|
for e in events:
|
|
141
141
|
print(e["args"]["from"],
|
|
@@ -165,10 +165,10 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
165
165
|
|
|
166
166
|
:param argument_filters: Filter by argument values. Indexed arguments are
|
|
167
167
|
filtered by the node while non-indexed arguments are filtered by the library.
|
|
168
|
-
:param
|
|
169
|
-
:param
|
|
168
|
+
:param from_block: block number or "latest", defaults to "latest"
|
|
169
|
+
:param to_block: block number or "latest". Defaults to "latest"
|
|
170
170
|
:param block_hash: block hash. Cannot be set at the
|
|
171
|
-
same time as
|
|
171
|
+
same time as ``from_block`` or ``to_block``
|
|
172
172
|
:yield: Tuple of :class:`AttributeDict` instances
|
|
173
173
|
"""
|
|
174
174
|
event_abi = self._get_event_abi()
|
|
@@ -183,7 +183,7 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
183
183
|
)
|
|
184
184
|
|
|
185
185
|
_filter_params = self._get_event_filter_params(
|
|
186
|
-
event_abi, argument_filters,
|
|
186
|
+
event_abi, argument_filters, from_block, to_block, block_hash
|
|
187
187
|
)
|
|
188
188
|
# call JSON-RPC API
|
|
189
189
|
logs = await self.w3.eth.get_logs(_filter_params)
|
|
@@ -204,8 +204,8 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
204
204
|
self,
|
|
205
205
|
*, # PEP 3102
|
|
206
206
|
argument_filters: Optional[Dict[str, Any]] = None,
|
|
207
|
-
|
|
208
|
-
|
|
207
|
+
from_block: Optional[BlockIdentifier] = None,
|
|
208
|
+
to_block: BlockIdentifier = "latest",
|
|
209
209
|
address: Optional[ChecksumAddress] = None,
|
|
210
210
|
topics: Optional[Sequence[Any]] = None,
|
|
211
211
|
) -> AsyncLogFilter:
|
|
@@ -215,8 +215,8 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
215
215
|
filter_builder = AsyncEventFilterBuilder(self._get_event_abi(), self.w3.codec)
|
|
216
216
|
self._set_up_filter_builder(
|
|
217
217
|
argument_filters,
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
from_block,
|
|
219
|
+
to_block,
|
|
220
220
|
address,
|
|
221
221
|
topics,
|
|
222
222
|
filter_builder,
|