Skip to content

Commit 407de86

Browse files
committed
catch InsufficientDataBytes errors when parsing logs
1 parent 2f7d895 commit 407de86

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

newsfragments/3388.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Properly handle ``InsufficientDataBytes`` errors when processing receipts

tests/core/contracts/test_extracting_event_data.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
import copy
12
import pytest
23
import re
34

5+
from eth_abi.exceptions import (
6+
InsufficientDataBytes,
7+
)
48
from eth_utils import (
59
is_same_address,
610
)
@@ -1233,3 +1237,29 @@ def test_get_all_entries_with_nested_tuple_event_non_strict(
12331237
assert log_entry.blockNumber == txn_receipt["blockNumber"]
12341238
assert log_entry.transactionIndex == txn_receipt["transactionIndex"]
12351239
assert is_same_address(log_entry.address, non_strict_emitter.address)
1240+
1241+
1242+
def test_receipt_processing_catches_insufficientdatabytes_error_by_default(
1243+
w3, emitter, wait_for_transaction
1244+
):
1245+
txn_hash = emitter.functions.logListArgs([b"13"], [b"54"]).transact()
1246+
txn_receipt = wait_for_transaction(w3, txn_hash)
1247+
event_instance = emitter.events.LogListArgs()
1248+
1249+
# web3 doesn't generate logs with non-standard lengths, so we have to do it manually
1250+
txn_receipt_dict = copy.deepcopy(txn_receipt)
1251+
txn_receipt_dict["logs"][0] = dict(txn_receipt_dict["logs"][0])
1252+
txn_receipt_dict["logs"][0]["data"] = txn_receipt_dict["logs"][0]["data"][:-8]
1253+
1254+
# WARN is default
1255+
assert len(event_instance.process_receipt(txn_receipt_dict)) == 0
1256+
assert len(event_instance.process_receipt(txn_receipt_dict, errors=WARN)) == 0
1257+
assert len(event_instance.process_receipt(txn_receipt_dict, errors=DISCARD)) == 0
1258+
1259+
# IGNORE includes the InsufficientDataBytes error in the log
1260+
assert len(event_instance.process_receipt(txn_receipt_dict, errors=IGNORE)) == 1
1261+
1262+
# STRICT raises an error to be caught
1263+
with pytest.raises(InsufficientDataBytes):
1264+
returned_log = event_instance.process_receipt(txn_receipt_dict, errors=STRICT)
1265+
assert len(returned_log) == 0

web3/contract/base_contract.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
)
1717
import warnings
1818

19+
from eth_abi.exceptions import (
20+
InsufficientDataBytes,
21+
)
1922
from eth_typing import (
2023
Address,
2124
ChecksumAddress,
@@ -174,7 +177,13 @@ def _parse_logs(
174177
for log in txn_receipt["logs"]:
175178
try:
176179
rich_log = get_event_data(self.w3.codec, self.abi, log)
177-
except (MismatchedABI, LogTopicError, InvalidEventABI, TypeError) as e:
180+
except (
181+
MismatchedABI,
182+
LogTopicError,
183+
InvalidEventABI,
184+
TypeError,
185+
InsufficientDataBytes,
186+
) as e:
178187
if errors == DISCARD:
179188
continue
180189
elif errors == IGNORE:

0 commit comments

Comments
 (0)