Skip to content

Commit c9e756d

Browse files
committed
Change pytest scope to function for all integration tests:
- Instantiate a new geth instance for each test to avoid muddied context between tests - Lower the ``dev.period`` to ``1`` since the tests don't need to account for each other anymore - Parallelize the tests in CI with pytest-xdist (``-n 10``) - Properly disconnect the ``async_await_w3`` ws tests
1 parent fc44e9e commit c9e756d

16 files changed

+215
-138
lines changed

newsfragments/3659.internal.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Run each integration test in isolation and parallelize, instead of running them all within a single `geth` (for example) process. This prevents muddied test contexts.

tests/core/eth-module/test_transactions.py

+101
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,24 @@
22
import collections
33
import itertools
44

5+
from eth_account import (
6+
Account,
7+
)
58
from eth_utils import (
69
to_checksum_address,
710
to_int,
811
)
912
from hexbytes import (
1013
HexBytes,
1114
)
15+
import pytest_asyncio
1216

17+
from tests.core.contracts.utils import (
18+
async_deploy,
19+
)
20+
from web3._utils.contract_sources.contract_data.math_contract import (
21+
MATH_CONTRACT_DATA,
22+
)
1323
from web3._utils.ens import (
1424
ens_addresses,
1525
)
@@ -29,6 +39,20 @@
2939
RECEIPT_TIMEOUT = 0.2
3040

3141

42+
@pytest.fixture
43+
def async_math_contract_factory(async_w3):
44+
return async_w3.eth.contract(**MATH_CONTRACT_DATA)
45+
46+
47+
@pytest_asyncio.fixture
48+
async def async_math_contract(
49+
async_w3, async_math_contract_factory, address_conversion_func
50+
):
51+
return await async_deploy(
52+
async_w3, async_math_contract_factory, address_conversion_func
53+
)
54+
55+
3256
def _tx_indexing_response_iterator():
3357
while True:
3458
yield {"error": {"message": "transaction indexing in progress"}}
@@ -420,3 +444,80 @@ async def test_async_send_raw_blob_transaction(async_w3):
420444
assert transaction["blobVersionedHashes"][0] == HexBytes(
421445
"0x0127c38bcad458d932e828b580b9ad97310be01407dfa0ed88118735980a3e9a"
422446
)
447+
448+
449+
@pytest.mark.asyncio
450+
async def test_send_set_code_transaction(async_w3, async_math_contract):
451+
pkey = async_w3.provider.ethereum_tester.backend.account_keys[0]
452+
acct = Account.from_key(pkey)
453+
454+
nonce = await async_w3.eth.get_transaction_count(acct.address)
455+
chain_id = await async_w3.eth.chain_id
456+
457+
math_contract_address = (
458+
f"0x{async_math_contract.address.hex()}"
459+
if isinstance(async_math_contract.address, bytes)
460+
else async_math_contract.address
461+
)
462+
auth = {
463+
"chainId": chain_id,
464+
"address": math_contract_address,
465+
"nonce": nonce + 1,
466+
}
467+
signed_auth = acct.sign_authorization(auth)
468+
469+
# get current math counter and increase it only in the delegation by n
470+
math_counter = await async_math_contract.functions.counter().call()
471+
built_tx = await async_math_contract.functions.incrementCounter(
472+
math_counter + 1337
473+
).build_transaction({})
474+
txn = {
475+
"chainId": chain_id,
476+
"to": acct.address,
477+
"value": 0,
478+
"gas": 200_000,
479+
"nonce": nonce,
480+
"maxPriorityFeePerGas": 10**9,
481+
"maxFeePerGas": 10**9,
482+
"data": built_tx["data"],
483+
"authorizationList": [signed_auth],
484+
}
485+
486+
tx_hash = await async_w3.eth.send_transaction(txn)
487+
get_tx = await async_w3.eth.get_transaction(tx_hash)
488+
await async_w3.eth.wait_for_transaction_receipt(tx_hash, timeout=10)
489+
490+
code = await async_w3.eth.get_code(acct.address)
491+
492+
assert code.to_0x_hex().lower() == f"0xef0100{math_contract_address[2:].lower()}"
493+
delegated = async_w3.eth.contract(address=acct.address, abi=async_math_contract.abi)
494+
# assert the math counter is increased by 1337 only in delegated acct
495+
assert await async_math_contract.functions.counter().call() == math_counter
496+
delegated_call = await delegated.functions.counter().call()
497+
assert delegated_call == math_counter + 1337
498+
499+
assert len(get_tx["authorizationList"]) == 1
500+
get_auth = get_tx["authorizationList"][0]
501+
assert get_auth["chainId"] == chain_id
502+
assert get_auth["address"].lower() == math_contract_address.lower()
503+
assert get_auth["nonce"] == nonce + 1
504+
assert isinstance(get_auth["yParity"], int)
505+
assert isinstance(get_auth["r"], HexBytes)
506+
assert isinstance(get_auth["s"], HexBytes)
507+
508+
# reset code
509+
reset_auth = {
510+
"chainId": chain_id,
511+
"address": "0x" + ("00" * 20),
512+
"nonce": nonce + 3,
513+
}
514+
signed_reset_auth = acct.sign_authorization(reset_auth)
515+
new_txn = dict(txn)
516+
new_txn["authorizationList"] = [signed_reset_auth]
517+
new_txn["nonce"] = nonce + 2
518+
519+
reset_tx_hash = await async_w3.eth.send_transaction(new_txn)
520+
await async_w3.eth.wait_for_transaction_receipt(reset_tx_hash, timeout=10)
521+
522+
reset_code = await async_w3.eth.get_code(acct.address)
523+
assert reset_code == HexBytes("0x")

tests/integration/conftest.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -19,47 +19,47 @@
1919
)
2020

2121

22-
@pytest.fixture(scope="module")
22+
@pytest.fixture
2323
def math_contract_factory(w3):
2424
contract_factory = w3.eth.contract(
2525
abi=MATH_CONTRACT_ABI, bytecode=MATH_CONTRACT_BYTECODE
2626
)
2727
return contract_factory
2828

2929

30-
@pytest.fixture(scope="module")
30+
@pytest.fixture
3131
def emitter_contract_factory(w3):
3232
contract_factory = w3.eth.contract(
3333
abi=EMITTER_CONTRACT_ABI, bytecode=EMITTER_CONTRACT_BYTECODE
3434
)
3535
return contract_factory
3636

3737

38-
@pytest.fixture(scope="module")
38+
@pytest.fixture
3939
def revert_contract_factory(w3):
4040
contract_factory = w3.eth.contract(
4141
abi=REVERT_CONTRACT_ABI, bytecode=REVERT_CONTRACT_BYTECODE
4242
)
4343
return contract_factory
4444

4545

46-
@pytest.fixture(scope="module")
46+
@pytest.fixture
4747
def offchain_lookup_contract_factory(w3):
4848
contract_factory = w3.eth.contract(
4949
abi=OFFCHAIN_LOOKUP_ABI, bytecode=OFFCHAIN_LOOKUP_BYTECODE
5050
)
5151
return contract_factory
5252

5353

54-
@pytest.fixture(scope="module")
54+
@pytest.fixture
5555
def async_offchain_lookup_contract_factory(async_w3):
5656
contract_factory = async_w3.eth.contract(
5757
abi=OFFCHAIN_LOOKUP_ABI, bytecode=OFFCHAIN_LOOKUP_BYTECODE
5858
)
5959
return contract_factory
6060

6161

62-
@pytest.fixture(scope="module")
62+
@pytest.fixture
6363
def event_loop():
6464
loop = asyncio.get_event_loop_policy().new_event_loop()
6565
yield loop

0 commit comments

Comments
 (0)