Skip to content

Commit 758baf3

Browse files
new(tests): TSTORE: ensure transient storage is cleared after transactions (#798)
* new(tests): TSTORE: ensure transient storage is cleared after transactions * address review * tests: ensure eof/legacy gets properly switched * chore: fix mypy tox errors * address comment --------- Co-authored-by: spencer-tb <[email protected]>
1 parent ead3a92 commit 758baf3

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
"""
2+
Ethereum Transient Storage EIP Tests
3+
https://eips.ethereum.org/EIPS/eip-1153
4+
"""
5+
6+
from typing import Optional
7+
8+
import pytest
9+
10+
from ethereum_test_tools import (
11+
Account,
12+
Alloc,
13+
Block,
14+
BlockchainTestFiller,
15+
Environment,
16+
EVMCodeType,
17+
Initcode,
18+
Transaction,
19+
)
20+
from ethereum_test_tools.eof.v1 import Container
21+
from ethereum_test_tools.vm.opcode import Opcodes as Op
22+
23+
from .spec import ref_spec_1153
24+
25+
REFERENCE_SPEC_GIT_PATH = ref_spec_1153.git_path
26+
REFERENCE_SPEC_VERSION = ref_spec_1153.version
27+
28+
29+
@pytest.mark.valid_from("Cancun")
30+
@pytest.mark.with_all_evm_code_types
31+
def test_tstore_clear_after_deployment_tx(
32+
blockchain_test: BlockchainTestFiller,
33+
pre: Alloc,
34+
evm_code_type: EVMCodeType,
35+
):
36+
"""
37+
This test first creates a contract, which TSTOREs a value 1 in slot 1.
38+
After creating the contract, a new tx will call this contract, storing TLOAD(1) into slot 1.
39+
The transient storage should be cleared after creating the contract (at tx-level), so
40+
the storage should stay empty.
41+
"""
42+
env = Environment()
43+
44+
init_code = Op.TSTORE(1, 1)
45+
deploy_code = Op.SSTORE(1, Op.TLOAD(1))
46+
47+
code: Optional[Container | Initcode] = None
48+
if evm_code_type == EVMCodeType.EOF_V1:
49+
code = Container.Init(
50+
deploy_container=Container.Code(deploy_code), initcode_prefix=init_code
51+
)
52+
else:
53+
code = Initcode(deploy_code=deploy_code, initcode_prefix=init_code)
54+
55+
sender = pre.fund_eoa()
56+
57+
deployment_tx = Transaction(
58+
gas_limit=100000,
59+
data=code,
60+
to=None,
61+
sender=sender,
62+
)
63+
64+
address = deployment_tx.created_contract
65+
66+
invoke_contract_tx = Transaction(gas_limit=100000, to=address, sender=sender)
67+
68+
txs = [deployment_tx, invoke_contract_tx]
69+
70+
post = {
71+
address: Account(storage={0x01: 0x00}),
72+
}
73+
74+
blockchain_test(genesis_environment=env, pre=pre, post=post, blocks=[Block(txs=txs)])
75+
76+
77+
@pytest.mark.valid_from("Cancun")
78+
@pytest.mark.with_all_evm_code_types
79+
def test_tstore_clear_after_tx(
80+
blockchain_test: BlockchainTestFiller,
81+
pre: Alloc,
82+
):
83+
"""
84+
This test first SSTOREs the TLOAD value of key 1 in slot 1. Then, it TSTOREs 1 in slot 1.
85+
The second tx will re-call the contract. The storage should stay empty,
86+
because the transient storage is cleared after the transaction.
87+
"""
88+
env = Environment()
89+
90+
code = Op.SSTORE(1, Op.TLOAD(1)) + Op.TSTORE(1, 1)
91+
account = pre.deploy_contract(code)
92+
93+
sender = pre.fund_eoa()
94+
95+
poke_tstore_tx = Transaction(
96+
gas_limit=100000,
97+
to=account,
98+
sender=sender,
99+
)
100+
101+
re_poke_tstore_tx = Transaction(gas_limit=100000, to=account, sender=sender)
102+
103+
txs = [poke_tstore_tx, re_poke_tstore_tx]
104+
105+
post = {
106+
account: Account(storage={0x01: 0x00}),
107+
}
108+
109+
blockchain_test(genesis_environment=env, pre=pre, post=post, blocks=[Block(txs=txs)])

0 commit comments

Comments
 (0)