diff --git a/setup.py b/setup.py index 5d1001f387..7daecfbe8e 100644 --- a/setup.py +++ b/setup.py @@ -121,8 +121,8 @@ "eth-account>=0.10.0,<0.11", "eth-typing>=3.5.2,<4", "eth-utils>=2.3.1,<3", - "py-geth>=4.2.0,<5", - "web3[tester]>=6.15.1,<7", + "py-geth>=4.4.0,<5", + "web3[tester]>=6.16.0,<7", # ** Dependencies maintained by ApeWorX ** "eip712>=0.2.3,<0.4", "ethpm-types>=0.6.7,<0.7", diff --git a/src/ape_ethereum/provider.py b/src/ape_ethereum/provider.py index 69d95eb1dc..6188832ef0 100644 --- a/src/ape_ethereum/provider.py +++ b/src/ape_ethereum/provider.py @@ -14,7 +14,7 @@ import requests from eth_pydantic_types import HexBytes from eth_typing import BlockNumber, HexStr -from eth_utils import add_0x_prefix, to_hex +from eth_utils import add_0x_prefix, is_hex, to_hex from ethpm_types import EventABI from evm_trace import CallTreeNode as EvmCallTreeNode from evm_trace import ParityTraceList @@ -407,7 +407,6 @@ def send_call( ) -> HexBytes: if block_id is not None: kwargs["block_identifier"] = block_id - if kwargs.pop("skip_trace", False): return self._send_call(txn, **kwargs) elif self._test_runner is not None: @@ -1146,7 +1145,14 @@ def _handle_execution_reverted( contract_address: Optional[AddressType] = None, source_traceback: Optional[SourceTraceback] = None, ) -> ContractLogicError: - message = str(exception).split(":")[-1].strip() + + if hasattr(exception, "args") and len(exception.args) == 2: + message = exception.args[0] + data = exception.args[1] + else: + message = str(exception).split(":")[-1].strip() + data = None + params: Dict = { "trace": trace, "contract_address": contract_address, @@ -1155,31 +1161,35 @@ def _handle_execution_reverted( no_reason = message == "execution reverted" if isinstance(exception, Web3ContractLogicError) and no_reason: - # Check for custom exception data and use that as the message instead. - # This allows compiler exception enrichment to function. - err_trace = None - try: - if trace: - trace, err_trace = tee(trace) - elif txn: - err_trace = self.provider.get_transaction_trace(txn.txn_hash.hex()) - + if data is None: + # Check for custom exception data and use that as the message instead. + # This allows compiler exception enrichment to function. + err_trace = None try: - trace_ls: List[TraceFrame] = list(err_trace) if err_trace else [] - except Exception as err: - logger.error(f"Failed getting traceback: {err}") - trace_ls = [] - - data = trace_ls[-1].raw if len(trace_ls) > 0 else {} - memory = data.get("memory", []) - return_value = "".join([x[2:] for x in memory[4:]]) - if return_value: - message = f"0x{return_value}" - no_reason = False - - except (ApeException, NotImplementedError): - # Either provider does not support or isn't a custom exception. - pass + if trace: + trace, err_trace = tee(trace) + elif txn: + err_trace = self.provider.get_transaction_trace(txn.txn_hash.hex()) + + try: + trace_ls: List[TraceFrame] = list(err_trace) if err_trace else [] + except Exception as err: + logger.error(f"Failed getting traceback: {err}") + trace_ls = [] + + data = trace_ls[-1].raw if len(trace_ls) > 0 else {} + memory = data.get("memory", []) + return_value = "".join([x[2:] for x in memory[4:]]) + if return_value: + message = f"0x{return_value}" + no_reason = False + + except (ApeException, NotImplementedError): + # Either provider does not support or isn't a custom exception. + pass + + elif data != "no data" and is_hex(data): + message = add_0x_prefix(data) result = ( ContractLogicError(txn=txn, **params) @@ -1313,8 +1323,6 @@ def _complete_connect(self): else "Error getting chain id." ) - is_likely_poa = False - # NOTE: We have to check both earliest and latest # because if the chain was _ever_ PoA, we need # this middleware. diff --git a/tests/functional/test_contract_instance.py b/tests/functional/test_contract_instance.py index d3ada51e5d..1bfd9a61b0 100644 --- a/tests/functional/test_contract_instance.py +++ b/tests/functional/test_contract_instance.py @@ -772,7 +772,8 @@ def test_identifier_lookup(vyper_contract_instance): def test_source_path(project_with_contract, owner): contracts_folder = project_with_contract.contracts_folder - contract = project_with_contract.contracts["Contract"] + contracts = project_with_contract.load_contracts() + contract = contracts["Contract"] contract_instance = owner.deploy(project_with_contract.get_contract("Contract")) expected = contracts_folder / contract.source_id