Skip to content

Commit

Permalink
catch InsufficientDataBytes errors when parsing logs
Browse files Browse the repository at this point in the history
  • Loading branch information
pacrob committed May 15, 2024
1 parent 2f7d895 commit 407de86
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
1 change: 1 addition & 0 deletions newsfragments/3388.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Properly handle ``InsufficientDataBytes`` errors when processing receipts
30 changes: 30 additions & 0 deletions tests/core/contracts/test_extracting_event_data.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import copy
import pytest
import re

from eth_abi.exceptions import (
InsufficientDataBytes,
)
from eth_utils import (
is_same_address,
)
Expand Down Expand Up @@ -1233,3 +1237,29 @@ def test_get_all_entries_with_nested_tuple_event_non_strict(
assert log_entry.blockNumber == txn_receipt["blockNumber"]
assert log_entry.transactionIndex == txn_receipt["transactionIndex"]
assert is_same_address(log_entry.address, non_strict_emitter.address)


def test_receipt_processing_catches_insufficientdatabytes_error_by_default(
w3, emitter, wait_for_transaction
):
txn_hash = emitter.functions.logListArgs([b"13"], [b"54"]).transact()
txn_receipt = wait_for_transaction(w3, txn_hash)
event_instance = emitter.events.LogListArgs()

# web3 doesn't generate logs with non-standard lengths, so we have to do it manually
txn_receipt_dict = copy.deepcopy(txn_receipt)
txn_receipt_dict["logs"][0] = dict(txn_receipt_dict["logs"][0])
txn_receipt_dict["logs"][0]["data"] = txn_receipt_dict["logs"][0]["data"][:-8]

# WARN is default
assert len(event_instance.process_receipt(txn_receipt_dict)) == 0
assert len(event_instance.process_receipt(txn_receipt_dict, errors=WARN)) == 0
assert len(event_instance.process_receipt(txn_receipt_dict, errors=DISCARD)) == 0

# IGNORE includes the InsufficientDataBytes error in the log
assert len(event_instance.process_receipt(txn_receipt_dict, errors=IGNORE)) == 1

# STRICT raises an error to be caught
with pytest.raises(InsufficientDataBytes):
returned_log = event_instance.process_receipt(txn_receipt_dict, errors=STRICT)
assert len(returned_log) == 0
11 changes: 10 additions & 1 deletion web3/contract/base_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
)
import warnings

from eth_abi.exceptions import (
InsufficientDataBytes,
)
from eth_typing import (
Address,
ChecksumAddress,
Expand Down Expand Up @@ -174,7 +177,13 @@ def _parse_logs(
for log in txn_receipt["logs"]:
try:
rich_log = get_event_data(self.w3.codec, self.abi, log)
except (MismatchedABI, LogTopicError, InvalidEventABI, TypeError) as e:
except (
MismatchedABI,
LogTopicError,
InvalidEventABI,
TypeError,
InsufficientDataBytes,
) as e:
if errors == DISCARD:
continue
elif errors == IGNORE:
Expand Down

0 comments on commit 407de86

Please sign in to comment.