Giter Club home page Giter Club logo

ape-hardhat's Introduction

Quick Start

This is a Hardhat network provider plugin for Ape. Hardhat is a development framework written in Node.js for Ethereum that includes a local network implementation. Use this plugin to manage a Hardhat node process or connect to an existing one.

Dependencies

  • python3 version 3.9 up to 3.12.
  • Node.js, NPM, and Hardhat 2.12.0 or greater. See Hardhat's Installation documentation for steps.

Installation

via pip

You can install the latest release via pip:

pip install ape-hardhat

via setuptools

You can clone the repository and use setuptools for the most up-to-date version:

git clone https://github.com/ApeWorX/ape-hardhat.git
cd ape-hardhat
python3 setup.py install

Quick Usage

To use the plugin, first install Hardhat locally into your Ape project directory:

cd your-ape-project
npm install --save-dev hardhat

After that, you can use the --network ethereum:local:hardhat command line flag to use the hardhat network (if it's not already configured as the default).

This network provider takes additional Hardhat-specific configuration options. To use them, add these configs in your project's ape-config.yaml:

hardhat:
  host: 127.0.0.1:8555

To select a random port, use a value of "auto":

hardhat:
  host: auto

NOTE: If you plan on running multiple Hardhat nodes of any kind, you likely will want to use auto or configure multiple hosts (see examples below).

This is useful for multiprocessing and starting up multiple providers.

You can also adjust the request timeout setting:

hardhat:
  request_timeout: 20  # Defaults to 30
  fork_request_timeout: 600  # Defaults to 300

Mainnet Fork

The ape-hardhat plugin also includes a mainnet fork provider. It requires using another provider that has access to mainnet.

Use it in most commands like this:

ape console --network :mainnet-fork:hardhat

Specify the upstream archive-data provider in your ape-config.yaml:

hardhat:
  fork:
    ethereum:
      mainnet:
        upstream_provider: alchemy

Otherwise, it defaults to the default mainnet provider plugin. You can also specify a block_number.

NOTE: Make sure you have the upstream provider plugin installed for ape.

If you wish to run both a forked network and the local Hardhat network simultaneously, you may configure a separate host for the forked network(s).

hardhat:
  fork:
    ethereum:
      mainnet:
        upstream_provider: alchemy
        host: 127.0.0.1:8555
    polygon:
      mainnet:
        upstream_provider: alchemy
        host: 127.0.0.1:8556

Hardhat deployments are disabled for forks for performance reasons. If you want your contract deployments to run on your fork, you can set enable_hardhat_deployments to true in your config:

hardhat:
  fork:
    ethereum:
      mainnet:
        upstream_provider: alchemy
        enable_hardhat_deployments: true
ape plugins install alchemy

Remote Hardhat Node

To connect to a Hardhat node, set up your config like this:

hardhat:
  host: https://hardhat.example.com

Now, instead of launching a local process, it will attempt to connect to the remote Hardhat node and use this plugin as the ape interace.

Custom Hardhat Config File

By default, Ape generates and uses a basic config file for starting up a Hardhat node and having the same test accounts that Ape expects. To avoid conflict with other pre-existing Hardhat config files, Ape generates one in $HOME/.ape/hardhat and always refers to that one. To use a different one, such as the one in your local project instead, add the following to your ape-config.yaml:

hardhat:
  hardhat_config_file: ./hardhat.config.ts

NOTE: You can refer to either a Hardhat JS file or a Hardhat TS file.

Development

Please see the contributing guide to learn more how to contribute to this project. Comments, questions, criticisms and pull requests are welcomed.

ape-hardhat's People

Contributors

antazoey avatar bout3fiddy avatar delaaxe avatar dtdang avatar fubuloubu avatar jmanywhere avatar johnson2427 avatar laurentiu-andronache avatar lost-theory avatar mikeshultz avatar notpeopling2day avatar r4vp4 avatar sabotagebeats avatar solarthesis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

ape-hardhat's Issues

ape hardhat local node doesn't support the `create2()` [APE-1464]

Environment information

  • ape and plugin versions:
$ ape --version
0.6.22

$ ape plugins list
Installed Plugins
  alchemy     0.6.5
  hardhat     0.6.13
  solidity    0.6.9
  vyper       0.6.11

  • Python Version: 3.10.12
  • OS: linux

What went wrong?

Please include information like:

  • what command you ran
    ape test
  • the code that caused the failure (see this link for help with formatting code)
    create2(...)
  • full output of the error you received
    Always return zero address.

How can it be fixed?

This problem only occurs when I run the hardhat local node using the ape framework.
When I run the local node using the hardhat framework, it is always ok.

Auto-cache Hardhat console ABI [APE-645]

Overview

It would be nice if the Hardhat provider automatically cached the Hardhat console ABI in the session's contracts' cache.
One benefit is that it will help traces know the contract type for console log statements (could potentially ignore them by modifying other methods in ape-hardhat related to getting traces. This is also probably needed for ApeWorX/ape#685

I got this idea from looking at this code: https://github.com/Ackee-Blockchain/woke/blob/main/woke/testing/call_trace.py#L373

Specification

TBD but something like

  1. Hardcode or find a way to fetch console ABIs in the plugin
  2. On connect(), set the contract type address using the chain.contracts[addr] = ct. I think the address is "0x000000000000000000636F6e736F6c652e6c6f67" based on the woke project.
  3. Use console log in your tests and see how it looks in a trace in Ape.

Dependencies

Include links to any open issues that must be resolved before this feature can be implemented.

import config item from ape.api instead of ape.api.config

Overview

Once ape a30 or greater is released, we can import ConfigItem from ape.api instead of ape.api.config

Specification

Replace

from ape.api import NetworkAPI, TransactionAPI
from ape.api.config import ConfigItem

with

from ape.api import ConfigItem, NetworkAPI, TransactionAPI

Dependencies

ape 0.1.0a30

Support calling JS tasks for deeper access to Hardhat internal

Overview

Use this PR as reference point: #6
The idea to be able to call Hardhat Tasks via Ape somehow, perhaps through an Ape script:

from ape_hardhat import run_hh_task

def main():
    run_hh_task("MyScript.js")

Specification

Describe the syntax and semantics of how you would like to see this feature implemented. The more detailed the better!

Remember, your feature is much more likely to be included if it does not involve any breaking changes.

Dependencies

Include links to any open issues that must be resolved before this feature can be implemented.

Hangs when hardhat is not installed correctly -- Node.js out of date

Environment information

Node and hardhat installed globally on Ubuntu 20.04

  • ape and plugin versions:
$ ape --version
# .0.1.0b4

$ ape plugins list
# Installed Plugins:
  hardhat     0.1.0b3.dev1+g64bca80.d20220119
  • Python Version: 3.8.10
  • OS: Ubuntu 20.04

What went wrong?

Please include information like:

  • ape test --network ::hardhat
def test_snapshot_and_revert(hardhat_provider):
    snap = hardhat_provider.snapshot()
    assert snap == "1"

    block_1 = hardhat_provider._web3.eth.get_block("latest")
    hardhat_provider.mine()
    block_2 = hardhat_provider._web3.eth.get_block("latest")
    assert block_2.number > block_1.number
    assert block_1.hash != block_2.hash

    hardhat_provider.revert(snap)
    block_3 = hardhat_provider._web3.eth.get_block("latest")
    assert block_1.number == block_3.number
    assert block_1.hash == block_3.hash

def test_set_timestamp(hardhat_provider):
    seconds = 5
    pending_time_stamp = hardhat_provider.get_block("pending").timestamp
    time_1 = hardhat_provider.set_timestamp(seconds + pending_time_stamp)
    time_2 = hardhat_provider.set_timestamp(2 * seconds + pending_time_stamp)
    assert time_2 - time_1 == seconds
platform linux -- Python 3.8.10, pytest-6.2.5, py-1.11.0, pluggy-0.13.1
rootdir: /home/blake/ApeWorX/ape-hardhat, configfile: pyproject.toml, testpaths: tests
plugins: eth-ape-0.1.0b4, cov-3.0.0, forked-1.4.0, web3-5.26.0, xdist-2.5.0, hypothesis-6.36.0
collected 16 items                                                                                                                                                                                                                    

tests/test_hardhat.py ..........F..F..                                                                                                                                                                                          [100%]

============================================================================================================== FAILURES ===============================================================================================================
_________________________________________________________________________________________________________ test_set_timestamp __________________________________________________________________________________________________________

formatters = {'baseFeePerGas': <function apply_formatter_if at 0x7f850057c040>, 'difficulty': <function apply_formatter_if at 0x7f8...extraData': <function to_hexbytes at 0x7f84fbbb0af0>, 'gasLimit': <function apply_formatter_if at 0x7f850057c040>, ...}
value = {'baseFeePerGas': '0x0', 'difficulty': '0x20000', 'extraData': '0x', 'gasLimit': '0x1c9c380', ...}

    @to_dict
    def apply_formatters_to_dict(
        formatters: Dict[Any, Any], value: Dict[Any, Any]
    ) -> Generator[Tuple[Any, Any], None, None]:
        for key, item in value.items():
            if key in formatters:
                try:
>                   yield key, formatters[key](item)

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/eth_utils/applicators.py:84: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

>   ???

cytoolz/functoolz.pyx:254: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

>   ???

cytoolz/functoolz.pyx:250: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

num_bytes = 32, val = None, variable_length = False

    @curry
    def to_hexbytes(
        num_bytes: int, val: Union[str, int, bytes], variable_length: bool = False
    ) -> HexBytes:
        if isinstance(val, (str, int, bytes)):
            result = HexBytes(val)
        else:
>           raise TypeError("Cannot convert %r to HexBytes" % val)
E           TypeError: Cannot convert None to HexBytes

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/web3/_utils/method_formatters.py:126: TypeError

The above exception was the direct cause of the following exception:

hardhat_provider = HardhatProvider(name='hardhat', network=NetworkAPI(name='development', ecosystem=Ethereum(name='ethereum', network_man...1, 1, 5], process_attempts=10, mainnet_fork=None), provider_settings={}, data_folder=PosixPath('.'), request_header='')

    def test_set_timestamp(hardhat_provider):
        seconds = 5
>       pending_time_stamp = hardhat_provider.get_block("pending").timestamp

tests/test_hardhat.py:99: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/ape/api/providers.py:734: in get_block
    block_data = self._web3.eth.get_block(block_id)
../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/web3/eth.py:642: in get_block
    return self._get_block(block_identifier, full_transactions)
../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/web3/module.py:57: in caller
    result = w3.manager.request_blocking(method_str,
../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/web3/manager.py:197: in request_blocking
    response = self._make_request(method, params)
../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/web3/manager.py:150: in _make_request
    return request_func(method, params)
cytoolz/functoolz.pyx:254: in cytoolz.functoolz.curry.__call__
    ???
cytoolz/functoolz.pyx:250: in cytoolz.functoolz.curry.__call__
    ???
../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/web3/middleware/formatting.py:76: in apply_formatters
    response = make_request(method, params)
../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/web3/middleware/gas_price_strategy.py:90: in middleware
    return make_request(method, params)
cytoolz/functoolz.pyx:254: in cytoolz.functoolz.curry.__call__
    ???
cytoolz/functoolz.pyx:250: in cytoolz.functoolz.curry.__call__
    ???
../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/web3/middleware/formatting.py:76: in apply_formatters
    response = make_request(method, params)
../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/web3/middleware/attrdict.py:33: in middleware
    response = make_request(method, params)
cytoolz/functoolz.pyx:254: in cytoolz.functoolz.curry.__call__
    ???
cytoolz/functoolz.pyx:250: in cytoolz.functoolz.curry.__call__
    ???
../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/web3/middleware/formatting.py:83: in apply_formatters
    formatter(response["result"]),
cytoolz/functoolz.pyx:254: in cytoolz.functoolz.curry.__call__
    ???
cytoolz/functoolz.pyx:250: in cytoolz.functoolz.curry.__call__
    ???
../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/eth_utils/applicators.py:72: in apply_formatter_if
    return formatter(value)
cytoolz/functoolz.pyx:254: in cytoolz.functoolz.curry.__call__
    ???
cytoolz/functoolz.pyx:250: in cytoolz.functoolz.curry.__call__
    ???
../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/eth_utils/functional.py:45: in inner
    return callback(fn(*args, **kwargs))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

formatters = {'baseFeePerGas': <function apply_formatter_if at 0x7f850057c040>, 'difficulty': <function apply_formatter_if at 0x7f8...extraData': <function to_hexbytes at 0x7f84fbbb0af0>, 'gasLimit': <function apply_formatter_if at 0x7f850057c040>, ...}
value = {'baseFeePerGas': '0x0', 'difficulty': '0x20000', 'extraData': '0x', 'gasLimit': '0x1c9c380', ...}

    @to_dict
    def apply_formatters_to_dict(
        formatters: Dict[Any, Any], value: Dict[Any, Any]
    ) -> Generator[Tuple[Any, Any], None, None]:
        for key, item in value.items():
            if key in formatters:
                try:
                    yield key, formatters[key](item)
                except ValueError as exc:
                    new_error_message = "Could not format invalid value %r as field %r" % (
                        item,
                        key,
                    )
                    raise ValueError(new_error_message) from exc
                except TypeError as exc:
                    new_error_message = (
                        "Could not format invalid type of %r for field %r" % (item, key)
                    )
>                   raise TypeError(new_error_message) from exc
E                   TypeError: Could not format invalid type of None for field 'mixHash'

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/eth_utils/applicators.py:95: TypeError
-------------------------------------------------------------------------------------------------------- Captured stdout setup --------------------------------------------------------------------------------------------------------
INFO: Connecting to existing Hardhat node at port '8545'.
--------------------------------------------------------------------------------------------------------- Captured log setup ----------------------------------------------------------------------------------------------------------
INFO     ape:process.py:146 Connecting to existing Hardhat node at port '8545'.
______________________________________________________________________________________________________ test_snapshot_and_revert _______________________________________________________________________________________________________

hardhat_provider = HardhatProvider(name='hardhat', network=NetworkAPI(name='development', ecosystem=Ethereum(name='ethereum', network_man...1, 1, 5], process_attempts=10, mainnet_fork=None), provider_settings={}, data_folder=PosixPath('.'), request_header='')

    def test_snapshot_and_revert(hardhat_provider):
        snap = hardhat_provider.snapshot()
>       assert snap == "1"
E       AssertionError: assert '2' == '1'
E         - 1
E         + 2

tests/test_hardhat.py:118: AssertionError
-------------------------------------------------------------------------------------------------------- Captured stdout setup --------------------------------------------------------------------------------------------------------
INFO: Connecting to existing Hardhat node at port '8545'.
--------------------------------------------------------------------------------------------------------- Captured log setup ----------------------------------------------------------------------------------------------------------
INFO     ape:process.py:146 Connecting to existing Hardhat node at port '8545'.
========================================================================================================== warnings summary ===========================================================================================================
../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114
  /home/blake/.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape
    self._mark_plugins_for_rewrite(hook)

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114
  /home/blake/.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_accounts
    self._mark_plugins_for_rewrite(hook)

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114
  /home/blake/.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_compile
    self._mark_plugins_for_rewrite(hook)

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114
  /home/blake/.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_console
    self._mark_plugins_for_rewrite(hook)

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114
  /home/blake/.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_ethereum
    self._mark_plugins_for_rewrite(hook)

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114
  /home/blake/.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_geth
    self._mark_plugins_for_rewrite(hook)

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114
  /home/blake/.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_networks
    self._mark_plugins_for_rewrite(hook)

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114
  /home/blake/.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_plugins
    self._mark_plugins_for_rewrite(hook)

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114
  /home/blake/.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_pm
    self._mark_plugins_for_rewrite(hook)

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114
  /home/blake/.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_run
    self._mark_plugins_for_rewrite(hook)

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114
  /home/blake/.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_test
    self._mark_plugins_for_rewrite(hook)

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114
  /home/blake/.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ens
    self._mark_plugins_for_rewrite(hook)

../../.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114
  /home/blake/.local/share/virtualenvs/ape-hardhat-_w4hTD5y/lib/python3.8/site-packages/_pytest/config/__init__.py:1114: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: web3
    self._mark_plugins_for_rewrite(hook)

-- Docs: https://docs.pytest.org/en/stable/warnings.html

---------- coverage: platform linux, python 3.8.10-final-0 -----------
Name                        Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------
ape_hardhat/__init__.py        10     10      0      0     0%
ape_hardhat/exceptions.py      53     29     28      8    42%
ape_hardhat/process.py        124     62     34     11    50%
ape_hardhat/providers.py      176    117     52      8    34%
ape_hardhat/version.py          2      2      0      0     0%
-------------------------------------------------------------
TOTAL                         365    220    114     27    40%
Coverage HTML written to dir htmlcov
Coverage XML written to file coverage.xml

======================================================================================================= short test summary info =======================================================================================================
FAILED tests/test_hardhat.py::test_set_timestamp - TypeError: Could not format invalid type of None for field 'mixHash'
FAILED tests/test_hardhat.py::test_snapshot_and_revert - AssertionError: assert '2' == '1'
============================================================================================= 2 failed, 14 passed, 13 warnings in 28.70s ==============================================================================================
INFO: Stopping Hardhat node.
INFO: Stopping Hardhat node.
INFO: Stopping Hardhat node.
INFO: Stopping Hardhat node.

How can it be fixed?

Fill this in if you have ideas on how the bug could be fixed.

Load hardhat project files and deployments

Overview

If this is out of scope of this plugin, let me know.

It would be pretty useful if we could automatically get deployed hardhat contracts initialized in the console/API. I'm currently trying to work the Ape console into my workflow with a hardhat project. I'm currently creating web3.py contracts so I can interact with them but it's manual, doesn't keep up on ABI and address changes, and doesn't integrate well with the rest of the Ape API (e.g. accounts).

Would love to just be able to overlay Ape on top of hardhat and act-as-if it were just an Ape project. I'd be willing to put some work into this one, with some direction on where to start.

Specification

I'm not clear on what the scope would be so I'm probably missing some things here:

  • Read files from deployments/[network_name]/[contract_name].json for deployment ABI and addresses
  • Have Ape contract instances created and available on project.[contract_name]

Dependencies

Maybe #63 is a prereq or even this issue may be a duplicate of it.

If hardhat forks takes longer than expected to start, ape crashes

Environment information

  • ape and plugin versions:
$ ape --version
0.5.5.dev9+gec67e5a8

$ ape plugins list
Installed Plugins:
  hardhat     0.5.2
  vyper       0.5.1
  alchemy     0.5.2
  polygon     0.5.1a1
  • Python Version: 3.10.4
  • OS: linux : Linux sajal-thinkpad 5.15.0-39-generic #42-Ubuntu SMP Thu Jun 9 23:42:32 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

What went wrong?

When using hardhat in forking mode (eth mainnet) with following config

hardhat:
  fork:
    ethereum:
      mainnet:
        upstream_provider: alchemy
        block_number: 15936703
  fork_request_timeout: 1200

and following test case

import ape

import pytest

def test_vitalik_balance():
    assert ape.api.address.Address("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045").balance == 739992029493125111147

with following command WEB3_ETHEREUM_MAINNET_ALCHEMY_API_KEY="REMOVED" ape test --network :mainnet-fork:hardhat -v DEBUG tests/test_Fork.py

The result is random.

How can it be fixed?

My thoughts are that sometimes hardhat takes longer than expected(especially given that I'm 300ms away from alchemy) to start listening on port 8545 and connection refused error is not handled anywhere. Some experiments shows that if we catch the error here things work fine.

Change so that `upstream_provider` is required to be set

Elevator pitch:

Currently, if you do not set an upstream provider, the plugin uses the default provider.
However - this may confuse some users who attempt to use the plugin without specifying either and ending up connection errors (as hardhat is unable to connect to the upstream provider).

This pitch proposes changing it so required setting an upstream_provider.

There are pros and cons to both

Pros:

  • More explicit
  • Less likely to have errors for new users

Cons:

  • Have to specify your default provider in more than one place if you are already specifying it the Ethereum config.
    ** This is particularly gross if you are using many forked networks in the same project and they all use the same provider. That is N times you have to specify the same provider.

Value:

Users

Dependencies:

Design approach:

self explanatory

Task list:

  • Change default

Estimated completion date:

n/a

Design review:

Do not signoff unless:

    1. agreed the tasks and design approach will achieve acceptance, and
    1. the work can be completed by one person within the SLA.
      Design reviewers should consider simpler approaches to achieve goals.

(Please leave a comment to sign off)

Chain ID mismatch on testing veYFI

Some wacky error here:

    def test_reward_checkpoint(accounts, ve_yfi_rewards, ve_yfi, panda, gov):
        with ape.reverts("!authorized"):
            ve_yfi_rewards.rewardCheckpoint(panda, sender=panda)
        with ape.reverts("!authorized"):
            ve_yfi_rewards.rewardCheckpoint(panda, sender=gov)
>       ve_yfi_rewards.rewardCheckpoint(panda, sender=ve_yfi)

tests/functional/test_ve_yfi_rewards.py:95: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
site-packages/ape_hardhat/providers.py:347: in send_transaction
    txn_hash = self._web3.eth.send_transaction(txn_dict)  # type: ignore
site-packages/web3/eth.py:815: in send_transaction
    return self._send_transaction(transaction)
site-packages/web3/module.py:57: in caller
    result = w3.manager.request_blocking(method_str,
site-packages/web3/manager.py:197: in request_blocking
    response = self._make_request(method, params)
site-packages/web3/manager.py:150: in _make_request
    return request_func(method, params)
site-packages/web3/middleware/formatting.py:94: in middleware
    response = make_request(method, params)
site-packages/web3/middleware/gas_price_strategy.py:89: in middleware
    return make_request(method, (transaction,))
site-packages/web3/middleware/formatting.py:94: in middleware
    response = make_request(method, params)
site-packages/web3/middleware/attrdict.py:33: in middleware
    response = make_request(method, params)
site-packages/web3/middleware/formatting.py:94: in middleware
    response = make_request(method, params)
site-packages/web3/middleware/formatting.py:93: in middleware
    params = formatter(params)
cytoolz/functoolz.pyx:503: in cytoolz.functoolz.Compose.__call__
    ???
cytoolz/functoolz.pyx:250: in cytoolz.functoolz.curry.__call__
    ???
site-packages/eth_utils/decorators.py:91: in wrapper
    return ReturnType(result)  # type: ignore
site-packages/eth_utils/applicators.py:22: in apply_formatter_at_index
    yield formatter(item)
cytoolz/functoolz.pyx:250: in cytoolz.functoolz.curry.__call__
    ???
site-packages/eth_utils/functional.py:45: in inner
    return callback(fn(*args, **kwargs))
site-packages/eth_utils/applicators.py:84: in apply_formatters_to_dict
    yield key, formatters[key](item)
cytoolz/functoolz.pyx:250: in cytoolz.functoolz.curry.__call__
    ???
site-packages/eth_utils/applicators.py:72: in apply_formatter_if
    return formatter(value)
cytoolz/functoolz.pyx:250: in cytoolz.functoolz.curry.__call__
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

web3_chain_id = 31337, chain_id = 0

    @curry
    def _validate_chain_id(web3_chain_id: int, chain_id: int) -> int:
        if to_integer_if_hex(chain_id) == web3_chain_id:
            return chain_id
        else:
>           raise ValidationError(
                "The transaction declared chain ID %r, "
                "but the connected node is on %r" % (
                    chain_id,
                    web3_chain_id,
                )
            )
E           web3.exceptions.ValidationError: The transaction declared chain ID 0, but the connected node is on 31337

site-packages/web3/middleware/validation.py:61: ValidationError

Originally posted by @fubuloubu in ApeWorX/ape#619 (comment)

Only default to random port if 8545 is taken (provided the user did not specify a port)

Idea

I believe that the only reason we are doing the random port thing is make x-dist work.
It is unusual to not default to port 8545 though.

My proposition is this: default to 8545 unless that port is taken. Then, use the random port methodology.
If the user configured port, use that one though (how it works currently).

Reason

  • It is more expected, predictable behavior
  • It is more portable, if using postman or something too

ape plugins add alchemy from readme doesn't work

Environment information

  • ape and plugin versions:

$ ape --version
0.1.4.dev4+gcc458e80

$ ape plugins list

Installed Plugins:
  tokens       
  hardhat      
  infura       
  vyper        
  ens          
  alchemy      
  solidity     
  etherscan
  • Python Version: 3.9.9
  • OS: wsl2 linux

What went wrong?

Please include information like:

  • what command you ran
    ape plugins add alchemy
  • the code that caused the failure (see this link for help with formatting code)
    following docs
  • full output of the error you received
    Error: No such command 'add'.

How can it be fixed?

update docs

Connection Anomalies

Environment information

Sometimes, it randomly can't connect and cycles through ports endlessly... Maybe the process is not always cleaned up??
Other times, web3 is still None after connect was called

^Both of these failures are quite infrequent but still suspicious...

What went wrong?

Please include information like:

  • what command you ran
  • the code that caused the failure (see this link for help with formatting code)
  • full output of the error you received

How can it be fixed?

Fill this in if you have ideas on how the bug could be fixed.

Delete random port code and replace with usage of system 0 port.

Overview

Seems like letting the system handle randomizing the port works just as good (if not better) as our own custom functionality.
We could delete a lot of code and just delegate to the system, as suggested by someone on telegram.

Later on, we can a deterministic port selecting approach

Specification

  • Delete code for port selecting
  • Delete related configs for that
  • When user says "auto", use port of 0.
  • tada!

Dependencies

Include links to any open issues that must be resolved before this feature can be implemented.

Auto-release notes do not seem to be working?

Environment information

gitHub latest

What went wrong?

There does not appear to be a draft release containing the latest merge commit PR titles

How can it be fixed?

Not sure yet! But we have seen this issue in other plugins I think, like Infura

Revert custom get pending block logic

Overview

Now that ethereum/web3.py#2317 has been resolved, we can update web3.py and remove out custom get_block method (just use the super class now).

Specification

Delete get_block method (will force the usage of super class, like all other providers).

Dependencies

web3.py > 5.26.0

FAILED tests/test_gas_report.py::test_gas_flag_exclude_method_using_cli_option - AssertionError: ' TokenA Gas' does not match pattern ' +TestContractVy Gas'

Environment information

  • ape and plugin versions:
(.venv) nebu@LAPTOP-FMQAOP35:~/ApeWorX/ape-hardhat$ ape --version
0.5.9
(.venv) nebu@LAPTOP-FMQAOP35:~/ApeWorX/ape-hardhat$ ape plugins list
Installed Plugins:
  alchemy     0.5.4
  hardhat     0.1.dev64+g0c5bb30.d20230120
(.venv) nebu@LAPTOP-FMQAOP35:~/ApeWorX/ape-hardhat$ python --version
Python 3.9.16
  • Python Version: 3.9.16
  • OS: win WSL2
PS C:\Users\Nebu> wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu                 Running         2

What went wrong?

(.venv) nebu@LAPTOP-FMQAOP35:~/ApeWorX/ape-hardhat$ ape test
INFO: Compiling 'fixtures.json'.
================================================================================================================================= test session starts ==================================================================================================================================
platform linux -- Python 3.9.16, pytest-7.2.1, pluggy-1.0.0
rootdir: /home/nebu/ApeWorX/ape-hardhat, configfile: pyproject.toml, testpaths: tests
plugins: eth-ape-0.5.9, cov-4.0.0, xdist-3.1.0, hypothesis-6.62.1, mock-3.10.0, web3-6.0.0b7
collected 64 items

tests/test_fork_provider.py .............                                                                                                                                                                                                                                        [ 20%]
tests/test_provider.py ......                                                                                                                                                                                                                                                    [ 29%]
tests/test_fork_provider.py .....                                                                                                                                                                                                                                                [ 37%]
tests/test_provider.py ......                                                                                                                                                                                                                                                    [ 46%]
tests/test_fork_provider.py .......                                                                                                                                                                                                                                              [ 57%]
tests/test_gas_report.py .F                                                                                                                                                                                                                                                      [ 60%]
tests/test_provider.py .....................                                                                                                                                                                                                                                     [ 93%]
tests/test_trace.py ..                                                                                                                                                                                                                                                         [100%]

======================================================================================================================================= FAILURES =======================================================================================================================================
____________________________________________________________________________________________________________________ test_gas_flag_exclude_method_using_cli_option _____________________________________________________________________________________________________________________
ape_pytester = <Pytester PosixPath('/tmp/pytest-of-nebu/pytest-3/test_gas_flag_exclude_method_using_cli_option0')>

    @pytest.mark.sync
    def test_gas_flag_exclude_method_using_cli_option(ape_pytester):
        # NOTE: Includes both a mutable and a view method.
        expected = filter_expected_methods("fooAndBar", "myNumber")
        # Also ensure can filter out whole class
        expected = expected.replace(TOKEN_B_GAS_REPORT, "")
        result = ape_pytester.runpytest("--gas", "--gas-exclude", "*:fooAndBar,*:myNumber,tokenB:*")
>       run_gas_test(result, expected_report=expected)

/home/nebu/ApeWorX/ape-hardhat/tests/test_gas_report.py:99:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
result = <RunResult ret=ExitCode.OK len(stdout.lines)=23 len(stderr.lines)=0 duration=2.92s>
expected_report = '\n +TestContractVy Gas\n\n  Method +Times called +Min. +Max. +Mean +Median\n โ”€+\n  setNumber +\\d +\\d+ + \\d+ + \\d+... +Max. +Mean +Median\n โ”€+\n  balanceOf +\\d +\\d+ + \\d+ + \\d+ + \\d+\n  transfer +\\d +\\d+ + \\d+ + \\d+ + \\d+\n\n'

    def run_gas_test(result, expected_report: str = EXPECTED_GAS_REPORT):
        result.assert_outcomes(passed=NUM_TESTS), "\n".join(result.outlines)

        gas_header_line_index = None
        for index, line in enumerate(result.outlines):
            if "Gas Profile" in line:
                gas_header_line_index = index

        assert gas_header_line_index is not None, "'Gas Profile' not in output."
        expected = expected_report.split("\n")[1:]
        start_index = gas_header_line_index + 1
        end_index = start_index + len(expected)
        actual = [x.rstrip() for x in result.outlines[start_index:end_index]]
        assert "WARNING: No gas usage data found." not in actual, "Gas data missing!"

        actual_len = len(actual)
        expected_len = len(expected)

        if actual_len > expected_len:
            remainder = "\n".join(actual[expected_len:])
            pytest.fail(f"Actual contains more than expected:\n{remainder}")
        elif expected_len > actual_len:
            remainder = "\n".join(expected[actual_len:])
            pytest.fail(f"Expected contains more than actual:\n{remainder}")

        for actual_line, expected_line in zip(actual, expected):
            message = f"'{actual_line}' does not match pattern '{expected_line}'."
>           assert re.match(expected_line, actual_line), message
E           AssertionError: '                        TokenA Gas' does not match pattern ' +TestContractVy Gas'.
E           assert None
E            +  where None = <function match at 0x7f348d012af0>(' +TestContractVy Gas', '                        TokenA Gas')
E            +    where <function match at 0x7f348d012af0> = re.match

/home/nebu/ApeWorX/ape-hardhat/tests/test_gas_report.py:80: AssertionError
--------------------------------------------------------------------------------------------------------------------------------- Captured stdout call ---------------------------------------------------------------------------------------------------------------------------------
============================= test session starts ==============================
platform linux -- Python 3.9.16, pytest-7.2.1, pluggy-1.0.0
rootdir: /tmp/pytest-of-nebu/pytest-3/test_gas_flag_exclude_method_using_cli_option0
plugins: cov-4.0.0, xdist-3.1.0, eth-ape-0.5.9, hypothesis-6.62.1, mock-3.10.0, web3-6.0.0b7
collected 7 items
INFO: Connecting to existing 'Hardhat node' process.

test_gas_flag_exclude_method_using_cli_option.py .......                 [100%]
================================= Gas Profile ==================================
                        TokenA Gas

  Method      Times called   Min.   Max.   Mean   Median
 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  balanceOf              1   2462   2462   2462     2462

                        TokenB Gas

  Method      Times called   Min.   Max.   Mean   Median
 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  balanceOf              1   2462   2462   2462     2462


============================== 7 passed in 2.73s ===============================
---------------------------------------------------------------------------------------------------------------------------------- Captured log call -----------------------------------------------------------------------------------------------------------------------------------
INFO     ape:providers.py:1210 Connecting to existing 'Hardhat node' process.
INFO     ape:providers.py:1082 Confirmed 0x430a9ba46f0fdc70b078a3e7859f7cbdf0fffd675b29d208bda823e1d8bc7528 (total fees paid = 0)
SUCCESS  ape:base.py:988 Contract 'TestContractVy' deployed to: 0x274b028b03A250cA03644E6c578D81f019eE1323
INFO     ape:providers.py:1082 Confirmed 0x6c95b1876fd633fbefb4d3544a42c243654f6b812a1f40cdfaed1c0f3a845ccc (total fees paid = 0)
INFO     ape:providers.py:1082 Confirmed 0xdb60a1bf4711154e0382da3d85980e44158689f237ea9cfebe1c0548fb6c8b20 (total fees paid = 0)
INFO     ape:providers.py:1082 Confirmed 0xba66e6bdf86a8ac7ec35d72285a12bb5176b0137b457c68a4454978d65b5f283 (total fees paid = 0)
INFO     ape:providers.py:1082 Confirmed 0x6b059acf20dc96851433cd94b729a1f8ea387d3a2c7ff8f7b612b6476f57c9be (total fees paid = 0)
INFO     ape:providers.py:1082 Confirmed 0xfe6c5882f11f1ab557426de312c4212cf813f64560aa7472a35154a8d242c6bc (total fees paid = 0)
SUCCESS  ape:base.py:988 Contract 'TestContractVy' deployed to: 0xF2Df0b975c0C9eFa2f8CA0491C2d1685104d2488
INFO     ape:providers.py:1082 Confirmed 0xfe83fc44ac66434695926a026963695770237a8039e2fee108d70e5de31b2c2c (total fees paid = 0)
INFO     ape:providers.py:1082 Confirmed 0xea7e6bd969a30d336e200f058554d3063d35f522bff5aebb52fb2721ea14e232 (total fees paid = 0)
INFO     ape:providers.py:1082 Confirmed 0x56d088a673d1fda26a00689343e2aa5864d354e63a499a1668ce45adcaec8bba (total fees paid = 0)
SUCCESS  ape:base.py:988 Contract 'TokenA' deployed to: 0xF2Df0b975c0C9eFa2f8CA0491C2d1685104d2488
INFO     ape:providers.py:1082 Confirmed 0x80ede01fb841efd59574782a97e48785cc495646e7ea8024e12be4fea960ed6c (total fees paid = 0)
SUCCESS  ape:base.py:988 Contract 'TokenB' deployed to: 0x4B3E65104805A303c274f078127D5a7E9F9b47b2
INFO     ape:providers.py:1082 Confirmed 0x57e96e36179840c9c3ee004c92a0efba6c834c38801a9a0530a58facaa31538b (total fees paid = 0)
INFO     ape:providers.py:1082 Confirmed 0xb89cd248f3c7fbd31052aa196783bfb5ae8f97dbfe72fa0931f21647eab069c0 (total fees paid = 0)
INFO     ape:providers.py:1082 Confirmed 0xa782932bd1df72aef33590f74159780f69ada9128ebdf368d362244f71fa97a9 (total fees paid = 0)
INFO     ape:providers.py:1082 Confirmed 0xa14ccbd938bf0b37b91bf4c98f01ff39914e37b32f1fdd98785dfd487eff6ad3 (total fees paid = 0)
INFO     ape:providers.py:1082 Confirmed 0x47fc09a2cd18114fabf98e550e2d94617af995d4b699ff6fcdeb4499e8d821b8 (total fees paid = 0)
INFO     ape:providers.py:1082 Confirmed 0x3eedeb6a130fe0d07125a57d22a13de7cfa29b67a2a6ae6d7f6903fa4426a213 (total fees paid = 0)
=================================================================================================================================== warnings summary ===================================================================================================================================
.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_accounts
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_cache
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_compile
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_console
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_ethereum
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_geth
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_init
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_networks
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_plugins
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_pm
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_run
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ape_test
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: ens
    self._mark_plugins_for_rewrite(hook)

.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171
  /home/nebu/ApeWorX/ape-hardhat/.venv/lib/python3.9/site-packages/_pytest/config/__init__.py:1171: PytestAssertRewriteWarning: Module already imported so cannot be rewritten: web3
    self._mark_plugins_for_rewrite(hook)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html

---------- coverage: platform linux, python 3.9.16-final-0 -----------
Name                        Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------
ape_hardhat/__init__.py        26     10      2      0    64%
ape_hardhat/exceptions.py       6      6      0      0     0%
ape_hardhat/provider.py       342    164    104     23    55%
ape_hardhat/version.py          2      2      0      0     0%
-------------------------------------------------------------
TOTAL                         376    182    106     23    55%
Coverage HTML written to dir htmlcov
Coverage XML written to file coverage.xml

=============================================================================================================================== short test summary info ================================================================================================================================
FAILED tests/test_gas_report.py::test_gas_flag_exclude_method_using_cli_option - AssertionError: '                        TokenA Gas' does not match pattern ' +TestContractVy Gas'.
================================================================================================================ 1 failed, 63 passed, 15 warnings in 370.13s (0:06:10) =================================================================================================================
INFO: Stopping 'Hardhat node' process.
INFO: Stopping 'Hardhat node' process.
INFO: Stopping 'Hardhat node' process.

How can it be fixed?

Fill this in if you have ideas on how the bug could be fixed.

Disable hardhat deployments on forks

Overview

Today I was running into timeout issues when starting a fork in a pre-existing hardhat project directory. Speaking with @unparalleled-js, I'm aware of the timeout config now, but still would prefer to be able to disable these as they're unnecessary and slow. In my case though, the timeouts were mostly caused by the fact that the hardhat node will run all the deployment scripts deploying all of the contracts to the fork. This can take a minute or two in this case.

I initially wanted to just submit a PR disabling these deployments but figured I should check in to see if there's any good argument against it. As an untested example:

diff --git a/ape_hardhat/providers.py b/ape_hardhat/providers.py
index ce98eb6..aa94992 100644
--- a/ape_hardhat/providers.py
+++ b/ape_hardhat/providers.py
@@ -500,6 +500,7 @@ class HardhatForkProvider(HardhatProvider):
 
         cmd = super().build_command()
         cmd.extend(("--fork", self.fork_url))
+        cmd.extend("--no-deploy")
         if self.fork_block_number is not None:
             cmd.extend(("--fork-block-number", str(self.fork_block_number)))
 

I don't think there's much use case for these hardhat deployment scripts since the deployed contract instances can't (currently) be referenced via Ape, anyway. Not without reading in network.json or expecting deterministic deployment addresses, which are likely to be an edge case at best. That said, maybe there's a use case I'm not seeing or someone that might find use in having these deployments run.

In that case, perhaps there should be a CLI option to enable deployments or users should run them manually?

Contract using local library are not available in ProjectManager

Environment information

  • ape and plugin versions:
$ ape --version
0.5.8

$ ape plugins list
Installed Plugins:
  ganache     0.5.0
  hardhat     0.5.4
  solidity    0.5.3

  • Python Version: 3.8.10
  • OS: linux

What went wrong?

Contract using library generate compilation warning WARNING: Libraries must be deployed and configured separately. , does not show up on the bytecode size report (--size) and is not available in project fixture for testing.

How to reproduce

Contracts:

MyContract.sol

pragma solidity ^0.8.0;

import "./MyLib.sol";

contract MyContract {

    uint256 public value;
    function update(uint256 _value) public {
        value = MyLib.calculate(_value);
        //value = _value * _value;
    }
}

MyLib.sol

pragma solidity ^0.8.0;

library MyLib {
    function calculate(uint256 x) public pure returns(uint256) {
        return x * x;
    }
}

NoLibContract.sol

pragma solidity ^0.8.0;

contract NoLibContract {

    uint256 public value;
    function update(uint256 _value) public {
        value = _value + 1;
    }
}

Tests files:

my_test.py

import pytest

@pytest.fixture
def deploy_contract(accounts, project):
    accounts[0].deploy(project.MyLib)
    return accounts[0].deploy(project.MyContract)

def test(deploy_contract, accounts):
    mycontract = deploy_contract
    assert mycontract.value() == 0
    mycontract.update(7, sender=accounts[0])
    assert mycontract.value() == 7 * 7

nolib_test.py

import pytest

@pytest.fixture
def deploy_contract(accounts, project):
    return accounts[0].deploy(project.NoLibContract)

def test(deploy_contract, accounts):
    nolibcontract = deploy_contract
    assert nolibcontract.value() == 0
    nolibcontract.update(7, sender=accounts[0])
    assert nolibcontract.value() == 7 + 1

Run ape compile --size -f

INFO: Compiling 'NoLibContract.sol'.
INFO: Compiling 'MyContract.sol'.
INFO: Compiling 'MyLib.sol'.
WARNING: Libraries must be deployed and configured separately.

============ Deployment Bytecode Sizes ============
  MyLib          -     277B  (1.13%)
  NoLibContract  -     261B  (1.06%)


Run ape test -v SUCCESS

platform linux -- Python 3.8.10, pytest-7.2.0, pluggy-1.0.0
rootdir: /home/user/ape-test
plugins: eth-ape-0.5.8, web3-6.0.0b7
collected 2 items                                                                                                                                                                                                                                                                                                                                                    

tests/my_test.py E                                                                                                                                                                                                                                                                                                                                             
tests/nolib_test.py . 

SUCCESS: Contract 'MyLib' deployed to: 0x274b028b03A250cA03644E6c578D81f019eE1323
ERROR tests/my_test.py::test - AttributeError: ProjectManager has no attribute or contract named 'MyContract'.

Hardhat process does not stop [APE-953]

Environment information

For some reason, the hardhat process no longer terminates when ape is done.
I noticed this problem only happens with ape-hardhat but not ape-foundry, ape-geth, or ape-ganache, even tho they use the same base class and logic for shutting down.
i am guessing it may have to do with npm or something? not sure.
will need this fixed. it is important.

What went wrong?

Please include information like:

  • what command you ran
  • the code that caused the failure (see this link for help with formatting code)
  • full output of the error you received

How can it be fixed?

Fill this in if you have ideas on how the bug could be fixed.

Handle and raise VM / TX related Errors

Overview

Handle hardhat specific VM errors for a consistent ape experience as well as enabling support for ape test reverts-checking.

Specification

  • Will require not inheriting from ape_http
  • Catch errors related to contract logic and raise ContractLogicError (from ape.exceptions)
  • Raise OutOfGasError when the transaction runs out of gas
  • Raise VirtualMachineError for all other errors that occur in VM

^ See ape-http implementation as an example, but NOTE: the errors will be different so handling them will be different. One major difference may be the OutOfGasError, which has a base error that does not get raised in Geth but it does in Hardhat.

Dependencies

na

chain ID is not what Ape expects

if running hardhat separately (using ape networks run) and connecting to it, ape is expecting the default local chain ID but hardhat is using its own

fix: change to the one ape expects as the default and allow users to configure it from the same spot

Add HardhatProject(ProjectAPI) implementation

Overview

Allow users of this plugin to be able to compile Hardhat projects out-of-the-box without needing an ape-config.yaml file, the same we have BrownieProject(ProjectAPI) in core ape.

Specification

  • If the user has Open Zeppelin dependencies (or other whitelisted ones), AND they have the solidity plugin installed, automatically use the configuration to do the remappings so "it just works".

Dependencies

Include links to any open issues that must be resolved before this feature can be implemented.

ape-hardhat with local fork gives INTERNALERROR with newer pydantic version [APE-1583]

Environment information

  • OS: Ubuntu 22.* (new laptop, fresh install, updated to the latest versions)

  • Python Version: 3.10.12

  • ape and plugin versions:
    ape 0.6.26

    plugins:

    • name: infura
    • name: alchemy
    • name: vyper
    • name: ens
    • name: etherscan
    • name: hardhat

Additional related software
vyper 0.3.10
hardhat 2.19.1
ape-hardhat latest version

What went wrong?

I am trying to run my tests using my own node's RPC and fork to a local hardhat instance
ape test --network ethereum:mainnet-fork:hardhat

I'm getting pydantic errors, and it seems it is misinterpreting the package-lock.json.

================================================================================== test session starts ===================================================================================
platform linux -- Python 3.10.12, pytest-7.4.3, pluggy-1.3.0
rootdir: /home/user/Projects/vyper/shibber
plugins: eth-ape-0.6.26, forked-1.4.0, xdist-1.34.0, hypothesis-6.27.3, web3-6.11.4
collected 6 items                                                                                                                                                                        
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/_pytest/main.py", line 271, in wrap_session
INTERNALERROR>     session.exitstatus = doit(config, session) or 0
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/_pytest/main.py", line 324, in _main
INTERNALERROR>     config.hook.pytest_collection(session=session)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/pluggy/_hooks.py", line 493, in __call__
INTERNALERROR>     return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/pluggy/_manager.py", line 115, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/pluggy/_callers.py", line 152, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/pluggy/_result.py", line 114, in get_result
INTERNALERROR>     raise exc.with_traceback(exc.__traceback__)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/pluggy/_callers.py", line 77, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/_pytest/main.py", line 335, in pytest_collection
INTERNALERROR>     session.perform_collect()
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/_pytest/main.py", line 682, in perform_collect
INTERNALERROR>     hook.pytest_collection_finish(session=self)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/pluggy/_hooks.py", line 493, in __call__
INTERNALERROR>     return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/pluggy/_manager.py", line 115, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/pluggy/_callers.py", line 130, in _multicall
INTERNALERROR>     teardown[0].send(outcome)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/ape/pytest/runners.py", line 209, in pytest_collection_finish
INTERNALERROR>     self._provider_context.push_provider()
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/ape/pytest/runners.py", line 39, in _provider_context
INTERNALERROR>     return self.network_manager.parse_network_choice(self.config_wrapper.network)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/ape/managers/networks.py", line 446, in parse_network_choice
INTERNALERROR>     provider = self.get_provider_from_choice(
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/ape/managers/networks.py", line 408, in get_provider_from_choice
INTERNALERROR>     return network.get_provider(
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/ape/api/networks.py", line 936, in get_provider
INTERNALERROR>     if provider.connection_id in ProviderContextManager.connected_providers:
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/ape/api/providers.py", line 1765, in connection_id
INTERNALERROR>     cmd_id = ",".join(self.build_command())
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/ape_hardhat/provider.py", line 1027, in build_command
INTERNALERROR>     if not self.enable_hardhat_deployments and self._has_hardhat_plugin("hardhat-deploy"):
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/ape_hardhat/provider.py", line 484, in _has_hardhat_plugin
INTERNALERROR>     return next((True for plugin in self._hardhat_plugins if plugin == plugin_name), False)
INTERNALERROR>   File "/usr/lib/python3.10/functools.py", line 981, in __get__
INTERNALERROR>     val = self.func(instance)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/ape_hardhat/provider.py", line 475, in _hardhat_plugins
INTERNALERROR>     if self._package_json.dependencies:
INTERNALERROR>   File "/usr/lib/python3.10/functools.py", line 981, in __get__
INTERNALERROR>     val = self.func(instance)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/ape_hardhat/provider.py", line 466, in _package_json
INTERNALERROR>     return PackageJson.parse_file(json_path)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/typing_extensions.py", line 2360, in wrapper
INTERNALERROR>     return arg(*args, **kwargs)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/pydantic/main.py", line 1111, in parse_file
INTERNALERROR>     return cls.parse_obj(obj)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/typing_extensions.py", line 2360, in wrapper
INTERNALERROR>     return arg(*args, **kwargs)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/pydantic/main.py", line 1027, in parse_obj
INTERNALERROR>     return cls.model_validate(obj)
INTERNALERROR>   File "/home/user/.local/lib/python3.10/site-packages/pydantic/main.py", line 503, in model_validate
INTERNALERROR>     return cls.__pydantic_validator__.validate_python(
INTERNALERROR> pydantic_core._pydantic_core.ValidationError: 4 validation errors for PackageJson
INTERNALERROR> name
INTERNALERROR>   Field required [type=missing, input_value={'devDependencies': {'hardhat': '^2.19.1'}}, input_type=dict]
INTERNALERROR>     For further information visit https://errors.pydantic.dev/2.5/v/missing
INTERNALERROR> version
INTERNALERROR>   Field required [type=missing, input_value={'devDependencies': {'hardhat': '^2.19.1'}}, input_type=dict]
INTERNALERROR>     For further information visit https://errors.pydantic.dev/2.5/v/missing
INTERNALERROR> description
INTERNALERROR>   Field required [type=missing, input_value={'devDependencies': {'hardhat': '^2.19.1'}}, input_type=dict]
INTERNALERROR>     For further information visit https://errors.pydantic.dev/2.5/v/missing
INTERNALERROR> dependencies
INTERNALERROR>   Field required [type=missing, input_value={'devDependencies': {'hardhat': '^2.19.1'}}, input_type=dict]
INTERNALERROR>     For further information visit https://errors.pydantic.dev/2.5/v/missing

================================================================================== 8 warnings in 1.79s ===================================================================================

How can it be fixed?

Downgrade pydantic. On my dev VM it is version 1.10.9

Seems like pydantic 2.5.* changed the way it handles dictionaries. Didn't downgrade to any sub versions of pydantic 2.* since my focus was on getting things running again

Fill this in if you have ideas on how the bug could be fixed.
pip3 uninstall pydantic pydantic-core
pip3 install pydantic==1.10.9 fixed it.

I think ape-hardhat needs to be updated to correctly use pydantic 2.*

Typescript config file

Overview

Add support for hardhat.config.ts. Pretty common for projects to use the typescript file, and the JS one created by Ape can cause conflicts.

Specification

At a glance I didn't see how the JS file was consumed so I'm not sure all what needs to be done for this.

Can connect Mainnet Fork Provider to already running normal provider

Environment information

Different providers allow you to connect to existing network when they should not, and it is not immediately obvious what the problem is because things might not work as expected, such as fork mode.

What went wrong?

When you start a node process using one provider (such as the normal Hardhat provider), you are allowed to connect to it with a different provider (such as the MainnetForkHardhatProvider).

How can it be fixed?

Determine if already running provider is a mainnet-fork or not. Also figure out upstream provider URL.
Make sure if attempting to connect to already running provider that it was run with the same params, such as the same fork URL etc.

^ This might be tricky

Wrong error when hardhat is not installed correctly [APE-910]

Environment information

  • ape and plugin versions:
    Installed Plugins:
    infura 0.6.1
    vyper 0.6.4
    hardhat 0.6.4
$ ape --version
0.6.8

$ ape plugins list
Installed Plugins:
  hardhat     0.6.4
  vyper       0.6.4
  infura      0.6.1

# ...copy and paste result of above command here...
  • Python Version: 3.10.6
  • OS: macOS

What went wrong?

Hardhat was installed with
npm install -g hardhat

but apparently npx wants hardhat to be installed locally.
When running ape I was getting the following error:


INTERNALERROR> ape.exceptions.RPCTimeoutError: Timed out waiting for successful RPC connection to the 'Hardhat node' process (20 seconds).

How can it be fixed?

The ape plugin should check that hardhat is installed correctly.
A simple print of npx hardhat --version would help debug issues as well.

ape hardhat local node Reached heap limit Allocation failed - JavaScript heap out of memory [APE-1468]

Environment information

  • ape and plugin versions:
$ ape --version
0.6.22

$ ape plugins list
  alchemy     0.6.5
  hardhat     0.6.13
  solidity    0.6.9
  vyper       0.6.11
  • Python Version: 3.10.12
  • OS: linux

What went wrong?

Please include information like:

  • what command you ran
    ape test
  • the code that caused the failure (see this link for help with formatting code)
    compile and run test cases
  • full output of the error you received
th_getTransactionReceipt
eth_getTransactionByHash
eth_gasPrice

<--- Last few GCs --->

[117881:0x7107180]   164897 ms: Scavenge 3992.4 (4118.7) -> 3989.4 (4120.0) MB, 10.6 / 0.0 ms  (average mu = 0.891, current mu = 0.817) allocation failure;
[117881:0x7107180]   164974 ms: Scavenge 3996.6 (4123.2) -> 3994.4 (4142.0) MB, 36.6 / 0.0 ms  (average mu = 0.891, current mu = 0.817) allocation failure;
[117881:0x7107180]   167246 ms: Mark-sweep 3996.8 (4143.0) -> 3995.7 (4146.0) MB, 2266.6 / 0.0 ms  (average mu = 0.670, current mu = 0.139) allocation failure; scavenge might not succeed


<--- JS stacktrace --->

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
1: 0xb83f50 node::Abort() [/home/one/.nvm/versions/node/v18.17.0/bin/node]
2: 0xa94834  [/home/one/.nvm/versions/node/v18.17.0/bin/node]
3: 0xd647c0 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/home/one/.nvm/versions/node/v18.17.0/bin/node]
4: 0xd64b67 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/home/one/.nvm/versions/node/v18.17.0/bin/node]
5: 0xf42265  [/home/one/.nvm/versions/node/v18.17.0/bin/node]
6: 0xf5474d v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/home/one/.nvm/versions/node/v18.17.0/bin/node]
7: 0xf2ee4e v8::internal::HeapAllocator::AllocateRawWithLightRetrySlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/home/one/.nvm/versions/node/v18.17.0/bin/node]
8: 0xf30217 v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/home/one/.nvm/versions/node/v18.17.0/bin/node]
9: 0xf10760 v8::internal::Factory::AllocateRaw(int, v8::internal::AllocationType, v8::internal::AllocationAlignment) [/home/one/.nvm/versions/node/v18.17.0/bin/node]
10: 0xf081d4 v8::internal::FactoryBase<v8::internal::Factory>::AllocateRawWithImmortalMap(int, v8::internal::AllocationType, v8::internal::Map, v8::internal::AllocationAlignment) [/home/one/.nvm/versions/node/v18.17.0/bin/node]
11: 0xf0a488 v8::internal::FactoryBase<v8::internal::Factory>::NewRawOneByteString(int, v8::internal::AllocationType) [/home/one/.nvm/versions/node/v18.17.0/bin/node]
12: 0xf20e5e v8::internal::Factory::NewStringFromOneByte(v8::base::Vector<unsigned char const> const&, v8::internal::AllocationType) [/home/one/.nvm/versions/node/v18.17.0/bin/node]
13: 0xd73953 v8::String::NewFromOneByte(v8::Isolate*, unsigned char const*, v8::NewStringType, int) [/home/one/.nvm/versions/node/v18.17.0/bin/node]
14: 0xc6d35a node::StringBytes::Encode(v8::Isolate*, char const*, unsigned long, node::encoding, v8::Local<v8::Value>*) [/home/one/.nvm/versions/node/v18.17.0/bin/node]
15: 0xb5985a  [/home/one/.nvm/versions/node/v18.17.0/bin/node]
16: 0x1688e2f  [/home/one/.nvm/versions/node/v18.17.0/bin/node]
Stopping 'Hardhat node' process.

How can it be fixed?

Fill this in if you have ideas on how the bug could be fixed.

Add configurable gas limit

Overview

While Hardhat has its own configuration where you can specify gas limit, we need a configuration to provide a gas limit that lets you bypass estimate_gas_cost() entirely

Specification

The configuration key/value should be set in your ape-config.yaml

Ideally you should be able to set different gas limits for the different chains (local versus mainnet-fork, for example)

When executing a transaction, you should still be able to specify a limit that is not overridden, such as token.transfer(..., gas_limit=int(...)))

Dependencies

N/A

feat: Configurable chainID

Overview

Right now this is hardcoded so it would be best to configure chainID with config file.

Specification

chainID in config file

Dependencies

#48

A way to upgrade hardhat.config.js defaults from the plugin

Overview

Right now, the hardhat.config.js file only gets written if it does not already exist.
When we update values in the default config however, (such as the recent mnemonic change), there is no easy way to user to grab those changes.

Specification

One idea: hide the hardhat.config.js file completely from the user and only allow us to control it, like what we do with genesis.json in the geth provider. The benefits of this are that things are less breakable and there is only one source of truth (ape-config.yaml). Downside is less flexibility, can't mess with both settings.

Another idea is just to document that the user should save their current config, delete the one in their project, let hardhat re-generate one, and add back the missing pieces manually.

Dependencies

  • discuss with other team apes

Use logger.debug for network-related print statements.

Overview

Use logger.debug() for print() statements (or whichever log lever makes sense)

Specification

Currently, it is a bit noisy when using this plugin. I know @lost-theory as this work somewhere, am wondering if you could open a PR? Just would like to log the Network retries at the debug level. It will help out demos dependent on hardhat.

Improve error when NPM version not supportd

Overview

If npx hardhat node fails, it times out. However, when running separately, you can see better reasons, such as incompatible node versions. Show better errors when possible instead of Timed out trying to connect to node after 20 seconds

Specification

ERROR: (ProviderError) NPM version not supported.

Dependencies

Include links to any open issues that must be resolved before this feature can be implemented.

bug: ape.reverts inconsistency [APE-693]

Environment information

  • ape and plugin versions:
$ ape --version
0.6.4

$ ape plugins list
Installed Plugins:
  alchemy      0.6.0
  solidity     0.6.0
  etherscan    0.6.0
  tokens       0.6.0
  ens          0.6.0
  hardhat      0.6.0

  • Python Version: 3.9.10
  • OS: linux

What went wrong?

There seems to be some inconsistencies with revert handling between hardhat and the default test network (EthereumTester?). Trying to handle a revert with the default test network, I have to do something like this:

with ape.reverts(str(decode_hex(Web3.keccak(text="MySolidityError()").hex()[2:10]))):
        my_contract.reverts()

However, if I try and do something similar for hardhat, I'll receive this error:

[...]
self = <ape.pytest.contextmanagers.RevertsContextManager object at 0x7f8bea737430>, exc_type = <class 'ape.exceptions.VirtualMachineError'>
exc_value = VirtualMachineError('Error: VM Exception while processing transaction: reverted with an unrecognized custom error (return data: 0xd05cb609)')
traceback = <traceback object at 0x7f8bea6fb7c0>

    def __exit__(self, exc_type: Type, exc_value: Exception, traceback) -> bool:
        if exc_type is None:
            raise AssertionError("Transaction did not revert.")
    
        if not isinstance(exc_value, ContractLogicError):
>           raise AssertionError(
                f"Transaction did not revert.\n"
                f"However, an exception of type {type(exc_value)} occurred: {exc_value}."
            ) from exc_value
E           AssertionError: Transaction did not revert.
E           However, an exception of type <class 'ape.exceptions.VirtualMachineError'> occurred: Error: VM Exception while processing transaction: reverted with an unrecognized custom error (return data: 0xd3bd13a1).

../../.venvs/ape/lib/python3.9/site-packages/ape/pytest/contextmanagers.py:157: AssertionError

That's a little truncated, let me know if you need a more complete example and I can put one together when I get a chance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.