From 2da3856e1f1ba5d88e3beb14688389efed873cbe Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 13 Sep 2024 20:01:37 +0200 Subject: [PATCH 1/5] new(tests): TSTORE: ensure transient storage is cleared after transactions --- .../test_tstorage_clear_after_tx.py | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py diff --git a/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py b/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py new file mode 100644 index 00000000000..cd07c4aae3c --- /dev/null +++ b/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py @@ -0,0 +1,96 @@ +""" +Ethereum Transient Storage EIP Tests +https://eips.ethereum.org/EIPS/eip-1153 +""" + +import pytest + +from ethereum_test_tools import ( + Account, + Alloc, + Block, + BlockchainTestFiller, + Environment, + Initcode, + Transaction, +) +from ethereum_test_tools.vm.opcode import Opcodes as Op + +from .spec import ref_spec_1153 + +REFERENCE_SPEC_GIT_PATH = ref_spec_1153.git_path +REFERENCE_SPEC_VERSION = ref_spec_1153.version + + +@pytest.mark.valid_from("Cancun") +def test_tstore_clear_after_deployment_tx( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +): + """ + This test first creates a contract, which TSTOREs a value 1 in slot 1. + After creating the contract, a new tx will call this contract, storing TLOAD(1) into slot 1. + The transient storage should be cleared after creating the contract (at tx-level), so + the storage should stay empty. + """ + env = Environment() + + init_code = Op.TSTORE(1, 1) + deploy_code = Op.SSTORE(1, Op.TLOAD(1)) + + code = Initcode(deploy_code=deploy_code, initcode_prefix=init_code) + + sender = pre.fund_eoa() + + deployment_tx = Transaction( + gas_limit=100000, + data=code, + to=None, + sender=sender, + ) + + address = deployment_tx.created_contract + + invoke_contract_tx = Transaction(gas_limit=100000, to=address, sender=sender) + + txs = [deployment_tx, invoke_contract_tx] + + post = { + address: Account(storage={0x01: 0x00}), + } + + blockchain_test(genesis_environment=env, pre=pre, post=post, blocks=[Block(txs=txs)]) + + +@pytest.mark.valid_from("Cancun") +def test_tstore_clear_after_tx( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +): + """ + This test first SSTOREs the TLOAD value of key 1 in slot 1. Then, it TSTOREs 1 in slot 1. + The second tx will re-call the contract. The storage should stay empty, + because the transient storage is cleared after the transaction. + """ + env = Environment() + + contract_code = Op.SSTORE(1, Op.TLOAD(1)) + Op.TSTORE(1, 1) + account = pre.deploy_contract(contract_code) + + sender = pre.fund_eoa() + + poke_tstore_tx = Transaction( + gas_limit=100000, + to=account, + sender=sender, + ) + + re_poke_tstore_tx = Transaction(gas_limit=100000, to=account, sender=sender) + + txs = [poke_tstore_tx, re_poke_tstore_tx] + + post = { + account: Account(storage={0x01: 0x00}), + } + + blockchain_test(genesis_environment=env, pre=pre, post=post, blocks=[Block(txs=txs)]) From 74473307065521b78a6954503392798a25cce72f Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Sun, 15 Sep 2024 21:07:37 +0200 Subject: [PATCH 2/5] address review --- .../test_tstorage_clear_after_tx.py | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py b/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py index cd07c4aae3c..7b0e0abf797 100644 --- a/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py +++ b/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py @@ -11,9 +11,11 @@ Block, BlockchainTestFiller, Environment, + EVMCodeType, Initcode, Transaction, ) +from ethereum_test_tools.eof.v1 import Container from ethereum_test_tools.vm.opcode import Opcodes as Op from .spec import ref_spec_1153 @@ -23,9 +25,11 @@ @pytest.mark.valid_from("Cancun") +@pytest.mark.with_all_evm_code_types def test_tstore_clear_after_deployment_tx( blockchain_test: BlockchainTestFiller, pre: Alloc, + evm_code_type: EVMCodeType, ): """ This test first creates a contract, which TSTOREs a value 1 in slot 1. @@ -38,6 +42,15 @@ def test_tstore_clear_after_deployment_tx( init_code = Op.TSTORE(1, 1) deploy_code = Op.SSTORE(1, Op.TLOAD(1)) + code = None + + if evm_code_type == EVMCodeType.EOF_V1: + code = Container.Init( + deploy_container=Container.Code(deploy_code), initcode_prefix=init_code + ) + else: + code = Initcode(deploy_code=deploy_code, initcode_prefix=init_code) + code = Initcode(deploy_code=deploy_code, initcode_prefix=init_code) sender = pre.fund_eoa() @@ -63,9 +76,11 @@ def test_tstore_clear_after_deployment_tx( @pytest.mark.valid_from("Cancun") +@pytest.mark.with_all_evm_code_types def test_tstore_clear_after_tx( blockchain_test: BlockchainTestFiller, pre: Alloc, + evm_code_type: EVMCodeType, ): """ This test first SSTOREs the TLOAD value of key 1 in slot 1. Then, it TSTOREs 1 in slot 1. @@ -74,8 +89,15 @@ def test_tstore_clear_after_tx( """ env = Environment() - contract_code = Op.SSTORE(1, Op.TLOAD(1)) + Op.TSTORE(1, 1) - account = pre.deploy_contract(contract_code) + runtime_code = Op.SSTORE(1, Op.TLOAD(1)) + Op.TSTORE(1, 1) + code = None + + if evm_code_type == EVMCodeType.EOF_V1: + code = Container.Code(runtime_code) + else: + code = runtime_code + + account = pre.deploy_contract(code) sender = pre.fund_eoa() From bf7b82a90dd5c89cdd2c7f22389327f6f1afadcf Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Tue, 17 Sep 2024 18:54:46 +0200 Subject: [PATCH 3/5] tests: ensure eof/legacy gets properly switched --- tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py b/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py index 7b0e0abf797..7c2f2c67744 100644 --- a/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py +++ b/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py @@ -51,8 +51,6 @@ def test_tstore_clear_after_deployment_tx( else: code = Initcode(deploy_code=deploy_code, initcode_prefix=init_code) - code = Initcode(deploy_code=deploy_code, initcode_prefix=init_code) - sender = pre.fund_eoa() deployment_tx = Transaction( From 986241049f0ce71cd5290bbb51e0129c32e29058 Mon Sep 17 00:00:00 2001 From: spencer-tb Date: Tue, 17 Sep 2024 13:18:27 -0400 Subject: [PATCH 4/5] chore: fix mypy tox errors --- .../cancun/eip1153_tstore/test_tstorage_clear_after_tx.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py b/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py index 7c2f2c67744..70b13fbbc43 100644 --- a/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py +++ b/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py @@ -3,6 +3,8 @@ https://eips.ethereum.org/EIPS/eip-1153 """ +from typing import Optional + import pytest from ethereum_test_tools import ( @@ -10,6 +12,7 @@ Alloc, Block, BlockchainTestFiller, + Bytecode, Environment, EVMCodeType, Initcode, @@ -42,8 +45,7 @@ def test_tstore_clear_after_deployment_tx( init_code = Op.TSTORE(1, 1) deploy_code = Op.SSTORE(1, Op.TLOAD(1)) - code = None - + code: Optional[Container | Initcode] = None if evm_code_type == EVMCodeType.EOF_V1: code = Container.Init( deploy_container=Container.Code(deploy_code), initcode_prefix=init_code @@ -88,8 +90,8 @@ def test_tstore_clear_after_tx( env = Environment() runtime_code = Op.SSTORE(1, Op.TLOAD(1)) + Op.TSTORE(1, 1) - code = None + code: Optional[Container | Bytecode] = None if evm_code_type == EVMCodeType.EOF_V1: code = Container.Code(runtime_code) else: From 48e070aa17b54a7eee53026edc720892389898e5 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Thu, 19 Sep 2024 00:11:11 +0200 Subject: [PATCH 5/5] address comment --- .../eip1153_tstore/test_tstorage_clear_after_tx.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py b/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py index 70b13fbbc43..1e8f16ad30f 100644 --- a/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py +++ b/tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py @@ -12,7 +12,6 @@ Alloc, Block, BlockchainTestFiller, - Bytecode, Environment, EVMCodeType, Initcode, @@ -80,7 +79,6 @@ def test_tstore_clear_after_deployment_tx( def test_tstore_clear_after_tx( blockchain_test: BlockchainTestFiller, pre: Alloc, - evm_code_type: EVMCodeType, ): """ This test first SSTOREs the TLOAD value of key 1 in slot 1. Then, it TSTOREs 1 in slot 1. @@ -89,14 +87,7 @@ def test_tstore_clear_after_tx( """ env = Environment() - runtime_code = Op.SSTORE(1, Op.TLOAD(1)) + Op.TSTORE(1, 1) - - code: Optional[Container | Bytecode] = None - if evm_code_type == EVMCodeType.EOF_V1: - code = Container.Code(runtime_code) - else: - code = runtime_code - + code = Op.SSTORE(1, Op.TLOAD(1)) + Op.TSTORE(1, 1) account = pre.deploy_contract(code) sender = pre.fund_eoa()