Skip to content

Commit

Permalink
Merge pull request #1541 from eth-brownie/anvil
Browse files Browse the repository at this point in the history
initial anvil support
  • Loading branch information
iamdefinitelyahuman authored May 28, 2022
2 parents 89bb74f + 57aed40 commit 2453e82
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ This changelog format is based on [Keep a Changelog](https://keepachangelog.com/
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased](https://github.com/eth-brownie/brownie)
### Added
- Initial support for [Anvil](https://github.com/foundry-rs/foundry/tree/master/anvil), a blazing-fast local testnet node implementation in Rust ([#1541](https://github.com/eth-brownie/brownie/pull/1541))


## [1.18.2](https://github.com/eth-brownie/brownie/tree/v1.18.2) - 2022-05-15
### Added
Expand Down
13 changes: 13 additions & 0 deletions brownie/data/network-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,19 @@ live:
explorer: https://blockscout.com/poa/sokol/api

development:
- name: Anvil
id: anvil
cmd: anvil
host: http://127.0.0.1
cmd_settings:
port: 8545
- name: Anvil (Mainnet Fork)
id: anvil-fork
cmd: anvil
host: http://127.0.0.1
cmd_settings:
fork: mainnet
port: 8545
- name: Ganache-CLI
id: development
cmd: ganache-cli
Expand Down
3 changes: 2 additions & 1 deletion brownie/network/rpc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@
from brownie.network.state import Chain
from brownie.network.web3 import web3

from . import ganache, geth, hardhat
from . import anvil, ganache, geth, hardhat

chain = Chain()

ATTACH_BACKENDS = {"ethereumjs testrpc": ganache, "geth": geth, "hardhat": hardhat}

LAUNCH_BACKENDS = {
"anvil": anvil,
"ganache": ganache,
"ethnode": geth,
"geth": geth,
Expand Down
85 changes: 85 additions & 0 deletions brownie/network/rpc/anvil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/usr/bin/python3

import sys
import warnings
from subprocess import DEVNULL, PIPE
from typing import Dict, List, Optional

import psutil
from requests.exceptions import ConnectionError as RequestsConnectionError

from brownie.exceptions import InvalidArgumentWarning, RPCRequestError
from brownie.network.web3 import web3

CLI_FLAGS = {
"port": "--port",
"host": "--host",
"fork": "--fork-url",
"fork_block": "--fork-block-number",
"chain_id": "--chain-id",
}


def launch(cmd: str, **kwargs: Dict) -> None:
"""Launches the RPC client.
Args:
cmd: command string to execute as subprocess"""
if sys.platform == "win32" and not cmd.split(" ")[0].endswith(".cmd"):
if " " in cmd:
cmd = cmd.replace(" ", ".cmd ", 1)
else:
cmd += ".cmd"
cmd_list = cmd.split(" ")
for key, value in [(k, v) for k, v in kwargs.items() if v]:
try:
cmd_list.extend([CLI_FLAGS[key], str(value)])
except KeyError:
warnings.warn(
f"Ignoring invalid commandline setting for anvil: "
f'"{key}" with value "{value}".',
InvalidArgumentWarning,
)
print(f"\nLaunching '{' '.join(cmd_list)}'...")
out = DEVNULL if sys.platform == "win32" else PIPE

return psutil.Popen(cmd_list, stdin=DEVNULL, stdout=out, stderr=out)


def on_connection() -> None:
# set gas limit to the same as the forked network
gas_limit = web3.eth.get_block("latest").gasLimit
web3.provider.make_request("evm_setBlockGasLimit", [hex(gas_limit)]) # type: ignore


def _request(method: str, args: List) -> int:
try:
response = web3.provider.make_request(method, args) # type: ignore
if "result" in response:
return response["result"]
except (AttributeError, RequestsConnectionError):
raise RPCRequestError("Web3 is not connected.")
raise RPCRequestError(response["error"]["message"])


def sleep(seconds: int) -> int:
_request("evm_increaseTime", [hex(seconds)])
return seconds


def mine(timestamp: Optional[int] = None) -> None:
if timestamp:
_request("evm_setNextBlockTimestamp", [timestamp])
_request("evm_mine", [1])


def snapshot() -> int:
return _request("evm_snapshot", [])


def revert(snapshot_id: int) -> None:
_request("evm_revert", [snapshot_id])


def unlock_account(address: str) -> None:
web3.provider.make_request("anvil_impersonateAccount", [address]) # type: ignore
16 changes: 16 additions & 0 deletions docs/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,19 @@ Once installed, include the ``--network hardhat`` flag to run Brownie with Hardh
The first time you use Hardhat within a Brownie project, a ``hardhat.config.js`` `configuration file <https://hardhat.org/config/>`_ is generated. You should not modify any of the settings within this file as they are required for compatibility.

If you have updated your brownie version from older versions, hardhat networks will be missing. You have to update ``~/.brownie/network-config.yaml``. It can be updated using the one `here <https://github.com/eth-brownie/brownie/blob/master/brownie/data/network-config.yaml>`_


Using Brownie with Anvil
==========================

`Anvil <https://github.com/foundry-rs/foundry/tree/master/anvil>`_ is a blazing-fast local testnet node implementation in Rust. Anvil may be used as an alternative to Ganache within Brownie.

To use Anvil with Brownie, you must first `follow their steps to install Anvil <https://github.com/foundry-rs/foundry/tree/master/anvil#installation>`_.

Once installed, include the ``--network anvil`` or ``--network anvil-fork`` flag to run Brownie with Anvil. For example, to launch the console:

.. code-block:: bash
brownie console --network anvil
If you have updated your brownie version from older versions, anvil networks will be missing. You have to update ``~/.brownie/network-config.yaml``. It can be updated using the one `here <https://github.com/eth-brownie/brownie/blob/master/brownie/data/network-config.yaml>`_

0 comments on commit 2453e82

Please sign in to comment.