|
14 | 14 | STRICT, |
15 | 15 | WARN, |
16 | 16 | ) |
| 17 | +from web3.exceptions import ( |
| 18 | + LogTopicError, |
| 19 | +) |
17 | 20 |
|
18 | 21 |
|
19 | 22 | @pytest.fixture() |
@@ -89,6 +92,23 @@ def indexed_event_contract( |
89 | 92 | return indexed_event_contract |
90 | 93 |
|
91 | 94 |
|
| 95 | +@pytest.fixture() |
| 96 | +def dup_txn_receipt( |
| 97 | + web3, |
| 98 | + indexed_event_contract, |
| 99 | + wait_for_transaction, |
| 100 | + event_contract): |
| 101 | + |
| 102 | + emitter_fn = indexed_event_contract.functions.logTwoEvents |
| 103 | + |
| 104 | + txn_hash = emitter_fn(12345).transact() |
| 105 | + wait_for_transaction(web3, txn_hash) |
| 106 | + |
| 107 | + event_contract_fn = event_contract.functions.logTwoEvents |
| 108 | + dup_txn_hash = event_contract_fn(12345).transact() |
| 109 | + return wait_for_transaction(web3, dup_txn_hash) |
| 110 | + |
| 111 | + |
92 | 112 | @pytest.mark.parametrize( |
93 | 113 | 'contract_fn,event_name,call_args,expected_args', |
94 | 114 | ( |
@@ -202,7 +222,6 @@ def test_dynamic_length_argument_extraction(web3, |
202 | 222 | @pytest.mark.parametrize( |
203 | 223 | 'contract_fn,event_name,call_args,expected_args', |
204 | 224 | ( |
205 | | - ('logNoArgs', 'LogAnonymous', [], {}), |
206 | 225 | ('logNoArgs', 'LogNoArguments', [], {}), |
207 | 226 | ('logSingle', 'LogSingleArg', [12345], {'arg0': 12345}), |
208 | 227 | ('logSingle', 'LogSingleWithIndex', [12345], {'arg0': 12345}), |
@@ -269,76 +288,112 @@ def test_event_rich_log( |
269 | 288 | assert is_same_address(rich_log['address'], emitter.address) |
270 | 289 | assert rich_log['event'] == event_name |
271 | 290 |
|
| 291 | + rich_logs = event_instance.processReceipt(txn_receipt) |
| 292 | + quiet_event = emitter.events['LogBytes'] |
| 293 | + with pytest.warns(UserWarning, |
| 294 | + match='The event signature did not match the provided ABI'): |
| 295 | + empty_rich_log = quiet_event().processReceipt(txn_receipt) |
| 296 | + assert empty_rich_log == tuple() |
| 297 | + |
| 298 | + |
| 299 | +def test_nonanonymous_event_abi_mismatch_warning( |
| 300 | + web3, |
| 301 | + emitter, |
| 302 | + emitter_event_ids, |
| 303 | + wait_for_transaction): |
| 304 | + emitter_fn = emitter.functions.logNoArgs |
| 305 | + event_id = getattr(emitter_event_ids, 'LogAnonymous') |
| 306 | + txn_hash = emitter_fn(event_id).transact() |
| 307 | + txn_receipt = wait_for_transaction(web3, txn_hash) |
| 308 | + |
| 309 | + event_instance = emitter.events.LogAnonymous() |
| 310 | + |
| 311 | + event_instance.processReceipt(txn_receipt) |
272 | 312 | quiet_event = emitter.events['LogBytes'] |
273 | | - empty_rich_log = quiet_event().processReceipt(txn_receipt) |
274 | | - assert empty_rich_log == tuple() |
| 313 | + with pytest.warns(UserWarning, |
| 314 | + match='Expected non-anonymous event to have 1 or more topics'): |
| 315 | + empty_rich_log = quiet_event().processReceipt(txn_receipt) |
| 316 | + assert empty_rich_log == tuple() |
275 | 317 |
|
276 | 318 |
|
277 | | -@pytest.mark.parametrize( |
278 | | - 'error_flag', |
279 | | - ( |
280 | | - (DISCARD), |
281 | | - (IGNORE), |
282 | | - (STRICT), |
283 | | - (WARN), |
284 | | - ('something_else'), |
285 | | - ) |
286 | | -) |
287 | | -def test_event_processing_with_caught_errors( |
| 319 | +def test_event_processing_with_discard_flag( |
288 | 320 | web3, |
289 | 321 | event_contract, |
290 | 322 | indexed_event_contract, |
291 | | - wait_for_transaction, |
292 | | - error_flag): |
| 323 | + dup_txn_receipt, |
| 324 | + wait_for_transaction): |
293 | 325 |
|
294 | | - emitter_fn = indexed_event_contract.functions.logTwoEvents |
| 326 | + event_instance = indexed_event_contract.events.LogSingleWithIndex() |
| 327 | + returned_logs = event_instance.processReceipt(dup_txn_receipt, errors=DISCARD) |
295 | 328 |
|
296 | | - txn_hash = emitter_fn(12345).transact() |
297 | | - wait_for_transaction(web3, txn_hash) |
| 329 | + assert returned_logs == () |
298 | 330 |
|
299 | | - event_contract_fn = event_contract.functions.logTwoEvents |
300 | | - dup_txn_hash = event_contract_fn(12345).transact() |
301 | | - dup_txn_receipt = wait_for_transaction(web3, dup_txn_hash) |
| 331 | + |
| 332 | +def test_event_processing_with_ignore_flag( |
| 333 | + web3, |
| 334 | + event_contract, |
| 335 | + indexed_event_contract, |
| 336 | + dup_txn_receipt, |
| 337 | + wait_for_transaction): |
302 | 338 |
|
303 | 339 | event_instance = indexed_event_contract.events.LogSingleWithIndex() |
| 340 | + returned_logs = event_instance.processReceipt(dup_txn_receipt, errors=IGNORE) |
| 341 | + assert len(returned_logs) == 2 |
304 | 342 |
|
305 | | - if error_flag is DISCARD: |
306 | | - returned_logs = event_instance.processReceipt(dup_txn_receipt, errors=error_flag) |
307 | | - assert returned_logs == () |
308 | | - elif error_flag is IGNORE: |
309 | | - returned_logs = event_instance.processReceipt(dup_txn_receipt, errors=error_flag) |
310 | | - assert len(returned_logs) == 2 |
311 | | - first_log = dict(returned_logs[0]) |
312 | | - |
313 | | - expected_error = re.compile("Expected 1 log topics. Got 0") |
314 | | - assert expected_error.search(str(first_log['errors'])) is not None |
315 | | - |
316 | | - # Check that the returned log is the same as what got sent in, minus the |
317 | | - # added errors field |
318 | | - del first_log['errors'] |
319 | | - assert first_log == dup_txn_receipt['logs'][0] |
320 | | - assert is_same_address(first_log['address'], event_contract.address) |
321 | | - |
322 | | - # Then, do the same with the other log: |
323 | | - second_log = dict(returned_logs[1]) |
324 | | - |
325 | | - abi_error = re.compile("The event signature did not match the provided ABI") |
326 | | - assert abi_error.search(str(second_log['errors'])) is not None |
327 | | - |
328 | | - # Check that the returned log is the same as what got sent in, minus the |
329 | | - # added errors field |
330 | | - del second_log['errors'] |
331 | | - assert second_log == dup_txn_receipt['logs'][1] |
332 | | - assert is_same_address(second_log['address'], event_contract.address) |
333 | | - elif error_flag is WARN: |
334 | | - with pytest.warns(UserWarning, match='Expected 1 log topics. Got 0'): |
335 | | - returned_log = event_instance.processReceipt(dup_txn_receipt, errors=error_flag) |
336 | | - assert len(returned_log) == 0 |
337 | | - elif error_flag is STRICT: |
338 | | - with pytest.raises(ValueError, match="Expected 1 log topics. Got 0"): |
339 | | - event_instance.processReceipt(dup_txn_receipt, errors=error_flag) |
340 | | - elif error_flag is 'something_else': |
341 | | - with pytest.raises(AttributeError, match="Error flag must be one of:"): |
342 | | - event_instance.processReceipt(dup_txn_receipt, errors=error_flag) |
343 | | - else: |
344 | | - raise Exception('Unreachable!') |
| 343 | + first_log = dict(returned_logs[0]) |
| 344 | + |
| 345 | + # Check that the correct error is appended to the log |
| 346 | + expected_error = re.compile("Expected 1 log topics. Got 0") |
| 347 | + assert expected_error.search(str(first_log['errors'])) is not None |
| 348 | + |
| 349 | + # Check that the returned log is the same as what got sent in, |
| 350 | + # except the added errors field |
| 351 | + del first_log['errors'] |
| 352 | + assert first_log == dup_txn_receipt['logs'][0] |
| 353 | + assert is_same_address(first_log['address'], event_contract.address) |
| 354 | + |
| 355 | + # Then, do the same with the other log: |
| 356 | + second_log = dict(returned_logs[1]) |
| 357 | + |
| 358 | + abi_error = re.compile("The event signature did not match the provided ABI") |
| 359 | + assert abi_error.search(str(second_log['errors'])) is not None |
| 360 | + |
| 361 | + # Check that the returned log is the same as what got sent in, |
| 362 | + # except the added errors field |
| 363 | + del second_log['errors'] |
| 364 | + assert second_log == dup_txn_receipt['logs'][1] |
| 365 | + assert is_same_address(second_log['address'], event_contract.address) |
| 366 | + |
| 367 | + |
| 368 | +def test_event_processing_with_warn_flag( |
| 369 | + web3, |
| 370 | + indexed_event_contract, |
| 371 | + dup_txn_receipt): |
| 372 | + |
| 373 | + event_instance = indexed_event_contract.events.LogSingleWithIndex() |
| 374 | + |
| 375 | + with pytest.warns(UserWarning, match='Expected 1 log topics. Got 0'): |
| 376 | + returned_log = event_instance.processReceipt(dup_txn_receipt, errors=WARN) |
| 377 | + assert len(returned_log) == 0 |
| 378 | + |
| 379 | + |
| 380 | +def test_event_processing_with_strict_flag( |
| 381 | + web3, |
| 382 | + indexed_event_contract, |
| 383 | + dup_txn_receipt): |
| 384 | + |
| 385 | + event_instance = indexed_event_contract.events.LogSingleWithIndex() |
| 386 | + |
| 387 | + with pytest.raises(LogTopicError, match="Expected 1 log topics. Got 0"): |
| 388 | + event_instance.processReceipt(dup_txn_receipt, errors=STRICT) |
| 389 | + |
| 390 | + |
| 391 | +def test_event_processing_with_invalid_flag( |
| 392 | + web3, |
| 393 | + indexed_event_contract, |
| 394 | + dup_txn_receipt): |
| 395 | + |
| 396 | + event_instance = indexed_event_contract.events.LogSingleWithIndex() |
| 397 | + |
| 398 | + with pytest.raises(AttributeError, match=f"Error flag must be one of: "): |
| 399 | + event_instance.processReceipt(dup_txn_receipt, errors='not-a-flag') |
0 commit comments