Skip to content

Commit

Permalink
fix: issue causing entire plugin to no longer function [APE-1207] (#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey committed Jul 19, 2023
1 parent 2f49991 commit dd5b0f3
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 12 deletions.
46 changes: 39 additions & 7 deletions ape_hardhat/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@
HARDHAT_CONFIG = """
// See https://hardhat.org/config/ for config options.
module.exports = {{
hardfork: "{hard_fork}",
networks: {{
hardhat: {{
hardfork: "{hard_fork}",
// Base fee of 0 allows use of 0 gas price when testing
initialBaseFeePerGas: 0,
accounts: {{
Expand Down Expand Up @@ -234,7 +234,11 @@ def timeout(self) -> int:

@property
def _clean_uri(self) -> str:
return str(URL(self.uri).with_user(None).with_password(None))
try:
return str(URL(self.uri).with_user(None).with_password(None))
except ValueError:
# Likely isn't a real URI.
return self.uri

@property
def _port(self) -> Optional[int]:
Expand Down Expand Up @@ -327,7 +331,15 @@ def is_connected(self) -> bool:

@property
def bin_path(self) -> Path:
return self.project_folder / "node_modules" / ".bin" / "hardhat"
suffix = Path("node_modules") / ".bin" / "hardhat"
options = (self.project_folder, Path.home())
for base in options:
path = base / suffix
if path.exists():
return path

# Default to the expected path suffx (relative).
return suffix

@property
def hardhat_config_file(self) -> Path:
Expand Down Expand Up @@ -368,6 +380,15 @@ def package_is_plugin(package: str) -> bool:

return plugins

@property
def gas_price(self) -> int:
# TODO: Remove this once Ape > 0.6.13
result = super().gas_price
if isinstance(result, str) and is_0x_prefixed(result):
return int(result, 16)

return result

def _has_hardhat_plugin(self, plugin_name: str) -> bool:
return next((True for plugin in self._hardhat_plugins if plugin == plugin_name), False)

Expand Down Expand Up @@ -413,8 +434,11 @@ def connect(self):
if self.is_connected:
# Connects to already running process
self._start()
elif self.config.manage_process:
elif self.config.manage_process and (
"localhost" in self._host or "127.0.0.1" in self._host or self._host == "auto"
):
# Only do base-process setup if not connecting to already-running process
# and is running on localhost.
super().connect()

if self._host:
Expand All @@ -438,17 +462,25 @@ def connect(self):
except SubprocessError as exc:
logger.info("Retrying Hardhat subprocess startup: %r", exc)
self._host = None
else:

elif not self.is_connected:
raise HardhatProviderError(
f"Failed to connect to remote Hardhat node at {self._clean_uri}`"
f"Failed to connect to remote Hardhat node at '{self._clean_uri}'."
)

def _set_web3(self):
if not self._host:
return

self._web3 = _create_web3(self.uri, self.timeout)
if not self._web3.is_connected():

try:
is_connected = self._web3.is_connected()
except Exception:
self._web3 = None
return

if not is_connected:
self._web3 = None
return

Expand Down
13 changes: 13 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import shutil
import subprocess
import tempfile
from contextlib import contextmanager
Expand Down Expand Up @@ -282,3 +283,15 @@ def side_effect(cmd_ls):
check_output_mock = mocker.patch("ape_hardhat.provider.check_output")
check_output_mock.side_effect = side_effect
return check_output_mock


@pytest.fixture
def no_hardhat_bin(project):
bin_path = project.path / "node_modules" / ".bin" / "hardhat"
bin_copy = project.path / "node_modules" / ".bin" / "hardhat-2"
shutil.move(bin_path, bin_copy)

try:
yield
finally:
shutil.move(bin_copy, bin_path)
40 changes: 35 additions & 5 deletions tests/test_provider.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import shutil
import tempfile
from pathlib import Path

Expand All @@ -12,7 +13,7 @@
from evm_trace import CallType
from hexbytes import HexBytes

from ape_hardhat.exceptions import HardhatNotInstalledError, HardhatSubprocessError
from ape_hardhat.exceptions import HardhatNotInstalledError, HardhatProviderError
from ape_hardhat.provider import HARDHAT_CHAIN_ID

TEST_WALLET_ADDRESS = "0xD9b7fdb3FC0A0Aa3A507dCf0976bc23D49a9C7A3"
Expand Down Expand Up @@ -262,16 +263,18 @@ def test_host(temp_config, networks, host):
assert provider.uri == "https://example.com"


def test_use_different_config(temp_config, networks):
def test_use_different_config(temp_config, networks, project):
data = {"hardhat": {"hardhat_config_file": "./hardhat.config.ts"}}
with temp_config(data):
provider = networks.ethereum.local.get_provider("hardhat")
assert provider.hardhat_config_file.name == "hardhat.config.ts"
assert "--config" in provider._get_command()

with pytest.raises(HardhatSubprocessError):
# This raises because Hardhat is not installed in the temp project.
provider.build_command()
actual = provider._get_command()
assert "npx" in actual[0]
# Will either be home dir hardhat if installed there
# or just the relative suffix (like in CI).
assert actual[1].endswith("node_modules/.bin/hardhat")


def test_connect_when_hardhat_not_installed(networks, mock_web3, install_detection_fail):
Expand Down Expand Up @@ -299,3 +302,30 @@ def test_get_virtual_machine_error_when_sol_panic(connected_provider):
actual = connected_provider.get_virtual_machine_error(err)
expected = "0x1"
assert actual.revert_message == expected


def test_bin_path(connected_provider, project):
actual = connected_provider.bin_path
expected = project.path / "node_modules" / ".bin" / "hardhat"
assert actual == expected

bin_cp = project.path / "node_modules" / ".bin" / "hardhat-2"
shutil.move(expected, bin_cp)

try:
actual = connected_provider.bin_path
assert actual.as_posix().endswith("node_modules/.bin/hardhat")

finally:
shutil.move(bin_cp, expected)


def test_remote_host(temp_config, networks, no_hardhat_bin, project):
data = {"hardhat": {"host": "https://example.com"}}
with temp_config(data):
with pytest.raises(
HardhatProviderError,
match=r"Failed to connect to remote Hardhat node at 'https://example.com'\.",
):
with networks.ethereum.local.use_provider("hardhat"):
pass

0 comments on commit dd5b0f3

Please sign in to comment.