Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP / R&D] - EELS backend with eth-tester #3447

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 90 additions & 6 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ parameters:
type: string

common: &common
parameters:
python_exec:
type: string
default: "python"
working_directory: ~/repo
steps:
- checkout
Expand All @@ -28,6 +32,38 @@ common: &common
- restore_cache:
keys:
- cache-v1-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }}
- run:
name: install pypy3 if python_exec is pypy3
command: |
if [ "<< parameters.python_exec >>" == "pypy3" ]; then
sudo apt-get update

# If .pyenv already exists, remove and reinstall to get latest version
if [ -d "$HOME/.pyenv" ]; then
echo "Removing existing .pyenv directory..."
rm -rf $HOME/.pyenv
fi
curl https://pyenv.run | bash
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

# Find the latest PyPy version matching the python minor version
latest_pypy_version=$(pyenv install --list | grep -E "pypy3\.<< parameters.python_minor_version >>" | grep -v "\-src" | tail -1 | tr -d ' ')
echo "Latest PyPy version: $latest_pypy_version"

# Install the latest PyPy 3.10 version using pyenv if not already installed
pyenv install "$latest_pypy_version"
pyenv global "$latest_pypy_version"

# Verify the correct PyPy version is being used
pypy3 --version

# Install pip using the newly installed PyPy version
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
pypy3 get-pip.py
fi
- run:
name: install dependencies
command: |
Expand All @@ -36,7 +72,7 @@ common: &common
python web3/scripts/install_pre_releases.py
- run:
name: run tox
command: python -m tox run -r
command: << parameters.python_exec >> -m tox -r
- save_cache:
paths:
- .hypothesis
Expand Down Expand Up @@ -145,12 +181,30 @@ jobs:
type: string
tox_env:
type: string
python_exec:
type: string
default: "python"
<<: *common
docker:
- image: cimg/python:3.<< parameters.python_minor_version >>
environment:
TOXENV: py3<< parameters.python_minor_version >>-<< parameters.tox_env >>

common-pypy:
parameters:
python_minor_version:
type: string
tox_env:
type: string
python_exec:
type: string
default: "pypy3"
<<: *common
docker:
- image: cimg/python:3.<< parameters.python_minor_version >>
environment:
TOXENV: pypy3<< parameters.python_minor_version >>-<< parameters.tox_env >>

geth:
parameters:
python_minor_version:
Expand Down Expand Up @@ -228,13 +282,44 @@ workflows:
python_minor_version: ["8", "9", "10", "11", "12"]
tox_env: [
"lint",
"core",
"core_async",
"ens",
"core-pyevm",
"core-pyevm_async",
"ens-pyevm",
"ensip15",
"wheel"
]
python_exec: "python"
name: "py3<< matrix.python_minor_version >>-<< matrix.tox_env >>"
- common:
matrix:
parameters:
# eels only supports 3.10 and above
python_minor_version: ["10", "11", "12"]
tox_env: [
"core-eels",
"core-eels_async",
"ens-eels",
"integration-ethtester-eels"
]
python_exec: "python"
name: "py3<< matrix.python_minor_version >>-<< matrix.tox_env >>"
- common-pypy:
matrix:
parameters:
# eels only supports 3.10 and above; pyenv only has pypy3.10 available
python_minor_version: ["10"]
tox_env: [
"core-eels",
"core-eels_async",
"ens-eels",
"integration-ethtester-eels",
"core-pyevm",
"core-pyevm_async",
"ens-pyevm",
"integration-ethtester-pyevm"
]
python_exec: "pypy3"
name: "pypy3<< matrix.python_minor_version >>-<< matrix.tox_env >>"
- geth:
matrix:
parameters:
Expand All @@ -246,7 +331,7 @@ workflows:
"integration-goethereum-http_async",
"integration-goethereum-legacy_ws",
"integration-goethereum-ws",
"integration-ethtester"
"integration-ethtester-pyevm"
]
name: "py3<< matrix.python_minor_version >>-<< matrix.tox_env >>"
- docs:
Expand All @@ -260,7 +345,6 @@ workflows:
python_minor_version: ["10", "11", "12"]
name: "py3<< matrix.python_minor_version >>-windows-wheel"


nightly:
triggers:
- schedule:
Expand Down
11 changes: 7 additions & 4 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
import time
import warnings

from eth_tester import (
EthereumTester,
)
import pytest_asyncio

from tests.utils import (
Expand Down Expand Up @@ -71,15 +74,15 @@ def _wait_for_transaction(w3, txn_hash, timeout=120):


@pytest.fixture
def w3():
w3 = Web3(EthereumTesterProvider())
def w3(backend_class):
w3 = Web3(EthereumTesterProvider(EthereumTester(backend=backend_class())))
w3.eth.default_account = w3.eth.accounts[0]
return w3


@pytest.fixture(scope="module")
def w3_non_strict_abi():
w3 = Web3(EthereumTesterProvider())
def w3_non_strict_abi(backend_class):
w3 = Web3(EthereumTesterProvider(EthereumTester(backend=backend_class())))
w3.eth.default_account = w3.eth.accounts[0]
w3.strict_bytes_type_checking = False
return w3
Expand Down
5 changes: 3 additions & 2 deletions docs/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,12 @@ Typically, you'll just want to run a subset instead, like:
$ pytest tests/core/eth-module/test_accounts.py


You can use ``tox`` to run all the tests for a given version of Python:
You can use ``tox`` to run all the core tests for a given version of Python. You must
an available backend for eth-tester to use (currently {'pyevm', 'eels'}).

.. code:: sh

$ tox -e py38-core
$ tox -e py38-core --backend=pyevm


Linting is also performed by the CI. You can save yourself some time by checking for
Expand Down
6 changes: 5 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@
setup,
)

CUSTOM_ETH_TESTER_BRANCH = " @ git+https://github.com/fselmo/eth-tester@eels-backend"

extras_require = {
"tester": [
# Note: ethereum-maintained libraries in this list should be added to the
# `install_pre_releases.py` script.
"eth-tester[py-evm]>=0.11.0b1,<0.13.0b1",
f"eth-tester[py-evm]{CUSTOM_ETH_TESTER_BRANCH}",
# if python version >= 3.10, install the eels backend:
f"eth-tester[eels]{CUSTOM_ETH_TESTER_BRANCH} ; python_version >= '3.10'",
"py-geth>=5.0.0",
],
"dev": [
Expand Down
48 changes: 47 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
Type,
)

from eth_tester import (
PyEVMBackend,
)
from eth_utils import (
event_signature_to_log_topic,
to_bytes,
Expand All @@ -23,20 +26,63 @@
get_open_port,
)

SUPPORTED_ETH_TESTER_BACKENDS = {"pyevm", "eels"}


@pytest.fixture(scope="module", params=[lambda x: to_bytes(hexstr=x), identity])
def address_conversion_func(request):
return request.param


@pytest.fixture()
@pytest.fixture
def open_port():
return get_open_port()


# --- session-scoped constants --- #


def pytest_addoption(parser):
parser.addoption(
"--backend",
action="store",
default=None,
help="Specify the backend for `EthereumTester` to use.",
)


def pytest_collection_modifyitems(config, items):
backend_required_for_tests = any(
"backend_class" in item.fixturenames for item in items
)
if backend_required_for_tests:
backend = config.getoption("--backend")
if not backend:
raise pytest.UsageError(
"This test run requires a specified a backend via the `--backend` "
"command line option. Supported backends are: "
f"{SUPPORTED_ETH_TESTER_BACKENDS}"
)
elif backend not in SUPPORTED_ETH_TESTER_BACKENDS:
raise pytest.UsageError(f"Unsupported backend: `{backend}`.")


@pytest.fixture(scope="session")
def backend_class(request):
backend = request.config.getoption("--backend")
if backend == "pyevm":
return PyEVMBackend
elif backend == "eels":
# conditionally import since eels is only supported on python >= 3.10
from eth_tester.backends.eels import (
EELSBackend,
)

return EELSBackend
else:
raise ValueError("Invariant: Unreachable code path.")


@pytest.fixture(scope="session")
def emitter_contract_data():
return EMITTER_CONTRACT_DATA
Expand Down
11 changes: 7 additions & 4 deletions tests/core/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import pytest

from eth_tester import (
EthereumTester,
)
import pytest_asyncio

from web3 import (
Expand Down Expand Up @@ -117,16 +120,16 @@ def __init__(self, a, b):


@pytest_asyncio.fixture
async def async_w3():
w3 = AsyncWeb3(AsyncEthereumTesterProvider())
async def async_w3(backend_class):
w3 = AsyncWeb3(AsyncEthereumTesterProvider(EthereumTester(backend=backend_class())))
accounts = await w3.eth.accounts
w3.eth.default_account = accounts[0]
return w3


@pytest_asyncio.fixture
async def async_w3_non_strict_abi():
w3 = AsyncWeb3(AsyncEthereumTesterProvider())
async def async_w3_non_strict_abi(backend_class):
w3 = AsyncWeb3(AsyncEthereumTesterProvider(EthereumTester(backend=backend_class())))
w3.strict_bytes_type_checking = False
accounts = await w3.eth.accounts
w3.eth.default_account = accounts[0]
Expand Down
2 changes: 1 addition & 1 deletion tests/core/contracts/test_contract_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
)


@pytest.fixture()
@pytest.fixture
def abi():
return """[{"anonymous":false,"inputs":[{"indexed":false,"name":"value","type":"uint256"}],"name":"Increased","type":"function"}, {"anonymous":false,"inputs":[{"indexed":false,"name":"value","type":"uint256"}],"name":"Increased","type":"event"}]""" # noqa: E501

Expand Down
Loading