Skip to content

Commit 7933670

Browse files
committed
fix(tests): EIP-7702 system-contract tests
1 parent cd28bbf commit 7933670

File tree

1 file changed

+92
-23
lines changed

1 file changed

+92
-23
lines changed

tests/prague/eip7702_set_code_tx/test_set_code_txs.py

Lines changed: 92 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
""" # noqa: E501
55

66
from enum import Enum
7+
from hashlib import sha256
78
from itertools import count
89
from typing import List
910

@@ -32,10 +33,14 @@
3233
Storage,
3334
Transaction,
3435
TransactionException,
36+
call_return_code,
3537
compute_create_address,
3638
)
3739
from ethereum_test_tools.eof.v1 import Container, Section
3840

41+
from ..eip6110_deposits.helpers import DepositRequest
42+
from ..eip7002_el_triggerable_withdrawals.helpers import WithdrawalRequest
43+
from ..eip7251_consolidations.helpers import ConsolidationRequest
3944
from .spec import Spec, ref_spec_7702
4045

4146
REFERENCE_SPEC_GIT_PATH = ref_spec_7702.git_path
@@ -2015,6 +2020,19 @@ def test_set_code_to_precompile(
20152020
)
20162021

20172022

2023+
def deposit_contract_initial_storage() -> Storage:
2024+
"""
2025+
Return the initial storage of the deposit contract.
2026+
"""
2027+
storage = Storage()
2028+
DEPOSIT_CONTRACT_TREE_DEPTH = 32
2029+
next_hash = sha256(b"\x00" * 64).digest()
2030+
for i in range(DEPOSIT_CONTRACT_TREE_DEPTH + 2, DEPOSIT_CONTRACT_TREE_DEPTH * 2 + 1):
2031+
storage[i] = next_hash
2032+
next_hash = sha256(next_hash + next_hash).digest()
2033+
return storage
2034+
2035+
20182036
@pytest.mark.with_all_call_opcodes(
20192037
lambda opcode: opcode
20202038
not in [Op.STATICCALL, Op.CALLCODE, Op.DELEGATECALL, Op.EXTDELEGATECALL, Op.EXTSTATICCALL]
@@ -2029,48 +2047,94 @@ def test_set_code_to_system_contract(
20292047
"""
20302048
Test setting the code of an account to a pre-compile address.
20312049
"""
2032-
auth_signer = pre.fund_eoa(auth_account_start_balance)
2033-
20342050
caller_code_storage = Storage()
2035-
call_return_code_slot = caller_code_storage.store_next(True)
2036-
call_return_data_size_slot = caller_code_storage.store_next(0)
2037-
caller_code = (
2038-
Op.SSTORE(call_return_code_slot, call_opcode(address=auth_signer))
2039-
+ Op.SSTORE(call_return_data_size_slot, Op.RETURNDATASIZE)
2040-
+ Op.STOP
2051+
call_return_code_slot = caller_code_storage.store_next(
2052+
call_return_code(
2053+
call_opcode,
2054+
True,
2055+
)
20412056
)
2042-
txs: List[Transaction] = []
2057+
call_return_data_size_slot = caller_code_storage.store_next(0)
2058+
2059+
call_value = 0
2060+
2061+
# Setup the initial storage of the account to mimic the system contract if required
20432062
match system_contract:
2063+
case Address(0x00000000219AB540356CBB839CBE05303D7705FA): # EIP-6110
2064+
# Deposit contract needs specific storage values, so we set them on the account
2065+
auth_signer = pre.fund_eoa(
2066+
auth_account_start_balance, storage=deposit_contract_initial_storage()
2067+
)
20442068
case Address(0x000F3DF6D732807EF1319FB7B8BB8522D0BEAC02): # EIP-4788
2045-
caller_payload = Hash(0)
2046-
caller_code_storage[call_return_data_size_slot] = 0
2069+
auth_signer = pre.fund_eoa(auth_account_start_balance, storage=Storage({1: 1}))
2070+
case _:
2071+
# Pre-fund without storage
2072+
auth_signer = pre.fund_eoa(auth_account_start_balance)
2073+
2074+
# Fabricate the payload for the system contract
2075+
match system_contract:
2076+
case Address(0x000F3DF6D732807EF1319FB7B8BB8522D0BEAC02): # EIP-4788
2077+
caller_payload = Hash(1)
2078+
caller_code_storage[call_return_data_size_slot] = 32
20472079
case Address(0x00000000219AB540356CBB839CBE05303D7705FA): # EIP-6110
2048-
caller_payload = Hash(0)
2049-
caller_code_storage[call_return_data_size_slot] = 0
2080+
# Fabricate a valid deposit request to the set-code account
2081+
deposit_request = DepositRequest(
2082+
pubkey=0x01,
2083+
withdrawal_credentials=0x02,
2084+
amount=1_000_000_000,
2085+
signature=0x03,
2086+
index=0x0,
2087+
)
2088+
caller_payload = deposit_request.calldata
2089+
call_value = deposit_request.value
20502090
case Address(0x00A3CA265EBCB825B45F985A16CEFB49958CE017): # EIP-7002
2051-
caller_payload = Hash(0)
2052-
caller_code_storage[call_return_data_size_slot] = 0
2091+
# Fabricate a valid withdrawal request to the set-code account
2092+
withdrawal_request = WithdrawalRequest(
2093+
source_address=0x01,
2094+
validator_pubkey=0x02,
2095+
amount=0x03,
2096+
fee=0x01,
2097+
)
2098+
caller_payload = withdrawal_request.calldata
2099+
call_value = withdrawal_request.value
20532100
case Address(0x00B42DBF2194E931E80326D950320F7D9DBEAC02): # EIP-7251
2054-
caller_payload = Hash(0)
2055-
caller_code_storage[call_return_data_size_slot] = 0
2101+
# Fabricate a valid consolidation request to the set-code account
2102+
consolidation_request = ConsolidationRequest(
2103+
source_address=0x01,
2104+
source_pubkey=0x02,
2105+
target_pubkey=0x03,
2106+
fee=0x01,
2107+
)
2108+
caller_payload = consolidation_request.calldata
2109+
call_value = consolidation_request.value
20562110
case Address(0x0AAE40965E6800CD9B1F4B05FF21581047E3F91E): # EIP-2935
20572111
caller_payload = Hash(0)
2058-
caller_code_storage[call_return_data_size_slot] = 0
2112+
caller_code_storage[call_return_data_size_slot] = 32
20592113
case _:
2060-
raise ValueError(f"Unsupported system contract: {system_contract}")
2114+
raise ValueError(f"Not implemented system contract: {system_contract}")
20612115

2116+
caller_code = (
2117+
Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE)
2118+
+ Op.SSTORE(
2119+
call_return_code_slot,
2120+
call_opcode(address=auth_signer, value=call_value, args_size=Op.CALLDATASIZE),
2121+
)
2122+
+ Op.SSTORE(call_return_data_size_slot, Op.RETURNDATASIZE)
2123+
+ Op.STOP
2124+
)
20622125
caller_code_address = pre.deploy_contract(caller_code)
20632126

2064-
txs += [
2127+
txs = [
20652128
Transaction(
20662129
sender=pre.fund_eoa(),
20672130
gas_limit=500_000,
20682131
to=caller_code_address,
2132+
value=call_value,
20692133
data=caller_payload,
20702134
authorization_list=[
20712135
AuthorizationTuple(
20722136
address=Address(system_contract),
2073-
nonce=0,
2137+
nonce=auth_signer.nonce,
20742138
signer=auth_signer,
20752139
),
20762140
],
@@ -2079,10 +2143,15 @@ def test_set_code_to_system_contract(
20792143

20802144
blockchain_test(
20812145
pre=pre,
2082-
blocks=[Block(txs=txs)],
2146+
blocks=[
2147+
Block(
2148+
txs=txs,
2149+
requests_root=[], # Verify nothing slipped into the requests trie
2150+
)
2151+
],
20832152
post={
20842153
auth_signer: Account(
2085-
nonce=1,
2154+
nonce=auth_signer.nonce + 1,
20862155
code=b"",
20872156
),
20882157
caller_code_address: Account(

0 commit comments

Comments
 (0)