From bf46ecd7b18d53aa37a6cf578f4cafbceb840d4c Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Fri, 8 Nov 2024 04:51:07 -0600 Subject: [PATCH] new(tests): EIP-7702: Set code of non-empty-storage account (#948) * fix(plugins/filler): More accurate nonce in `fund_eoa` for edge-case * new(tests): EIP-7702: test_set_code_to_non_empty_storage * docs: changelog --- docs/CHANGELOG.md | 1 + src/pytest_plugins/filler/pre_alloc.py | 7 ++- .../eip7702_set_code_tx/test_set_code_txs.py | 60 +++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 29a3e301cb..9aa5441fa4 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -16,6 +16,7 @@ Test fixtures for use by clients are available for each release on the [Github r - 💥 `PragueEIP7692` fork in tests has been updated to `Osaka` ([#869](https://github.com/ethereum/execution-spec-tests/pull/869)) - ✨ Update [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110), [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002), [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251), [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685), and [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) tests for Devnet-4 ([#832](https://github.com/ethereum/execution-spec-tests/pull/832)) - ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) many delegations test ([#923](https://github.com/ethereum/execution-spec-tests/pull/923)) +- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) set code of non-empty-storage account test ([#948](https://github.com/ethereum/execution-spec-tests/pull/948)) ### 🛠️ Framework diff --git a/src/pytest_plugins/filler/pre_alloc.py b/src/pytest_plugins/filler/pre_alloc.py index 5451638fa7..15f1f00ec7 100644 --- a/src/pytest_plugins/filler/pre_alloc.py +++ b/src/pytest_plugins/filler/pre_alloc.py @@ -228,7 +228,12 @@ def fund_eoa( # Type-4 transaction is sent to the EOA to set the storage, so the nonce must be 1 if not isinstance(delegation, Address) and delegation == "Self": delegation = eoa - nonce = Number(1 if nonce is None else nonce) + # If delegation is None but storage is not, realistically the nonce should be 2 + # because the account must have delegated to set the storage and then again to + # reset the delegation (but can be overridden by the test for a non-realistic + # scenario) + real_nonce = 2 if delegation is None else 1 + nonce = Number(real_nonce if nonce is None else nonce) account = Account( nonce=nonce, balance=amount, diff --git a/tests/prague/eip7702_set_code_tx/test_set_code_txs.py b/tests/prague/eip7702_set_code_tx/test_set_code_txs.py index 60049ce7d7..3af6d5e151 100644 --- a/tests/prague/eip7702_set_code_tx/test_set_code_txs.py +++ b/tests/prague/eip7702_set_code_tx/test_set_code_txs.py @@ -216,6 +216,66 @@ def test_set_code_to_sstore( ) +@pytest.mark.parametrize( + "auth_signer_nonce", + [ + pytest.param( + 0, + id="zero_nonce", + marks=pytest.mark.execute(pytest.mark.skip("unrealistic scenario")), + ), + pytest.param(None, id="non_zero_nonce"), + ], +) +def test_set_code_to_non_empty_storage( + state_test: StateTestFiller, + pre: Alloc, + auth_signer_nonce: int, +): + """ + Test the setting the code to an account that has non-empty storage. + """ + auth_signer = pre.fund_eoa( + amount=0, + storage=Storage({0: 1}), # type: ignore + nonce=auth_signer_nonce, + ) + sender = pre.fund_eoa() + + set_code = Op.SSTORE(0, Op.ADD(Op.SLOAD(0), 1)) + Op.STOP + set_code_to_address = pre.deploy_contract( + set_code, + ) + + tx = Transaction( + gas_limit=500_000, + to=auth_signer, + value=0, + authorization_list=[ + AuthorizationTuple( + address=set_code_to_address, + nonce=auth_signer.nonce, + signer=auth_signer, + ), + ], + sender=sender, + ) + + state_test( + env=Environment(), + pre=pre, + tx=tx, + post={ + set_code_to_address: Account( + storage={}, + ), + auth_signer: Account( + storage={0: 2}, + ), + }, + ) + + def test_set_code_to_sstore_then_sload( blockchain_test: BlockchainTestFiller, pre: Alloc,