1
+ import asyncio
1
2
import pytest
2
3
3
4
from hypothesis import (
4
5
given ,
5
6
settings ,
6
7
strategies as st ,
7
8
)
9
+ import pytest_asyncio
8
10
9
- from web3 import Web3
11
+ from tests .core .filtering .utils import (
12
+ _async_emitter_fixture_logic ,
13
+ _async_w3_fixture_logic ,
14
+ _emitter_fixture_logic ,
15
+ _w3_fixture_logic ,
16
+ )
17
+ from tests .utils import (
18
+ _async_wait_for_block_fixture_logic ,
19
+ _async_wait_for_transaction_fixture_logic ,
20
+ )
10
21
from web3 ._utils .module_testing .emitter_contract import (
11
22
CONTRACT_EMITTER_ABI ,
12
23
CONTRACT_EMITTER_CODE ,
13
24
CONTRACT_EMITTER_RUNTIME ,
14
25
)
15
- from web3 .middleware import (
16
- local_filter_middleware ,
17
- )
18
- from web3 .providers .eth_tester import (
19
- EthereumTesterProvider ,
20
- )
21
-
22
-
23
- @pytest .fixture (
24
- scope = "module" ,
25
- params = [True , False ],
26
- ids = ["local_filter_middleware" , "node_based_filter" ],
27
- )
28
- def w3 (request ):
29
- use_filter_middleware = request .param
30
- provider = EthereumTesterProvider ()
31
- w3 = Web3 (provider )
32
- if use_filter_middleware :
33
- w3 .middleware_onion .add (local_filter_middleware )
34
- return w3
35
26
36
27
37
28
@pytest .fixture (scope = "module" )
@@ -58,25 +49,6 @@ def EMITTER(EMITTER_CODE, EMITTER_RUNTIME, EMITTER_ABI):
58
49
}
59
50
60
51
61
- @pytest .fixture (scope = "module" )
62
- def Emitter (w3 , EMITTER ):
63
- return w3 .eth .contract (** EMITTER )
64
-
65
-
66
- @pytest .fixture (scope = "module" )
67
- def emitter (w3 , Emitter , wait_for_transaction , wait_for_block , address_conversion_func ):
68
- wait_for_block (w3 )
69
- deploy_txn_hash = Emitter .constructor ().transact ({"gas" : 10000000 })
70
- deploy_receipt = wait_for_transaction (w3 , deploy_txn_hash )
71
- contract_address = address_conversion_func (deploy_receipt ["contractAddress" ])
72
-
73
- bytecode = w3 .eth .get_code (contract_address )
74
- assert bytecode == Emitter .bytecode_runtime
75
- _emitter = Emitter (address = contract_address )
76
- assert _emitter .address == contract_address
77
- return _emitter
78
-
79
-
80
52
def not_empty_string (x ):
81
53
return x != ""
82
54
@@ -130,6 +102,30 @@ def array_values(draw):
130
102
return (matching , non_matching )
131
103
132
104
105
+ # --- sync --- #
106
+
107
+
108
+ @pytest .fixture (
109
+ scope = "module" ,
110
+ params = [True , False ],
111
+ ids = ["local_filter_middleware" , "node_based_filter" ],
112
+ )
113
+ def w3 (request ):
114
+ return _w3_fixture_logic (request )
115
+
116
+
117
+ @pytest .fixture (scope = "module" )
118
+ def Emitter (w3 , EMITTER ):
119
+ return w3 .eth .contract (** EMITTER )
120
+
121
+
122
+ @pytest .fixture (scope = "module" )
123
+ def emitter (w3 , Emitter , wait_for_transaction , wait_for_block , address_conversion_func ):
124
+ return _emitter_fixture_logic (
125
+ w3 , Emitter , wait_for_transaction , wait_for_block , address_conversion_func
126
+ )
127
+
128
+
133
129
@pytest .mark .parametrize ("api_style" , ("v4" , "build_filter" ))
134
130
@given (vals = dynamic_values ())
135
131
@settings (max_examples = 5 , deadline = None )
@@ -284,3 +280,219 @@ def test_data_filters_with_list_arguments(
284
280
else :
285
281
with pytest .raises (TypeError ):
286
282
create_filter (emitter , ["LogListArgs" , {"filter" : {"arg1" : matching }}])
283
+
284
+
285
+ # --- async --- #
286
+
287
+
288
+ @pytest_asyncio .fixture (scope = "module" )
289
+ async def async_wait_for_block ():
290
+ return _async_wait_for_block_fixture_logic
291
+
292
+
293
+ @pytest_asyncio .fixture (scope = "module" )
294
+ async def async_wait_for_transaction ():
295
+ return _async_wait_for_transaction_fixture_logic
296
+
297
+
298
+ @pytest .fixture (scope = "module" )
299
+ def event_loop ():
300
+ policy = asyncio .get_event_loop_policy ()
301
+ loop = policy .new_event_loop ()
302
+ yield loop
303
+ loop .close ()
304
+
305
+
306
+ @pytest .fixture (
307
+ scope = "module" ,
308
+ params = [True , False ],
309
+ ids = ["local_filter_middleware" , "node_based_filter" ],
310
+ )
311
+ def async_w3 (request ):
312
+ return _async_w3_fixture_logic (request )
313
+
314
+
315
+ @pytest .fixture (scope = "module" )
316
+ def AsyncEmitter (async_w3 , EMITTER ):
317
+ return async_w3 .eth .contract (** EMITTER )
318
+
319
+
320
+ @pytest_asyncio .fixture (scope = "module" )
321
+ async def async_emitter (
322
+ async_w3 ,
323
+ AsyncEmitter ,
324
+ async_wait_for_transaction ,
325
+ async_wait_for_block ,
326
+ address_conversion_func ,
327
+ ):
328
+ return await _async_emitter_fixture_logic (
329
+ async_w3 ,
330
+ AsyncEmitter ,
331
+ async_wait_for_transaction ,
332
+ async_wait_for_block ,
333
+ address_conversion_func ,
334
+ )
335
+
336
+
337
+ @pytest .mark .asyncio
338
+ @pytest .mark .parametrize ("api_style" , ("v4" , "build_filter" ))
339
+ @given (vals = dynamic_values ())
340
+ @settings (max_examples = 5 , deadline = None )
341
+ async def test_async_data_filters_with_dynamic_arguments (
342
+ async_w3 ,
343
+ async_wait_for_transaction ,
344
+ async_create_filter ,
345
+ async_emitter ,
346
+ api_style ,
347
+ vals ,
348
+ ):
349
+ if api_style == "build_filter" :
350
+ filter_builder = async_emitter .events .LogDynamicArgs .build_filter ()
351
+ filter_builder .args ["arg1" ].match_single (vals ["matching" ])
352
+ event_filter = await filter_builder .deploy (async_w3 )
353
+ else :
354
+ event_filter = await async_create_filter (
355
+ async_emitter , ["LogDynamicArgs" , {"filter" : {"arg1" : vals ["matching" ]}}]
356
+ )
357
+
358
+ txn_hashes = [
359
+ await async_emitter .functions .logDynamicArgs (
360
+ arg0 = vals ["matching" ], arg1 = vals ["matching" ]
361
+ ).transact (
362
+ {"maxFeePerGas" : 10 ** 9 , "maxPriorityFeePerGas" : 10 ** 9 , "gas" : 400000 }
363
+ ),
364
+ await async_emitter .functions .logDynamicArgs (
365
+ arg0 = vals ["non_matching" ][0 ], arg1 = vals ["non_matching" ][0 ]
366
+ ).transact (
367
+ {"maxFeePerGas" : 10 ** 9 , "maxPriorityFeePerGas" : 10 ** 9 , "gas" : 400000 }
368
+ ),
369
+ ]
370
+
371
+ for txn_hash in txn_hashes :
372
+ await async_wait_for_transaction (async_w3 , txn_hash )
373
+
374
+ log_entries = await event_filter .get_new_entries ()
375
+ assert len (log_entries ) == 1
376
+ assert log_entries [0 ]["transactionHash" ] == txn_hashes [0 ]
377
+
378
+
379
+ @pytest .mark .asyncio
380
+ @pytest .mark .parametrize ("api_style" , ("v4" , "build_filter" ))
381
+ @given (vals = fixed_values ())
382
+ @settings (max_examples = 5 , deadline = None )
383
+ async def test_async_data_filters_with_fixed_arguments (
384
+ async_w3 ,
385
+ async_emitter ,
386
+ async_wait_for_transaction ,
387
+ async_create_filter ,
388
+ api_style ,
389
+ vals ,
390
+ ):
391
+ if api_style == "build_filter" :
392
+ filter_builder = async_emitter .events .LogQuadrupleArg .build_filter ()
393
+ filter_builder .args ["arg0" ].match_single (vals ["matching" ][0 ])
394
+ filter_builder .args ["arg1" ].match_single (vals ["matching" ][1 ])
395
+ filter_builder .args ["arg2" ].match_single (vals ["matching" ][2 ])
396
+ filter_builder .args ["arg3" ].match_single (vals ["matching" ][3 ])
397
+ event_filter = await filter_builder .deploy (async_w3 )
398
+ else :
399
+ event_filter = await async_create_filter (
400
+ async_emitter ,
401
+ [
402
+ "LogQuadrupleArg" ,
403
+ {
404
+ "filter" : {
405
+ "arg0" : vals ["matching" ][0 ],
406
+ "arg1" : vals ["matching" ][1 ],
407
+ "arg2" : vals ["matching" ][2 ],
408
+ "arg3" : vals ["matching" ][3 ],
409
+ }
410
+ },
411
+ ],
412
+ )
413
+
414
+ txn_hashes = []
415
+ txn_hashes .append (
416
+ await async_emitter .functions .logQuadruple (
417
+ which = 5 ,
418
+ arg0 = vals ["matching" ][0 ],
419
+ arg1 = vals ["matching" ][1 ],
420
+ arg2 = vals ["matching" ][2 ],
421
+ arg3 = vals ["matching" ][3 ],
422
+ ).transact (
423
+ {"maxFeePerGas" : 10 ** 9 , "maxPriorityFeePerGas" : 10 ** 9 , "gas" : 100000 }
424
+ )
425
+ )
426
+ txn_hashes .append (
427
+ await async_emitter .functions .logQuadruple (
428
+ which = 5 ,
429
+ arg0 = vals ["non_matching" ][0 ],
430
+ arg1 = vals ["non_matching" ][1 ],
431
+ arg2 = vals ["non_matching" ][2 ],
432
+ arg3 = vals ["non_matching" ][3 ],
433
+ ).transact (
434
+ {"maxFeePerGas" : 10 ** 9 , "maxPriorityFeePerGas" : 10 ** 9 , "gas" : 100000 }
435
+ )
436
+ )
437
+
438
+ for txn_hash in txn_hashes :
439
+ await async_wait_for_transaction (async_w3 , txn_hash )
440
+
441
+ log_entries = await event_filter .get_new_entries ()
442
+ assert len (log_entries ) == 1
443
+ assert log_entries [0 ]["transactionHash" ] == txn_hashes [0 ]
444
+
445
+
446
+ @pytest .mark .asyncio
447
+ @pytest .mark .parametrize ("api_style" , ("v4" , "build_filter" ))
448
+ @given (vals = array_values ())
449
+ @settings (max_examples = 5 , deadline = None )
450
+ async def test_async_data_filters_with_list_arguments (
451
+ async_w3 ,
452
+ async_emitter ,
453
+ async_wait_for_transaction ,
454
+ async_create_filter ,
455
+ api_style ,
456
+ vals ,
457
+ ):
458
+ matching , non_matching = vals
459
+
460
+ if api_style == "build_filter" :
461
+ filter_builder = async_emitter .events .LogListArgs .build_filter ()
462
+ filter_builder .args ["arg1" ].match_single (matching )
463
+ event_filter = await filter_builder .deploy (async_w3 )
464
+
465
+ txn_hashes = []
466
+ txn_hashes .append (
467
+ await async_emitter .functions .logListArgs (
468
+ arg0 = matching , arg1 = matching
469
+ ).transact ({"maxFeePerGas" : 10 ** 9 , "maxPriorityFeePerGas" : 10 ** 9 })
470
+ )
471
+ txn_hashes .append (
472
+ await async_emitter .functions .logListArgs (
473
+ arg0 = non_matching , arg1 = non_matching
474
+ ).transact ({"maxFeePerGas" : 10 ** 9 , "maxPriorityFeePerGas" : 10 ** 9 })
475
+ )
476
+ txn_hashes .append (
477
+ await async_emitter .functions .logListArgs (
478
+ arg0 = non_matching , arg1 = matching
479
+ ).transact ({"maxFeePerGas" : 10 ** 9 , "maxPriorityFeePerGas" : 10 ** 9 })
480
+ )
481
+ txn_hashes .append (
482
+ await async_emitter .functions .logListArgs (
483
+ arg0 = matching , arg1 = non_matching
484
+ ).transact ({"maxFeePerGas" : 10 ** 9 , "maxPriorityFeePerGas" : 10 ** 9 })
485
+ )
486
+
487
+ for txn_hash in txn_hashes :
488
+ await async_wait_for_transaction (async_w3 , txn_hash )
489
+
490
+ log_entries = await event_filter .get_new_entries ()
491
+ assert len (log_entries ) == 2
492
+ assert log_entries [0 ]["transactionHash" ] == txn_hashes [0 ]
493
+ assert log_entries [1 ]["transactionHash" ] == txn_hashes [2 ]
494
+ else :
495
+ with pytest .raises (TypeError ):
496
+ await async_create_filter (
497
+ async_emitter , ["LogListArgs" , {"filter" : {"arg1" : matching }}]
498
+ )
0 commit comments