Skip to content

Commit f10fc75

Browse files
committed
type(tests): convert create suicide store test
1 parent 2a7a6d7 commit f10fc75

File tree

2 files changed

+144
-102
lines changed

2 files changed

+144
-102
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
"""
2+
Test dynamically created address is still callable and perform storage operations
3+
after being called for self destruct in a call.
4+
"""
5+
6+
from enum import Enum
7+
8+
import pytest
9+
10+
from ethereum_test_forks import Byzantium, Fork
11+
from ethereum_test_tools import (
12+
Account,
13+
Alloc,
14+
Case,
15+
Environment,
16+
Initcode,
17+
StateTestFiller,
18+
Storage,
19+
Switch,
20+
Transaction,
21+
compute_create_address,
22+
)
23+
from ethereum_test_tools import Opcodes as Op
24+
25+
26+
class Operation(Enum):
27+
"""Enum for created contract actions."""
28+
29+
SUICIDE = 1
30+
STORE_SOMETHING = 2
31+
GET_SOMETHING = 3
32+
33+
def __int__(self):
34+
"""Convert to int."""
35+
return int(self.value)
36+
37+
38+
@pytest.mark.ported_from(
39+
[
40+
"https://github.com/ethereum/tests/blob/v13.3/src/GeneralStateTestsFiller/stCreateTest/CREATE_AcreateB_BSuicide_BStoreFiller.json",
41+
],
42+
pr=["https://github.com/ethereum/execution-spec-tests/pull/1867"],
43+
coverage_missed_reason="Converting solidity code result in following opcode not being used:"
44+
"PUSH29, DUP4, DUP8, SWAP2, ISZERO, AND, MUL, DIV, CALLVALUE, EXTCODESIZE",
45+
)
46+
@pytest.mark.valid_from("Frontier")
47+
@pytest.mark.with_all_create_opcodes
48+
def test_create_suicide_store(
49+
state_test: StateTestFiller,
50+
fork: Fork,
51+
pre: Alloc,
52+
create_opcode: Op,
53+
):
54+
"""
55+
Create dynamic contract that suicides, then called to push some storage
56+
and then called to return that storage value.
57+
"""
58+
tload_support = fork.valid_opcodes().count(Op.TLOAD)
59+
subcall_storage = 0x12
60+
suicide_initcode: Initcode = Initcode(
61+
deploy_code=Switch(
62+
cases=[
63+
Case(
64+
condition=Op.EQ(Op.CALLDATALOAD(0), int(Operation.SUICIDE)),
65+
action=Op.SELFDESTRUCT(0x11),
66+
),
67+
Case(
68+
condition=Op.EQ(Op.CALLDATALOAD(0), int(Operation.STORE_SOMETHING)),
69+
action=Op.SSTORE(1, subcall_storage)
70+
+ (Op.TSTORE(1, subcall_storage) if tload_support else Op.STOP),
71+
),
72+
Case(
73+
condition=Op.EQ(Op.CALLDATALOAD(0), int(Operation.GET_SOMETHING)),
74+
action=(
75+
Op.MSTORE(0, Op.ADD(Op.SLOAD(1), Op.TLOAD(1)))
76+
if tload_support
77+
else Op.MSTORE(0, Op.SLOAD(1))
78+
)
79+
+ Op.RETURN(0, 32),
80+
),
81+
],
82+
default_action=None,
83+
)
84+
)
85+
86+
sender = pre.fund_eoa()
87+
expect_post = Storage()
88+
89+
slot_create_result = 0
90+
slot_suicide_sstore_return = 1
91+
slot_program_success = 2
92+
create_contract = pre.deploy_contract(
93+
code=Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE)
94+
+ Op.SSTORE(slot_create_result, create_opcode(size=Op.CALLDATASIZE()))
95+
+ Op.MSTORE(64, int(Operation.SUICIDE))
96+
+ Op.CALL(
97+
gas=Op.SUB(Op.GAS, 300_000),
98+
address=Op.SLOAD(slot_create_result),
99+
args_offset=64,
100+
args_size=32,
101+
)
102+
+ Op.MSTORE(64, int(Operation.STORE_SOMETHING))
103+
+ Op.CALL(
104+
gas=Op.SUB(Op.GAS, 300_000),
105+
address=Op.SLOAD(slot_create_result),
106+
args_offset=64,
107+
args_size=32,
108+
)
109+
+ Op.MSTORE(64, int(Operation.GET_SOMETHING))
110+
+ Op.CALL(
111+
gas=Op.SUB(Op.GAS, 300_000),
112+
address=Op.SLOAD(0),
113+
args_offset=64,
114+
args_size=32,
115+
ret_offset=100,
116+
ret_size=32,
117+
)
118+
+ Op.SSTORE(slot_suicide_sstore_return, Op.MLOAD(100))
119+
+ Op.SSTORE(slot_program_success, 1)
120+
)
121+
122+
expected_create_address = compute_create_address(
123+
address=create_contract, nonce=1, initcode=suicide_initcode, opcode=create_opcode
124+
)
125+
expect_post[slot_create_result] = expected_create_address
126+
expect_post[slot_suicide_sstore_return] = (
127+
subcall_storage * 2 if tload_support else subcall_storage
128+
)
129+
expect_post[slot_program_success] = 1
130+
131+
tx = Transaction(
132+
gas_limit=2_000_000,
133+
to=create_contract,
134+
data=suicide_initcode,
135+
nonce=0,
136+
sender=sender,
137+
protected=fork >= Byzantium,
138+
)
139+
140+
post = {
141+
create_contract: Account(storage=expect_post),
142+
expected_create_address: Account.NONEXISTENT,
143+
}
144+
state_test(env=Environment(), pre=pre, post=post, tx=tx)

tests/static/state_tests/stCreateTest/CREATE_AcreateB_BSuicide_BStoreFiller.json

Lines changed: 0 additions & 102 deletions
This file was deleted.

0 commit comments

Comments
 (0)