Skip to content

Commit

Permalink
fix: issue where deploy failures would not enrichment [APE-1142] (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey committed Jul 5, 2023
1 parent 2abd3c3 commit 4046c6f
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 29 deletions.
47 changes: 20 additions & 27 deletions ape_solidity/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,45 +694,38 @@ def enrich_error(self, err: ContractLogicError) -> ContractLogicError:
bytes_message = HexBytes(err.revert_message)
selector = bytes_message[:4]
input_data = bytes_message[4:]
address = err.contract_address or getattr(err.txn, "receiver", None)
if not address:

# TODO: Any version after Ape 0.6.11 we can replace this with `err.address`.
if not (
address := err.contract_address
or getattr(err.txn, "receiver", None)
or getattr(err.txn, "contract_address", None)
):
return err

if not self.network_manager.active_provider:
# Connection required.
return err

contract = self.chain_manager.contracts.instance_at(address)
if not contract:
return err

if selector not in contract.contract_type.errors:
# Not an ErrorABI selector.
if (
not (contract := self.chain_manager.contracts.instance_at(address))
or selector not in contract.contract_type.errors
):
return err

ecosystem = self.provider.network.ecosystem
abi = contract.contract_type.errors[selector]
inputs = ecosystem.decode_calldata(abi, input_data)
error_class = contract.get_error_by_signature(abi.signature)
if self._ape_version <= Version("0.6.10"):
return error_class(
abi,
inputs,
txn=err.txn,
trace=err.trace,
contract_address=err.contract_address,
)
else:
# TODO Bump Ape on next release and remove this conditional
return error_class(
abi,
inputs,
base_err=err.base_err,
contract_address=err.contract_address, # type: ignore[call-arg]
source_traceback=err.source_traceback, # type: ignore[call-arg]
trace=err.trace,
txn=err.txn,
)
return error_class(
abi,
inputs,
base_err=err.base_err,
contract_address=err.contract_address,
source_traceback=err.source_traceback,
trace=err.trace,
txn=err.txn,
)

def _flatten_source(
self, path: Path, base_path: Optional[Path] = None, raw_import_name: Optional[str] = None
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
include_package_data=True,
install_requires=[
"py-solc-x>=1.1.0,<2",
"eth-ape>=0.6.11,<0.7",
"eth-ape>=0.6.12,<0.7",
"ethpm-types", # Use the version ape requires
"packaging", # Use the version ape requires
"requests",
Expand Down
6 changes: 6 additions & 0 deletions tests/contracts/HasError.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ error Unauthorized(address addr, uint256 counter);
contract HasError {
address payable owner = payable(msg.sender);

constructor(uint256 value) {
if (value == 0) {
revert Unauthorized(msg.sender, 123);
}
}

function withdraw() public {
if (msg.sender != owner)
revert Unauthorized(msg.sender, 123);
Expand Down
13 changes: 12 additions & 1 deletion tests/test_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@

import pytest
import solcx # type: ignore
from ape import reverts
from ape.contracts import ContractContainer
from ape.exceptions import CompilerError, ContractLogicError
from ethpm_types.ast import ASTClassification
from pkg_resources import get_distribution
from semantic_version import Version # type: ignore

from ape_solidity import Extension
Expand All @@ -34,6 +36,7 @@
)
raises_because_not_sol = pytest.raises(CompilerError, match=EXPECTED_NON_SOLIDITY_ERR_MSG)
DEFAULT_OPTIMIZER = {"enabled": True, "runs": 200}
APE_VERSION = Version(get_distribution("eth-ape").version.split(".dev")[0].strip())


@pytest.mark.parametrize(
Expand Down Expand Up @@ -400,13 +403,21 @@ def test_enrich_error_when_custom(compiler, project, owner, not_owner, connectio
compiler.compile((project.contracts_folder / "HasError.sol",))

# Deploy so Ape know about contract type.
contract = owner.deploy(project.HasError)
contract = owner.deploy(project.HasError, 1)
with pytest.raises(contract.Unauthorized) as err:
contract.withdraw(sender=not_owner)

assert err.value.inputs == {"addr": not_owner.address, "counter": 123}


def test_enrich_error_when_custom_in_constructor(compiler, project, owner, not_owner, connection):
# Deploy so Ape know about contract type.
with reverts(project.HasError.Unauthorized) as err:
not_owner.deploy(project.HasError, 0)

assert err.value.inputs == {"addr": not_owner.address, "counter": 123}


def test_enrich_error_when_builtin(project, owner, connection):
# TODO: Any version after eth-ape 0.6.11, you can uncomment this and delete the rest.
# contract = project.BuiltinErrorChecker.deploy(sender=owner)
Expand Down

0 comments on commit 4046c6f

Please sign in to comment.