From 10a19be75f2e8708322b658478a0f0c5c653d714 Mon Sep 17 00:00:00 2001
From: fselmo <fselmo2@gmail.com>
Date: Thu, 1 Aug 2024 14:19:10 -0600
Subject: [PATCH 1/9] After checking against EELS backend, minor test updates

---
 .../test_contract_build_transaction.py        | 20 +++++++++----------
 .../contracts/test_contract_estimate_gas.py   |  5 ++---
 .../core/utilities/test_async_transaction.py  | 11 +++++-----
 3 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/tests/core/contracts/test_contract_build_transaction.py b/tests/core/contracts/test_contract_build_transaction.py
index a49d60effc..1cd480ab36 100644
--- a/tests/core/contracts/test_contract_build_transaction.py
+++ b/tests/core/contracts/test_contract_build_transaction.py
@@ -186,26 +186,26 @@ def test_build_transaction_with_contract_to_address_supplied_errors(
             False,
         ),
         (  # legacy transaction, explicit gasPrice
-            {"gasPrice": 22**8},
+            {"gasPrice": 22 * 10**8},
             (5,),
             {},
             {
                 "data": "0x6abbb3b40000000000000000000000000000000000000000000000000000000000000005",  # noqa: E501
                 "value": 0,
-                "gasPrice": 22**8,
+                "gasPrice": 22 * 10**8,
                 "chainId": 131277322940537,
             },
             False,
         ),
         (
-            {"maxFeePerGas": 22**8, "maxPriorityFeePerGas": 22**8},
+            {"maxFeePerGas": 22 * 10**8, "maxPriorityFeePerGas": 22 * 10**8},
             (5,),
             {},
             {
                 "data": "0x6abbb3b40000000000000000000000000000000000000000000000000000000000000005",  # noqa: E501
                 "value": 0,
-                "maxFeePerGas": 22**8,
-                "maxPriorityFeePerGas": 22**8,
+                "maxFeePerGas": 22 * 10**8,
+                "maxPriorityFeePerGas": 22 * 10**8,
                 "chainId": 131277322940537,
             },
             False,
@@ -467,26 +467,26 @@ async def test_async_build_transaction_with_contract_to_address_supplied_errors(
             False,
         ),
         (  # legacy transaction, explicit gasPrice
-            {"gasPrice": 22**8},
+            {"gasPrice": 22 * 10**8},
             (5,),
             {},
             {
                 "data": "0x6abbb3b40000000000000000000000000000000000000000000000000000000000000005",  # noqa: E501
                 "value": 0,
-                "gasPrice": 22**8,
+                "gasPrice": 22 * 10**8,
                 "chainId": 131277322940537,
             },
             False,
         ),
         (
-            {"maxFeePerGas": 22**8, "maxPriorityFeePerGas": 22**8},
+            {"maxFeePerGas": 22 * 10**8, "maxPriorityFeePerGas": 22 * 10**8},
             (5,),
             {},
             {
                 "data": "0x6abbb3b40000000000000000000000000000000000000000000000000000000000000005",  # noqa: E501
                 "value": 0,
-                "maxFeePerGas": 22**8,
-                "maxPriorityFeePerGas": 22**8,
+                "maxFeePerGas": 22 * 10**8,
+                "maxPriorityFeePerGas": 22 * 10**8,
                 "chainId": 131277322940537,
             },
             False,
diff --git a/tests/core/contracts/test_contract_estimate_gas.py b/tests/core/contracts/test_contract_estimate_gas.py
index 3b8e784297..bf6209d7c4 100644
--- a/tests/core/contracts/test_contract_estimate_gas.py
+++ b/tests/core/contracts/test_contract_estimate_gas.py
@@ -87,10 +87,9 @@ def test_estimate_gas_sending_ether_to_nonpayable_function(
 
 
 def test_estimate_gas_accepts_latest_block(w3, math_contract, transact):
-    gas_estimate = math_contract.functions.counter().estimate_gas(
+    gas_estimate = math_contract.functions.incrementCounter().estimate_gas(
         block_identifier="latest"
     )
-
     txn_hash = transact(contract=math_contract, contract_function="incrementCounter")
 
     txn_receipt = w3.eth.wait_for_transaction_receipt(txn_hash)
@@ -196,7 +195,7 @@ async def test_async_estimate_gas_sending_ether_to_nonpayable_function(
 async def test_async_estimate_gas_accepts_latest_block(
     async_w3, async_math_contract, async_transact
 ):
-    gas_estimate = await async_math_contract.functions.counter().estimate_gas(
+    gas_estimate = await async_math_contract.functions.incrementCounter().estimate_gas(
         block_identifier="latest"
     )
 
diff --git a/tests/core/utilities/test_async_transaction.py b/tests/core/utilities/test_async_transaction.py
index 323f1b5190..779f6a8fc3 100644
--- a/tests/core/utilities/test_async_transaction.py
+++ b/tests/core/utilities/test_async_transaction.py
@@ -74,15 +74,14 @@ async def test_async_fill_transaction_defaults_for_all_params(async_w3):
     }
 
 
-@pytest.mark.asyncio()
-async def test_async_fill_transaction_defaults_nondynamic_transaction_fee(async_w3):
-    gasPrice_transaction = {
-        "gasPrice": 10,
+@pytest.mark.asyncio
+async def test_async_fill_transaction_defaults_non_dynamic_transaction_fee(async_w3):
+    gas_price_transaction = {
+        "gasPrice": 10**9,
     }
     default_transaction = await async_fill_transaction_defaults(
-        async_w3, gasPrice_transaction
+        async_w3, gas_price_transaction
     )
-
     assert none_in_dict(DYNAMIC_FEE_TXN_PARAMS, default_transaction)
 
 

From f368a19e7f0b382eff1d3df77466e36ae0fe37c9 Mon Sep 17 00:00:00 2001
From: fselmo <fselmo2@gmail.com>
Date: Fri, 2 Aug 2024 17:03:09 -0600
Subject: [PATCH 2/9] Implement EELS integration tests (almost all passing);
 temporarily turn on EELS backend for core tests (all passing).

---
 conftest.py                                   |  10 +-
 tests/core/conftest.py                        |   9 +-
 .../test_contract_build_transaction.py        |  38 ++---
 tests/core/eth-module/test_eth_properties.py  |   6 +-
 tests/core/module-class/test_module.py        |   5 +-
 .../core/web3-module/test_web3_inheritance.py |   2 +-
 tests/integration/ethereum_tester/__init__.py |   0
 .../common.py}                                |   2 +-
 tests/integration/ethereum_tester/conftest.py | 154 ++++++++++++++++++
 .../integration/ethereum_tester/test_eels.py  |  88 ++++++++++
 .../integration/ethereum_tester/test_pyevm.py |  72 ++++++++
 tox.ini                                       |   5 +-
 web3/_utils/module_testing/eth_module.py      |   4 +-
 web3/providers/eth_tester/defaults.py         |   6 +-
 14 files changed, 361 insertions(+), 40 deletions(-)
 create mode 100644 tests/integration/ethereum_tester/__init__.py
 rename tests/integration/{test_ethereum_tester.py => ethereum_tester/common.py} (99%)
 create mode 100644 tests/integration/ethereum_tester/conftest.py
 create mode 100644 tests/integration/ethereum_tester/test_eels.py
 create mode 100644 tests/integration/ethereum_tester/test_pyevm.py

diff --git a/conftest.py b/conftest.py
index 06cbbdcacc..0676201d24 100644
--- a/conftest.py
+++ b/conftest.py
@@ -2,6 +2,10 @@
 import time
 import warnings
 
+from eth_tester import (
+    EELSBackend,
+    EthereumTester,
+)
 import pytest_asyncio
 
 from tests.utils import (
@@ -72,14 +76,16 @@ def _wait_for_transaction(w3, txn_hash, timeout=120):
 
 @pytest.fixture
 def w3():
-    w3 = Web3(EthereumTesterProvider())
+    t = EthereumTester(backend=EELSBackend("cancun"))
+    w3 = Web3(EthereumTesterProvider(t))
     w3.eth.default_account = w3.eth.accounts[0]
     return w3
 
 
 @pytest.fixture(scope="module")
 def w3_non_strict_abi():
-    w3 = Web3(EthereumTesterProvider())
+    t = EthereumTester(backend=EELSBackend("cancun"))
+    w3 = Web3(EthereumTesterProvider(t))
     w3.eth.default_account = w3.eth.accounts[0]
     w3.strict_bytes_type_checking = False
     return w3
diff --git a/tests/core/conftest.py b/tests/core/conftest.py
index 4210a1245c..1dc712def0 100644
--- a/tests/core/conftest.py
+++ b/tests/core/conftest.py
@@ -1,5 +1,9 @@
 import pytest
 
+from eth_tester import (
+    EELSBackend,
+    EthereumTester,
+)
 import pytest_asyncio
 
 from web3 import (
@@ -118,7 +122,10 @@ def __init__(self, a, b):
 
 @pytest_asyncio.fixture
 async def async_w3():
-    w3 = AsyncWeb3(AsyncEthereumTesterProvider())
+    t = EthereumTester(backend=EELSBackend("cancun"))
+    provider = AsyncEthereumTesterProvider()
+    provider.ethereum_tester = t
+    w3 = AsyncWeb3(provider)
     accounts = await w3.eth.accounts
     w3.eth.default_account = accounts[0]
     return w3
diff --git a/tests/core/contracts/test_contract_build_transaction.py b/tests/core/contracts/test_contract_build_transaction.py
index 1cd480ab36..87f8dcba02 100644
--- a/tests/core/contracts/test_contract_build_transaction.py
+++ b/tests/core/contracts/test_contract_build_transaction.py
@@ -22,7 +22,7 @@ def test_build_transaction_not_paying_to_nonpayable_function(
         "value": 0,
         "maxFeePerGas": 2750000000,
         "maxPriorityFeePerGas": 10**9,
-        "chainId": 131277322940537,
+        "chainId": w3.eth.chain_id,
     }
 
 
@@ -49,7 +49,7 @@ def test_build_transaction_with_contract_no_arguments(
         "value": 0,
         "maxFeePerGas": 2750000000,
         "maxPriorityFeePerGas": 10**9,
-        "chainId": 131277322940537,
+        "chainId": w3.eth.chain_id,
     }
 
 
@@ -77,7 +77,7 @@ def test_build_transaction_with_contract_fallback_function(
         "value": 0,
         "maxFeePerGas": 2750000000,
         "maxPriorityFeePerGas": 10**9,
-        "chainId": 131277322940537,
+        "chainId": w3.eth.chain_id,
     }
 
 
@@ -95,7 +95,7 @@ def test_build_transaction_with_contract_class_method(
         "value": 0,
         "maxFeePerGas": 2750000000,
         "maxPriorityFeePerGas": 10**9,
-        "chainId": 131277322940537,
+        "chainId": w3.eth.chain_id,
     }
 
 
@@ -111,7 +111,7 @@ def test_build_transaction_with_contract_default_account_is_set(
         "value": 0,
         "maxFeePerGas": 2750000000,
         "maxPriorityFeePerGas": 10**9,
-        "chainId": 131277322940537,
+        "chainId": w3.eth.chain_id,
     }
 
 
@@ -130,7 +130,7 @@ def my_gas_price_strategy(w3, transaction_params):
         "data": "0x5b34b966",
         "value": 0,
         "gasPrice": 5,
-        "chainId": 131277322940537,
+        "chainId": w3.eth.chain_id,
     }
 
 
@@ -168,7 +168,6 @@ def test_build_transaction_with_contract_to_address_supplied_errors(
                 "value": 0,
                 "maxFeePerGas": 2750000000,
                 "maxPriorityFeePerGas": 1000000000,
-                "chainId": 131277322940537,
             },
             False,
         ),
@@ -181,7 +180,6 @@ def test_build_transaction_with_contract_to_address_supplied_errors(
                 "value": 0,
                 "maxFeePerGas": 2750000000,
                 "maxPriorityFeePerGas": 1000000000,
-                "chainId": 131277322940537,
             },
             False,
         ),
@@ -193,7 +191,6 @@ def test_build_transaction_with_contract_to_address_supplied_errors(
                 "data": "0x6abbb3b40000000000000000000000000000000000000000000000000000000000000005",  # noqa: E501
                 "value": 0,
                 "gasPrice": 22 * 10**8,
-                "chainId": 131277322940537,
             },
             False,
         ),
@@ -206,7 +203,6 @@ def test_build_transaction_with_contract_to_address_supplied_errors(
                 "value": 0,
                 "maxFeePerGas": 22 * 10**8,
                 "maxPriorityFeePerGas": 22 * 10**8,
-                "chainId": 131277322940537,
             },
             False,
         ),
@@ -220,7 +216,6 @@ def test_build_transaction_with_contract_to_address_supplied_errors(
                 "maxFeePerGas": 2750000000,
                 "maxPriorityFeePerGas": 1000000000,
                 "nonce": 7,
-                "chainId": 131277322940537,
             },
             True,
         ),
@@ -233,7 +228,6 @@ def test_build_transaction_with_contract_to_address_supplied_errors(
                 "value": 20000,
                 "maxFeePerGas": 2750000000,
                 "maxPriorityFeePerGas": 1000000000,
-                "chainId": 131277322940537,
             },
             False,
         ),
@@ -261,6 +255,7 @@ def test_build_transaction_with_contract_arguments(
     if skip_testrpc:
         skip_if_testrpc(w3)
 
+    expected["chainId"] = w3.eth.chain_id
     txn = build_transaction(
         contract=math_contract,
         contract_function="incrementCounter",
@@ -290,7 +285,7 @@ async def test_async_build_transaction_not_paying_to_nonpayable_function(
         "value": 0,
         "maxFeePerGas": 2750000000,
         "maxPriorityFeePerGas": 10**9,
-        "chainId": 131277322940537,
+        "chainId": await async_w3.eth.chain_id,
     }
 
 
@@ -319,7 +314,7 @@ async def test_async_build_transaction_with_contract_no_arguments(
         "value": 0,
         "maxFeePerGas": 2750000000,
         "maxPriorityFeePerGas": 10**9,
-        "chainId": 131277322940537,
+        "chainId": await async_w3.eth.chain_id,
     }
 
 
@@ -349,7 +344,7 @@ async def test_async_build_transaction_with_contract_fallback_function(
         "value": 0,
         "maxFeePerGas": 2750000000,
         "maxPriorityFeePerGas": 10**9,
-        "chainId": 131277322940537,
+        "chainId": await async_w3.eth.chain_id,
     }
 
 
@@ -371,7 +366,7 @@ async def test_async_build_transaction_with_contract_class_method(
         "value": 0,
         "maxFeePerGas": 2750000000,
         "maxPriorityFeePerGas": 10**9,
-        "chainId": 131277322940537,
+        "chainId": await async_w3.eth.chain_id,
     }
 
 
@@ -388,7 +383,7 @@ async def test_async_build_transaction_with_contract_default_account_is_set(
         "value": 0,
         "maxFeePerGas": 2750000000,
         "maxPriorityFeePerGas": 10**9,
-        "chainId": 131277322940537,
+        "chainId": await async_w3.eth.chain_id,
     }
 
 
@@ -408,7 +403,7 @@ def my_gas_price_strategy(async_w3, transaction_params):
         "data": "0x5b34b966",
         "value": 0,
         "gasPrice": 5,
-        "chainId": 131277322940537,
+        "chainId": await async_w3.eth.chain_id,
     }
 
 
@@ -449,7 +444,6 @@ async def test_async_build_transaction_with_contract_to_address_supplied_errors(
                 "value": 0,
                 "maxFeePerGas": 2750000000,
                 "maxPriorityFeePerGas": 1000000000,
-                "chainId": 131277322940537,
             },
             False,
         ),
@@ -462,7 +456,6 @@ async def test_async_build_transaction_with_contract_to_address_supplied_errors(
                 "value": 0,
                 "maxFeePerGas": 2750000000,
                 "maxPriorityFeePerGas": 1000000000,
-                "chainId": 131277322940537,
             },
             False,
         ),
@@ -474,7 +467,6 @@ async def test_async_build_transaction_with_contract_to_address_supplied_errors(
                 "data": "0x6abbb3b40000000000000000000000000000000000000000000000000000000000000005",  # noqa: E501
                 "value": 0,
                 "gasPrice": 22 * 10**8,
-                "chainId": 131277322940537,
             },
             False,
         ),
@@ -487,7 +479,6 @@ async def test_async_build_transaction_with_contract_to_address_supplied_errors(
                 "value": 0,
                 "maxFeePerGas": 22 * 10**8,
                 "maxPriorityFeePerGas": 22 * 10**8,
-                "chainId": 131277322940537,
             },
             False,
         ),
@@ -501,7 +492,6 @@ async def test_async_build_transaction_with_contract_to_address_supplied_errors(
                 "maxFeePerGas": 2750000000,
                 "maxPriorityFeePerGas": 1000000000,
                 "nonce": 7,
-                "chainId": 131277322940537,
             },
             True,
         ),
@@ -514,7 +504,6 @@ async def test_async_build_transaction_with_contract_to_address_supplied_errors(
                 "value": 20000,
                 "maxFeePerGas": 2750000000,
                 "maxPriorityFeePerGas": 1000000000,
-                "chainId": 131277322940537,
             },
             False,
         ),
@@ -542,6 +531,7 @@ async def test_async_build_transaction_with_contract_with_arguments(
     if skip_testrpc:
         async_skip_if_testrpc(async_w3)
 
+    expected["chainId"] = await async_w3.eth.chain_id
     txn = await async_build_transaction(
         contract=async_math_contract,
         contract_function="incrementCounter",
diff --git a/tests/core/eth-module/test_eth_properties.py b/tests/core/eth-module/test_eth_properties.py
index 39333d6045..ac789d4dd4 100644
--- a/tests/core/eth-module/test_eth_properties.py
+++ b/tests/core/eth-module/test_eth_properties.py
@@ -16,11 +16,9 @@ def async_w3():
 
 
 def test_eth_chain_id(w3):
-    assert w3.eth.chain_id == 131277322940537  # from fixture generation file
+    assert w3.eth.chain_id == w3.provider.eth_tester.chain_id
 
 
 @pytest.mark.asyncio
 async def test_async_eth_chain_id(async_w3):
-    assert (
-        await async_w3.eth.chain_id == 131277322940537
-    )  # from fixture generation file
+    assert await async_w3.eth.chain_id == async_w3.provider.eth_tester.chain_id
diff --git a/tests/core/module-class/test_module.py b/tests/core/module-class/test_module.py
index 8fe97b7d7f..d9bb35cdb5 100644
--- a/tests/core/module-class/test_module.py
+++ b/tests/core/module-class/test_module.py
@@ -37,8 +37,9 @@ def test_attach_methods_to_module(web3_with_external_modules):
         }
     )
 
-    assert w3.eth.chain_id == 131277322940537
-    assert w3.module1.property1 == 131277322940537
+    configured_chain_id = w3.provider.eth_tester.chain_id
+    assert w3.eth.chain_id == configured_chain_id
+    assert w3.module1.property1 == configured_chain_id
 
     account = w3.eth.accounts[0]
     assert w3.eth.get_balance(account, "latest") == 1000000000000000000000000
diff --git a/tests/core/web3-module/test_web3_inheritance.py b/tests/core/web3-module/test_web3_inheritance.py
index 8201a9ed8b..9de5a2f5b9 100644
--- a/tests/core/web3-module/test_web3_inheritance.py
+++ b/tests/core/web3-module/test_web3_inheritance.py
@@ -9,4 +9,4 @@ class InheritsFromWeb3(Web3):
         pass
 
     inherited_w3 = InheritsFromWeb3(EthereumTesterProvider())
-    assert inherited_w3.eth.chain_id == 131277322940537
+    assert inherited_w3.eth.chain_id == inherited_w3.provider.eth_tester.chain_id
diff --git a/tests/integration/ethereum_tester/__init__.py b/tests/integration/ethereum_tester/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/integration/test_ethereum_tester.py b/tests/integration/ethereum_tester/common.py
similarity index 99%
rename from tests/integration/test_ethereum_tester.py
rename to tests/integration/ethereum_tester/common.py
index 153c66cfbb..86030fc5d5 100644
--- a/tests/integration/test_ethereum_tester.py
+++ b/tests/integration/ethereum_tester/common.py
@@ -476,7 +476,7 @@ def test_eth_call_old_contract_state(
     def test_eth_chain_id(self, w3):
         chain_id = w3.eth.chain_id
         assert is_integer(chain_id)
-        assert chain_id == 131277322940537
+        assert chain_id == w3.provider.eth_tester.chain_id
 
     @disable_auto_mine
     def test_eth_wait_for_transaction_receipt_unmined(
diff --git a/tests/integration/ethereum_tester/conftest.py b/tests/integration/ethereum_tester/conftest.py
new file mode 100644
index 0000000000..c0ba0ea943
--- /dev/null
+++ b/tests/integration/ethereum_tester/conftest.py
@@ -0,0 +1,154 @@
+import pytest
+
+from eth_typing import (
+    ChecksumAddress,
+)
+from eth_utils import (
+    is_checksum_address,
+    is_dict,
+)
+
+from web3._utils.contract_sources.contract_data._custom_contract_data import (
+    EMITTER_ENUM,
+)
+from web3._utils.contract_sources.contract_data.panic_errors_contract import (
+    PANIC_ERRORS_CONTRACT_DATA,
+)
+from web3._utils.contract_sources.contract_data.storage_contract import (
+    STORAGE_CONTRACT_DATA,
+)
+
+# set up the keyfile account with a known address (same from geth setup)
+KEYFILE_ACCOUNT_PKEY = (
+    "0x58d23b55bc9cdce1f18c2500f40ff4ab7245df9a89505e9b1fa4851f623d241d"
+)
+KEYFILE_ACCOUNT_ADDRESS = "0xdC544d1AA88Ff8bbd2F2AeC754B1F1e99e1812fd"
+
+
+def _deploy_contract(w3, contract_factory):
+    deploy_txn_hash = contract_factory.constructor().transact(
+        {"from": w3.eth.default_account}
+    )
+    deploy_receipt = w3.eth.wait_for_transaction_receipt(deploy_txn_hash)
+    assert is_dict(deploy_receipt)
+    contract_address = deploy_receipt["contractAddress"]
+    assert is_checksum_address(contract_address)
+    return contract_factory(contract_address)
+
+
+@pytest.fixture(scope="module")
+def keyfile_account_pkey():
+    yield KEYFILE_ACCOUNT_PKEY
+
+
+@pytest.fixture(scope="module")
+def keyfile_account_address():
+    yield KEYFILE_ACCOUNT_ADDRESS
+
+
+@pytest.fixture(scope="module")
+def math_contract_deploy_txn_hash(w3, math_contract_factory):
+    deploy_txn_hash = math_contract_factory.constructor().transact(
+        {"from": w3.eth.default_account}
+    )
+    return deploy_txn_hash
+
+
+@pytest.fixture(scope="module")
+def math_contract(w3, math_contract_factory, math_contract_deploy_txn_hash):
+    deploy_receipt = w3.eth.wait_for_transaction_receipt(math_contract_deploy_txn_hash)
+    assert is_dict(deploy_receipt)
+    contract_address = deploy_receipt["contractAddress"]
+    assert is_checksum_address(contract_address)
+    return math_contract_factory(contract_address)
+
+
+@pytest.fixture(scope="module")
+def math_contract_address(math_contract, address_conversion_func):
+    return address_conversion_func(math_contract.address)
+
+
+@pytest.fixture(scope="module")
+def storage_contract(w3):
+    contract_factory = w3.eth.contract(**STORAGE_CONTRACT_DATA)
+    return _deploy_contract(w3, contract_factory)
+
+
+@pytest.fixture(scope="module")
+def emitter_contract(w3, emitter_contract_factory):
+    return _deploy_contract(w3, emitter_contract_factory)
+
+
+@pytest.fixture(scope="module")
+def emitter_contract_address(emitter_contract, address_conversion_func):
+    return address_conversion_func(emitter_contract.address)
+
+
+@pytest.fixture(scope="module")
+def empty_block(w3):
+    w3.testing.mine()
+    block = w3.eth.get_block("latest")
+    assert not block["transactions"]
+    return block
+
+
+@pytest.fixture(scope="module")
+def block_with_txn(w3):
+    txn_hash = w3.eth.send_transaction(
+        {
+            "from": ChecksumAddress(w3.eth.default_account),
+            "to": ChecksumAddress(w3.eth.default_account),
+            "value": w3.to_wei(1, "gwei"),
+            "gas": 21000,
+            "gasPrice": w3.to_wei(1, "gwei"),  # needs to be > base_fee post London
+        }
+    )
+    txn = w3.eth.get_transaction(txn_hash)
+    block = w3.eth.get_block(txn["blockNumber"])
+    return block
+
+
+@pytest.fixture(scope="module")
+def mined_txn_hash(block_with_txn):
+    return block_with_txn["transactions"][0]
+
+
+@pytest.fixture(scope="module")
+def block_with_txn_with_log(w3, emitter_contract):
+    txn_hash = emitter_contract.functions.logDouble(
+        which=EMITTER_ENUM["LogDoubleWithIndex"],
+        arg0=12345,
+        arg1=54321,
+    ).transact({"from": w3.eth.default_account})
+    txn = w3.eth.get_transaction(txn_hash)
+    block = w3.eth.get_block(txn["blockNumber"])
+    return block
+
+
+@pytest.fixture(scope="module")
+def txn_hash_with_log(block_with_txn_with_log):
+    return block_with_txn_with_log["transactions"][0]
+
+
+@pytest.fixture(scope="module")
+def revert_contract(w3, revert_contract_factory):
+    return _deploy_contract(w3, revert_contract_factory)
+
+
+#
+# Offchain Lookup Contract Setup
+#
+@pytest.fixture(scope="module")
+def offchain_lookup_contract(w3, offchain_lookup_contract_factory):
+    return _deploy_contract(w3, offchain_lookup_contract_factory)
+
+
+@pytest.fixture(scope="module")
+def panic_errors_contract(w3):
+    panic_errors_contract_factory = w3.eth.contract(**PANIC_ERRORS_CONTRACT_DATA)
+    return _deploy_contract(w3, panic_errors_contract_factory)
+
+
+@pytest.fixture
+def keyfile_account_address_dual_type(keyfile_account_address, address_conversion_func):
+    yield keyfile_account_address
diff --git a/tests/integration/ethereum_tester/test_eels.py b/tests/integration/ethereum_tester/test_eels.py
new file mode 100644
index 0000000000..21f9265163
--- /dev/null
+++ b/tests/integration/ethereum_tester/test_eels.py
@@ -0,0 +1,88 @@
+import pytest
+from typing import (
+    cast,
+)
+
+from eth_tester import (
+    EELSBackend,
+    EthereumTester,
+)
+from eth_typing import (
+    ChecksumAddress,
+)
+
+from web3 import (
+    Web3,
+)
+from web3.providers.eth_tester import (
+    EthereumTesterProvider,
+)
+from web3.types import (  # noqa: F401
+    BlockData,
+)
+
+from .common import (
+    EthereumTesterEthModule,
+    EthereumTesterNetModule,
+    EthereumTesterWeb3Module,
+)
+
+
+def _eth_tester_state_setup(w3, keyfile_account_address, keyfile_account_pkey):
+    provider = cast(EthereumTesterProvider, w3.provider)
+    provider.ethereum_tester.add_account(keyfile_account_pkey)
+
+    # fund the account
+    w3.eth.send_transaction(
+        {
+            "from": ChecksumAddress(w3.eth.default_account),
+            "to": keyfile_account_address,
+            "value": w3.to_wei(0.5, "ether"),
+            "gas": 21000,
+            "gasPrice": 10**9,  # needs to be > base_fee post London
+        }
+    )
+
+
+@pytest.fixture(scope="module")
+def eth_tester():
+    return EthereumTester(backend=EELSBackend(debug_mode=True))
+
+
+@pytest.fixture(scope="module")
+def w3(eth_tester, keyfile_account_address, keyfile_account_pkey):
+    _w3 = Web3(EthereumTesterProvider(eth_tester))
+    _w3.eth.default_account = _w3.eth.accounts[0]
+    _eth_tester_state_setup(_w3, keyfile_account_address, keyfile_account_pkey)
+    return _w3
+
+
+# -- test classes -- #
+
+
+class TestEthereumTesterWeb3Module(EthereumTesterWeb3Module):
+    pass
+
+
+class TestEthereumTesterEthModule(EthereumTesterEthModule):
+    def test_eth_chain_id(self, w3):
+        chain_id = w3.eth.chain_id
+        assert chain_id == 1
+
+    @pytest.mark.xfail(reason="EELS backed does not yet support eth_feeHistory")
+    def test_eth_fee_history(self, w3: "Web3") -> None:
+        super().test_eth_fee_history(w3)
+
+    @pytest.mark.xfail(reason="EELS backed does not yet support eth_feeHistory")
+    def test_eth_fee_history_with_integer(
+        self, w3: "Web3", empty_block: BlockData
+    ) -> None:
+        super().test_eth_fee_history_with_integer(w3, empty_block)
+
+    @pytest.mark.xfail(reason="EELS backed does not yet support eth_feeHistory")
+    def test_eth_fee_history_no_reward_percentiles(self, w3: "Web3") -> None:
+        super().test_eth_fee_history_no_reward_percentiles(w3)
+
+
+class TestEthereumTesterNetModule(EthereumTesterNetModule):
+    pass
diff --git a/tests/integration/ethereum_tester/test_pyevm.py b/tests/integration/ethereum_tester/test_pyevm.py
new file mode 100644
index 0000000000..b3b70167c5
--- /dev/null
+++ b/tests/integration/ethereum_tester/test_pyevm.py
@@ -0,0 +1,72 @@
+import pytest
+from typing import (
+    cast,
+)
+
+from eth_tester import (
+    EthereumTester,
+    PyEVMBackend,
+)
+from eth_typing import (
+    ChecksumAddress,
+)
+
+from web3 import (
+    Web3,
+)
+from web3.providers.eth_tester import (
+    EthereumTesterProvider,
+)
+from web3.types import (  # noqa: F401
+    BlockData,
+)
+
+from .common import (
+    EthereumTesterEthModule,
+    EthereumTesterNetModule,
+    EthereumTesterWeb3Module,
+)
+
+
+def _eth_tester_state_setup(w3, keyfile_account_address, keyfile_account_pkey):
+    provider = cast(EthereumTesterProvider, w3.provider)
+    provider.ethereum_tester.add_account(keyfile_account_pkey)
+
+    # fund the account
+    w3.eth.send_transaction(
+        {
+            "from": ChecksumAddress(w3.eth.default_account),
+            "to": keyfile_account_address,
+            "value": w3.to_wei(0.5, "ether"),
+            "gas": 21000,
+            "gasPrice": 10**9,  # needs to be > base_fee post London
+        }
+    )
+
+
+@pytest.fixture(scope="module")
+def eth_tester():
+    return EthereumTester(backend=PyEVMBackend())
+
+
+@pytest.fixture(scope="module")
+def w3(eth_tester, keyfile_account_address, keyfile_account_pkey):
+    _w3 = Web3(EthereumTesterProvider(eth_tester))
+    _w3.eth.default_account = _w3.eth.accounts[0]
+    _eth_tester_state_setup(_w3, keyfile_account_address, keyfile_account_pkey)
+    return _w3
+
+
+# -- test classes -- #
+
+
+class TestEthereumTesterWeb3Module(EthereumTesterWeb3Module):
+    pass
+
+
+class TestEthereumTesterEthModule(EthereumTesterEthModule):
+    pass
+
+
+class TestEthereumTesterNetModule(EthereumTesterNetModule):
+    pass
diff --git a/tox.ini b/tox.ini
index cc74b5e199..b77b9d16aa 100644
--- a/tox.ini
+++ b/tox.ini
@@ -20,7 +20,7 @@ allowlist_externals=make,pre-commit
 install_command=python -m pip install {opts} {packages}
 usedevelop=True
 commands=
-    core: pytest {posargs:tests/core -m "not asyncio"}
+    core: pytest {posargs:tests/core -m "not asyncio" }
     core_async: pytest {posargs:tests/core -m asyncio}
     ens: pytest {posargs:tests/ens --ignore=tests/ens/normalization/test_normalize_name_ensip15.py -n auto --maxprocesses=15}
     ensip15: pytest {posargs:tests/ens/normalization/test_normalize_name_ensip15.py -q -n auto --maxprocesses=15}
@@ -30,7 +30,8 @@ commands=
     integration-goethereum-http_async: pytest {posargs:tests/integration/go_ethereum/test_goethereum_http.py -k Async -n auto --maxprocesses=15}
     integration-goethereum-legacy_ws: pytest {posargs:tests/integration/go_ethereum/test_goethereum_legacy_ws.py -n auto --maxprocesses=15}
     integration-goethereum-ws: pytest {posargs:tests/integration/go_ethereum/test_goethereum_ws -n auto --maxprocesses=15}
-    integration-ethtester: pytest {posargs:tests/integration/test_ethereum_tester.py -n auto --maxprocesses=15}
+    integration-ethtester-pyevm: pytest {posargs:tests/integration/ethereum_tester/test_pyevm.py -n auto --maxprocesses=15}
+    integration-ethtester-eels: pytest {posargs:tests/integration/ethereum_tester/test_eels.py -n auto --maxprocesses=15}
     docs: make check-docs-ci
 deps =
     .[test]
diff --git a/web3/_utils/module_testing/eth_module.py b/web3/_utils/module_testing/eth_module.py
index e9614cf7b6..b617907d5d 100644
--- a/web3/_utils/module_testing/eth_module.py
+++ b/web3/_utils/module_testing/eth_module.py
@@ -3348,7 +3348,7 @@ def test_eth_send_transaction_no_gas(
             "from": keyfile_account_address_dual_type,
             "to": keyfile_account_address_dual_type,
             "value": Wei(1),
-            "maxFeePerGas": Wei(250 * 10**9),
+            "maxFeePerGas": Wei(2 * 10**9),
             "maxPriorityFeePerGas": Wei(2 * 10**9),
         }
         txn_hash = w3.eth.send_transaction(txn_params)
@@ -3836,7 +3836,7 @@ def test_eth_send_raw_transaction(
     ) -> None:
         keyfile_account = w3.eth.account.from_key(keyfile_account_pkey)
         txn = {
-            "chainId": 131277322940537,  # the chainId set for the fixture
+            "chainId": w3.eth.chain_id,
             "from": keyfile_account.address,
             "to": keyfile_account.address,
             "value": Wei(0),
diff --git a/web3/providers/eth_tester/defaults.py b/web3/providers/eth_tester/defaults.py
index 57985a7053..b6197c0c37 100644
--- a/web3/providers/eth_tester/defaults.py
+++ b/web3/providers/eth_tester/defaults.py
@@ -243,7 +243,7 @@ def create_new_account(eth_tester: "EthereumTester") -> HexAddress:
     "eth": {
         "protocolVersion": static_return(63),
         "syncing": static_return(False),
-        "chainId": static_return(131277322940537),  # from fixture generation file
+        "chainId": call_eth_tester("chain_id"),
         "feeHistory": call_eth_tester("get_fee_history"),
         "maxPriorityFeePerGas": static_return(10**9),
         "blobBaseFee": static_return(10**9),
@@ -302,6 +302,10 @@ def create_new_account(eth_tester: "EthereumTester") -> HexAddress:
         "getTransactionByHash": null_if_transaction_not_found(
             call_eth_tester("get_transaction_by_hash")
         ),
+        "eth_getBlockTransactionCountByHash": not_implemented,
+        "eth_getBlockTransactionCountByNumber": not_implemented,
+        "eth_getRawTransactionByBlockNumberAndIndex": not_implemented,
+        "eth_getRawTransactionByBlockHashAndIndex": not_implemented,
         "getTransactionByBlockHashAndIndex": get_transaction_by_block_hash_and_index,
         "getTransactionByBlockNumberAndIndex": get_transaction_by_block_number_and_index,  # noqa: E501
         "getTransactionReceipt": null_if_transaction_not_found(

From 24a5ec5fe2135747af4b18ce21b1e868d251f05b Mon Sep 17 00:00:00 2001
From: fselmo <fselmo2@gmail.com>
Date: Mon, 5 Aug 2024 15:45:56 -0600
Subject: [PATCH 3/9] Updates to test suite after running for EELS backend

---
 conftest.py                                   | 11 ++---
 setup.py                                      |  6 ++-
 tests/conftest.py                             | 46 +++++++++++++++++++
 tests/core/conftest.py                        | 12 ++---
 .../contracts/test_contract_attributes.py     |  2 +-
 .../test_contract_caller_interface.py         |  4 +-
 tests/core/contracts/test_contract_example.py | 13 ++++--
 tests/core/contracts/test_contract_init.py    |  2 +-
 .../contracts/test_extracting_event_data.py   |  2 +-
 .../test_extracting_event_data_old.py         | 22 +++++++++
 tests/core/eth-module/test_accounts.py        | 17 ++++---
 tests/core/eth-module/test_eth_filter.py      | 13 ++++--
 tests/core/eth-module/test_eth_properties.py  | 15 ++++--
 tests/core/filtering/conftest.py              |  8 ++--
 .../filtering/test_contract_data_filters.py   |  8 ++--
 .../filtering/test_contract_topic_filters.py  |  8 ++--
 .../test_existing_filter_instance.py          |  2 +-
 tests/core/filtering/utils.py                 | 16 ++++---
 .../test_name_to_address_middleware.py        | 10 +++-
 .../middleware/test_transaction_signing.py    | 20 ++++----
 tests/core/module-class/test_module.py        |  2 +-
 tests/core/utilities/conftest.py              |  9 ++--
 tests/core/utilities/test_abi.py              |  2 +-
 .../core/web3-module/test_web3_inheritance.py |  5 +-
 tests/ens/conftest.py                         | 19 +++++---
 tests/ens/test_get_text.py                    | 30 ++++++++----
 tests/ens/test_setup_name.py                  |  4 +-
 tests/integration/ethereum_tester/common.py   |  5 --
 .../integration/ethereum_tester/test_eels.py  |  2 +-
 .../integration/ethereum_tester/test_pyevm.py |  4 +-
 .../test_goethereum_ws/conftest.py            | 17 +++++++
 tox.ini                                       | 13 ++++--
 web3/providers/eth_tester/main.py             | 30 ++++++++----
 33 files changed, 264 insertions(+), 115 deletions(-)

diff --git a/conftest.py b/conftest.py
index 0676201d24..c3d8e7d64f 100644
--- a/conftest.py
+++ b/conftest.py
@@ -3,7 +3,6 @@
 import warnings
 
 from eth_tester import (
-    EELSBackend,
     EthereumTester,
 )
 import pytest_asyncio
@@ -75,17 +74,15 @@ def _wait_for_transaction(w3, txn_hash, timeout=120):
 
 
 @pytest.fixture
-def w3():
-    t = EthereumTester(backend=EELSBackend("cancun"))
-    w3 = Web3(EthereumTesterProvider(t))
+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():
-    t = EthereumTester(backend=EELSBackend("cancun"))
-    w3 = Web3(EthereumTesterProvider(t))
+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
diff --git a/setup.py b/setup.py
index 4b3f0a722a..a8b7bfdcc1 100644
--- a/setup.py
+++ b/setup.py
@@ -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.13.0b1,<0.14.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.1.0",
     ],
     "dev": [
diff --git a/tests/conftest.py b/tests/conftest.py
index 66ea6dd086..9b72b0b074 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -3,6 +3,9 @@
     Type,
 )
 
+from eth_tester import (
+    PyEVMBackend,
+)
 from eth_utils import (
     event_signature_to_log_topic,
     to_bytes,
@@ -19,6 +22,8 @@
     RequestMocker,
 )
 
+SUPPORTED_ETH_TESTER_BACKENDS = {"pyevm", "eels"}
+
 
 @pytest.fixture(scope="module", params=[lambda x: to_bytes(hexstr=x), identity])
 def address_conversion_func(request):
@@ -28,6 +33,47 @@ def address_conversion_func(request):
 # --- 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
diff --git a/tests/core/conftest.py b/tests/core/conftest.py
index 1dc712def0..8497aa1a03 100644
--- a/tests/core/conftest.py
+++ b/tests/core/conftest.py
@@ -1,7 +1,6 @@
 import pytest
 
 from eth_tester import (
-    EELSBackend,
     EthereumTester,
 )
 import pytest_asyncio
@@ -121,19 +120,16 @@ def __init__(self, a, b):
 
 
 @pytest_asyncio.fixture
-async def async_w3():
-    t = EthereumTester(backend=EELSBackend("cancun"))
-    provider = AsyncEthereumTesterProvider()
-    provider.ethereum_tester = t
-    w3 = AsyncWeb3(provider)
+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]
diff --git a/tests/core/contracts/test_contract_attributes.py b/tests/core/contracts/test_contract_attributes.py
index 53fc296229..79275eb695 100644
--- a/tests/core/contracts/test_contract_attributes.py
+++ b/tests/core/contracts/test_contract_attributes.py
@@ -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
 
diff --git a/tests/core/contracts/test_contract_caller_interface.py b/tests/core/contracts/test_contract_caller_interface.py
index 0c3df9ce90..81b85972eb 100644
--- a/tests/core/contracts/test_contract_caller_interface.py
+++ b/tests/core/contracts/test_contract_caller_interface.py
@@ -8,12 +8,12 @@
 )
 
 
-@pytest.fixture()
+@pytest.fixture
 def address(w3):
     return w3.eth.accounts[1]
 
 
-@pytest.fixture()
+@pytest.fixture
 def transaction_dict(w3, address):
     return {
         "from": address,
diff --git a/tests/core/contracts/test_contract_example.py b/tests/core/contracts/test_contract_example.py
index e47c9352d9..9eb9a1e7de 100644
--- a/tests/core/contracts/test_contract_example.py
+++ b/tests/core/contracts/test_contract_example.py
@@ -2,6 +2,9 @@
 # of how to write unit tests with web3.py
 import pytest
 
+from eth_tester import (
+    EthereumTester,
+)
 import pytest_asyncio
 
 from web3 import (
@@ -15,8 +18,8 @@
 
 
 @pytest.fixture
-def tester_provider():
-    return EthereumTesterProvider()
+def tester_provider(backend_class):
+    return EthereumTesterProvider(EthereumTester(backend=backend_class()))
 
 
 @pytest.fixture
@@ -118,8 +121,10 @@ def async_eth_tester():
 
 
 @pytest_asyncio.fixture()
-async def async_w3():
-    async_w3 = AsyncWeb3(AsyncEthereumTesterProvider())
+async def async_w3(backend_class):
+    async_w3 = AsyncWeb3(
+        AsyncEthereumTesterProvider(EthereumTester(backend=backend_class()))
+    )
     accounts = await async_w3.eth.accounts
     async_w3.eth.default_account = accounts[0]
     return async_w3
diff --git a/tests/core/contracts/test_contract_init.py b/tests/core/contracts/test_contract_init.py
index 7d6dc3f700..e0beacd74c 100644
--- a/tests/core/contracts/test_contract_init.py
+++ b/tests/core/contracts/test_contract_init.py
@@ -11,7 +11,7 @@
 )
 
 
-@pytest.fixture()
+@pytest.fixture
 def math_addr(math_contract_factory, address_conversion_func):
     w3 = math_contract_factory.w3
     deploy_txn = math_contract_factory.constructor().transact(
diff --git a/tests/core/contracts/test_extracting_event_data.py b/tests/core/contracts/test_extracting_event_data.py
index 30fcea0c64..d61f890308 100644
--- a/tests/core/contracts/test_extracting_event_data.py
+++ b/tests/core/contracts/test_extracting_event_data.py
@@ -28,7 +28,7 @@
 )
 
 
-@pytest.fixture()
+@pytest.fixture
 def dup_txn_receipt(w3, indexed_event_contract, wait_for_transaction, event_contract):
     emitter_fn = indexed_event_contract.functions.logTwoEvents
 
diff --git a/tests/core/contracts/test_extracting_event_data_old.py b/tests/core/contracts/test_extracting_event_data_old.py
index 12cb2fc0f5..39ef9506bf 100644
--- a/tests/core/contracts/test_extracting_event_data_old.py
+++ b/tests/core/contracts/test_extracting_event_data_old.py
@@ -9,6 +9,28 @@
 )
 
 
+@pytest.fixture
+def emitter(
+    w3,
+    emitter_contract_data,
+    wait_for_transaction,
+    wait_for_block,
+    address_conversion_func,
+):
+    emitter_contract_factory = w3.eth.contract(**emitter_contract_data)
+
+    wait_for_block(w3)
+    deploy_txn_hash = emitter_contract_factory.constructor().transact({"gas": 10000000})
+    deploy_receipt = wait_for_transaction(w3, deploy_txn_hash)
+    contract_address = address_conversion_func(deploy_receipt["contractAddress"])
+
+    bytecode = w3.eth.get_code(contract_address)
+    assert bytecode == emitter_contract_factory.bytecode_runtime
+    _emitter = emitter_contract_factory(address=contract_address)
+    assert _emitter.address == contract_address
+    return _emitter
+
+
 @pytest.mark.parametrize(
     "contract_fn,event_name,call_args,expected_args",
     (
diff --git a/tests/core/eth-module/test_accounts.py b/tests/core/eth-module/test_accounts.py
index 6f935acf4e..78cf51adc6 100644
--- a/tests/core/eth-module/test_accounts.py
+++ b/tests/core/eth-module/test_accounts.py
@@ -9,6 +9,9 @@
 from eth_account.signers.local import (
     LocalAccount,
 )
+from eth_tester import (
+    EthereumTester,
+)
 from eth_utils import (
     is_bytes,
     is_checksum_address,
@@ -98,9 +101,9 @@ def acct(request, w3):
     raise Exception("Unreachable!")
 
 
-@pytest.fixture()
-def w3():
-    return Web3(EthereumTesterProvider())
+@pytest.fixture
+def w3(backend_class):
+    return Web3(EthereumTesterProvider(EthereumTester(backend=backend_class())))
 
 
 def test_eth_default_account_is_empty_by_default(w3):
@@ -560,9 +563,11 @@ def test_eth_account_sign_and_send_EIP155_transaction_to_eth_tester(
 # -- async -- #
 
 
-@pytest.fixture()
-def async_w3():
-    return AsyncWeb3(AsyncEthereumTesterProvider())
+@pytest.fixture
+def async_w3(backend_class):
+    return AsyncWeb3(
+        AsyncEthereumTesterProvider(EthereumTester(backend=backend_class()))
+    )
 
 
 @patch("web3.eth.BaseEth.account", "wired via BaseEth")
diff --git a/tests/core/eth-module/test_eth_filter.py b/tests/core/eth-module/test_eth_filter.py
index beac58d431..427e43fb95 100644
--- a/tests/core/eth-module/test_eth_filter.py
+++ b/tests/core/eth-module/test_eth_filter.py
@@ -1,5 +1,8 @@
 import pytest
 
+from eth_tester import (
+    EthereumTester,
+)
 import pytest_asyncio
 
 from web3 import (
@@ -30,11 +33,11 @@ def test_eth_filter_creates_correct_filter_type(w3):
 # --- async --- #
 
 
-@pytest_asyncio.fixture()
-async def async_w3():
-    provider = AsyncEthereumTesterProvider()
-    w3 = AsyncWeb3(provider)
-    return w3
+@pytest_asyncio.fixture
+async def async_w3(backend_class):
+    return AsyncWeb3(
+        AsyncEthereumTesterProvider(EthereumTester(backend=backend_class()))
+    )
 
 
 @pytest.mark.asyncio
diff --git a/tests/core/eth-module/test_eth_properties.py b/tests/core/eth-module/test_eth_properties.py
index ac789d4dd4..25a12bd6c4 100644
--- a/tests/core/eth-module/test_eth_properties.py
+++ b/tests/core/eth-module/test_eth_properties.py
@@ -1,5 +1,9 @@
 import pytest
 
+from eth_tester import (
+    EthereumTester,
+)
+
 from web3 import (
     AsyncWeb3,
 )
@@ -9,16 +13,19 @@
 
 
 @pytest.fixture
-def async_w3():
+def async_w3(backend_class):
     return AsyncWeb3(
-        AsyncEthereumTesterProvider(),
+        AsyncEthereumTesterProvider(EthereumTester(backend=backend_class())),
     )
 
 
 def test_eth_chain_id(w3):
-    assert w3.eth.chain_id == w3.provider.eth_tester.chain_id
+    assert w3.eth.chain_id == w3.provider.ethereum_tester.backend.chain.chain_id
 
 
 @pytest.mark.asyncio
 async def test_async_eth_chain_id(async_w3):
-    assert await async_w3.eth.chain_id == async_w3.provider.eth_tester.chain_id
+    assert (
+        await async_w3.eth.chain_id
+        == async_w3.provider.ethereum_tester.backend.chain.chain_id
+    )
diff --git a/tests/core/filtering/conftest.py b/tests/core/filtering/conftest.py
index bc78b065d4..71f8be92f9 100644
--- a/tests/core/filtering/conftest.py
+++ b/tests/core/filtering/conftest.py
@@ -22,8 +22,8 @@
     params=[True, False],
     ids=["LocalFilterMiddleware", "node_based_filter"],
 )
-def w3(request):
-    return _w3_fixture_logic(request)
+def w3(request, backend_class):
+    return _w3_fixture_logic(request, backend_class)
 
 
 @pytest.fixture
@@ -69,8 +69,8 @@ def create_filter(request):
     params=[True, False],
     ids=["LocalFilterMiddleware", "node_based_filter"],
 )
-async def async_w3(request):
-    return await _async_w3_fixture_logic(request)
+async def async_w3(request, backend_class):
+    return await _async_w3_fixture_logic(request, backend_class)
 
 
 @pytest.fixture
diff --git a/tests/core/filtering/test_contract_data_filters.py b/tests/core/filtering/test_contract_data_filters.py
index d77c71f6fb..bb514987fd 100644
--- a/tests/core/filtering/test_contract_data_filters.py
+++ b/tests/core/filtering/test_contract_data_filters.py
@@ -84,8 +84,8 @@ def array_values(draw):
     params=[True, False],
     ids=["LocalFilterMiddleware", "node_based_filter"],
 )
-def w3(request):
-    return _w3_fixture_logic(request)
+def w3(request, backend_class):
+    return _w3_fixture_logic(request, backend_class)
 
 
 @pytest.fixture(scope="module")
@@ -287,8 +287,8 @@ def event_loop():
     params=[True, False],
     ids=["LocalFilterMiddleware", "node_based_filter"],
 )
-async def async_w3(request):
-    return await _async_w3_fixture_logic(request)
+async def async_w3(request, backend_class):
+    return await _async_w3_fixture_logic(request, backend_class)
 
 
 @pytest.fixture(scope="module")
diff --git a/tests/core/filtering/test_contract_topic_filters.py b/tests/core/filtering/test_contract_topic_filters.py
index 870e406223..7c7f0bff8a 100644
--- a/tests/core/filtering/test_contract_topic_filters.py
+++ b/tests/core/filtering/test_contract_topic_filters.py
@@ -84,8 +84,8 @@ def array_values(draw):
     params=[True, False],
     ids=["LocalFilterMiddleware", "node_based_filter"],
 )
-def w3(request):
-    return _w3_fixture_logic(request)
+def w3(request, backend_class):
+    return _w3_fixture_logic(request, backend_class)
 
 
 @pytest.fixture(scope="module")
@@ -268,8 +268,8 @@ def event_loop():
     params=[True, False],
     ids=["LocalFilterMiddleware", "node_based_filter"],
 )
-async def async_w3(request):
-    return await _async_w3_fixture_logic(request)
+async def async_w3(request, backend_class):
+    return await _async_w3_fixture_logic(request, backend_class)
 
 
 @pytest_asyncio.fixture(scope="module")
diff --git a/tests/core/filtering/test_existing_filter_instance.py b/tests/core/filtering/test_existing_filter_instance.py
index 8ae2cdd2ee..ccf97be687 100644
--- a/tests/core/filtering/test_existing_filter_instance.py
+++ b/tests/core/filtering/test_existing_filter_instance.py
@@ -7,7 +7,7 @@
 )
 
 
-@pytest.fixture()
+@pytest.fixture
 def filter_id(w3):
     block_filter = w3.eth.filter("latest")
     return block_filter.filter_id
diff --git a/tests/core/filtering/utils.py b/tests/core/filtering/utils.py
index e97cae895f..742950ebf8 100644
--- a/tests/core/filtering/utils.py
+++ b/tests/core/filtering/utils.py
@@ -1,3 +1,7 @@
+from eth_tester import (
+    EthereumTester,
+)
+
 from web3 import (
     AsyncWeb3,
     Web3,
@@ -13,10 +17,9 @@
 MAX_UINT_256 = 2**256 - 1
 
 
-def _w3_fixture_logic(request):
+def _w3_fixture_logic(request, backend_class):
     use_filter_middleware = request.param
-    provider = EthereumTesterProvider()
-    w3 = Web3(provider)
+    w3 = Web3(EthereumTesterProvider(EthereumTester(backend=backend_class())))
     w3.eth.default_account = w3.eth.accounts[0]
     if use_filter_middleware:
         w3.middleware_onion.add(LocalFilterMiddleware)
@@ -45,10 +48,11 @@ def _emitter_fixture_logic(
 # --- async --- #
 
 
-async def _async_w3_fixture_logic(request):
+async def _async_w3_fixture_logic(request, backend_class):
     use_filter_middleware = request.param
-    provider = AsyncEthereumTesterProvider()
-    async_w3 = AsyncWeb3(provider)
+    async_w3 = AsyncWeb3(
+        AsyncEthereumTesterProvider(EthereumTester(backend=backend_class()))
+    )
 
     accounts = await async_w3.eth.accounts
     async_w3.eth.default_account = accounts[0]
diff --git a/tests/core/middleware/test_name_to_address_middleware.py b/tests/core/middleware/test_name_to_address_middleware.py
index e3c9196236..bb55c6949c 100644
--- a/tests/core/middleware/test_name_to_address_middleware.py
+++ b/tests/core/middleware/test_name_to_address_middleware.py
@@ -1,5 +1,8 @@
 import pytest
 
+from eth_tester import (
+    EthereumTester,
+)
 import pytest_asyncio
 
 from web3 import (
@@ -30,8 +33,11 @@ def address(self, name):
 
 
 @pytest.fixture
-def _w3_setup():
-    return Web3(provider=EthereumTesterProvider(), middleware=[])
+def _w3_setup(backend_class):
+    return Web3(
+        provider=EthereumTesterProvider(EthereumTester(backend=backend_class())),
+        middleware=[],
+    )
 
 
 @pytest.fixture
diff --git a/tests/core/middleware/test_transaction_signing.py b/tests/core/middleware/test_transaction_signing.py
index ee1030b958..f2cb467074 100644
--- a/tests/core/middleware/test_transaction_signing.py
+++ b/tests/core/middleware/test_transaction_signing.py
@@ -10,11 +10,13 @@
     LocalAccount,
 )
 import eth_keys
+from eth_tester import (
+    EthereumTester,
+)
 from eth_tester.exceptions import (
     ValidationError,
 )
 from eth_utils import (
-    ValidationError as EthUtilsValidationError,
     is_hexstr,
     to_bytes,
     to_hex,
@@ -226,7 +228,7 @@ def hex_to_bytes(s):
     ),
     (
         {"gas": 21000, "gasPrice": 0, "value": 1},
-        EthUtilsValidationError,
+        Exception,
         MIXED_KEY_MIXED_TYPE,
         ADDRESS_1,
     ),
@@ -244,7 +246,7 @@ def hex_to_bytes(s):
     (
         {
             "value": 22,
-            "maxFeePerGas": 20**9,
+            "maxFeePerGas": 10**9,
             "maxPriorityFeePerGas": 10**9,
         },
         -1,
@@ -310,9 +312,9 @@ def assert_method_and_txn_signed(actual, expected):
     assert is_hexstr(raw_txn)
 
 
-@pytest.fixture()
-def w3():
-    _w3 = Web3(EthereumTesterProvider())
+@pytest.fixture
+def w3(backend_class):
+    _w3 = Web3(EthereumTesterProvider(EthereumTester(backend=backend_class())))
     _w3.eth.default_account = _w3.eth.accounts[0]
     return _w3
 
@@ -494,8 +496,10 @@ async def async_w3_dummy(request_mocker):
 
 
 @pytest_asyncio.fixture
-async def async_w3():
-    _async_w3 = AsyncWeb3(AsyncEthereumTesterProvider())
+async def async_w3(backend_class):
+    _async_w3 = AsyncWeb3(
+        AsyncEthereumTesterProvider(EthereumTester(backend=backend_class()))
+    )
     accounts = await _async_w3.eth.accounts
     _async_w3.eth.default_account = accounts[0]
     return _async_w3
diff --git a/tests/core/module-class/test_module.py b/tests/core/module-class/test_module.py
index d9bb35cdb5..df641da306 100644
--- a/tests/core/module-class/test_module.py
+++ b/tests/core/module-class/test_module.py
@@ -37,7 +37,7 @@ def test_attach_methods_to_module(web3_with_external_modules):
         }
     )
 
-    configured_chain_id = w3.provider.eth_tester.chain_id
+    configured_chain_id = w3.provider.ethereum_tester.backend.chain.chain_id
     assert w3.eth.chain_id == configured_chain_id
     assert w3.module1.property1 == configured_chain_id
 
diff --git a/tests/core/utilities/conftest.py b/tests/core/utilities/conftest.py
index 8274f13e5c..263f1a722d 100644
--- a/tests/core/utilities/conftest.py
+++ b/tests/core/utilities/conftest.py
@@ -1,5 +1,9 @@
 import pytest
 
+from eth_tester import (
+    EthereumTester,
+)
+
 from web3.main import (
     Web3,
 )
@@ -9,6 +13,5 @@
 
 
 @pytest.fixture(scope="module")
-def w3():
-    provider = EthereumTesterProvider()
-    return Web3(provider)
+def w3(backend_class):
+    return Web3(EthereumTesterProvider(EthereumTester(backend=backend_class())))
diff --git a/tests/core/utilities/test_abi.py b/tests/core/utilities/test_abi.py
index baebbec247..07b9a038eb 100644
--- a/tests/core/utilities/test_abi.py
+++ b/tests/core/utilities/test_abi.py
@@ -200,7 +200,7 @@
 ABI_ERROR = ABIError({"type": "error", "name": "error"})
 
 
-@pytest.fixture()
+@pytest.fixture
 def contract_abi() -> ABI:
     return CONTRACT_ABI
 
diff --git a/tests/core/web3-module/test_web3_inheritance.py b/tests/core/web3-module/test_web3_inheritance.py
index 9de5a2f5b9..40d4c15fb2 100644
--- a/tests/core/web3-module/test_web3_inheritance.py
+++ b/tests/core/web3-module/test_web3_inheritance.py
@@ -9,4 +9,7 @@ class InheritsFromWeb3(Web3):
         pass
 
     inherited_w3 = InheritsFromWeb3(EthereumTesterProvider())
-    assert inherited_w3.eth.chain_id == inherited_w3.provider.eth_tester.chain_id
+    assert (
+        inherited_w3.eth.chain_id
+        == inherited_w3.provider.ethereum_tester.backend.chain.chain_id
+    )
diff --git a/tests/ens/conftest.py b/tests/ens/conftest.py
index 44e47177f1..2207edc07e 100644
--- a/tests/ens/conftest.py
+++ b/tests/ens/conftest.py
@@ -163,8 +163,8 @@ def ens(ens_setup, mocker):
 
 # session scope for performance
 @pytest.fixture(scope="session")
-def ens_setup():
-    w3 = Web3(EthereumTesterProvider(EthereumTester()))
+def ens_setup(backend_class):
+    w3 = Web3(EthereumTesterProvider(EthereumTester(backend=backend_class())))
 
     # ** Set up ENS contracts **
 
@@ -355,7 +355,7 @@ def ens_setup():
     return ENS.from_web3(w3, ens_contract.address)
 
 
-@pytest.fixture()
+@pytest.fixture
 def TEST_ADDRESS(address_conversion_func):
     return address_conversion_func("0x000000000000000000000000000000000000dEaD")
 
@@ -364,8 +364,10 @@ def TEST_ADDRESS(address_conversion_func):
 
 
 @pytest_asyncio.fixture(scope="session")
-def async_w3():
-    _async_w3 = AsyncWeb3(AsyncEthereumTesterProvider())
+def async_w3(backend_class):
+    _async_w3 = AsyncWeb3(
+        AsyncEthereumTesterProvider(EthereumTester(backend=backend_class()))
+    )
     return _async_w3
 
 
@@ -461,8 +463,11 @@ def event_loop():
 
 # add session scope with above session-scoped `event_loop` for better performance
 @pytest_asyncio.fixture(scope="session")
-async def async_ens_setup(async_w3):
+async def async_ens_setup(backend_class):
     # ** Set up ENS contracts **
+    async_w3 = AsyncWeb3(
+        AsyncEthereumTesterProvider(EthereumTester(backend=backend_class()))
+    )
 
     # remove account that creates ENS, so test transactions don't have write access
     accounts = await async_w3.eth.accounts
@@ -479,7 +484,7 @@ async def async_ens_setup(async_w3):
     )
     reverse_tld_namehash = bytes32(
         0xA097F6721CE401E757D1223A763FEF49B8B5F90BB18567DDB86FD205DFF71D34
-    )  # noqa: E501
+    )
     reverser_namehash = bytes32(
         0x91D1777781884D03A6757A803996E38DE2A42967FB37EEACA72729271025A9E2
     )
diff --git a/tests/ens/test_get_text.py b/tests/ens/test_get_text.py
index a04f26b568..1f8414f161 100644
--- a/tests/ens/test_get_text.py
+++ b/tests/ens/test_get_text.py
@@ -1,7 +1,7 @@
 import pytest
 
-from eth_utils import (
-    ValidationError as EthUtilsValidationError,
+from eth_tester.exceptions import (
+    ValidationError as EthTesterValidationError,
 )
 
 from ens.exceptions import (
@@ -31,9 +31,14 @@ def test_set_text_fails_with_bad_address(ens):
     address = ens.w3.eth.accounts[2]
     ens.setup_address("tester.eth", address)
     zero_address = "0x" + "00" * 20
-    with pytest.raises(EthUtilsValidationError):
+    with pytest.raises(EthTesterValidationError):
         ens.set_text(
-            "tester.eth", "url", "http://example.com", transact={"from": zero_address}
+            "tester.eth",
+            "url",
+            "http://example.com",
+            # add gas so we don't call eth_estimateGas which can fail the transaction
+            # in a different way
+            transact={"from": zero_address, "gas": 222_222},
         )
 
     # teardown
@@ -49,8 +54,8 @@ def test_set_text_pass_in_transaction_dict(ens):
         "avatar",
         "example.jpeg",
         transact={
-            "maxFeePerGas": Web3.to_wei(100, "gwei"),
-            "maxPriorityFeePerGas": Web3.to_wei(100, "gwei"),
+            "maxFeePerGas": Web3.to_wei(1, "gwei"),
+            "maxPriorityFeePerGas": Web3.to_wei(1, "gwei"),
         },
     )
     assert ens.get_text("tester.eth", "url") == "http://example.com"
@@ -102,9 +107,14 @@ async def test_async_set_text_fails_with_bad_address(async_ens):
     address = accounts[2]
     await async_ens.setup_address("tester.eth", address)
     zero_address = "0x" + "00" * 20
-    with pytest.raises(EthUtilsValidationError):
+    with pytest.raises(EthTesterValidationError):
         await async_ens.set_text(
-            "tester.eth", "url", "http://example.com", transact={"from": zero_address}
+            "tester.eth",
+            "url",
+            "http://example.com",
+            # add gas so we don't call eth_estimateGas which can fail the transaction
+            # in a different way
+            transact={"from": zero_address, "gas": 222_222},
         )
 
     # teardown
@@ -125,8 +135,8 @@ async def test_async_set_text_pass_in_transaction_dict(async_ens):
         "avatar",
         "example.jpeg",
         transact={
-            "maxFeePerGas": Web3.to_wei(100, "gwei"),
-            "maxPriorityFeePerGas": Web3.to_wei(100, "gwei"),
+            "maxFeePerGas": Web3.to_wei(1, "gwei"),
+            "maxPriorityFeePerGas": Web3.to_wei(1, "gwei"),
         },
     )
     assert await async_ens.get_text("tester.eth", "url") == "http://example.com"
diff --git a/tests/ens/test_setup_name.py b/tests/ens/test_setup_name.py
index cef22d9bf2..752e39b7d4 100644
--- a/tests/ens/test_setup_name.py
+++ b/tests/ens/test_setup_name.py
@@ -92,7 +92,7 @@ def test_setup_name_default_address(ens):
     assert not ens.name(new_resolution)
     assert ens.owner(name) == owner
     assert ens.address(name) == new_resolution
-    ens.setup_name(name)
+    ens.setup_name(name, transact={"gas": 222_222})
     assert ens.name(new_resolution) == name
     ens.setup_name(None, new_resolution)
 
@@ -190,7 +190,7 @@ async def test_async_setup_name_default_address(async_ens):
     assert not await async_ens.name(new_resolution)
     assert await async_ens.owner(name) == owner
     assert await async_ens.address(name) == new_resolution
-    await async_ens.setup_name(name)
+    await async_ens.setup_name(name, transact={"gas": 222_222})
     assert await async_ens.name(new_resolution) == name
     await async_ens.setup_name(None, new_resolution)
 
diff --git a/tests/integration/ethereum_tester/common.py b/tests/integration/ethereum_tester/common.py
index 86030fc5d5..cedb1e00b8 100644
--- a/tests/integration/ethereum_tester/common.py
+++ b/tests/integration/ethereum_tester/common.py
@@ -473,11 +473,6 @@ def test_eth_call_old_contract_state(
             w3, math_contract, keyfile_account_address
         )
 
-    def test_eth_chain_id(self, w3):
-        chain_id = w3.eth.chain_id
-        assert is_integer(chain_id)
-        assert chain_id == w3.provider.eth_tester.chain_id
-
     @disable_auto_mine
     def test_eth_wait_for_transaction_receipt_unmined(
         self, eth_tester, w3, keyfile_account_address_dual_type
diff --git a/tests/integration/ethereum_tester/test_eels.py b/tests/integration/ethereum_tester/test_eels.py
index 21f9265163..1af4ac75f3 100644
--- a/tests/integration/ethereum_tester/test_eels.py
+++ b/tests/integration/ethereum_tester/test_eels.py
@@ -46,7 +46,7 @@ def _eth_tester_state_setup(w3, keyfile_account_address, keyfile_account_pkey):
 
 @pytest.fixture(scope="module")
 def eth_tester():
-    return EthereumTester(backend=EELSBackend(debug_mode=True))
+    return EthereumTester(backend=EELSBackend())
 
 
 @pytest.fixture(scope="module")
diff --git a/tests/integration/ethereum_tester/test_pyevm.py b/tests/integration/ethereum_tester/test_pyevm.py
index b3b70167c5..08a157322f 100644
--- a/tests/integration/ethereum_tester/test_pyevm.py
+++ b/tests/integration/ethereum_tester/test_pyevm.py
@@ -65,7 +65,9 @@ class TestEthereumTesterWeb3Module(EthereumTesterWeb3Module):
 
 
 class TestEthereumTesterEthModule(EthereumTesterEthModule):
-    pass
+    def test_eth_chain_id(self, w3):
+        chain_id = w3.eth.chain_id
+        assert chain_id == 131277322940537
 
 
 class TestEthereumTesterNetModule(EthereumTesterNetModule):
diff --git a/tests/integration/go_ethereum/test_goethereum_ws/conftest.py b/tests/integration/go_ethereum/test_goethereum_ws/conftest.py
index 007aaed0ab..363ead7534 100644
--- a/tests/integration/go_ethereum/test_goethereum_ws/conftest.py
+++ b/tests/integration/go_ethereum/test_goethereum_ws/conftest.py
@@ -3,6 +3,23 @@
 from tests.integration.common import (
     COINBASE,
 )
+from tests.utils import (
+    get_open_port,
+)
+from web3 import (
+    AsyncWeb3,
+    WebSocketProvider,
+)
+
+
+@pytest.fixture
+def w3():
+    """
+    Defined for the sake of overriding the `w3` in the `AsyncWeb3ModuleTest` test cases.
+    """
+    return AsyncWeb3(WebSocketProvider())
+
+
 
 
 def _geth_command_arguments(base_geth_command_arguments, geth_version):
diff --git a/tox.ini b/tox.ini
index b77b9d16aa..9de2d8c1b0 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,9 @@
 [tox]
 envlist=
-    py{38,39,310,311,312,313}-{ens,core,lint,wheel}
+    py{38,39,310,311,312,313}-{ens,core,lint,wheel}-pyevm
+    py{310,311,312, 313}-{ens,core}-eels
     py{38,39,310,311,312,313}-integration-{goethereum,ethtester}
+    py{310,311,312,313}-integration-ethtester-eels
     docs
     benchmark
     windows-wheel
@@ -20,9 +22,12 @@ allowlist_externals=make,pre-commit
 install_command=python -m pip install {opts} {packages}
 usedevelop=True
 commands=
-    core: pytest {posargs:tests/core -m "not asyncio" }
-    core_async: pytest {posargs:tests/core -m asyncio}
-    ens: pytest {posargs:tests/ens --ignore=tests/ens/normalization/test_normalize_name_ensip15.py -n auto --maxprocesses=15}
+    core-pyevm: pytest {posargs:tests/core -m "not asyncio" --backend=pyevm -n auto --maxprocesses=15}
+    core-pyevm_async: pytest {posargs:tests/core -m asyncio --backend=pyevm -n auto --maxprocesses=15}
+    core-eels: pytest {posargs:tests/core -m "not asyncio" --backend=eels -n auto --maxprocesses=15}
+    core-eels_async: pytest {posargs:tests/core -m asyncio --backend=eels -n auto --maxprocesses=15}
+    ens-pyevm: pytest {posargs:tests/ens --ignore=tests/ens/normalization/test_normalize_name_ensip15.py --backend=pyevm -n auto --maxprocesses=15}
+    ens-eels: pytest {posargs:tests/ens --ignore=tests/ens/normalization/test_normalize_name_ensip15.py --backend=eels -n auto --maxprocesses=15}
     ensip15: pytest {posargs:tests/ens/normalization/test_normalize_name_ensip15.py -q -n auto --maxprocesses=15}
     integration-goethereum-ipc: pytest {posargs:tests/integration/go_ethereum/test_goethereum_ipc.py -k "not Async" -n auto --maxprocesses=15}
     integration-goethereum-ipc_async: pytest {posargs:tests/integration/go_ethereum/test_goethereum_ipc.py -k Async -n auto --maxprocesses=15}
diff --git a/web3/providers/eth_tester/main.py b/web3/providers/eth_tester/main.py
index 48fdd260fb..9ede4e2849 100644
--- a/web3/providers/eth_tester/main.py
+++ b/web3/providers/eth_tester/main.py
@@ -66,20 +66,30 @@ class AsyncEthereumTesterProvider(AsyncBaseProvider):
         ethereum_tester_middleware,
     )
 
-    def __init__(self) -> None:
+    def __init__(
+        self,
+        ethereum_tester: Optional["EthereumTester"] = None,
+        api_endpoints: Optional[
+            Dict[str, Dict[str, Callable[..., RPCResponse]]]
+        ] = None,
+    ) -> None:
         super().__init__()
+        if not ethereum_tester:
+            from eth_tester import (
+                EthereumTester,
+            )
 
-        # do not import eth_tester until runtime, it is not a default dependency
-        from eth_tester import (
-            EthereumTester,
-        )
+            ethereum_tester = EthereumTester()
 
-        from web3.providers.eth_tester.defaults import (
-            API_ENDPOINTS,
-        )
+        if not api_endpoints:
+            from web3.providers.eth_tester.defaults import (
+                API_ENDPOINTS,
+            )
+
+            api_endpoints = API_ENDPOINTS
 
-        self.ethereum_tester = EthereumTester()
-        self.api_endpoints = API_ENDPOINTS
+        self.ethereum_tester = ethereum_tester
+        self.api_endpoints = api_endpoints
 
     async def request_func(
         self, async_w3: "AsyncWeb3", middleware_onion: "MiddlewareOnion"

From 8d3ccadfdca199600b93fa7407877a5b39b61e3f Mon Sep 17 00:00:00 2001
From: fselmo <fselmo2@gmail.com>
Date: Fri, 9 Aug 2024 11:37:49 -0600
Subject: [PATCH 4/9] Add pypy test runs to eels backend tests:

- Add pypy py-evm CI jobs; refactor testenvs in ``tox.ini``.
---
 .circleci/config.yml  | 96 ++++++++++++++++++++++++++++++++++++++++---
 tox.ini               |  7 ++--
 web3/_utils/module.py |  5 ++-
 3 files changed, 98 insertions(+), 10 deletions(-)

diff --git a/.circleci/config.yml b/.circleci/config.yml
index 2dcec59499..fcd7a6c2d9 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -11,6 +11,10 @@ parameters:
     type: string
 
 common: &common
+  parameters:
+    python_exec:
+      type: string
+      default: "python"
   working_directory: ~/repo
   steps:
     - checkout
@@ -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: |
@@ -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
@@ -141,12 +177,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:
@@ -224,13 +278,44 @@ workflows:
               python_minor_version: ["8", "9", "10", "11", "12", "13"]
               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:
@@ -242,7 +327,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:
@@ -256,7 +341,6 @@ workflows:
               python_minor_version: ["10", "11", "12", "13"]
           name: "py3<< matrix.python_minor_version >>-windows-wheel"
 
-
   nightly:
     triggers:
       - schedule:
diff --git a/tox.ini b/tox.ini
index 9de2d8c1b0..8732161cae 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,9 +1,10 @@
 [tox]
 envlist=
-    py{38,39,310,311,312,313}-{ens,core,lint,wheel}-pyevm
-    py{310,311,312, 313}-{ens,core}-eels
-    py{38,39,310,311,312,313}-integration-{goethereum,ethtester}
+    py{py}{38,39,310,311,312,313}-{ens,core}-pyevm
+    py{py}{310,311,312,313}-{ens,core}-eels
+    py{38,39,310,311,312,313}-integration-{goethereum,ethtester-pyevm}
     py{310,311,312,313}-integration-ethtester-eels
+    py{38,39,310,311,312,313}-{lint,wheel}
     docs
     benchmark
     windows-wheel
diff --git a/web3/_utils/module.py b/web3/_utils/module.py
index 63fc151232..bf32e0cdfa 100644
--- a/web3/_utils/module.py
+++ b/web3/_utils/module.py
@@ -27,7 +27,10 @@
 def _validate_init_params_and_return_if_found(module_class: Any) -> List[str]:
     init_params_raw = list(inspect.signature(module_class.__init__).parameters)
     module_init_params = [
-        param for param in init_params_raw if param not in ["self", "args", "kwargs"]
+        param
+        for param in init_params_raw
+        # pypy uses `obj` and `keywords` instead of `self` and `kwargs`, respectively
+        if param not in ["self", "obj", "args", "kwargs", "keywords"]
     ]
 
     if len(module_init_params) > 1:

From da73cd47647236866cddb6d127cc4d36fe90d72d Mon Sep 17 00:00:00 2001
From: fselmo <fselmo2@gmail.com>
Date: Thu, 22 Aug 2024 12:55:06 -0600
Subject: [PATCH 5/9] Make clear what python version is building the wheel from
 script.

---
 web3/scripts/release/test_wheel_install.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/web3/scripts/release/test_wheel_install.sh b/web3/scripts/release/test_wheel_install.sh
index df2b63ae3e..8573f47d5a 100755
--- a/web3/scripts/release/test_wheel_install.sh
+++ b/web3/scripts/release/test_wheel_install.sh
@@ -2,6 +2,7 @@
 
 set -e
 rm -rf build dist
+python --version
 python -m build
 cd $(mktemp -d)
 python -m venv venv-test

From 9ff49f4775afbd5396b496dd5af2a6b9397fd244 Mon Sep 17 00:00:00 2001
From: fselmo <fselmo2@gmail.com>
Date: Tue, 24 Sep 2024 14:18:41 -0600
Subject: [PATCH 6/9] Fix issues with new tests after rebasing

---
 docs/web3.contract.rst                                  | 2 +-
 tests/core/contracts/test_contract_build_transaction.py | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/docs/web3.contract.rst b/docs/web3.contract.rst
index 1348012cff..69aee7888e 100644
--- a/docs/web3.contract.rst
+++ b/docs/web3.contract.rst
@@ -277,7 +277,7 @@ Each Contract Factory exposes the following methods.
     .. doctest:: contractmethods
 
         >>> contract.constructor(1000000).estimate_gas()
-        664971
+        664953
 
 .. py:classmethod:: Contract.constructor(*args, **kwargs).build_transaction(transaction=None)
     :noindex:
diff --git a/tests/core/contracts/test_contract_build_transaction.py b/tests/core/contracts/test_contract_build_transaction.py
index 87f8dcba02..f00768b202 100644
--- a/tests/core/contracts/test_contract_build_transaction.py
+++ b/tests/core/contracts/test_contract_build_transaction.py
@@ -63,7 +63,7 @@ def test_build_transaction_with_contract_no_arguments_no_parens(
         "value": 0,
         "maxFeePerGas": 2750000000,
         "maxPriorityFeePerGas": 10**9,
-        "chainId": 131277322940537,
+        "chainId": w3.eth.chain_id,
     }
 
 
@@ -329,7 +329,7 @@ async def test_async_build_transaction_with_contract_no_arguments_no_parens(
         "value": 0,
         "maxFeePerGas": 2750000000,
         "maxPriorityFeePerGas": 10**9,
-        "chainId": 131277322940537,
+        "chainId": await async_w3.eth.chain_id,
     }
 
 

From 422811a08b3347536293d8247610c595790cb495 Mon Sep 17 00:00:00 2001
From: fselmo <fselmo2@gmail.com>
Date: Sat, 15 Feb 2025 22:20:57 -0700
Subject: [PATCH 7/9] Add py3.13 runs for eels backend

---
 .circleci/config.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.circleci/config.yml b/.circleci/config.yml
index fcd7a6c2d9..907750bec2 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -290,7 +290,7 @@ workflows:
           matrix:
             parameters:
               # eels only supports 3.10 and above
-              python_minor_version: ["10", "11", "12"]
+              python_minor_version: ["10", "11", "12", "13"]
               tox_env: [
                 "core-eels",
                 "core-eels_async",

From f461a341e7ecfcc3fdcf5b4a87451949b8a390fd Mon Sep 17 00:00:00 2001
From: fselmo <fselmo2@gmail.com>
Date: Wed, 21 May 2025 13:53:11 -0600
Subject: [PATCH 8/9] pytest-xdist updates

---
 .../caching-utils/test_request_caching.py     | 22 +++++------
 .../middleware/test_eth_tester_middleware.py  |  2 +-
 tox.ini                                       | 38 +++++++++----------
 3 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/tests/core/caching-utils/test_request_caching.py b/tests/core/caching-utils/test_request_caching.py
index 3727cbecd1..700c5248b2 100644
--- a/tests/core/caching-utils/test_request_caching.py
+++ b/tests/core/caching-utils/test_request_caching.py
@@ -204,7 +204,7 @@ def test_all_providers_do_not_cache_by_default_and_can_set_caching_properties(pr
     "threshold",
     (RequestCacheValidationThreshold.FINALIZED, RequestCacheValidationThreshold.SAFE),
 )
-@pytest.mark.parametrize("endpoint", BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT)
+@pytest.mark.parametrize("endpoint", sorted(BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT))
 @pytest.mark.parametrize(
     "blocknum,should_cache",
     (
@@ -254,7 +254,7 @@ def test_blocknum_validation_against_validation_threshold_when_caching_mainnet(
     "threshold",
     (RequestCacheValidationThreshold.FINALIZED, RequestCacheValidationThreshold.SAFE),
 )
-@pytest.mark.parametrize("endpoint", BLOCKNUM_IN_PARAMS)
+@pytest.mark.parametrize("endpoint", sorted(BLOCKNUM_IN_PARAMS))
 @pytest.mark.parametrize(
     "block_id,blocknum,should_cache",
     (
@@ -297,7 +297,7 @@ def test_block_id_param_caching_mainnet(
     "threshold",
     (RequestCacheValidationThreshold.FINALIZED, RequestCacheValidationThreshold.SAFE),
 )
-@pytest.mark.parametrize("endpoint", BLOCKHASH_IN_PARAMS)
+@pytest.mark.parametrize("endpoint", sorted(BLOCKHASH_IN_PARAMS))
 @pytest.mark.parametrize(
     "blocknum,should_cache",
     (
@@ -360,7 +360,7 @@ def test_request_caching_validation_threshold_defaults(
 
 
 @pytest.mark.parametrize(
-    "endpoint", BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT | BLOCKHASH_IN_PARAMS
+    "endpoint", sorted(BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT | BLOCKHASH_IN_PARAMS)
 )
 @pytest.mark.parametrize(
     "time_from_threshold,should_cache",
@@ -436,7 +436,7 @@ def test_sync_validation_against_validation_threshold_time_based(
     ),
 )
 @pytest.mark.parametrize(
-    "endpoint", BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT | BLOCKHASH_IN_PARAMS
+    "endpoint", sorted(BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT | BLOCKHASH_IN_PARAMS)
 )
 def test_validation_against_validation_threshold_time_based_configured(
     time_from_threshold, should_cache, chain_id, endpoint, sync_provider, request_mocker
@@ -642,7 +642,7 @@ async def test_async_request_caching_does_not_share_state_between_providers(
     "threshold",
     (RequestCacheValidationThreshold.FINALIZED, RequestCacheValidationThreshold.SAFE),
 )
-@pytest.mark.parametrize("endpoint", BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT)
+@pytest.mark.parametrize("endpoint", sorted(BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT))
 @pytest.mark.parametrize(
     "blocknum,should_cache",
     (
@@ -689,7 +689,7 @@ async def test_async_blocknum_validation_against_validation_threshold_mainnet(
     "threshold",
     (RequestCacheValidationThreshold.FINALIZED, RequestCacheValidationThreshold.SAFE),
 )
-@pytest.mark.parametrize("endpoint", BLOCKNUM_IN_PARAMS)
+@pytest.mark.parametrize("endpoint", sorted(BLOCKNUM_IN_PARAMS))
 @pytest.mark.parametrize(
     "block_id,blocknum,should_cache",
     (
@@ -735,7 +735,7 @@ async def test_async_block_id_param_caching_mainnet(
     "threshold",
     (RequestCacheValidationThreshold.FINALIZED, RequestCacheValidationThreshold.SAFE),
 )
-@pytest.mark.parametrize("endpoint", BLOCKHASH_IN_PARAMS)
+@pytest.mark.parametrize("endpoint", sorted(BLOCKHASH_IN_PARAMS))
 @pytest.mark.parametrize(
     "blocknum,should_cache",
     (
@@ -794,7 +794,7 @@ async def test_async_request_caching_validation_threshold_defaults(
 
 @pytest.mark.asyncio
 @pytest.mark.parametrize(
-    "endpoint", BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT | BLOCKHASH_IN_PARAMS
+    "endpoint", sorted(BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT | BLOCKHASH_IN_PARAMS)
 )
 @pytest.mark.parametrize(
     "time_from_threshold,should_cache",
@@ -856,7 +856,7 @@ async def test_async_validation_against_validation_threshold_time_based(
 
 @pytest.mark.asyncio
 @pytest.mark.parametrize(
-    "endpoint", BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT | BLOCKHASH_IN_PARAMS
+    "endpoint", sorted(BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT | BLOCKHASH_IN_PARAMS)
 )
 @pytest.mark.parametrize("blocknum", ("0x0", "0x1", "0x2", "0x3", "0x4", "0x5"))
 async def test_async_request_caching_with_validation_threshold_set_to_none(
@@ -901,7 +901,7 @@ async def test_async_request_caching_with_validation_threshold_set_to_none(
     ),
 )
 @pytest.mark.parametrize(
-    "endpoint", BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT | BLOCKHASH_IN_PARAMS
+    "endpoint", sorted(BLOCKNUM_IN_PARAMS | BLOCK_IN_RESULT | BLOCKHASH_IN_PARAMS)
 )
 async def test_async_validation_against_validation_threshold_time_based_configured(
     time_from_threshold,
diff --git a/tests/core/middleware/test_eth_tester_middleware.py b/tests/core/middleware/test_eth_tester_middleware.py
index 1b8b834a92..e5f6d6cea9 100644
--- a/tests/core/middleware/test_eth_tester_middleware.py
+++ b/tests/core/middleware/test_eth_tester_middleware.py
@@ -18,7 +18,7 @@
 SAMPLE_ADDRESS = "0x0000000000000000000000000000000000000004"
 
 
-@pytest.mark.parametrize("block_number", {0, "0x0", "earliest"})
+@pytest.mark.parametrize("block_number", (0, "0x0", "earliest"))
 def test_get_transaction_count_formatters(w3, block_number):
     tx_counts = w3.eth.get_transaction_count(w3.eth.accounts[-1], block_number)
     assert tx_counts == 0
diff --git a/tox.ini b/tox.ini
index 8732161cae..26183b3be9 100644
--- a/tox.ini
+++ b/tox.ini
@@ -10,13 +10,13 @@ envlist=
     windows-wheel
 
 [flake8]
-exclude= venv*,.tox,docs,build
-extend-ignore=E203,W503
-max-line-length=88
-per-file-ignores=__init__.py:F401
+exclude = venv*,.tox,docs,build
+extend-ignore = E203,W503
+max-line-length = 88
+per-file-ignores = __init__.py:F401
 
 [blocklint]
-max_issue_threshold=1
+max_issue_threshold = 1
 
 [testenv]
 allowlist_externals=make,pre-commit
@@ -41,7 +41,7 @@ commands=
     docs: make check-docs-ci
 deps =
     .[test]
-    ; install both `docs` and `test` dependencies for the `docs` environment
+; install both `docs` and `test` dependencies for the `docs` environment
     docs: .[docs]
 passenv =
     GETH_BINARY
@@ -60,37 +60,37 @@ basepython =
     py313: python3.13
 
 [testenv:py{38,39,310,311,312,313}-lint]
-deps=pre-commit
-extras=dev
-commands=
+deps = pre-commit
+extras = dev
+commands =
     pre-commit install
     pre-commit run --all-files --show-diff-on-failure
 
 [testenv:benchmark]
-basepython=python
-commands=
+basepython = python
+commands =
     python {toxinidir}/web3/tools/benchmark/main.py --num-calls 5
     python {toxinidir}/web3/tools/benchmark/main.py --num-calls 50
     python {toxinidir}/web3/tools/benchmark/main.py --num-calls 100
 
 
 [testenv:py{38,39,310,311,312,313}-wheel]
-deps=
+deps =
     wheel
     build[virtualenv]
-allowlist_externals=
+allowlist_externals =
     /bin/rm
     /bin/bash
-commands=
+commands =
     /bin/bash {toxinidir}/web3/scripts/release/test_wheel_install.sh
-skip_install=true
+skip_install = true
 
 [testenv:windows-wheel]
-deps=
+deps =
     wheel
     build[virtualenv]
-allowlist_externals=
+allowlist_externals =
     bash.exe
-commands=
+commands =
     bash.exe {toxinidir}/web3/scripts/release/test_windows_wheel_install.sh
-skip_install=true
+skip_install = true

From 3f28363e5bdd1b76fa9a911371228acd0b68ad4d Mon Sep 17 00:00:00 2001
From: fselmo <fselmo2@gmail.com>
Date: Thu, 5 Jun 2025 11:38:44 -0600
Subject: [PATCH 9/9] Changes for eth-tester next breaking major version

---
 tests/core/module-class/test_module.py        |   2 +-
 tests/integration/ethereum_tester/common.py   |  12 +-
 .../integration/ethereum_tester/test_eels.py  |  12 +-
 .../integration/ethereum_tester/test_pyevm.py |  12 +-
 .../test_goethereum_ws/conftest.py            |   5 -
 web3/_utils/method_formatters.py              |   6 +-
 web3/providers/eth_tester/defaults.py         |   6 +-
 web3/providers/eth_tester/main.py             | 259 +++++++++---------
 8 files changed, 157 insertions(+), 157 deletions(-)

diff --git a/tests/core/module-class/test_module.py b/tests/core/module-class/test_module.py
index df641da306..c4b656441b 100644
--- a/tests/core/module-class/test_module.py
+++ b/tests/core/module-class/test_module.py
@@ -87,7 +87,7 @@ def test_attach_methods_with_mungers(web3_with_external_modules):
         }
     )
 
-    w3.provider.ethereum_tester.mine_block()
+    w3.provider.ethereum_tester.include_block()
     assert w3.eth.get_block(0, False)["baseFeePerGas"] == 1000000000
     assert w3.eth.get_block(1, False)["baseFeePerGas"] == 875000000
 
diff --git a/tests/integration/ethereum_tester/common.py b/tests/integration/ethereum_tester/common.py
index cedb1e00b8..75d8bdeb90 100644
--- a/tests/integration/ethereum_tester/common.py
+++ b/tests/integration/ethereum_tester/common.py
@@ -237,18 +237,18 @@ def disable_auto_mine(func):
     @functools.wraps(func)
     def func_wrapper(self, eth_tester, *args, **kwargs):
         snapshot = eth_tester.take_snapshot()
-        eth_tester.disable_auto_mine_transactions()
+        eth_tester.disable_auto_transactions_inclusion()
         try:
             func(self, eth_tester, *args, **kwargs)
         finally:
-            eth_tester.enable_auto_mine_transactions()
-            eth_tester.mine_block()
+            eth_tester.enable_auto_transaction_inclusion()
+            eth_tester.include_block()
             eth_tester.revert_to_snapshot(snapshot)
 
     return func_wrapper
 
 
-class TestEthereumTesterWeb3Module(Web3ModuleTest):
+class EthereumTesterWeb3ModuleTest(Web3ModuleTest):
     def _check_web3_client_version(self, client_version):
         assert client_version.startswith("EthereumTester/")
 
@@ -270,7 +270,7 @@ def _check_web3_client_version(self, client_version):
     )
 
 
-class TestEthereumTesterEthModule(EthModuleTest):
+class EthereumTesterEthModuleTest(EthModuleTest):
     test_eth_sign = not_implemented(EthModuleTest.test_eth_sign, MethodUnavailable)
     test_eth_sign_ens_names = not_implemented(
         EthModuleTest.test_eth_sign_ens_names, MethodUnavailable
@@ -673,5 +673,5 @@ def test_eth_get_balance_with_block_identifier(self, w3: "Web3") -> None:
         assert later_balance > genesis_balance
 
 
-class TestEthereumTesterNetModule(NetModuleTest):
+class EthereumTesterNetModuleTest(NetModuleTest):
     pass
diff --git a/tests/integration/ethereum_tester/test_eels.py b/tests/integration/ethereum_tester/test_eels.py
index 1af4ac75f3..10105c6353 100644
--- a/tests/integration/ethereum_tester/test_eels.py
+++ b/tests/integration/ethereum_tester/test_eels.py
@@ -22,9 +22,9 @@
 )
 
 from .common import (
-    EthereumTesterEthModule,
-    EthereumTesterNetModule,
-    EthereumTesterWeb3Module,
+    EthereumTesterEthModuleTest,
+    EthereumTesterNetModuleTest,
+    EthereumTesterWeb3ModuleTest,
 )
 
 
@@ -60,11 +60,11 @@ def w3(eth_tester, keyfile_account_address, keyfile_account_pkey):
 # -- test classes -- #
 
 
-class TestEthereumTesterWeb3Module(EthereumTesterWeb3Module):
+class TestEthereumTesterWeb3Module(EthereumTesterWeb3ModuleTest):
     pass
 
 
-class TestEthereumTesterEthModule(EthereumTesterEthModule):
+class TestEthereumTesterEthModule(EthereumTesterEthModuleTest):
     def test_eth_chain_id(self, w3):
         chain_id = w3.eth.chain_id
         assert chain_id == 1
@@ -84,5 +84,5 @@ def test_eth_fee_history_no_reward_percentiles(self, w3: "Web3") -> None:
         super().test_eth_fee_history_no_reward_percentiles(w3)
 
 
-class TestEthereumTesterNetModule(EthereumTesterNetModule):
+class TestEthereumTesterNetModule(EthereumTesterNetModuleTest):
     pass
diff --git a/tests/integration/ethereum_tester/test_pyevm.py b/tests/integration/ethereum_tester/test_pyevm.py
index 08a157322f..41deda1b50 100644
--- a/tests/integration/ethereum_tester/test_pyevm.py
+++ b/tests/integration/ethereum_tester/test_pyevm.py
@@ -22,9 +22,9 @@
 )
 
 from .common import (
-    EthereumTesterEthModule,
-    EthereumTesterNetModule,
-    EthereumTesterWeb3Module,
+    EthereumTesterEthModuleTest,
+    EthereumTesterNetModuleTest,
+    EthereumTesterWeb3ModuleTest,
 )
 
 
@@ -60,15 +60,15 @@ def w3(eth_tester, keyfile_account_address, keyfile_account_pkey):
 # -- test classes -- #
 
 
-class TestEthereumTesterWeb3Module(EthereumTesterWeb3Module):
+class TestEthereumTesterWeb3Module(EthereumTesterWeb3ModuleTest):
     pass
 
 
-class TestEthereumTesterEthModule(EthereumTesterEthModule):
+class TestEthereumTesterEthModule(EthereumTesterEthModuleTest):
     def test_eth_chain_id(self, w3):
         chain_id = w3.eth.chain_id
         assert chain_id == 131277322940537
 
 
-class TestEthereumTesterNetModule(EthereumTesterNetModule):
+class TestEthereumTesterNetModule(EthereumTesterNetModuleTest):
     pass
diff --git a/tests/integration/go_ethereum/test_goethereum_ws/conftest.py b/tests/integration/go_ethereum/test_goethereum_ws/conftest.py
index 363ead7534..93aa378c96 100644
--- a/tests/integration/go_ethereum/test_goethereum_ws/conftest.py
+++ b/tests/integration/go_ethereum/test_goethereum_ws/conftest.py
@@ -3,9 +3,6 @@
 from tests.integration.common import (
     COINBASE,
 )
-from tests.utils import (
-    get_open_port,
-)
 from web3 import (
     AsyncWeb3,
     WebSocketProvider,
@@ -20,8 +17,6 @@ def w3():
     return AsyncWeb3(WebSocketProvider())
 
 
-
-
 def _geth_command_arguments(base_geth_command_arguments, geth_version):
     yield from base_geth_command_arguments
     if geth_version.major == 1:
diff --git a/web3/_utils/method_formatters.py b/web3/_utils/method_formatters.py
index d66852ed9d..691badf4ff 100644
--- a/web3/_utils/method_formatters.py
+++ b/web3/_utils/method_formatters.py
@@ -8,6 +8,7 @@
     Dict,
     Iterable,
     NoReturn,
+    Optional,
     Tuple,
     TypeVar,
     Union,
@@ -1246,9 +1247,12 @@ def apply_module_to_formatters(
 
 def get_result_formatters(
     method_name: RPCEndpoint,
-    module: "Module",
+    module: Optional["Module"] = None,
 ) -> Callable[[RPCResponse], Any]:
     formatters = combine_formatters((PYTHONIC_RESULT_FORMATTERS,), method_name)
+    if module is None:
+        return compose(*formatters)
+
     formatters_requiring_module = combine_formatters(
         (FILTER_RESULT_FORMATTERS,), method_name
     )
diff --git a/web3/providers/eth_tester/defaults.py b/web3/providers/eth_tester/defaults.py
index b6197c0c37..379fdde449 100644
--- a/web3/providers/eth_tester/defaults.py
+++ b/web3/providers/eth_tester/defaults.py
@@ -116,7 +116,7 @@ def call_eth_tester(
 
 
 def without_eth_tester(
-    fn: Callable[[TParams], TReturn]
+    fn: Callable[[TParams], TReturn],
 ) -> Callable[["EthereumTester", TParams], TReturn]:
     # workaround for: https://github.com/pytoolz/cytoolz/issues/103
     # @functools.wraps(fn)
@@ -127,7 +127,7 @@ def inner(eth_tester: "EthereumTester", params: TParams) -> TReturn:
 
 
 def without_params(
-    fn: Callable[[TParams], TReturn]
+    fn: Callable[[TParams], TReturn],
 ) -> Callable[["EthereumTester", TParams], TReturn]:
     # workaround for: https://github.com/pytoolz/cytoolz/issues/103
     # @functools.wraps(fn)
@@ -311,7 +311,7 @@ def create_new_account(eth_tester: "EthereumTester") -> HexAddress:
         "getTransactionReceipt": null_if_transaction_not_found(
             compose(
                 apply_formatter_if(
-                    compose(is_null, operator.itemgetter("block_number")),
+                    compose(is_null, operator.itemgetter("blockNumber")),
                     static_return(None),
                 ),
                 call_eth_tester("get_transaction_receipt"),
diff --git a/web3/providers/eth_tester/main.py b/web3/providers/eth_tester/main.py
index 9ede4e2849..fb973f2f37 100644
--- a/web3/providers/eth_tester/main.py
+++ b/web3/providers/eth_tester/main.py
@@ -32,16 +32,23 @@
     RPCResponse,
 )
 
+from ..._utils.method_formatters import (
+    get_null_result_formatters,
+    get_request_formatters,
+    get_result_formatters,
+)
 from ...exceptions import (
     Web3TypeError,
 )
+from ...method import (
+    _apply_request_formatters,
+)
 from ...middleware import (
     async_combine_middleware,
     combine_middleware,
 )
 from .middleware import (
     default_transaction_fields_middleware,
-    ethereum_tester_middleware,
 )
 
 if TYPE_CHECKING:
@@ -59,38 +66,135 @@
     )
 
 
-class AsyncEthereumTesterProvider(AsyncBaseProvider):
-    _current_request_id = 0
-    _middleware = (
-        default_transaction_fields_middleware,
-        ethereum_tester_middleware,
-    )
+class BaseEthereumTesterProvider:
+    """
+    Base class for EthereumTesterProvider and AsyncEthereumTesterProvider.
+    Contains shared logic for making requests to the EthereumTester instance.
+    """
+
+    api_endpoints: Optional[Dict[str, Dict[str, Callable[..., RPCResponse]]]] = None
 
     def __init__(
         self,
-        ethereum_tester: Optional["EthereumTester"] = None,
+        ethereum_tester: Optional[Union["EthereumTester", "BaseChainBackend"]] = None,
         api_endpoints: Optional[
             Dict[str, Dict[str, Callable[..., RPCResponse]]]
         ] = None,
     ) -> None:
-        super().__init__()
-        if not ethereum_tester:
-            from eth_tester import (
-                EthereumTester,
-            )
+        # do not import eth_tester until runtime, it is not a default dependency
+        from eth_tester import EthereumTester  # noqa: F811
+        from eth_tester.backends.base import (
+            BaseChainBackend,
+        )
 
-            ethereum_tester = EthereumTester()
+        if ethereum_tester is None:
+            self.ethereum_tester = EthereumTester()
+        elif isinstance(ethereum_tester, EthereumTester):
+            self.ethereum_tester = ethereum_tester
+        elif isinstance(ethereum_tester, BaseChainBackend):
+            self.ethereum_tester = EthereumTester(ethereum_tester)
+        else:
+            raise Web3TypeError(
+                "Expected ethereum_tester to be of type `eth_tester.EthereumTester` or "
+                "a subclass of `eth_tester.backends.base.BaseChainBackend`, "
+                f"instead received {type(ethereum_tester)}. "
+                "If you would like a custom eth-tester instance to test with, see the "
+                "eth-tester documentation. https://github.com/ethereum/eth-tester."
+            )
 
-        if not api_endpoints:
-            from web3.providers.eth_tester.defaults import (
+        if api_endpoints is None:
+            # do not import eth_tester derivatives until runtime,
+            # it is not a default dependency
+            from .defaults import (
                 API_ENDPOINTS,
             )
 
-            api_endpoints = API_ENDPOINTS
+            self.api_endpoints = API_ENDPOINTS
+        else:
+            self.api_endpoints = api_endpoints
+
+        self._request_formatters = get_request_formatters
+        self._result_formatters = get_result_formatters
+        self._null_result_formatters = get_null_result_formatters
+
+        self._current_request_id = 0
+        self._middleware = (default_transaction_fields_middleware,)
+
+    def _make_request(
+        self,
+        method: RPCEndpoint,
+        params: Any,
+        api_endpoints: Dict[str, Dict[str, Any]],
+        ethereum_tester_instance: "EthereumTester",
+        request_id: str,
+    ) -> RPCResponse:
+        # do not import eth_tester derivatives until runtime,
+        # it is not a default dependency
+        from eth_tester.exceptions import (
+            TransactionFailed,
+        )
+
+        namespace, _, endpoint = method.partition("_")
+
+        try:
+            delegator = api_endpoints[namespace][endpoint]
+        except KeyError as e:
+            return self._make_response(
+                method, e, request_id, message=f"Unknown RPC Endpoint: {method}"
+            )
+        try:
+            params = (
+                _apply_request_formatters(params, self._request_formatters(method)),
+            )
+            response = delegator(ethereum_tester_instance, params[0])
+        except NotImplementedError as e:
+            return self._make_response(
+                method,
+                e,
+                request_id,
+                message=f"RPC Endpoint has not been implemented: {method}",
+            )
+        except TransactionFailed as e:
+            first_arg = e.args[0]
+            try:
+                # sometimes eth-tester wraps an exception in another exception
+                raw_error_msg = (
+                    first_arg
+                    if not isinstance(first_arg, Exception)
+                    else first_arg.args[0]
+                )
+                reason = (
+                    abi.decode(["string"], raw_error_msg[4:])[0]
+                    if is_bytes(raw_error_msg)
+                    else raw_error_msg
+                )
+            except DecodingError:
+                reason = first_arg
+            raise TransactionFailed(f"execution reverted: {reason}")
+        else:
+            return self._make_response(method, response, request_id)
+
+    def _make_response(
+        self, method: RPCEndpoint, result: Any, response_id: str, message: str = ""
+    ) -> RPCResponse:
+        if isinstance(result, Exception):
+            return cast(
+                RPCResponse,
+                {
+                    "id": response_id,
+                    "jsonrpc": "2.0",
+                    "error": cast(RPCError, {"code": -32601, "message": message}),
+                },
+            )
+
+        formatter = self._result_formatters(method)
+        return cast(
+            RPCResponse,
+            {"id": response_id, "jsonrpc": "2.0", "result": formatter(result)},
+        )
 
-        self.ethereum_tester = ethereum_tester
-        self.api_endpoints = api_endpoints
 
+class AsyncEthereumTesterProvider(BaseEthereumTesterProvider, AsyncBaseProvider):
     async def request_func(
         self, async_w3: "AsyncWeb3", middleware_onion: "MiddlewareOnion"
     ) -> Callable[..., Coroutine[Any, Any, RPCResponse]]:
@@ -111,7 +215,7 @@ async def request_func(
         return self._request_func_cache[-1]
 
     async def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
-        response = _make_request(
+        response = self._make_request(
             method,
             params,
             self.api_endpoints,
@@ -125,54 +229,11 @@ async def is_connected(self, show_traceback: bool = False) -> Literal[True]:
         return True
 
 
-class EthereumTesterProvider(BaseProvider):
-    _current_request_id = 0
-    _middleware = (
-        default_transaction_fields_middleware,
-        ethereum_tester_middleware,
-    )
-    ethereum_tester = None
-    api_endpoints: Optional[Dict[str, Dict[str, Callable[..., RPCResponse]]]] = None
-
-    def __init__(
-        self,
-        ethereum_tester: Optional[Union["EthereumTester", "BaseChainBackend"]] = None,
-        api_endpoints: Optional[
-            Dict[str, Dict[str, Callable[..., RPCResponse]]]
-        ] = None,
-    ) -> None:
-        # do not import eth_tester until runtime, it is not a default dependency
-        super().__init__()
-        from eth_tester import EthereumTester  # noqa: F811
-        from eth_tester.backends.base import (
-            BaseChainBackend,
-        )
-
-        if ethereum_tester is None:
-            self.ethereum_tester = EthereumTester()
-        elif isinstance(ethereum_tester, EthereumTester):
-            self.ethereum_tester = ethereum_tester
-        elif isinstance(ethereum_tester, BaseChainBackend):
-            self.ethereum_tester = EthereumTester(ethereum_tester)
-        else:
-            raise Web3TypeError(
-                "Expected ethereum_tester to be of type `eth_tester.EthereumTester` or "
-                "a subclass of `eth_tester.backends.base.BaseChainBackend`, "
-                f"instead received {type(ethereum_tester)}. "
-                "If you would like a custom eth-tester instance to test with, see the "
-                "eth-tester documentation. https://github.com/ethereum/eth-tester."
-            )
-
-        if api_endpoints is None:
-            # do not import eth_tester derivatives until runtime,
-            # it is not a default dependency
-            from .defaults import (
-                API_ENDPOINTS,
-            )
-
-            self.api_endpoints = API_ENDPOINTS
-        else:
-            self.api_endpoints = api_endpoints
+class EthereumTesterProvider(BaseEthereumTesterProvider, BaseProvider):
+    """
+    Provider for EthereumTester, used for testing and development.
+    It allows interaction with the EthereumTester instance.
+    """
 
     def request_func(
         self, w3: "Web3", middleware_onion: "MiddlewareOnion"
@@ -194,7 +255,7 @@ def request_func(
         return self._request_func_cache[-1]
 
     def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
-        response = _make_request(
+        response = self._make_request(
             method,
             params,
             self.api_endpoints,
@@ -206,63 +267,3 @@ def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
 
     def is_connected(self, show_traceback: bool = False) -> Literal[True]:
         return True
-
-
-def _make_response(result: Any, response_id: str, message: str = "") -> RPCResponse:
-    if isinstance(result, Exception):
-        return cast(
-            RPCResponse,
-            {
-                "id": response_id,
-                "jsonrpc": "2.0",
-                "error": cast(RPCError, {"code": -32601, "message": message}),
-            },
-        )
-
-    return cast(RPCResponse, {"id": response_id, "jsonrpc": "2.0", "result": result})
-
-
-def _make_request(
-    method: RPCEndpoint,
-    params: Any,
-    api_endpoints: Dict[str, Dict[str, Any]],
-    ethereum_tester_instance: "EthereumTester",
-    request_id: str,
-) -> RPCResponse:
-    # do not import eth_tester derivatives until runtime,
-    # it is not a default dependency
-    from eth_tester.exceptions import (
-        TransactionFailed,
-    )
-
-    namespace, _, endpoint = method.partition("_")
-
-    try:
-        delegator = api_endpoints[namespace][endpoint]
-    except KeyError as e:
-        return _make_response(e, request_id, message=f"Unknown RPC Endpoint: {method}")
-    try:
-        response = delegator(ethereum_tester_instance, params)
-    except NotImplementedError as e:
-        return _make_response(
-            e,
-            request_id,
-            message=f"RPC Endpoint has not been implemented: {method}",
-        )
-    except TransactionFailed as e:
-        first_arg = e.args[0]
-        try:
-            # sometimes eth-tester wraps an exception in another exception
-            raw_error_msg = (
-                first_arg if not isinstance(first_arg, Exception) else first_arg.args[0]
-            )
-            reason = (
-                abi.decode(["string"], raw_error_msg[4:])[0]
-                if is_bytes(raw_error_msg)
-                else raw_error_msg
-            )
-        except DecodingError:
-            reason = first_arg
-        raise TransactionFailed(f"execution reverted: {reason}")
-    else:
-        return _make_response(response, request_id)